From dbf1d9f33275c06c1d9dbe067fc42e79b681b087 Mon Sep 17 00:00:00 2001 From: Astra <93453568+Astrrra@users.noreply.github.com> Date: Tue, 12 Jul 2022 22:38:40 +0300 Subject: [PATCH 01/37] Add a FORCE=1 checker for flash (#1386) --- SConstruct | 2 ++ 1 file changed, 2 insertions(+) diff --git a/SConstruct b/SConstruct index 33463cdc..9c17a82a 100644 --- a/SConstruct +++ b/SConstruct @@ -145,6 +145,8 @@ distenv.Alias("copro_dist", copro_dist) firmware_flash = distenv.AddOpenOCDFlashTarget(firmware_env) distenv.Alias("flash", firmware_flash) +if distenv["FORCE"]: + distenv.AlwaysBuild(firmware_flash) firmware_bm_flash = distenv.PhonyTarget( "flash_blackmagic", From fd498bdfcfad7806c37674622e32244d659a16ea Mon Sep 17 00:00:00 2001 From: Max Andreev Date: Thu, 14 Jul 2022 19:24:26 +0300 Subject: [PATCH 02/37] [FL-2554] Embedded arm-none-eabi toolchain (#1351) --- .gitattributes | 3 + .gitignore | 5 +- SConstruct | 4 +- applications/about/about.c | 2 +- applications/extapps.scons | 1 - fbt | 30 ++-- fbt.cmd | 16 ++- fbt_options.py | 8 +- firmware.scons | 2 +- scripts/toolchain/fbtenv.cmd | 45 ++++++ scripts/toolchain/fbtenv.sh | 54 +++++++ scripts/toolchain/unix-toolchain-download.sh | 135 ++++++++++++++++++ .../toolchain/windows-toolchain-download.ps1 | 34 +++++ site_scons/fbt/appmanifest.py | 9 +- site_scons/fbt/util.py | 3 +- site_scons/site_tools/crosscc.py | 3 +- site_scons/site_tools/fbt_apps.py | 13 +- 17 files changed, 332 insertions(+), 35 deletions(-) create mode 100644 scripts/toolchain/fbtenv.cmd create mode 100755 scripts/toolchain/fbtenv.sh create mode 100755 scripts/toolchain/unix-toolchain-download.sh create mode 100644 scripts/toolchain/windows-toolchain-download.ps1 diff --git a/.gitattributes b/.gitattributes index 6313b56c..bd82ecaa 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1 +1,4 @@ * text=auto eol=lf +*.bat eol=crlf +*.ps1 eol=crlf +*.cmd eol=crlf diff --git a/.gitignore b/.gitignore index 2d66413b..21f39174 100644 --- a/.gitignore +++ b/.gitignore @@ -46,4 +46,7 @@ dist build/ # Toolchain -toolchain*/ \ No newline at end of file +/toolchain + +# openocd output file +openocd.log diff --git a/SConstruct b/SConstruct index 9c17a82a..7cdf88fc 100644 --- a/SConstruct +++ b/SConstruct @@ -8,6 +8,8 @@ import os +EnsurePythonVersion(3, 8) + DefaultEnvironment(tools=[]) # Progress(["OwO\r", "owo\r", "uwu\r", "owo\r"], interval=15) @@ -32,7 +34,7 @@ coreenv["ROOT_DIR"] = Dir(".") # Create a separate "dist" environment and add construction envs to it distenv = coreenv.Clone( tools=["fbt_dist", "openocd", "blackmagic"], - OPENOCD_GDB_PIPE=["|openocd -c 'gdb_port pipe' ${[SINGLEQUOTEFUNC(OPENOCD_OPTS)]}"], + OPENOCD_GDB_PIPE=["|openocd -c 'gdb_port pipe; log_output debug/openocd.log' ${[SINGLEQUOTEFUNC(OPENOCD_OPTS)]}"], GDBOPTS_BASE=[ "-ex", "target extended-remote ${GDBREMOTE}", diff --git a/applications/about/about.c b/applications/about/about.c index 6f8ebdf3..4d12ed02 100644 --- a/applications/about/about.c +++ b/applications/about/about.c @@ -206,4 +206,4 @@ int32_t about_settings_app(void* p) { furi_record_close("gui"); return 0; -} +} \ No newline at end of file diff --git a/applications/extapps.scons b/applications/extapps.scons index 7b1cae7d..a53620b9 100644 --- a/applications/extapps.scons +++ b/applications/extapps.scons @@ -3,7 +3,6 @@ Import("ENV") from fbt.appmanifest import FlipperAppType - appenv = ENV.Clone(tools=["fbt_extapps"]) appenv.Replace( diff --git a/fbt b/fbt index b3d2ca35..0ea572b1 100755 --- a/fbt +++ b/fbt @@ -1,18 +1,22 @@ -#!/bin/bash +#!/bin/sh -set -e +# shellcheck disable=SC2086 source=/dev/null +# unofficial strict mode +set -eu; -SCRIPTDIR="$( dirname -- "$0"; )"; -SCONS_EP=${SCRIPTDIR}/lib/scons/scripts/scons.py +SCONS_DEFAULT_FLAGS="-Q --warn=target-not-built"; +SCRIPT_PATH="$(cd "$(dirname "$0")" && pwd -P)"; -if [[ -z "${FBT_NO_SYNC:-}" ]] ; then - if [[ -d .git ]]; then - git submodule update --init - else - echo Not in a git repo, please clone with git clone --recursive - exit 1 - fi +if [ -z "${FBT_NOENV:-}" ]; then + . "$SCRIPT_PATH/scripts/toolchain/fbtenv.sh"; fi -SCONS_DEFAULT_FLAGS="-Q --warn=target-not-built" -python3 ${SCONS_EP} ${SCONS_DEFAULT_FLAGS} "$@" +if [ -z "${FBT_NO_SYNC:-}" ]; then + if [ ! -d "$SCRIPT_PATH/.git" ]; then + echo "\".git\" directory not found, please clone repo via \"git clone --recursive\""; + exit 1; + fi + git submodule update --init; +fi + +python3 "$SCRIPT_PATH/lib/scons/scripts/scons.py" $SCONS_DEFAULT_FLAGS "$@" \ No newline at end of file diff --git a/fbt.cmd b/fbt.cmd index 5edecd21..2339eaaa 100644 --- a/fbt.cmd +++ b/fbt.cmd @@ -1,15 +1,17 @@ @echo off +call %~dp0scripts\toolchain\fbtenv.cmd env set SCONS_EP=%~dp0\lib\scons\scripts\scons.py if [%FBT_NO_SYNC%] == [] ( - if exist ".git" ( - git submodule update --init - ) else ( - echo Not in a git repo, please clone with git clone --recursive - exit /b 1 - ) + if exist ".git" ( + git submodule update --init + ) else ( + echo Not in a git repo, please clone with git clone --recursive + exit /b 1 + ) ) +git submodule update --init set "SCONS_DEFAULT_FLAGS=-Q --warn=target-not-built" -python %SCONS_EP% %SCONS_DEFAULT_FLAGS% %* +python lib\scons\scripts\scons.py %SCONS_DEFAULT_FLAGS% %* \ No newline at end of file diff --git a/fbt_options.py b/fbt_options.py index 1c9f9c82..fb06cecd 100644 --- a/fbt_options.py +++ b/fbt_options.py @@ -10,8 +10,8 @@ COMPACT = 0 ## Optimize for debugging experience DEBUG = 1 -# Suffix to add to files when building distribution. -# If OS environment has DIST_SUFFIX set, it will be used instead.. +# Suffix to add to files when building distribution +# If OS environment has DIST_SUFFIX set, it will be used instead DIST_SUFFIX = "local" # Coprocessor firmware @@ -27,7 +27,7 @@ COPRO_STACK_BIN = "stm32wb5x_BLE_Stack_light_fw.bin" # Firmware also supports "ble_full", but it might not fit into debug builds COPRO_STACK_TYPE = "ble_light" -# Leave 0 to lets scripts automatically calculate it +# Leave 0 to let scripts automatically calculate it COPRO_STACK_ADDR = "0x0" # If you override COPRO_CUBE_DIR on commandline, override this aswell @@ -56,7 +56,7 @@ OPENOCD_OPTS = [ SVD_FILE = "debug/STM32WB55_CM4.svd" -# Look for blackmagic probe on serial ports +# Look for blackmagic probe on serial ports and local network BLACKMAGIC = "auto" FIRMWARE_APPS = { diff --git a/firmware.scons b/firmware.scons index 7cc67f43..2ad29c21 100644 --- a/firmware.scons +++ b/firmware.scons @@ -201,7 +201,7 @@ fwelf = fwenv["FW_ELF"] = fwenv.Program( ], ) - +# Make it depend on everything child builders returned # Firmware depends on everything child builders returned Depends(fwelf, lib_targets) # Output extra details after building firmware diff --git a/scripts/toolchain/fbtenv.cmd b/scripts/toolchain/fbtenv.cmd new file mode 100644 index 00000000..34adb12c --- /dev/null +++ b/scripts/toolchain/fbtenv.cmd @@ -0,0 +1,45 @@ +@echo off + +if not [%FBT_ROOT%] == [] ( + goto already_set +) + +set "FBT_ROOT=%~dp0\..\..\" +pushd %FBT_ROOT% +set "FBT_ROOT=%cd%" +popd + +if not [%FBT_NOENV%] == [] ( + exit /b 0 +) + +set "FLIPPER_TOOLCHAIN_VERSION=3" +set "FBT_TOOLCHAIN_ROOT=%FBT_ROOT%\toolchain\i686-windows" + + +if not exist "%FBT_TOOLCHAIN_ROOT%" ( + powershell -ExecutionPolicy Bypass -File %FBT_ROOT%\scripts\toolchain\windows-toolchain-download.ps1 "%flipper_toolchain_version%" +) +if not exist "%FBT_TOOLCHAIN_ROOT%\VERSION" ( + powershell -ExecutionPolicy Bypass -File %FBT_ROOT%\scripts\toolchain\windows-toolchain-download.ps1 "%flipper_toolchain_version%" +) +set /p REAL_TOOLCHAIN_VERSION=<%FBT_TOOLCHAIN_ROOT%\VERSION +if not "%REAL_TOOLCHAIN_VERSION%" == "%FLIPPER_TOOLCHAIN_VERSION%" ( + powershell -ExecutionPolicy Bypass -File %FBT_ROOT%\scripts\toolchain\windows-toolchain-download.ps1 "%flipper_toolchain_version%" +) + + +set "HOME=%USERPROFILE%" +set "PYTHONHOME=%FBT_TOOLCHAIN_ROOT%\python" +set "PATH=%FBT_TOOLCHAIN_ROOT%\python;%FBT_TOOLCHAIN_ROOT%\bin;%FBT_TOOLCHAIN_ROOT%\protoc\bin;%FBT_TOOLCHAIN_ROOT%\openocd\bin;%PATH%" +set "PROMPT=(fbt) %PROMPT%" + +:already_set + +if not "%1" == "env" ( + echo ********************************* + echo * fbt build environment * + echo ********************************* + cd %FBT_ROOT% + cmd /k +) diff --git a/scripts/toolchain/fbtenv.sh b/scripts/toolchain/fbtenv.sh new file mode 100755 index 00000000..df2b2457 --- /dev/null +++ b/scripts/toolchain/fbtenv.sh @@ -0,0 +1,54 @@ +#!/bin/sh + +# unofficial strict mode +set -eu; + +FLIPPER_TOOLCHAIN_VERSION="3"; + +get_kernel_type() +{ + SYS_TYPE="$(uname -s)" + if [ "$SYS_TYPE" = "Darwin" ]; then + TOOLCHAIN_PATH="toolchain/x86_64-darwin"; + elif [ "$SYS_TYPE" = "Linux" ]; then + TOOLCHAIN_PATH="toolchain/x86_64-linux"; + elif echo "$SYS_TYPE" | grep -q "MINGW"; then + echo "In MinGW shell use \"fbt.cmd\" instead of \"fbt\""; + exit 1; + else + echo "Your system is not supported. Sorry. Please report us your configuration."; + exit 1; + fi +} + +check_download_toolchain() +{ + if [ ! -d "$SCRIPT_PATH/$TOOLCHAIN_PATH" ]; then + download_toolchain; + elif [ ! -f "$SCRIPT_PATH/$TOOLCHAIN_PATH/VERSION" ]; then + download_toolchain; + elif [ "$(cat "$SCRIPT_PATH/$TOOLCHAIN_PATH/VERSION")" -ne "$FLIPPER_TOOLCHAIN_VERSION" ]; then + download_toolchain; + fi +} + +download_toolchain() +{ + chmod 755 "$SCRIPT_PATH/scripts/toolchain/unix-toolchain-download.sh"; + "$SCRIPT_PATH/scripts/toolchain/unix-toolchain-download.sh" "$FLIPPER_TOOLCHAIN_VERSION" || exit 1; +} + +main() +{ + if [ -z "${SCRIPT_PATH:-}" ]; then + echo "Mannual running this script is now allowed."; + exit 1; + fi + get_kernel_type; # sets TOOLCHAIN_PATH + check_download_toolchain; + PATH="$SCRIPT_PATH/$TOOLCHAIN_PATH/python/bin:$PATH"; + PATH="$SCRIPT_PATH/$TOOLCHAIN_PATH/bin:$PATH"; + PATH="$SCRIPT_PATH/$TOOLCHAIN_PATH/protobuf/bin:$PATH"; + PATH="$SCRIPT_PATH/$TOOLCHAIN_PATH/openocd/bin:$PATH"; +} +main; diff --git a/scripts/toolchain/unix-toolchain-download.sh b/scripts/toolchain/unix-toolchain-download.sh new file mode 100755 index 00000000..386be2a3 --- /dev/null +++ b/scripts/toolchain/unix-toolchain-download.sh @@ -0,0 +1,135 @@ +#!/bin/sh +# shellcheck disable=SC2086,SC2034 + +# unofficial strict mode +set -eu; + +check_system() +{ + VER="$1"; # toolchain version + printf "Checking kernel type.."; + SYS_TYPE="$(uname -s)" + if [ "$SYS_TYPE" = "Darwin" ]; then + echo "darwin"; + TOOLCHAIN_URL="https://update.flipperzero.one/builds/toolchain/gcc-arm-none-eabi-10.3-x86_64-darwin-flipper-$VER.tar.gz"; + TOOLCHAIN_PATH="toolchain/x86_64-darwin"; + elif [ "$SYS_TYPE" = "Linux" ]; then + echo "linux"; + TOOLCHAIN_URL="https://update.flipperzero.one/builds/toolchain/gcc-arm-none-eabi-10.3-x86_64-linux-flipper-$VER.tar.gz"; + TOOLCHAIN_PATH="toolchain/x86_64-linux"; + else + echo "unsupported."; + echo "Your system is unsupported.. sorry.."; + exit 1; + fi +} + +check_tar() +{ + printf "Checking tar.."; + if ! tar --version > /dev/null 2>&1; then + echo "no"; + exit 1; + fi + echo "yes"; +} + + +curl_wget_check() +{ + printf "Checking curl.."; + if ! curl --version > /dev/null 2>&1; then + echo "no"; + printf "Checking wget.."; + if ! wget --version > /dev/null 2>&1; then + echo "no"; + echo "No curl or wget found in your PATH."; + echo "Please provide it or download this file:"; + echo; + echo "$TOOLCHAIN_URL"; + echo; + echo "And place in repo root dir mannualy."; + exit 1; + fi + echo "yes" + DOWNLOADER="wget"; + DOWNLOADER_ARGS="--show-progress --progress=bar:force -qO"; + return; + fi + echo "yes" + DOWNLOADER="curl"; + DOWNLOADER_ARGS="--progress-bar -SLo"; +} + +check_downloaded_toolchain() +{ + printf "Checking downloaded toolchain tgz.."; + if [ -f "$REPO_ROOT/$TOOLCHAIN_TAR" ]; then + echo "yes"; + return 0; + fi + echo "no"; + return 1; +} + +download_toolchain() +{ + echo "Downloading toolchain:"; + "$DOWNLOADER" $DOWNLOADER_ARGS "$REPO_ROOT/$TOOLCHAIN_TAR" "$TOOLCHAIN_URL"; + echo "done"; +} + +remove_old_tooclhain() +{ + printf "Removing old toolchain (if exist).."; + rm -rf "${REPO_ROOT:?}/$TOOLCHAIN_PATH"; + echo "done"; +} + +show_unpack_percentage() +{ + LINE=0; + while read -r line; do + LINE=$(( LINE + 1 )); + if [ $(( LINE % 300 )) -eq 0 ]; then + printf "#"; + fi + done + echo " 100.0%"; +} + +unpack_toolchain() +{ + echo "Unpacking toolchain:"; + tar -xvf "$REPO_ROOT/$TOOLCHAIN_TAR" -C "$REPO_ROOT/" 2>&1 | show_unpack_percentage; + mkdir -p "$REPO_ROOT/toolchain"; + mv "$REPO_ROOT/$TOOLCHAIN_DIR" "$REPO_ROOT/$TOOLCHAIN_PATH/"; + echo "done"; +} + +clearing() +{ + printf "Clearing.."; + rm -rf "${REPO_ROOT:?}/$TOOLCHAIN_TAR"; + echo "done"; +} + +main() +{ + SCRIPT_PATH="$(cd "$(dirname "$0")" && pwd -P)" + REPO_ROOT="$(cd "$SCRIPT_PATH/../../" && pwd)"; + check_system "$1"; # recives TOOLCHAIN_VERSION, defines TOOLCHAIN_URL and TOOLCHAIN_PATH + check_tar; + TOOLCHAIN_TAR="$(basename "$TOOLCHAIN_URL")"; + TOOLCHAIN_DIR="$(echo "$TOOLCHAIN_TAR" | sed "s/-$VER.tar.gz//g")"; + if ! check_downloaded_toolchain; then + curl_wget_check; + download_toolchain; + fi + remove_old_tooclhain; + unpack_toolchain; +} + +trap clearing EXIT; +trap clearing 2; # SIGINT not coverable by EXIT +main "$1"; # toochain version diff --git a/scripts/toolchain/windows-toolchain-download.ps1 b/scripts/toolchain/windows-toolchain-download.ps1 new file mode 100644 index 00000000..bcb8f998 --- /dev/null +++ b/scripts/toolchain/windows-toolchain-download.ps1 @@ -0,0 +1,34 @@ +Set-StrictMode -Version 2.0 +$ErrorActionPreference = "Stop" +[Net.ServicePointManager]::SecurityProtocol = "tls12, tls11, tls" +$repo_root = (Get-Item "$PSScriptRoot\..\..").FullName +$toolchain_version = $args[0] +$toolchain_url = "https://update.flipperzero.one/builds/toolchain/gcc-arm-none-eabi-10.3-i686-windows-flipper-$toolchain_version.zip" +$toolchain_zip = "gcc-arm-none-eabi-10.3-i686-windows-flipper-$toolchain_version.zip" +$toolchain_dir = "gcc-arm-none-eabi-10.3-i686-windows-flipper" + +if (Test-Path -LiteralPath "$repo_root\toolchain\i686-windows") { + Write-Host -NoNewline "Removing old Windows toolchain.." + Remove-Item -LiteralPath "$repo_root\toolchain\i686-windows" -Force -Recurse + Write-Host "done!" +} +if (!(Test-Path -Path "$repo_root\$toolchain_zip" -PathType Leaf)) { + Write-Host -NoNewline "Downloading Windows toolchain.." + $wc = New-Object net.webclient + $wc.Downloadfile("$toolchain_url", "$repo_root\$toolchain_zip") + Write-Host "done!" +} + +if (!(Test-Path -LiteralPath "$repo_root\toolchain")) { + New-Item "$repo_root\toolchain" -ItemType Directory +} + +Write-Host -NoNewline "Unziping Windows toolchain.." +Add-Type -Assembly "System.IO.Compression.Filesystem" +[System.IO.Compression.ZipFile]::ExtractToDirectory("$toolchain_zip", "$repo_root\") +Move-Item -Path "$repo_root\$toolchain_dir" -Destination "$repo_root\toolchain\i686-windows" +Write-Host "done!" + +Write-Host -NoNewline "Clearing temporary files.." +Remove-Item -LiteralPath "$repo_root\$toolchain_zip" -Force +Write-Host "done!" diff --git a/site_scons/fbt/appmanifest.py b/site_scons/fbt/appmanifest.py index 218b139f..990bd5b3 100644 --- a/site_scons/fbt/appmanifest.py +++ b/site_scons/fbt/appmanifest.py @@ -63,8 +63,13 @@ class AppManager: nonlocal app_manifests app_manifests.append(FlipperApplication(*args, **kw, _appdir=app_dir_name)) - with open(app_manifest_path, "rt") as manifest_file: - exec(manifest_file.read()) + try: + with open(app_manifest_path, "rt") as manifest_file: + exec(manifest_file.read()) + except Exception as e: + raise FlipperManifestException( + f"Failed parsing manifest '{app_manifest_path}' : {e}" + ) if len(app_manifests) == 0: raise FlipperManifestException( diff --git a/site_scons/fbt/util.py b/site_scons/fbt/util.py index a6bc4c06..8d8af518 100644 --- a/site_scons/fbt/util.py +++ b/site_scons/fbt/util.py @@ -1,5 +1,6 @@ import SCons from SCons.Subst import quote_spaces +from SCons.Errors import StopError import re import os @@ -30,7 +31,7 @@ def link_dir(target_path, source_path, is_windows): import _winapi if not os.path.isdir(source_path): - raise Exception(f"Source directory {source_path} is not a directory") + raise StopError(f"Source directory {source_path} is not a directory") if not os.path.exists(target_path): _winapi.CreateJunction(source_path, target_path) diff --git a/site_scons/site_tools/crosscc.py b/site_scons/site_tools/crosscc.py index 8d6b4a61..dbedf5c0 100644 --- a/site_scons/site_tools/crosscc.py +++ b/site_scons/site_tools/crosscc.py @@ -1,3 +1,4 @@ +from SCons.Errors import StopError from SCons.Tool import asm from SCons.Tool import gcc from SCons.Tool import gxx @@ -65,7 +66,7 @@ def generate(env, **kw): # print("CC version =", cc_version) # print(list(filter(lambda v: v in cc_version, whitelisted_versions))) if not any(filter(lambda v: v in cc_version, whitelisted_versions)): - raise Exception( + raise StopError( f"Toolchain version is not supported. Allowed: {whitelisted_versions}, toolchain: {cc_version} " ) diff --git a/site_scons/site_tools/fbt_apps.py b/site_scons/site_tools/fbt_apps.py index bdccccf7..1c2e0167 100644 --- a/site_scons/site_tools/fbt_apps.py +++ b/site_scons/site_tools/fbt_apps.py @@ -1,8 +1,14 @@ from SCons.Builder import Builder from SCons.Action import Action +from SCons.Errors import UserError import SCons -from fbt.appmanifest import FlipperAppType, AppManager, ApplicationsCGenerator +from fbt.appmanifest import ( + FlipperAppType, + AppManager, + ApplicationsCGenerator, + FlipperManifestException, +) # Adding objects for application management to env # AppManager env["APPMGR"] - loads all manifests; manages list of known apps @@ -13,7 +19,10 @@ def LoadApplicationManifests(env): appmgr = env["APPMGR"] = AppManager() for entry in env.Glob("#/applications/*"): if isinstance(entry, SCons.Node.FS.Dir) and not str(entry).startswith("."): - appmgr.load_manifest(entry.File("application.fam").abspath, entry.name) + try: + appmgr.load_manifest(entry.File("application.fam").abspath, entry.name) + except FlipperManifestException as e: + raise UserError(e) def PrepareApplicationsBuild(env): From 2caa5c3064b88d529a8c2e011c79f27799a9b1f2 Mon Sep 17 00:00:00 2001 From: Nikolay Minaylov Date: Thu, 14 Jul 2022 19:44:34 +0300 Subject: [PATCH 03/37] [FL-2633] Move files from /int to /ext on SD mount #1384 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: あく --- applications/storage/storage.h | 8 + applications/storage/storage_external_api.c | 128 +++++++++++++ .../storage_move_to_sd/application.fam | 19 ++ .../scenes/storage_move_to_sd_scene.c | 30 +++ .../scenes/storage_move_to_sd_scene.h | 29 +++ .../scenes/storage_move_to_sd_scene_config.h | 2 + .../scenes/storage_move_to_sd_scene_confirm.c | 70 +++++++ .../storage_move_to_sd_scene_progress.c | 32 ++++ .../storage_move_to_sd/storage_move_to_sd.c | 177 ++++++++++++++++++ .../storage_move_to_sd/storage_move_to_sd.h | 49 +++++ fbt_options.py | 1 + 11 files changed, 545 insertions(+) create mode 100644 applications/storage_move_to_sd/application.fam create mode 100644 applications/storage_move_to_sd/scenes/storage_move_to_sd_scene.c create mode 100644 applications/storage_move_to_sd/scenes/storage_move_to_sd_scene.h create mode 100644 applications/storage_move_to_sd/scenes/storage_move_to_sd_scene_config.h create mode 100644 applications/storage_move_to_sd/scenes/storage_move_to_sd_scene_confirm.c create mode 100644 applications/storage_move_to_sd/scenes/storage_move_to_sd_scene_progress.c create mode 100644 applications/storage_move_to_sd/storage_move_to_sd.c create mode 100644 applications/storage_move_to_sd/storage_move_to_sd.h diff --git a/applications/storage/storage.h b/applications/storage/storage.h index 1e6ced23..dcb8deee 100644 --- a/applications/storage/storage.h +++ b/applications/storage/storage.h @@ -190,6 +190,14 @@ FS_Error storage_common_rename(Storage* storage, const char* old_path, const cha */ FS_Error storage_common_copy(Storage* storage, const char* old_path, const char* new_path); +/** Copy one folder contents into another with rename of all conflicting files + * @param app pointer to the api + * @param old_path old path + * @param new_path new path + * @return FS_Error operation result + */ +FS_Error storage_common_merge(Storage* storage, const char* old_path, const char* new_path); + /** Creates a directory * @param app pointer to the api * @param path directory path diff --git a/applications/storage/storage_external_api.c b/applications/storage/storage_external_api.c index 77bb6550..dc29faa6 100644 --- a/applications/storage/storage_external_api.c +++ b/applications/storage/storage_external_api.c @@ -1,3 +1,4 @@ +#include "furi/log.h" #include #include #include "storage.h" @@ -5,8 +6,10 @@ #include "storage_message.h" #include #include +#include "toolbox/path.h" #define MAX_NAME_LENGTH 256 +#define MAX_EXT_LEN 16 #define TAG "StorageAPI" @@ -436,6 +439,131 @@ FS_Error storage_common_copy(Storage* storage, const char* old_path, const char* return error; } +static FS_Error + storage_merge_recursive(Storage* storage, const char* old_path, const char* new_path) { + FS_Error error = storage_common_mkdir(storage, new_path); + DirWalk* dir_walk = dir_walk_alloc(storage); + string_t path; + string_t tmp_new_path; + string_t tmp_old_path; + FileInfo fileinfo; + string_init(path); + string_init(tmp_new_path); + string_init(tmp_old_path); + + do { + if((error != FSE_OK) && (error != FSE_EXIST)) break; + + if(!dir_walk_open(dir_walk, old_path)) { + error = dir_walk_get_error(dir_walk); + break; + } + + while(1) { + DirWalkResult res = dir_walk_read(dir_walk, path, &fileinfo); + + if(res == DirWalkError) { + error = dir_walk_get_error(dir_walk); + break; + } else if(res == DirWalkLast) { + break; + } else { + string_set(tmp_old_path, path); + string_right(path, strlen(old_path)); + string_printf(tmp_new_path, "%s%s", new_path, string_get_cstr(path)); + + if(fileinfo.flags & FSF_DIRECTORY) { + if(storage_common_stat(storage, string_get_cstr(tmp_new_path), &fileinfo) == + FSE_OK) { + if(fileinfo.flags & FSF_DIRECTORY) { + error = storage_common_mkdir(storage, string_get_cstr(tmp_new_path)); + } + } + } else { + error = storage_common_merge( + storage, string_get_cstr(tmp_old_path), string_get_cstr(tmp_new_path)); + } + + if(error != FSE_OK) break; + } + } + + } while(false); + + string_clear(tmp_new_path); + string_clear(tmp_old_path); + string_clear(path); + dir_walk_free(dir_walk); + return error; +} + +FS_Error storage_common_merge(Storage* storage, const char* old_path, const char* new_path) { + FS_Error error; + const char* new_path_tmp; + string_t new_path_next; + string_init(new_path_next); + + FileInfo fileinfo; + error = storage_common_stat(storage, old_path, &fileinfo); + + if(error == FSE_OK) { + if(fileinfo.flags & FSF_DIRECTORY) { + error = storage_merge_recursive(storage, old_path, new_path); + } else { + error = storage_common_stat(storage, new_path, &fileinfo); + if(error == FSE_OK) { + string_set_str(new_path_next, new_path); + string_t dir_path; + string_t filename; + char extension[MAX_EXT_LEN]; + + string_init(dir_path); + string_init(filename); + + path_extract_filename(new_path_next, filename, true); + path_extract_dirname(new_path, dir_path); + path_extract_extension(new_path_next, extension, MAX_EXT_LEN); + + storage_get_next_filename( + storage, + string_get_cstr(dir_path), + string_get_cstr(filename), + extension, + new_path_next, + 255); + string_cat_printf(dir_path, "/%s%s", string_get_cstr(new_path_next), extension); + string_set(new_path_next, dir_path); + + string_clear(dir_path); + string_clear(filename); + new_path_tmp = string_get_cstr(new_path_next); + } else { + new_path_tmp = new_path; + } + Stream* stream_from = file_stream_alloc(storage); + Stream* stream_to = file_stream_alloc(storage); + + do { + if(!file_stream_open(stream_from, old_path, FSAM_READ, FSOM_OPEN_EXISTING)) break; + if(!file_stream_open(stream_to, new_path_tmp, FSAM_WRITE, FSOM_CREATE_NEW)) break; + stream_copy_full(stream_from, stream_to); + } while(false); + + error = file_stream_get_error(stream_from); + if(error == FSE_OK) { + error = file_stream_get_error(stream_to); + } + + stream_free(stream_from); + stream_free(stream_to); + } + } + + string_clear(new_path_next); + + return error; +} + FS_Error storage_common_mkdir(Storage* storage, const char* path) { S_API_PROLOGUE; S_API_DATA_PATH; diff --git a/applications/storage_move_to_sd/application.fam b/applications/storage_move_to_sd/application.fam new file mode 100644 index 00000000..60a6d987 --- /dev/null +++ b/applications/storage_move_to_sd/application.fam @@ -0,0 +1,19 @@ +App( + appid="storage_move_to_sd", + name="StorageMoveToSd", + apptype=FlipperAppType.SYSTEM, + entry_point="storage_move_to_sd_app", + requires=["gui","storage"], + provides=["storage_move_to_sd_start"], + stack_size=2 * 1024, + order=30, +) + +App( + appid="storage_move_to_sd_start", + apptype=FlipperAppType.STARTUP, + entry_point="storage_move_to_sd_start", + requires=["storage"], + order=120, +) + diff --git a/applications/storage_move_to_sd/scenes/storage_move_to_sd_scene.c b/applications/storage_move_to_sd/scenes/storage_move_to_sd_scene.c new file mode 100644 index 00000000..011bf47d --- /dev/null +++ b/applications/storage_move_to_sd/scenes/storage_move_to_sd_scene.c @@ -0,0 +1,30 @@ +#include "storage_move_to_sd_scene.h" + +// Generate scene on_enter handlers array +#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_enter, +void (*const storage_move_to_sd_on_enter_handlers[])(void*) = { +#include "storage_move_to_sd_scene_config.h" +}; +#undef ADD_SCENE + +// Generate scene on_event handlers array +#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_event, +bool (*const storage_move_to_sd_on_event_handlers[])(void* context, SceneManagerEvent event) = { +#include "storage_move_to_sd_scene_config.h" +}; +#undef ADD_SCENE + +// Generate scene on_exit handlers array +#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_exit, +void (*const storage_move_to_sd_on_exit_handlers[])(void* context) = { +#include "storage_move_to_sd_scene_config.h" +}; +#undef ADD_SCENE + +// Initialize scene handlers configuration structure +const SceneManagerHandlers storage_move_to_sd_scene_handlers = { + .on_enter_handlers = storage_move_to_sd_on_enter_handlers, + .on_event_handlers = storage_move_to_sd_on_event_handlers, + .on_exit_handlers = storage_move_to_sd_on_exit_handlers, + .scene_num = StorageMoveToSdSceneNum, +}; diff --git a/applications/storage_move_to_sd/scenes/storage_move_to_sd_scene.h b/applications/storage_move_to_sd/scenes/storage_move_to_sd_scene.h new file mode 100644 index 00000000..bdeb4a84 --- /dev/null +++ b/applications/storage_move_to_sd/scenes/storage_move_to_sd_scene.h @@ -0,0 +1,29 @@ +#pragma once + +#include + +// Generate scene id and total number +#define ADD_SCENE(prefix, name, id) StorageMoveToSd##id, +typedef enum { +#include "storage_move_to_sd_scene_config.h" + StorageMoveToSdSceneNum, +} StorageMoveToSdScene; +#undef ADD_SCENE + +extern const SceneManagerHandlers storage_move_to_sd_scene_handlers; + +// Generate scene on_enter handlers declaration +#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_enter(void*); +#include "storage_move_to_sd_scene_config.h" +#undef ADD_SCENE + +// Generate scene on_event handlers declaration +#define ADD_SCENE(prefix, name, id) \ + bool prefix##_scene_##name##_on_event(void* context, SceneManagerEvent event); +#include "storage_move_to_sd_scene_config.h" +#undef ADD_SCENE + +// Generate scene on_exit handlers declaration +#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_exit(void* context); +#include "storage_move_to_sd_scene_config.h" +#undef ADD_SCENE diff --git a/applications/storage_move_to_sd/scenes/storage_move_to_sd_scene_config.h b/applications/storage_move_to_sd/scenes/storage_move_to_sd_scene_config.h new file mode 100644 index 00000000..1d7b2d25 --- /dev/null +++ b/applications/storage_move_to_sd/scenes/storage_move_to_sd_scene_config.h @@ -0,0 +1,2 @@ +ADD_SCENE(storage_move_to_sd, confirm, Confirm) +ADD_SCENE(storage_move_to_sd, progress, Progress) diff --git a/applications/storage_move_to_sd/scenes/storage_move_to_sd_scene_confirm.c b/applications/storage_move_to_sd/scenes/storage_move_to_sd_scene_confirm.c new file mode 100644 index 00000000..71ce5a7c --- /dev/null +++ b/applications/storage_move_to_sd/scenes/storage_move_to_sd_scene_confirm.c @@ -0,0 +1,70 @@ +#include "../storage_move_to_sd.h" +#include "gui/canvas.h" +#include "gui/modules/widget_elements/widget_element_i.h" +#include "storage/storage.h" + +static void storage_move_to_sd_scene_confirm_widget_callback( + GuiButtonType result, + InputType type, + void* context) { + StorageMoveToSd* app = context; + furi_assert(app); + if(type == InputTypeShort) { + if(result == GuiButtonTypeRight) { + view_dispatcher_send_custom_event(app->view_dispatcher, MoveToSdCustomEventConfirm); + } else if(result == GuiButtonTypeLeft) { + view_dispatcher_send_custom_event(app->view_dispatcher, MoveToSdCustomEventExit); + } + } +} + +void storage_move_to_sd_scene_confirm_on_enter(void* context) { + StorageMoveToSd* app = context; + + widget_add_button_element( + app->widget, + GuiButtonTypeLeft, + "Cancel", + storage_move_to_sd_scene_confirm_widget_callback, + app); + widget_add_button_element( + app->widget, + GuiButtonTypeRight, + "Confirm", + storage_move_to_sd_scene_confirm_widget_callback, + app); + + widget_add_string_element( + app->widget, 64, 10, AlignCenter, AlignCenter, FontPrimary, "SD card inserted"); + widget_add_string_multiline_element( + app->widget, + 64, + 32, + AlignCenter, + AlignCenter, + FontSecondary, + "Move data from\ninternal storage to SD card?"); + + view_dispatcher_switch_to_view(app->view_dispatcher, StorageMoveToSdViewWidget); +} + +bool storage_move_to_sd_scene_confirm_on_event(void* context, SceneManagerEvent event) { + StorageMoveToSd* app = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == MoveToSdCustomEventConfirm) { + scene_manager_next_scene(app->scene_manager, StorageMoveToSdProgress); + consumed = true; + } else if(event.event == MoveToSdCustomEventExit) { + view_dispatcher_stop(app->view_dispatcher); + } + } + + return consumed; +} + +void storage_move_to_sd_scene_confirm_on_exit(void* context) { + StorageMoveToSd* app = context; + widget_reset(app->widget); +} diff --git a/applications/storage_move_to_sd/scenes/storage_move_to_sd_scene_progress.c b/applications/storage_move_to_sd/scenes/storage_move_to_sd_scene_progress.c new file mode 100644 index 00000000..d44b25c3 --- /dev/null +++ b/applications/storage_move_to_sd/scenes/storage_move_to_sd_scene_progress.c @@ -0,0 +1,32 @@ +#include "../storage_move_to_sd.h" +#include "cmsis_os2.h" + +void storage_move_to_sd_scene_progress_on_enter(void* context) { + StorageMoveToSd* app = context; + + widget_add_string_element( + app->widget, 64, 10, AlignCenter, AlignCenter, FontPrimary, "Moving..."); + + view_dispatcher_switch_to_view(app->view_dispatcher, StorageMoveToSdViewWidget); + + storage_move_to_sd_perform(); + view_dispatcher_send_custom_event(app->view_dispatcher, MoveToSdCustomEventExit); +} + +bool storage_move_to_sd_scene_progress_on_event(void* context, SceneManagerEvent event) { + StorageMoveToSd* app = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + view_dispatcher_stop(app->view_dispatcher); + } else if(event.type == SceneManagerEventTypeBack) { + consumed = true; + } + + return consumed; +} + +void storage_move_to_sd_scene_progress_on_exit(void* context) { + StorageMoveToSd* app = context; + widget_reset(app->widget); +} diff --git a/applications/storage_move_to_sd/storage_move_to_sd.c b/applications/storage_move_to_sd/storage_move_to_sd.c new file mode 100644 index 00000000..f703321d --- /dev/null +++ b/applications/storage_move_to_sd/storage_move_to_sd.c @@ -0,0 +1,177 @@ +#include "storage_move_to_sd.h" +#include "cmsis_os2.h" +#include "furi/common_defines.h" +#include "furi/log.h" +#include "loader/loader.h" +#include "m-string.h" +#include + +#define TAG "MoveToSd" + +#define MOVE_SRC "/int" +#define MOVE_DST "/ext" + +static const char* app_dirs[] = { + "subghz", + "lfrfid", + "nfc", + "infrared", + "ibutton", + "badusb", +}; + +bool storage_move_to_sd_perform(void) { + Storage* storage = furi_record_open("storage"); + string_t path_src; + string_t path_dst; + string_init(path_src); + string_init(path_dst); + + for(uint32_t i = 0; i < COUNT_OF(app_dirs); i++) { + string_printf(path_src, "%s/%s", MOVE_SRC, app_dirs[i]); + string_printf(path_dst, "%s/%s", MOVE_DST, app_dirs[i]); + storage_common_merge(storage, string_get_cstr(path_src), string_get_cstr(path_dst)); + storage_simply_remove_recursive(storage, string_get_cstr(path_src)); + } + + string_clear(path_src); + string_clear(path_dst); + + furi_record_close("storage"); + + return false; +} + +static bool storage_move_to_sd_check(void) { + Storage* storage = furi_record_open("storage"); + + FileInfo file_info; + bool state = false; + string_t path; + string_init(path); + + for(uint32_t i = 0; i < COUNT_OF(app_dirs); i++) { + string_printf(path, "%s/%s", MOVE_SRC, app_dirs[i]); + if(storage_common_stat(storage, string_get_cstr(path), &file_info) == FSE_OK) { + if((file_info.flags & FSF_DIRECTORY) != 0) { + state = true; + break; + } + } + } + + string_clear(path); + + furi_record_close("storage"); + + return state; +} + +static bool storage_move_to_sd_custom_event_callback(void* context, uint32_t event) { + furi_assert(context); + StorageMoveToSd* app = context; + return scene_manager_handle_custom_event(app->scene_manager, event); +} + +static bool storage_move_to_sd_back_event_callback(void* context) { + furi_assert(context); + StorageMoveToSd* app = context; + return scene_manager_handle_back_event(app->scene_manager); +} + +static void storage_move_to_sd_unmount_callback(const void* message, void* context) { + StorageMoveToSd* app = context; + furi_assert(app); + const StorageEvent* storage_event = message; + + if((storage_event->type == StorageEventTypeCardUnmount) || + (storage_event->type == StorageEventTypeCardMountError)) { + view_dispatcher_send_custom_event(app->view_dispatcher, MoveToSdCustomEventExit); + } +} + +static StorageMoveToSd* storage_move_to_sd_alloc() { + StorageMoveToSd* app = malloc(sizeof(StorageMoveToSd)); + + app->gui = furi_record_open("gui"); + app->notifications = furi_record_open("notification"); + + app->view_dispatcher = view_dispatcher_alloc(); + app->scene_manager = scene_manager_alloc(&storage_move_to_sd_scene_handlers, app); + + view_dispatcher_enable_queue(app->view_dispatcher); + view_dispatcher_set_event_callback_context(app->view_dispatcher, app); + + view_dispatcher_set_custom_event_callback( + app->view_dispatcher, storage_move_to_sd_custom_event_callback); + view_dispatcher_set_navigation_event_callback( + app->view_dispatcher, storage_move_to_sd_back_event_callback); + + view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen); + + app->widget = widget_alloc(); + view_dispatcher_add_view( + app->view_dispatcher, StorageMoveToSdViewWidget, widget_get_view(app->widget)); + + scene_manager_next_scene(app->scene_manager, StorageMoveToSdConfirm); + + Storage* storage = furi_record_open("storage"); + app->sub = furi_pubsub_subscribe( + storage_get_pubsub(storage), storage_move_to_sd_unmount_callback, app); + furi_record_close("storage"); + + return app; +} + +static void storage_move_to_sd_free(StorageMoveToSd* app) { + Storage* storage = furi_record_open("storage"); + furi_pubsub_unsubscribe(storage_get_pubsub(storage), app->sub); + furi_record_close("storage"); + furi_record_close("notification"); + + view_dispatcher_remove_view(app->view_dispatcher, StorageMoveToSdViewWidget); + widget_free(app->widget); + view_dispatcher_free(app->view_dispatcher); + scene_manager_free(app->scene_manager); + + furi_record_close("gui"); + + free(app); +} + +int32_t storage_move_to_sd_app(void* p) { + UNUSED(p); + + if(storage_move_to_sd_check()) { + StorageMoveToSd* app = storage_move_to_sd_alloc(); + notification_message(app->notifications, &sequence_display_backlight_on); + view_dispatcher_run(app->view_dispatcher); + storage_move_to_sd_free(app); + } else { + FURI_LOG_I(TAG, "Nothing to move"); + } + + return 0; +} + +static void storage_move_to_sd_mount_callback(const void* message, void* context) { + UNUSED(context); + + const StorageEvent* storage_event = message; + + if(storage_event->type == StorageEventTypeCardMount) { + Loader* loader = furi_record_open("loader"); + loader_start(loader, "StorageMoveToSd", NULL); + furi_record_close("loader"); + } +} + +int32_t storage_move_to_sd_start(void* p) { + UNUSED(p); + Storage* storage = furi_record_open("storage"); + + furi_pubsub_subscribe(storage_get_pubsub(storage), storage_move_to_sd_mount_callback, NULL); + + furi_record_close("storage"); + return 0; +} diff --git a/applications/storage_move_to_sd/storage_move_to_sd.h b/applications/storage_move_to_sd/storage_move_to_sd.h new file mode 100644 index 00000000..dc1d669b --- /dev/null +++ b/applications/storage_move_to_sd/storage_move_to_sd.h @@ -0,0 +1,49 @@ +#pragma once +#include "gui/modules/widget_elements/widget_element_i.h" +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include "scenes/storage_move_to_sd_scene.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + MoveToSdCustomEventExit, + MoveToSdCustomEventConfirm, +} MoveToSdCustomEvent; + +typedef struct { + // records + Gui* gui; + Widget* widget; + NotificationApp* notifications; + + // view managment + SceneManager* scene_manager; + ViewDispatcher* view_dispatcher; + + FuriPubSubSubscription* sub; + +} StorageMoveToSd; + +typedef enum { + StorageMoveToSdViewWidget, +} StorageMoveToSdView; + +bool storage_move_to_sd_perform(void); + +#ifdef __cplusplus +} +#endif diff --git a/fbt_options.py b/fbt_options.py index fb06cecd..fb2a0d36 100644 --- a/fbt_options.py +++ b/fbt_options.py @@ -67,6 +67,7 @@ FIRMWARE_APPS = { # Apps "basic_apps", "updater_app", + "storage_move_to_sd", "archive", # Settings "passport", From 975ee0c0094dfc4d0b42fe2f5693c53c696d6965 Mon Sep 17 00:00:00 2001 From: Astra <93453568+Astrrra@users.noreply.github.com> Date: Thu, 14 Jul 2022 19:58:52 +0300 Subject: [PATCH 04/37] Change # to ! for the inverted text example (#1395) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The code already works with "!", but the comment was wrong. Co-authored-by: あく --- applications/gui/elements.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/applications/gui/elements.h b/applications/gui/elements.h index 2b8b8d3f..2329ca27 100644 --- a/applications/gui/elements.h +++ b/applications/gui/elements.h @@ -204,7 +204,7 @@ void elements_string_fit_width(Canvas* canvas, string_t string, uint8_t width); * @param[in] text Formatted text. The following formats are available: * "\e#Bold text\e#" - bold font is used * "\e*Monospaced text\e*" - monospaced font is used - * "\e#Inversed text\e#" - white text on black background + * "\e!Inversed text\e!" - white text on black background * @param strip_to_dots Strip text to ... if does not fit to width */ void elements_text_box( From 6ac1ed2aaad4ab9bb8fe99510b57115afa4b8011 Mon Sep 17 00:00:00 2001 From: SG Date: Thu, 14 Jul 2022 20:06:25 +0300 Subject: [PATCH 05/37] IR: increase raw timings amount (#1388) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: あく --- lib/infrared/worker/infrared_worker.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/infrared/worker/infrared_worker.h b/lib/infrared/worker/infrared_worker.h index f54b3e01..c6617e50 100644 --- a/lib/infrared/worker/infrared_worker.h +++ b/lib/infrared/worker/infrared_worker.h @@ -7,7 +7,7 @@ extern "C" { #endif -#define MAX_TIMINGS_AMOUNT 512 +#define MAX_TIMINGS_AMOUNT 1024 /** Interface struct of infrared worker */ typedef struct InfraredWorker InfraredWorker; From c29ab50016655d57304e9ffd358a2923cc85faa1 Mon Sep 17 00:00:00 2001 From: Eric Betts Date: Sat, 16 Jul 2022 23:01:19 -0700 Subject: [PATCH 06/37] Calculate picopass CRC dynamically (#1389) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: あく --- lib/ST25RFAL002/include/rfal_picopass.h | 1 + lib/ST25RFAL002/source/rfal_picopass.c | 20 ++++---------------- 2 files changed, 5 insertions(+), 16 deletions(-) diff --git a/lib/ST25RFAL002/include/rfal_picopass.h b/lib/ST25RFAL002/include/rfal_picopass.h index c1b07981..baa8ea6f 100644 --- a/lib/ST25RFAL002/include/rfal_picopass.h +++ b/lib/ST25RFAL002/include/rfal_picopass.h @@ -9,6 +9,7 @@ */ #include "platform.h" #include "rfal_rf.h" +#include "rfal_crc.h" #include "st_errno.h" #define RFAL_PICOPASS_UID_LEN 8 diff --git a/lib/ST25RFAL002/source/rfal_picopass.c b/lib/ST25RFAL002/source/rfal_picopass.c index c99fa224..55dbe649 100644 --- a/lib/ST25RFAL002/source/rfal_picopass.c +++ b/lib/ST25RFAL002/source/rfal_picopass.c @@ -138,22 +138,12 @@ ReturnCode rfalPicoPassPollerCheck(uint8_t* mac, rfalPicoPassCheckRes* chkRes) { ReturnCode rfalPicoPassPollerReadBlock(uint8_t blockNum, rfalPicoPassReadBlockRes* readRes) { ReturnCode ret; - /* - * ./reveng -w 16 -s 0c07cc47 0c064556 0c083bbf 0c09b2ae - width=16 poly=0x1021 init=0xd924 refin=true refout=true xorout=0x0000 check=0x1329 residue=0x0000 name=(none) -0c 06 45 56 -0c 07 cc 47 -0c 08 3b bf -0c 09 b2 ae - */ - uint8_t readCmds[4][4] = { - {RFAL_PICOPASS_CMD_READ, 6, 0x45, 0x56}, - {RFAL_PICOPASS_CMD_READ, 7, 0xcc, 0x47}, - {RFAL_PICOPASS_CMD_READ, 8, 0x3b, 0xbf}, - {RFAL_PICOPASS_CMD_READ, 9, 0xb2, 0xae}}; + uint8_t txBuf[4] = {RFAL_PICOPASS_CMD_READ, 0, 0, 0}; + txBuf[1] = blockNum; + uint16_t crc = rfalCrcCalculateCcitt(0xE012, txBuf + 1, 1); + memcpy(txBuf + 2, &crc, sizeof(uint16_t)); - uint8_t* txBuf = readCmds[blockNum - 6]; uint16_t recvLen = 0; uint32_t flags = RFAL_PICOPASS_TXRX_FLAGS; uint32_t fwt = rfalConvMsTo1fc(20); @@ -166,7 +156,5 @@ ReturnCode rfalPicoPassPollerReadBlock(uint8_t blockNum, rfalPicoPassReadBlockRe &recvLen, flags, fwt); - // printf("check rx: %d %s\n", recvLen, hex2Str(readRes->data, RFAL_PICOPASS_MAX_BLOCK_LEN)); - return ret; } From edc6ca0c8f3cd66ccfa2a8b0bf102bb1828d388e Mon Sep 17 00:00:00 2001 From: Eric Betts Date: Sat, 16 Jul 2022 23:13:51 -0700 Subject: [PATCH 07/37] Log MFC nonces for use with mfkey32v2 (#1390) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: あく --- lib/nfc_protocols/mifare_classic.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/lib/nfc_protocols/mifare_classic.c b/lib/nfc_protocols/mifare_classic.c index 21d470bc..e35a1d6c 100644 --- a/lib/nfc_protocols/mifare_classic.c +++ b/lib/nfc_protocols/mifare_classic.c @@ -622,6 +622,19 @@ bool mf_classic_emulator(MfClassicEmulator* emulator, FuriHalNfcTxRxContext* tx_ break; } + uint32_t nr = nfc_util_bytes2num(tx_rx->rx_data, 4); + uint32_t ar = nfc_util_bytes2num(&tx_rx->rx_data[4], 4); + + FURI_LOG_D( + TAG, + "%08x key%c block %d nt/nr/ar: %08x %08x %08x", + emulator->cuid, + access_key == MfClassicKeyA ? 'A' : 'B', + sector_trailer_block, + nonce, + nr, + ar); + // Check if we store valid key if(access_key == MfClassicKeyA) { if(FURI_BIT(emulator->data.key_a_mask, mf_classic_get_sector_by_block(block)) == @@ -637,8 +650,6 @@ bool mf_classic_emulator(MfClassicEmulator* emulator, FuriHalNfcTxRxContext* tx_ } } - uint32_t nr = nfc_util_bytes2num(tx_rx->rx_data, 4); - uint32_t ar = nfc_util_bytes2num(&tx_rx->rx_data[4], 4); crypto1_word(&emulator->crypto, nr, 1); uint32_t cardRr = ar ^ crypto1_word(&emulator->crypto, 0, 0); if(cardRr != prng_successor(nonce, 64)) { From 877c5c812236337756bd8dba8694ac0ccf53da66 Mon Sep 17 00:00:00 2001 From: Nikolay Minaylov Date: Sun, 17 Jul 2022 10:41:16 +0300 Subject: [PATCH 08/37] [FL-1962, FL-2464, FL-2465, FL-2466, FL-2560, FL-2637, FL-2595] Ibutton, Infrared, LfRFID GUI fixes (#1392) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Ibutton, Infrared, LfRFID GUI fixes * Loading screens update Co-authored-by: あく --- .../archive/views/archive_browser_view.c | 13 ++--- applications/gui/modules/file_browser.c | 13 ++--- applications/gui/modules/loading.c | 15 +++--- .../ibutton/scenes/ibutton_scene_add_type.c | 4 +- .../scenes/ibutton_scene_exit_confirm.c | 4 +- .../scenes/ibutton_scene_read_crc_error.c | 5 +- .../scenes/ibutton_scene_read_key_menu.c | 6 ++- .../scenes/ibutton_scene_read_not_key_error.c | 5 +- .../scenes/ibutton_scene_saved_key_menu.c | 5 +- .../ibutton/scenes/ibutton_scene_start.c | 5 +- .../scenes/infrared_scene_ask_retry.c | 48 ++++++++++++++++++ .../infrared/scenes/infrared_scene_config.h | 1 + .../scenes/infrared_scene_learn_success.c | 3 +- .../scenes/infrared_scene_remote_list.c | 3 +- .../infrared/scenes/infrared_scene_start.c | 1 + .../scene/lfrfid_app_scene_exit_confirm.cpp | 2 +- .../lfrfid/scene/lfrfid_app_scene_read.cpp | 4 +- applications/nfc/nfc.c | 24 +++++++++ applications/nfc/nfc_device.c | 15 ++++++ applications/nfc/nfc_device.h | 7 +++ applications/nfc/nfc_i.h | 5 ++ .../nfc/scenes/nfc_scene_file_select.c | 3 ++ assets/icons/Archive/loading_10px.png | Bin 173 -> 4349 bytes assets/icons/Common/Loading_24/frame_01.png | Bin 194 -> 3650 bytes assets/icons/Common/Loading_24/frame_02.png | Bin 194 -> 3649 bytes assets/icons/Common/Loading_24/frame_03.png | Bin 192 -> 3649 bytes assets/icons/Common/Loading_24/frame_04.png | Bin 190 -> 3645 bytes assets/icons/Common/Loading_24/frame_05.png | Bin 203 -> 3654 bytes assets/icons/Common/Loading_24/frame_06.png | Bin 184 -> 3650 bytes assets/icons/Common/Loading_24/frame_07.png | Bin 203 -> 3655 bytes 30 files changed, 147 insertions(+), 44 deletions(-) create mode 100644 applications/infrared/scenes/infrared_scene_ask_retry.c diff --git a/applications/archive/views/archive_browser_view.c b/applications/archive/views/archive_browser_view.c index 34b875b8..810d5c8f 100644 --- a/applications/archive/views/archive_browser_view.c +++ b/applications/archive/views/archive_browser_view.c @@ -105,17 +105,10 @@ static void archive_draw_frame(Canvas* canvas, uint16_t idx, bool scrollbar, boo static void archive_draw_loading(Canvas* canvas, ArchiveBrowserViewModel* model) { furi_assert(model); - uint8_t width = 49; - uint8_t height = 47; - uint8_t x = 128 / 2 - width / 2; - uint8_t y = 64 / 2 - height / 2 + 6; + uint8_t x = 128 / 2 - 24 / 2; + uint8_t y = 64 / 2 - 24 / 2; - elements_bold_rounded_frame(canvas, x, y, width, height); - - canvas_set_font(canvas, FontSecondary); - elements_multiline_text(canvas, x + 7, y + 13, "Loading..."); - - canvas_draw_icon(canvas, x + 13, y + 19, &A_Loading_24); + canvas_draw_icon(canvas, x, y, &A_Loading_24); } static void draw_list(Canvas* canvas, ArchiveBrowserViewModel* model) { diff --git a/applications/gui/modules/file_browser.c b/applications/gui/modules/file_browser.c index 1cef1d07..4dc0ee54 100644 --- a/applications/gui/modules/file_browser.c +++ b/applications/gui/modules/file_browser.c @@ -354,19 +354,12 @@ static void browser_draw_frame(Canvas* canvas, uint16_t idx, bool scrollbar) { } static void browser_draw_loading(Canvas* canvas, FileBrowserModel* model) { - uint8_t width = 49; - uint8_t height = 47; - uint8_t x = 128 / 2 - width / 2; - uint8_t y = 64 / 2 - height / 2; - UNUSED(model); - elements_bold_rounded_frame(canvas, x, y, width, height); + uint8_t x = 128 / 2 - 24 / 2; + uint8_t y = 64 / 2 - 24 / 2; - canvas_set_font(canvas, FontSecondary); - elements_multiline_text(canvas, x + 7, y + 13, "Loading..."); - - canvas_draw_icon(canvas, x + 13, y + 19, &A_Loading_24); + canvas_draw_icon(canvas, x, y, &A_Loading_24); } static void browser_draw_list(Canvas* canvas, FileBrowserModel* model) { diff --git a/applications/gui/modules/loading.c b/applications/gui/modules/loading.c index 57512697..0fa2c128 100644 --- a/applications/gui/modules/loading.c +++ b/applications/gui/modules/loading.c @@ -20,17 +20,16 @@ typedef struct { static void loading_draw_callback(Canvas* canvas, void* _model) { LoadingModel* model = (LoadingModel*)_model; - uint8_t width = 49; - uint8_t height = 47; - uint8_t x = (canvas_width(canvas) - width) / 2; - uint8_t y = (canvas_height(canvas) - height) / 2; + canvas_set_color(canvas, ColorWhite); + canvas_draw_box(canvas, 0, 0, canvas_width(canvas), canvas_height(canvas)); + canvas_set_color(canvas, ColorBlack); - elements_bold_rounded_frame(canvas, x, y, width, height); + uint8_t x = canvas_width(canvas) / 2 - 24 / 2; + uint8_t y = canvas_height(canvas) / 2 - 24 / 2; - canvas_set_font(canvas, FontSecondary); - elements_multiline_text(canvas, x + 7, y + 13, "Loading..."); + canvas_draw_icon(canvas, x, y, &A_Loading_24); - canvas_draw_icon_animation(canvas, x + 13, y + 19, model->icon); + canvas_draw_icon_animation(canvas, x, y, model->icon); } static bool loading_input_callback(InputEvent* event, void* context) { diff --git a/applications/ibutton/scenes/ibutton_scene_add_type.c b/applications/ibutton/scenes/ibutton_scene_add_type.c index 273330e7..9a0583a5 100644 --- a/applications/ibutton/scenes/ibutton_scene_add_type.c +++ b/applications/ibutton/scenes/ibutton_scene_add_type.c @@ -23,7 +23,8 @@ void ibutton_scene_add_type_on_enter(void* context) { submenu_add_item( submenu, "Metakom", SubmenuIndexMetakom, ibutton_scene_add_type_submenu_callback, ibutton); - submenu_set_selected_item(submenu, SubmenuIndexCyfral); + submenu_set_selected_item( + submenu, scene_manager_get_scene_state(ibutton->scene_manager, iButtonSceneAddType)); view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewSubmenu); } @@ -34,6 +35,7 @@ bool ibutton_scene_add_type_on_event(void* context, SceneManagerEvent event) { bool consumed = false; if(event.type == SceneManagerEventTypeCustom) { + scene_manager_set_scene_state(ibutton->scene_manager, iButtonSceneAddType, event.event); consumed = true; if(event.event == SubmenuIndexCyfral) { ibutton_key_set_type(key, iButtonKeyCyfral); diff --git a/applications/ibutton/scenes/ibutton_scene_exit_confirm.c b/applications/ibutton/scenes/ibutton_scene_exit_confirm.c index abd171f6..c4e90892 100644 --- a/applications/ibutton/scenes/ibutton_scene_exit_confirm.c +++ b/applications/ibutton/scenes/ibutton_scene_exit_confirm.c @@ -19,9 +19,9 @@ void ibutton_scene_exit_confirm_on_enter(void* context) { widget_add_button_element( widget, GuiButtonTypeRight, "Stay", ibutton_scene_exit_confirm_widget_callback, ibutton); widget_add_string_element( - widget, 64, 19, AlignCenter, AlignBottom, FontPrimary, "Exit to iButton menu"); + widget, 64, 19, AlignCenter, AlignBottom, FontPrimary, "Exit to iButton menu?"); widget_add_string_element( - widget, 64, 29, AlignCenter, AlignBottom, FontSecondary, "All unsaved data will be lost"); + widget, 64, 31, AlignCenter, AlignBottom, FontSecondary, "All unsaved data will be lost."); view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewWidget); } diff --git a/applications/ibutton/scenes/ibutton_scene_read_crc_error.c b/applications/ibutton/scenes/ibutton_scene_read_crc_error.c index 28d59d2d..f822ff6a 100644 --- a/applications/ibutton/scenes/ibutton_scene_read_crc_error.c +++ b/applications/ibutton/scenes/ibutton_scene_read_crc_error.c @@ -43,7 +43,10 @@ bool ibutton_scene_read_crc_error_on_event(void* context, SceneManagerEvent even SceneManager* scene_manager = ibutton->scene_manager; bool consumed = false; - if(event.type == SceneManagerEventTypeCustom) { + if(event.type == SceneManagerEventTypeBack) { + consumed = true; + scene_manager_next_scene(scene_manager, iButtonSceneExitConfirm); + } else if(event.type == SceneManagerEventTypeCustom) { consumed = true; if(event.event == DialogExResultRight) { scene_manager_next_scene(scene_manager, iButtonSceneReadKeyMenu); diff --git a/applications/ibutton/scenes/ibutton_scene_read_key_menu.c b/applications/ibutton/scenes/ibutton_scene_read_key_menu.c index 7d479a46..921b24fc 100644 --- a/applications/ibutton/scenes/ibutton_scene_read_key_menu.c +++ b/applications/ibutton/scenes/ibutton_scene_read_key_menu.c @@ -31,8 +31,8 @@ void ibutton_scene_read_key_menu_on_enter(void* context) { ibutton_scene_read_key_menu_submenu_callback, ibutton); } - - submenu_set_selected_item(submenu, SubmenuIndexSave); + submenu_set_selected_item( + submenu, scene_manager_get_scene_state(ibutton->scene_manager, iButtonSceneReadKeyMenu)); view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewSubmenu); } @@ -42,6 +42,8 @@ bool ibutton_scene_read_key_menu_on_event(void* context, SceneManagerEvent event bool consumed = false; if(event.type == SceneManagerEventTypeCustom) { + scene_manager_set_scene_state( + ibutton->scene_manager, iButtonSceneReadKeyMenu, event.event); consumed = true; if(event.event == SubmenuIndexSave) { scene_manager_next_scene(ibutton->scene_manager, iButtonSceneSaveName); diff --git a/applications/ibutton/scenes/ibutton_scene_read_not_key_error.c b/applications/ibutton/scenes/ibutton_scene_read_not_key_error.c index 45fbefe8..8a752803 100644 --- a/applications/ibutton/scenes/ibutton_scene_read_not_key_error.c +++ b/applications/ibutton/scenes/ibutton_scene_read_not_key_error.c @@ -44,7 +44,10 @@ bool ibutton_scene_read_not_key_error_on_event(void* context, SceneManagerEvent SceneManager* scene_manager = ibutton->scene_manager; bool consumed = false; - if(event.type == SceneManagerEventTypeCustom) { + if(event.type == SceneManagerEventTypeBack) { + consumed = true; + scene_manager_next_scene(scene_manager, iButtonSceneExitConfirm); + } else if(event.type == SceneManagerEventTypeCustom) { consumed = true; if(event.event == DialogExResultRight) { scene_manager_next_scene(scene_manager, iButtonSceneReadKeyMenu); diff --git a/applications/ibutton/scenes/ibutton_scene_saved_key_menu.c b/applications/ibutton/scenes/ibutton_scene_saved_key_menu.c index 36529772..3d588dd0 100644 --- a/applications/ibutton/scenes/ibutton_scene_saved_key_menu.c +++ b/applications/ibutton/scenes/ibutton_scene_saved_key_menu.c @@ -42,7 +42,8 @@ void ibutton_scene_saved_key_menu_on_enter(void* context) { submenu_add_item( submenu, "Info", SubmenuIndexInfo, ibutton_scene_saved_key_menu_submenu_callback, ibutton); - submenu_set_selected_item(submenu, SubmenuIndexEmulate); + submenu_set_selected_item( + submenu, scene_manager_get_scene_state(ibutton->scene_manager, iButtonSceneSavedKeyMenu)); view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewSubmenu); } @@ -52,6 +53,8 @@ bool ibutton_scene_saved_key_menu_on_event(void* context, SceneManagerEvent even bool consumed = false; if(event.type == SceneManagerEventTypeCustom) { + scene_manager_set_scene_state( + ibutton->scene_manager, iButtonSceneSavedKeyMenu, event.event); consumed = true; if(event.event == SubmenuIndexEmulate) { scene_manager_next_scene(ibutton->scene_manager, iButtonSceneEmulate); diff --git a/applications/ibutton/scenes/ibutton_scene_start.c b/applications/ibutton/scenes/ibutton_scene_start.c index cc8af983..c2844cde 100644 --- a/applications/ibutton/scenes/ibutton_scene_start.c +++ b/applications/ibutton/scenes/ibutton_scene_start.c @@ -1,4 +1,5 @@ #include "../ibutton_i.h" +#include "ibutton/scenes/ibutton_scene.h" enum SubmenuIndex { SubmenuIndexRead, @@ -22,7 +23,8 @@ void ibutton_scene_start_on_enter(void* context) { submenu_add_item( submenu, "Add Manually", SubmenuIndexAdd, ibutton_scene_start_submenu_callback, ibutton); - submenu_set_selected_item(submenu, SubmenuIndexRead); + submenu_set_selected_item( + submenu, scene_manager_get_scene_state(ibutton->scene_manager, iButtonSceneStart)); view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewSubmenu); } @@ -32,6 +34,7 @@ bool ibutton_scene_start_on_event(void* context, SceneManagerEvent event) { bool consumed = false; if(event.type == SceneManagerEventTypeCustom) { + scene_manager_set_scene_state(ibutton->scene_manager, iButtonSceneStart, event.event); consumed = true; if(event.event == SubmenuIndexRead) { scene_manager_next_scene(ibutton->scene_manager, iButtonSceneRead); diff --git a/applications/infrared/scenes/infrared_scene_ask_retry.c b/applications/infrared/scenes/infrared_scene_ask_retry.c new file mode 100644 index 00000000..48a5cfcd --- /dev/null +++ b/applications/infrared/scenes/infrared_scene_ask_retry.c @@ -0,0 +1,48 @@ +#include "../infrared_i.h" + +static void infrared_scene_dialog_result_callback(DialogExResult result, void* context) { + Infrared* infrared = context; + view_dispatcher_send_custom_event(infrared->view_dispatcher, result); +} + +void infrared_scene_ask_retry_on_enter(void* context) { + Infrared* infrared = context; + DialogEx* dialog_ex = infrared->dialog_ex; + + dialog_ex_set_header(dialog_ex, "Return to reading?", 64, 0, AlignCenter, AlignTop); + dialog_ex_set_text( + dialog_ex, "All unsaved data\nwill be lost", 64, 31, AlignCenter, AlignCenter); + dialog_ex_set_icon(dialog_ex, 0, 0, NULL); + dialog_ex_set_left_button_text(dialog_ex, "Exit"); + dialog_ex_set_center_button_text(dialog_ex, NULL); + dialog_ex_set_right_button_text(dialog_ex, "Stay"); + dialog_ex_set_result_callback(dialog_ex, infrared_scene_dialog_result_callback); + dialog_ex_set_context(dialog_ex, context); + + view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewDialogEx); +} + +bool infrared_scene_ask_retry_on_event(void* context, SceneManagerEvent event) { + Infrared* infrared = context; + SceneManager* scene_manager = infrared->scene_manager; + bool consumed = false; + + if(event.type == SceneManagerEventTypeBack) { + consumed = true; + } else if(event.type == SceneManagerEventTypeCustom) { + if(event.event == DialogExResultLeft) { + scene_manager_search_and_switch_to_previous_scene(scene_manager, InfraredSceneLearn); + consumed = true; + } else if(event.event == DialogExResultRight) { + scene_manager_previous_scene(scene_manager); + consumed = true; + } + } + + return consumed; +} + +void infrared_scene_ask_retry_on_exit(void* context) { + Infrared* infrared = context; + dialog_ex_reset(infrared->dialog_ex); +} diff --git a/applications/infrared/scenes/infrared_scene_config.h b/applications/infrared/scenes/infrared_scene_config.h index 8ff3b167..26a92056 100644 --- a/applications/infrared/scenes/infrared_scene_config.h +++ b/applications/infrared/scenes/infrared_scene_config.h @@ -1,5 +1,6 @@ ADD_SCENE(infrared, start, Start) ADD_SCENE(infrared, ask_back, AskBack) +ADD_SCENE(infrared, ask_retry, AskRetry) ADD_SCENE(infrared, edit, Edit) ADD_SCENE(infrared, edit_delete, EditDelete) ADD_SCENE(infrared, edit_delete_done, EditDeleteDone) diff --git a/applications/infrared/scenes/infrared_scene_learn_success.c b/applications/infrared/scenes/infrared_scene_learn_success.c index ec950ca7..1297ebcf 100644 --- a/applications/infrared/scenes/infrared_scene_learn_success.c +++ b/applications/infrared/scenes/infrared_scene_learn_success.c @@ -89,8 +89,7 @@ bool infrared_scene_learn_success_on_event(void* context, SceneManagerEvent even } else if(event.type == SceneManagerEventTypeCustom) { if(event.event == DialogExResultLeft) { if(scene_state == InfraredSceneLearnSuccessStateIdle) { - scene_manager_search_and_switch_to_previous_scene( - scene_manager, InfraredSceneLearn); + scene_manager_next_scene(scene_manager, InfraredSceneAskRetry); } consumed = true; } else if(event.event == DialogExResultRight) { diff --git a/applications/infrared/scenes/infrared_scene_remote_list.c b/applications/infrared/scenes/infrared_scene_remote_list.c index 25b37759..b0038c1a 100644 --- a/applications/infrared/scenes/infrared_scene_remote_list.c +++ b/applications/infrared/scenes/infrared_scene_remote_list.c @@ -5,7 +5,6 @@ void infrared_scene_remote_list_on_enter(void* context) { SceneManager* scene_manager = infrared->scene_manager; ViewDispatcher* view_dispatcher = infrared->view_dispatcher; - string_set_str(infrared->file_path, INFRARED_APP_FOLDER); bool success = dialog_file_browser_show( infrared->dialogs, infrared->file_path, @@ -16,7 +15,7 @@ void infrared_scene_remote_list_on_enter(void* context) { true); if(success) { - view_set_orientation(view_stack_get_view(infrared->view_stack), ViewOrientationHorizontal); + view_set_orientation(view_stack_get_view(infrared->view_stack), ViewOrientationVertical); view_dispatcher_switch_to_view(view_dispatcher, InfraredViewStack); infrared_show_loading_popup(infrared, true); diff --git a/applications/infrared/scenes/infrared_scene_start.c b/applications/infrared/scenes/infrared_scene_start.c index 6b874a3a..d188a6c3 100644 --- a/applications/infrared/scenes/infrared_scene_start.c +++ b/applications/infrared/scenes/infrared_scene_start.c @@ -66,6 +66,7 @@ bool infrared_scene_start_on_event(void* context, SceneManagerEvent event) { scene_manager_next_scene(scene_manager, InfraredSceneLearn); consumed = true; } else if(submenu_index == SubmenuIndexSavedRemotes) { + string_set_str(infrared->file_path, INFRARED_APP_FOLDER); scene_manager_next_scene(scene_manager, InfraredSceneRemoteList); consumed = true; } else if(submenu_index == SubmenuIndexDebug) { diff --git a/applications/lfrfid/scene/lfrfid_app_scene_exit_confirm.cpp b/applications/lfrfid/scene/lfrfid_app_scene_exit_confirm.cpp index d423cec9..bac0247d 100644 --- a/applications/lfrfid/scene/lfrfid_app_scene_exit_confirm.cpp +++ b/applications/lfrfid/scene/lfrfid_app_scene_exit_confirm.cpp @@ -19,7 +19,7 @@ void LfRfidAppSceneExitConfirm::on_enter(LfRfidApp* app, bool /* need_restore */ line_1->set_text("Exit to RFID menu?", 64, 19, 128 - 2, AlignCenter, AlignBottom, FontPrimary); line_2->set_text( - "All unsaved data will be lost", 64, 29, 0, AlignCenter, AlignBottom, FontSecondary); + "All unsaved data will be lost.", 64, 31, 0, AlignCenter, AlignBottom, FontSecondary); app->view_controller.switch_to(); } diff --git a/applications/lfrfid/scene/lfrfid_app_scene_read.cpp b/applications/lfrfid/scene/lfrfid_app_scene_read.cpp index f87aa200..67279a16 100644 --- a/applications/lfrfid/scene/lfrfid_app_scene_read.cpp +++ b/applications/lfrfid/scene/lfrfid_app_scene_read.cpp @@ -22,9 +22,9 @@ bool LfRfidAppSceneRead::on_event(LfRfidApp* app, LfRfidApp::Event* event) { app->scene_controller.switch_to_next_scene(LfRfidApp::SceneType::ReadSuccess); } else { if(app->worker.any_read()) { - notification_message(app->notification, &sequence_blink_green_10); + notification_message(app->notification, &sequence_blink_yellow_10); } else if(app->worker.detect()) { - notification_message(app->notification, &sequence_blink_cyan_10); + notification_message(app->notification, &sequence_blink_yellow_10); } else { notification_message(app->notification, &sequence_blink_cyan_10); } diff --git a/applications/nfc/nfc.c b/applications/nfc/nfc.c index e98b5d9a..0dc4b3ae 100644 --- a/applications/nfc/nfc.c +++ b/applications/nfc/nfc.c @@ -125,6 +125,10 @@ Nfc* nfc_alloc() { nfc->popup = popup_alloc(); view_dispatcher_add_view(nfc->view_dispatcher, NfcViewPopup, popup_get_view(nfc->popup)); + // Loading + nfc->loading = loading_alloc(); + view_dispatcher_add_view(nfc->view_dispatcher, NfcViewLoading, loading_get_view(nfc->loading)); + // Text Input nfc->text_input = text_input_alloc(); view_dispatcher_add_view( @@ -179,6 +183,10 @@ void nfc_free(Nfc* nfc) { view_dispatcher_remove_view(nfc->view_dispatcher, NfcViewPopup); popup_free(nfc->popup); + // Loading + view_dispatcher_remove_view(nfc->view_dispatcher, NfcViewLoading); + loading_free(nfc->loading); + // TextInput view_dispatcher_remove_view(nfc->view_dispatcher, NfcViewTextInput); text_input_free(nfc->text_input); @@ -258,12 +266,27 @@ void nfc_blink_stop(Nfc* nfc) { notification_message(nfc->notifications, &sequence_blink_stop); } +void nfc_show_loading_popup(void* context, bool show) { + Nfc* nfc = context; + TaskHandle_t timer_task = xTaskGetHandle(configTIMER_SERVICE_TASK_NAME); + + if(show) { + // Raise timer priority so that animations can play + vTaskPrioritySet(timer_task, configMAX_PRIORITIES - 1); + view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewLoading); + } else { + // Restore default timer priority + vTaskPrioritySet(timer_task, configTIMER_TASK_PRIORITY); + } +} + int32_t nfc_app(void* p) { Nfc* nfc = nfc_alloc(); char* args = p; // Check argument and run corresponding scene if((*args != '\0')) { + nfc_device_set_loading_callback(nfc->dev, nfc_show_loading_popup, nfc); uint32_t rpc_ctx = 0; if(sscanf(p, "RPC %lX", &rpc_ctx) == 1) { nfc->rpc_ctx = (void*)rpc_ctx; @@ -281,6 +304,7 @@ int32_t nfc_app(void* p) { // Exit app view_dispatcher_stop(nfc->view_dispatcher); } + nfc_device_set_loading_callback(nfc->dev, NULL, nfc); } else { scene_manager_next_scene(nfc->scene_manager, NfcSceneStart); } diff --git a/applications/nfc/nfc_device.c b/applications/nfc/nfc_device.c index 155cc3f8..e4f9ac56 100644 --- a/applications/nfc/nfc_device.c +++ b/applications/nfc/nfc_device.c @@ -846,6 +846,10 @@ static bool nfc_device_load_data(NfcDevice* dev, string_t path, bool show_dialog string_init(temp_str); bool deprecated_version = false; + if(dev->loading_cb) { + dev->loading_cb(dev->loading_cb_ctx, true); + } + do { // Check existance of shadow file nfc_device_get_shadow_path(path, temp_str); @@ -887,6 +891,10 @@ static bool nfc_device_load_data(NfcDevice* dev, string_t path, bool show_dialog parsed = true; } while(false); + if(dev->loading_cb) { + dev->loading_cb(dev->loading_cb_ctx, false); + } + if((!parsed) && (show_dialog)) { if(deprecated_version) { dialog_message_show_storage_error(dev->dialogs, "File format deprecated"); @@ -1024,3 +1032,10 @@ bool nfc_device_restore(NfcDevice* dev, bool use_load_path) { string_clear(path); return restored; } + +void nfc_device_set_loading_callback(NfcDevice* dev, NfcLoadingCallback callback, void* context) { + furi_assert(dev); + + dev->loading_cb = callback; + dev->loading_cb_ctx = context; +} diff --git a/applications/nfc/nfc_device.h b/applications/nfc/nfc_device.h index 3b2875c0..fee9b07e 100644 --- a/applications/nfc/nfc_device.h +++ b/applications/nfc/nfc_device.h @@ -18,6 +18,8 @@ #define NFC_APP_EXTENSION ".nfc" #define NFC_APP_SHADOW_EXTENSION ".shd" +typedef void (*NfcLoadingCallback)(void* context, bool state); + typedef enum { NfcDeviceProtocolUnknown, NfcDeviceProtocolEMV, @@ -59,6 +61,9 @@ typedef struct { string_t load_path; NfcDeviceSaveFormat format; bool shadow_file_exist; + + NfcLoadingCallback loading_cb; + void* loading_cb_ctx; } NfcDevice; NfcDevice* nfc_device_alloc(); @@ -82,3 +87,5 @@ void nfc_device_clear(NfcDevice* dev); bool nfc_device_delete(NfcDevice* dev, bool use_load_path); bool nfc_device_restore(NfcDevice* dev, bool use_load_path); + +void nfc_device_set_loading_callback(NfcDevice* dev, NfcLoadingCallback callback, void* context); diff --git a/applications/nfc/nfc_i.h b/applications/nfc/nfc_i.h index c42ddced..4b806d40 100755 --- a/applications/nfc/nfc_i.h +++ b/applications/nfc/nfc_i.h @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -63,6 +64,7 @@ struct Nfc { Submenu* submenu; DialogEx* dialog_ex; Popup* popup; + Loading* loading; TextInput* text_input; ByteInput* byte_input; TextBox* text_box; @@ -77,6 +79,7 @@ typedef enum { NfcViewMenu, NfcViewDialogEx, NfcViewPopup, + NfcViewLoading, NfcViewTextInput, NfcViewByteInput, NfcViewTextBox, @@ -97,4 +100,6 @@ void nfc_blink_start(Nfc* nfc); void nfc_blink_stop(Nfc* nfc); +void nfc_show_loading_popup(void* context, bool show); + void nfc_rpc_exit_callback(Nfc* nfc); diff --git a/applications/nfc/scenes/nfc_scene_file_select.c b/applications/nfc/scenes/nfc_scene_file_select.c index 36614bb8..0278c3b9 100755 --- a/applications/nfc/scenes/nfc_scene_file_select.c +++ b/applications/nfc/scenes/nfc_scene_file_select.c @@ -1,13 +1,16 @@ #include "../nfc_i.h" +#include "nfc/nfc_device.h" void nfc_scene_file_select_on_enter(void* context) { Nfc* nfc = context; // Process file_select return + nfc_device_set_loading_callback(nfc->dev, nfc_show_loading_popup, nfc); if(nfc_file_select(nfc->dev)) { scene_manager_next_scene(nfc->scene_manager, NfcSceneSavedMenu); } else { scene_manager_search_and_switch_to_previous_scene(nfc->scene_manager, NfcSceneStart); } + nfc_device_set_loading_callback(nfc->dev, NULL, nfc); } bool nfc_scene_file_select_on_event(void* context, SceneManagerEvent event) { diff --git a/assets/icons/Archive/loading_10px.png b/assets/icons/Archive/loading_10px.png index 9cc33b7fdb0af039d777f83421c3035d59ca4ace..4f626b3d58c1800c375ebbfd358db6c72374dbcf 100644 GIT binary patch delta 4341 zcmVaB^>EX>4U6ba`-PAZ2)IW&i+q+O3*dmfJcK zME|jhUIH-#%fWa~@1U38Hvv*p4U(T<$+pTY3QXh>8IdS8{`cRh{=-)|Tu{!(6mkd$ zUoN|B3g4vT{x#0`d>m80cl_1oHGR8FtEV4a-)UaoT{pa2-hb`Bczd3eh3vxz!tGsu zcU}9J>-P2-^JG!F7BajZu4|*?@%WYQf9LFJvS%fCyW#@=3FoG+t*r03vEmrJJ{EXI z{(8QT>y>$>qa00Xcl4tjl~>c5XWL_Hr@JnC>apINZkXuIFp+m-nz8Fzve9JI>|wQa z$~x=xG|^_;ZGW=HHZ!c{s=3*s*K_lFT+@jMcg>wfvzX=+>!q%5{`U3lLUT58k!JUo zudvG)34<0dTKSi|2#B6n9{J_q>-G9YU|Ga*m$*5x!E)5SMD_ZfTUM<=TW<8cyZzzV z&joN1&-NIjEfF|^wq6H)L}Q}X_%RWmg5}04XDT7k-hZ2pmBv{c2u?EcY(5k9y4QHK zFH=GU!rNdYp~=KVVoE8eqO!@BTJ<^Pm{ZQV6dqbwx$xo0TTxX{G5Z?1-=n6_ zs1Y!=V&=H%iW-+=yq3@cCthMk#EjEKJW2#eXd^K@l6KBW;>ivziCp$yb@~~_YK8xVADUQeLs%dAl$EuDv+OTqy@yFzk*miiA=PcAOE6oz$ zT7OrEy6^J4P1aH8-C20{(OpwoD(>Q0cB-3i*#eO|N^G`HT%Brdx{@%njF5>|ttDY{ zOy0AQHZ3O5ss(q@4GyKdPjf^+(u&AYT%~I9!cmuX*;a8+Bc-v+$pf)cev&*{FUE}I z$5aHj*R{wXDdTKZz$9~*;f8b|oqA)dx_`+YviL=ENSJ_j8T%XF)KRgziDA1t4ZmXZ zV%BLC9(pm0#cpP)W!G}!GVIl?C!>IbXR~A2`cY$TdNKBr=*DSy+( zs~Xk&a{R0s)%$Y%tQyt(ay+ZijupS2o46{EP}WX@_8D`X62Ko#`)z!+Nz%Z!?(lvy z)kHzKRB*#C?W@FJ-_=h)IIRc=$P63|SG1TUHXLOaxC^a{0bW2u1Lh604+^kqy_rHDcrH@o%*uz$=h%S=BY zEn;@p!27bN9ATt&pNhkT4INc#)Dpzhq=I#o`1F}_-FVQYVh{>iqAkd9t+!TFEVtMC zVI}V0YkgVi*)FvW`+K|8ytet5cBw~)J=o>Pa{4i#i;yO04kSFliiQWZ51s=bgY*Du z8lI-Bf}lARk3$@3eoTiw(SI`moGW8e1RNK1B!P~Ur3m{CXl53UkrWSJm?roFrmb`X z)l9#k8pcajQ>3d@1=E)OpqdxnyfIRJLRmh+Nc9P2`2-{3M-weE4-c_iJ|zl}&;hd@ zBU1#W_n3XvS{$j!}(hvp<{>YV>ht7GkT)Vd*l)iz`&-U^<+i*p!TmkKITra= zSvsVbhvn=q{#^-RcjqtVB|z#+gaBd5Enx=Q&8EdrXeXp4Q$dtkm$WdxAT(MZnWq>X zt*W_;sKcknC=gnbrUHf9dH$?-$!zd|RH7~3>k!m5IDR1zgR`TBU$+|FDx+XAE zM)l}fkjV8cacdbO;X?;+LO7Zi;EmB3s#l9vb%Kb&y?;;=b-dv$U%8env$)pgNA-ap zJ#sB!9E)we;aZEiE%vy%mfFPa19t4pVH!6 z4=n*G7*E|n{m8|h1K7Y_stQJsqQ-4B2P6*^Aw?0>@e+q-#ZW!y!v!3o5SM#SL3Y#A zB;$iXjHf{KJ%OF6Yh}rqBt2Hw)JdnPgZRuBP~8{nv-5ULjEk)zQ1U|X|t{MH5fqxqcx!-Rgs6Ztt&`2lUl2pLSxDx>q zO|Yef-ZZHxnV{iG5rDFE1Tztg8My0CSt`W(x)YJ0_CS7NabSN2knGcflysjXfj^n_ z4YtrBj!UM>gIQ5+ow{W=I@OLN$DMw3$kD|xw(FLf_|5(5=70D2hzEhbCk{MgEw!_G z&wn8J(H7NVw`}TftLo@}btm53s#?JOoI+f##o61tQmD(n;$8Mn1vYJm5d-_crw}lY z5q1%tA;bDbP+O&RXjp7bH($X!K)pt6L$L$axE5!Oj9T|se{B1sU;Cr?nm4@5Y@V^`yV@O9D5UA7O<@Z%$A1bMzK|saMj=b|2wo(baji%$vxq;k?pz!I z1U*T?6v+K4Clp z@({trL4vFTg$G8dYCp{pZ;r41a=e;CQMb?TtSGiSL3%@JSa&@@ozKrm{fFm!=zk>Z zmCwDTK6mHu-c+Bv^LKBm&)xaEH`V9v{N0=C?~`%A%R+t=Jq_L%dTe=`w@vS7g=j(g zV*&p&Ix+E0%@}{U;rpJrsWoytOB1Bpr71`yFm;w@6gT6V-y)}Og#dS*x3y$~6!ye% zug7Xv3ky>^SdF`biBQlqOVvxIg?|wnOP5CjG@lTOt&9Zijm}B@TQxQTbf~QokJYX1 zc$wC!4V3?2THB7NMxkCiMU^>&9kiolMaY!qbg3bOnz3gT7kY1aAU2eY$%^Xz$osR2w|YPFew`Gb6DM#`CQhjDHF1I;^(4ok zd$urTqz+w3Jh{$dL2debbd`mr?I~K`a3HTm}0F39rNw0xZFW1~>XSK|I z1Wz%nZ|WDfzFR@kP`NmCt(M9qWuQL zBNy3)?4N7h?>L%BP=Aj#P861EiIAB$ksK>BG;qV9u|pAIS>&jUy`Yz=Y_vxZi-c^`f8 zqbLf$gl18$!OeJ-F7gH^2YgYJt+}Uw#ECT)ADe*N_s3T1&(E#CM@;qS=T_ezTd6-k zw|Y3Xk`s$u1%E8%oK{9Fgu`hBGMDo@qlsr|b=eKU#pT{%8d zdiC=JCjFchUyt*v>hHPhQ%-z;oL>=s;~jJTEGyJKElzR1!o5=Cx4e+7kT~D6LS1P= zgO-EHC6DnU@_0#vqer{tF(OzF###}1oWsK)Nq@r-i^47B&Zg=wgS>N!x8(6cD7{7U zn&`d`_0;oJPx>+u*V;mS*ST}((va|6p)~?!_*t6($X81XUeaa#o{XG9LRt091V~Py zKbg0j5G+DF$E{e&>|tG|-^f7-#1Mst>-q>tzTmfN&Da!80ZPY#m*^R}-NupYw~u0& z>VJn(@A*s~x@C5=l4<_@?W3^I5*FK%sfCx5nuvN7U~i=jab0bb=19@W2*c15y>OM= zj2-e`aBlXREk(UI!YU!D3%`3jV( z{{uzE1NsD#QilKl010qNS#tmY3ljhU3z0AoYX=Su7bEcspQ``>07^+jK~xyieUHHn zz%U2{ZIu02zCNgslT_tpIBbCceH8$#X_DD)vF=f>R`<4hnp#pQ`(Us8rz))zzTsgF ja-)vR)4GM delta 146 zcmeyXxR!B(ayFdh=jFp#HRM+RD&H|v2kEe@c zh{WaE{y@G11{_ZDzUSX4?%DEtMd6m%W8xeVs?Gi>6AtDql!!~Yr`&t%(&6k?G7|cq yFR%W_@3VSu&F0(DZEA0J#H_yk>9_L(#*Y`|=Ra0)6J_8An(XQ7=d#Wzp$P!)?>CeH diff --git a/assets/icons/Common/Loading_24/frame_01.png b/assets/icons/Common/Loading_24/frame_01.png index d1f35692590a934aa850a77b71c7923fc1b1b360..9c49dcad1cb6060c4057ad5c44d67f440c2a91b1 100644 GIT binary patch literal 3650 zcmaJ@c{r478-Fbo%94FarV*#I%z`i(+gL`8rLm1lHO63=t(n1$N>bWn%a%2vq=rh$ zBwMABEsBJ)WJ#7GAzAuH=XAdBk8{5Fy59GBp8L6fzx(&x_x)Vgd(p+oUQ$9;0ssI> z2eb`VFemx)%U2Ey7`kv+h|e3*Dsw!T`NPf4gkmz|S+~F4~>|C;{jP%Z_doipK)=`fl~| zK)o_>&-Hk-^uIHGbL5E6@vm$p0#M5I~kHUS_LVF0yNu2}?x5y^qJ zSN9hlp-1u1LO@Mpa&zjwb_01{@@v)5uhad5+XkPJ?_1-QcFOpP4}mjNGc@JUqav7= zO#q;}*!FbQ#3FulWN2W-ZL?rKliG;l24GOeg4@65_EJT;^k8#~%4Y7L_j>D!lfD9 zMV<@Tv5xZ?n_#o8A$d@C>=b-PBV|QAF;o)Zo^!5odbHtTBe^DgN=P_b3fCS2SccE) zT~^(g0Lb_o!Z`~7kXXGKXQ?9uG^gf&0)UFo%7<0S4%Hf(w-&#jTl ze5zhiqa=)9Z)3S>dyScl_4=WREfUw2Q>;|nY7kwb5ATVn=4?(MkSTo%Gm#wampycP zoUXL~sB-o*<%)CSqE_`{a`%aAfL+T-z* zhL1yHB@tXuYC>7ObiDJGrH1E2W%7s@7X~rnx!bY%NwRy5h!(@5H?G00({gU_Z!XM! zD|Y(=;@SZRN=}Fi#PxikoMCXfR&$0TsxeP@oahJYx*yH3)JNE}Jp9;m_D&FZRRCj+;xVyLo z8;Xr{Y2AM$uj7vn;c8v*r*K#6qxm`R?-l?S@S(Pe@FpPpqFboyX5>%~R%E z)tk1+s(0>T?K#0<1viC|=@sMo1BTBFYYU%`dHSpQUuR~`8Y$h}7vCtG8j`ByN-4Nh zK)n{$m^`dHRo?#a&0Jo_lZ@V?_msCEnvgF}-dS?g&roadevaf@eVbmu4IXRylvR*X z@N71I6mmG^u-D{s$wC6|TO5FGA0nS&&8K-qeg`Nrx3ss(0J^er=NJK+4P4vbFqjfRs zo~(y#GFPzPBrfTt!APXlD1B91BpCGi>!!CUyb{Y&IH2|e+N6!y+POLQT&q~0OgQc4 zB4(`Vk=TWPd-4UI21zANY4N1|&Ry`^`d{{!y0VV37IZtgLtab%m9aB%g_j@i=?Q$q z2=V6zlCfmML)DJbXWOdWnB4vM%XoXu zu8d@PB+r|C*mDx~BjB8~UGPf-ac8U!Cqd=PW6fDd51Y=9+}8KU-s_nrWhQ0jVI@f^ zr8@7RWjo58{d9B^C5Jd8lviqr=U*)hX)ZEndlbk~n6|u9Y_W@!A_j6xhka1_Ae)D- zL?3u-(C4@MWl?iuq~eLn_-t3y_JDh9k0(#OBSik#0;w) zq3r$0x*ird7u#Ig{Hj^R2yZlbu;~%E=j-*|dGlder@R|IR*LSFRlV2l?yUY0dVE&u zjJm>}kNl*GiibLE&!9@%lXKMesmKp;sy=Gv)g$2_c=n;rFS6r~-#ETu-j+We$fA*Z z?^airh*Pk;W459Z^x=#MT6e}|dgw#?fn8G1tcIWd(RcI2@lP(FueUt!ecs%ccB*Vn zY#hzeX-8BCbM^8lImqjk{Lh#3veXZ&+gFwS4Cli>5rXTC;ykl+vUVV67Kb7eKNa{E zWM?^9Am66-auzVlX+hrmy(|4ut=SeztSL;{k%flYkE3zk(-rh@;02!^t+IVZ$YP{@ zIDKURefJ=3oVd_9>1kHX`sO&kr;Y#S)Q`ZL4(7Y>@ASQ|aVq&QC)CQQ+8?&?w94nc zhs;kZg-T3edcDKq*msw!x>vqz_#yq}RO#w{VhyGL`_Y=Ct;vtZNlgdiddFG4V1Gef|jUoNa5B=}EJI7b%{ zipC&2z+ znFI!j&LYvMpfyIk4=tF51PjFec?t^sZ(1tzuS^MY24Umr5STu6?Nq-V9UcF_D~0m6 zHY8QeFNmWf!hy>|k!^?!QV7x4jzObne(*0VoPg{2DXsBapf znrr6U9*WWzMvmBFBnTTTO%tZpr`hc&Sz+WHm}<7k1|}rhB1@oEkbBJ+*L_H%j0|UdYo$Gf4DaPU;cPEB*=VV?2IV|apzK#qG8~eHcB(eheYymzY zuK)l42QotsU9JOCoCO|{#S9GG!XV7ZFl&wkP|(%W#W6(Uaxw$sxBv1I5fUsCGydBr zB%~B1B=E2%=_-g7CM3MbNJuDP(YnNxB&e+s#+2l*keAW0!u^nfu|rzpnUsVC28O;4 W-YVa~mCZmC89ZJ6T-G@yGywn-uQd|@ diff --git a/assets/icons/Common/Loading_24/frame_02.png b/assets/icons/Common/Loading_24/frame_02.png index b1617692131bd61a713453f0a025810acb8e446b..93a59fe681d26795d0db342a0c55ba42fc2c7529 100644 GIT binary patch literal 3649 zcmaJ@c{r3^8-FYniewGR7?BDy24yB=8_Oum7~4q77=ytqjlm2hDWzn~mNi>R4Q+~K zs}!Vu|T0fG&^kldAlcBl>S5JG204rZ&Cc^O@cJQ3w^Qg>RR zx8UiyV9wOk>ZjF;v5c{`7FO%duw7y*@uRsu02~{khv-s>wL#Z5REF_NqWk$lqN9zk zytcdnfEhj(GnDbrV2$Si72pME9UA+@>IQyYEXSxg0ibxGA1pSuohJ?p)N9z+O91t| zfroZaJcNKm0Ptg-H3kFsgn`K)7W!L&uEK;~X`m~2PoV%1%>$&Wn(yN^d;z#QT)?XF z*1Q6;*@j>Z{+eQ*Fz075bKbDZEkIxlE^eox8xWRitkwj8ba?^PUh!r=kR@L>w7t5& z@H8!=49x@7G$u8t9BC`)=T8#Fi5Kd3nP%I}deUiyHjr{FL+BPCr)96iQo*|Gxw zWS84sZs;1sjg1ZujCzjwaelnX-SC~Eg7p<=`!*`B^YR0t)~%fG(<39De6%{AhXK{T zg)Tt1BjDY)?5foxn0-R%eeiM=OLxt1Z&nVbUQd3H(Dv<9%I-Op(4i>(Us?my{;1GJ z?(RlU@Cl;(z*(Pd0m3+JI=uOHEzjv3{|W7ba-Z zTiteNz1m%IS&-kTUO*hLh=|>6`(r_iNryc~mwsx(;Tr=^)V_UwDya9&K?<&Y%dzv6_Jb4d+LR~!ZNE zNW`rZ7Ub+e48-nAp}2NHnsRfx6sj>_J+I?^8p(^a z6H7uQIVOcBjoq_%@OLoiVBOnpf8Sx}{Zo$T?wC0|!3-4&ew4c3Q7G^5qVRBW3pNNF zi)pnzomX{wJ$!{A{P=Q&S@vago;{)TtxU9{)LR&F7H8Z^cjTK;^Sx>1?(%qf(lT(% zs$3u>#L^Dsf6tTc8Sj}ndZw92F=CQPMg9JsJ6i2I2k`pUBXOL9O0YqO;TCg%%y?5yBfXA<7>V1+AQ++m#Iu& z@fy-$O6z;Fse9bn+FyyizIu3f609e`Hvi3V)q&Q(#uliikvlbn3+ce|Nv8cmQb;;eyXB)R9TO}{CZ#wEbvK$v2Kd~)3Pfn;!kUO3H zFmg`mJJJ#9jnD2Dr5Du(rjz?51|?z-v>#ZoqjYOdu1yL}rcG|0f-mA1l^4m2t@2HK z#N<1VGLD|5GXk0d{b&^v`2*Uo3u_Bsk2`tEdFA+L&g)3uIUd(2mJ*mEZAUJ+RzSHG z+?X^XJ6+!X^ut14`iu15qR-@yUz(6_&fQ#;wp2Uv4bv({VOcwX|1@Kj!qz3_z3mrsE|mH+lOoh{K@UTlTz z(3dpcAt>yuKu@67NYBYF6SR80)Y94{-w9+&o{(FCHmO+d?c5b}xmBP~G?aR0*>b$; znLuQ}xnE?N0!b!Sdik8hfrGGn8sBY8>=M!t2kE_V_%b2YRu6 z{IGt6$@H?YvU_D0m{)$9&ZdYl#PWw&h?FJd?jfejZWm@5x)Ocj zqgJ2i#`k5V?cq{qE8`ww${s%HDq}j&_JgZUUq~rM*+~a!Xu4v{J(#4K_H&KijgOPp zF@rd)!<-MRcP<8dvHkXK)S+-E?WDrQhDJ*9j}y-clK3PK2aZolhl}I+gVIT-*);au z;-3%A%0>sBtWS5GU0{*ByT2YQeK$3Mp2(k|u$P>x9~`UnG3t1Kc}BQMZZ>*E?lk$> zS4K{-&q7RdN%OmAJ{`QyluOeycF$bS;k?D*%=4~|j_XDDORGMsbaz&N2@07PxhOAr z^eZQEvf}9>rju`_>A3|;`*ir1SXp{-d09!qeoQ=$>xS13nwh!9Yx6YG?fovDhPT^Z^Wi45*rTV(sx>kCjTC)tK8Pk@fr;6aM$d`ql?mkGJC1x@NX7N3~WLvkK?w zoco0j5Oqp*3KcCZoH9;%UtOg_s_L5I24=o(g-}=U-eyUE?Ci!GWa-lU zY8YI37x%AHhGB|h*ik(hL3lb5F!G?f6G0YaycZEm#Cx#LG!XRwfKQcVk7MAhED;1M zSp&c6qroK8xM%>-Ghov21YaTp+3>pFg2?`3*2-4D^(!C&>a5x+Sg+X92b*_iHKa0Y^Gu0{nO1~LQi2ejR ziN+vNDWFY8ygN03fdq4t{r4%zw0~$R{(o1BTQdj~PlIS`KsQhI+tJGE|GSdO|9JZ| zu*Co5`#*{O?O8M;1WWX%2G9xI-gzo*hN2-*bRwQXrQ1`fe!mNe@uo7U{@zp?2&Sc> z1yZ%b6G)Uz%YnZjR#pfLia!HSArLK0kYFx}28rZ>(AGYzWd?^Do9aN1Xlk0GjEr@( zOwCY7bYYq>xRw_DH`ato2p|(FjNe#~|6oyn#BK_LOyfp2A<{{KL=Q7Ml??jp)Ckg_ zbAkVn?{BQfpK~$#BNoC<2C~`P|LXN`6IVc+(|^RvUHl_|B897YI#=9}_AkY9FUD4k zrM>B|@Xb4NEn;?-J6Kzo7}+zs^RX^M07#%``usTPM&dJQT7TW0pZvvcreZ!fk89eR zxb$l$y&OrR&%MN0k$&Et1-(znrXGup@9h&S%{ikQa$ LTALIbyM_M?u*zuP delta 178 zcmX>obBJ+*L_H%j0|UdYo$Gf4DaPU;cPEB*=VV?2IV|apzK#qG8~eHcB(eheYymzY zuK)l42QotsU9JOCoCO|{#S9GG!XV7ZFl&wkP|(%W#W6(Uaxw$sxBv1I5fUsCGydBr zB%~BHBF@(#&8+NJ%N#vSm#usi94g zY?ZPTMM7D!Bs3&s?Hlj+*7yDK^*z`1Jm;MI+`r#_pZoru>v}HQ+ggf>$cq2~AZmp% z!}7)*8?TT6@B6N(wFv-3&?Ge4-U^Kd)96%hQUDPESiRW}!MLPFS;K)vqPVkZ&&>U_ zfHMF@g(K7;;hHCL1;C$^kTiZ76)oZ{Eweof<5YLHO9Yc0J)FCz+{ffn^wAin<9c6} z`U@Y0g>a{*SKh5uj%SUpwz1pABeqMbC649!0s7b|17wdlu_}UJ1~VuKmKbY( z?z8D70L%!mS>eokMyq^xsQ^Df>(bgSSwHkMvcg`?1pp@kgAmE_t$Ybsph3&AK^kb- z0o-$V=p_Oq13&;f)D!~T76qohTN!QwdWw?zK|oL5&LSZomJdkZW4W8(_$lDwbOx)z zU;7-$1Zzw9B3vIMEcqj+u8VT~e(AU~7R~SZB>( zkvlD_9K#3HHm9_v9q!bYE>C$aAN*}*a9DZxdBA;BJZP_kx9|ugD=kw+3NtQX-L?$? z2i7Yu^9uqJw(ZGvGV0WY`FY3jTgf2nS3&?_mV0L3J(Dflo=J0R#j>6$ zR@Q>}@te(zx9zSqkTBgm60uX{`i@i+ImcRLkKm(w0`j@rGlnEepTYG+#|I^kpP8hA zHhb*IdA_6ays)52gOC(n85zCZGp+~HCIm{46NKO~I#(hJz!TBZM<6d7=mq>mrhbWT z7?p3DbZPzA{1*dq604Gefd59_~i@c9v5-)YW1>&QJk)Gye>fzcOXbcp*9E4 z723@o6CpJvbmE-E^MJDn36?l(9Qu~(luD^&g^-JI`GNbB$w(~p2+(N zI17&2SLI#GIjSfA5|eUI!t54nyfR`dqO6*Lu-aj^(j^*=3f{PeFip?BeWbN0=dIA~ zXymn{R^;3ud#J;OA}O7~4As_5S#)!OW`5V}43ZCN(HAN7y@rLb}gY@vBrP+`ffpCwga(oowY3dv$+sM*n@*p*H0<(Y8~X0-8pe_q+Xyy^F((5A=rg zR`+^N)2C&pCwsYpv~1&SjqG_O8MzoJT(Q66NJUgdUts$e!#9LU_Jr_!)4bTkhYrhm z^7s6C&=+nuw?pXwOh;&cf?NPxk1*4cK=|x`l~mp_b8hI?_GaIT#5&*n4y*jX%GJJJ z@cE?60vUR9s5?D5IvGmX-#MeohakaVk!~ zE6YCzU;VzaZ#6dRhI!V@Loxef>Qj4DLz_3H+N3UWt~wh!vz_Oi-*K$Ek56h$lDl03 z>=j%xw`C$Tn;+jQ&MdAA$|Mg+4@<}I?c6)>KAw+I^lX^rD~Vm!z{I&ZWy_tukP4jRr4tiq#=s9+%_R#_{xy~TFA8v)i(!Ge*q=Ibio^2bT`Frdb%09 z%}~a4o3N;>5Yf-b_)xACLe7n$qL^$>4lJ!K( zW1;9l%Yf)|C6Zh^Xems3?>@wBtuIGP9hfJXiyGaW5!V%;s<_$sqRUSX_W3=g2l;UP z0(IGc5Ub}N z{J3XPJ~r%P>)sVQ&nEZwemqpxG(Cx#ESRKl7F}!Z9;)&)>3V&BMzmOAHg;6OoqXsc z^LmKid|Yd3Yg4O$E?#%~Sj%Hh-?!`g^A|$0PrEfcuNB`ZtA4N6+gq~Q1#|ACACnr;f48RQ zfiM}nKXw-eNgK_Kp!Q}?X9Pc@9o;AP++_6GUjsKoPkplge7)^O|BKdv^wVYYLX#M_ zdMC0bkfWJT&P83X;(orIpRIU8(XzViXE+!Bi4a(?8}E{no4p4$yEJk(=~JOsVNSNK z5$bJvKYP)7HQnFsh+CBpx;@7T#QbVq=DyfC_i;SlZKjg;9kS@zr&@Nn7*&F@45zIP zVeTHIP7)WJr(Fz6nBQ$C4|Z_hoL=^;?P9$9@lMO_8oP@7YD%GuqV{2DxoXAykD!HV zP_W2X>wdS8c-Gz3>fW_4Tb9MYoGx9zPpl;m{_v>vXn)}<&J`2Bkh7lr^UZ~!PRka{ zE)@%v*!XNEB?VFWs&8IxNkfGX3Z>ec!kvGzCmDCf2iAsH4!7f0duFyS#kALyu#4vC z+&e{gk@YI|N|kMF)a=dG;+9=7VF)M!p~>^mWUwhrJWG?pQ2E7RMr07^ zBpQ=MrGPgW@t)K`CJMq!_TQ%<(|*%Z82?m?S2HLJPlLj>U>m3UJV}rD!Fqn7>foNrhg78SRNF*<$j?R8<3w@Y{xi0Jg9Bz&_G1b*J zw?H4zL%ZRux3<3Ael&E{=$0w#=>EL#BKZOK|bIUqF zpRu7p)4Rl?G{^zf&!e+|;JKE)Ux{?_&f{90+bm+9cMZd@9_8N#uwntfo@(#obAWMzL_H%j0|UdYo$Gf4DaPU;cPEB*=VV?2IV|apzK#qG8~eHcB(eheYymzY zuK)l42QotsU9JOCoCO|{#S9GG!XV7ZFl&wkP|(@a#W6(Uaxw$sxBv1I5fUsCGydBr zB%~BLBnYyzwe_*FvAHi$QdJOZOwwiRkkAa^TjR&jv9-bC3S$o237rWud3bmjN)33s UGJ6**0L^3YboFyt=akR{07E7*?*IS* diff --git a/assets/icons/Common/Loading_24/frame_04.png b/assets/icons/Common/Loading_24/frame_04.png index 7f55b0df457223e99a1eefbb4fbc5d1ad75dd431..adefde921e591dfbc18a438e6f350d27b314ae15 100644 GIT binary patch literal 3645 zcmaJ@c{r5q+kR|?vSb@eGDf^D7zV{;Y(qwkrLm1l8DlWa))>r4qEbp(vSm#uO$}|z zBwIyjEKwwsB}+nM3CYqo-rw8%`~LX)p5u6)`@XOHI?wC6uj{;z&|paqH^Pg@^^3ptS`kKj(0z5 z`c0#+`0=R-{?yd+`{l~9oUxTwR+~)p7CD{d(Sjhr3=?Y(@773kM%6V{MGGsU21LQK zqr4XZV)XzpEy7|(G45Ng2;HLs!T_yPf4f}6;IFe4E;^n7I2jm#$c=3hO2Pn*`fiO1 zK%+8n-}RB7B#;UKBvzyi1h^vwOn!H;5Cgi|DSaTIyI?C@9JnF`WbUxvE^PG-@Ntj9 z=nB`q0P;Cj5Pi|wQlV(CCop^A=qfQFECHJ&W90)xXWHmC17K5O0J%-RMFfl%$v5bz z8DJl$#d1+XKrJt=CF5X+kpegEjcWMp^uUnj&ThX0R8z zE)d5C)>BNft!7i&klgrb*o;Q{szge-6u>#}Tey+f&mCkvt zURetg#%-{*+PuBiT-Ij8aP(Hm8_Ma{DsHv#Zqdj0MO5>*WDUxeJvTI!8XJ&18Z$uy zZSYafd!bx;UP9EmQCuFU36I<2o6rqu6$fP|h(d5EK-qujP^eR83onb8F9i3hf+^$-- z4H5mMpt$|umrw?9>QVwey4_IP|MCai(aRU?d@f>DbsCiLBUlrUL=(I^c5j%XT5TSV zFTPzkK3aZK{Mb3!7o;;uN%mMY7I|BHQmag^Lflj0>^Z|1e?d}iJC|uk$Su_|ec=z1 zu=_bW-!!*r=4l`MOIrST3TnG_)74=oNlon}n8PNAU{o(kugJB?qC=LLgVvcyA~$^+ z7JnGc0cRwaC&?r^UtMl`Ib5y)ua6r-OB8I!6s5`?Fdgo3CSzcE9`ueMGPP=213Uf6%rrMZnMjHlhG0UW#jnR z_}TB_o2AZ6oozt*?obIQ?)}2jmcim;~9`iVLYrp#=m(Og8cS?6V+3N1k*n3J_G2xg* zm$pO43#*T>p81KFdU!r|fBtz?p&P#ZmC6-OrB^V*4A!QL?jbUv8+^^t_sGMgNpzUl zvRWAQB-#}ja>t+JpX{GIdZI;0`qhJhX|oSG2U;~-rCLwwiRfACJ?IK5@h^!g+1nG* zQ{Ce`MW0fdn&{z&(sHeGb#v$8WcXsJM8%$pLlv2rg(x9|chlIsEs+Z_u3;_7_6 z5b)WA39|6#P`CPWj6V_jg3WQhL|AW8T~YmT_0E>m;4J@&_OiE(=H^D-K2A5MX)?jA zGbcC?SN)-~cjZd#O}m`>1Mz#}8`68yBY9%!j_He>YaSLJERT7Q_Z)|=qZ7IlsLG-&*iUB`Yo?irvKa3dsl&IEMpU=mL*BP;{tN-n-sOt~Jx zOB+%BR?+eJ?R;VOv+TZ-59D_rn-TS=?k+p(XR9@NzeMn@zfUh>hfXwq&MnR^eleFc z20a#b%$r%;D+}T45!WwN->Qc6BdWEc zx}q|pHm>9?@B7JHP5e!7!FZAm!aCf+X_MZL9z9&dgk z9yef5isNb!RWdZz6Y}@ib0jr#A5@rQZ)f#Vg{{{M`9L8J$NwPVWMx9p}(Ew@ZKA z-_IQ#@^m`h89C1)_w;-^Q2u&q0yR-ILE$WV)!aK!6=dD{=KQo&iQ3GS5w+vw1D_Z- zB7)`c`aWtIK~y@eM!YLmNyIJ@fK&cOYh#hR>vYF7_+V%XP9u zyvyukEuvR4gS`)VR|O#3@+?7&Z|L&li%oN%#uB}!D{0>$i@v?uw8~kRqv!+iFT#>^VCB zF8dz5L90QdvXzCHxwTT#+Ix!6qAu){K3ss4;`9Gw7I`%!%fU*xYTQt1Tn zUVTG7yn%rMc(0kh86J-}_9K`X>4ISfFc{Rp2x@4oXJ`yJ*b9fj!2diDK|s2nKOAGb z|DSMz6#^2-V9?-DXn1(Iez=i7l^y^!G&3`U8o;11n4Z8xFN8&5;Fx-p5Ut+~wuBHo zok(L4sTA-!BhHr^%0NH_$^PdQWZJ*9l#qWaC8!yciK9Uc^$pff_1n?W@&9)vlmGP& zVPFXV&G-K#4sm1A2v7_mgc?f63wr0TwH}HFN74y629@qcrILOZ(j}0}poRoeX<(R< zz7cqbBMwibtXp>e4RLgYJ5WLxI0~NNV2gkVNc4$BKe&mlku}U@ud$tp!Cpf{JEXOZ ziILrYbP5y{o7X+Cmh-^!s6T=98`{`6N`0rE0 ziGR)o_D8;duzr8e#psV%s2~~WdT;+%uYa2a0$QK`D_+6kU-=U#0?pF};)bkgO$aW= z1{buO-LEt2cjQv+%#2_-;9zU*#_TD(YA6kW#YLX}I^APkC}#%3X9jA%v8q$_BiZOb zQes1*B#g$sLn6m+uWq_0Y$5D*>41uP?3^N1J!}V}!~z+kQwuN)0g6a>5?a6tIM_Ma JmfHB7`5%CoVEzCA delta 174 zcmdlhvyX9tL_H%j0|UdYo$Gf4DaPU;cPEB*=VV?2IV|apzK#qG8~eHcB(eheYymzY zuK)l42QotsU9JOCoCO|{#S9GG!XV7ZFl&wkP|(rS#W6(Uaxw$sxBv1I5fUsCGydBr zB%~BL9OU8U<>BdbaP@M~VLGa?OmNlWIhBigA zRSManNGLnWGM1428}IM!{e6FYea~?`&wbz5eVylZ-Pd*A$MIZ2*;@+<$_WAhAY_BI zKyyZ!?U$d2^Zi`Z@*V&L%?ak_C>wKg5S2#pCJ^xe!05?#48|laOBwYq<3(J|x@RA! z5ibB>Wfp&fs9T=s4FG#lRLtaUbc~>jgyfzqq;p+lryw#rW+?YSxsU19m=m$ir}SqO z`wE|hg|Mfm*FLXRj%SUpw=&yABKC->CXVI#0S4%3LwL7hyaTeXu_}UF5;?#N5*=%L z?ZfvL0A_iZjBxrR<8`iw6o4C`c53bys~_Bosz9l_0-!`-04z4Xiz@*QG-x_CNB|8o zz$3?}UV=a}01%m>W?dgR1pBpgWC*HyXvgOHzcGL_M zouNjTBe{Uurj(YnV;$NOfnJt-Aq0 zZl(RzroM5)_}IwcnD;o5{qt?!rvEGjY@{^Tzgc;Wn->tZZ)5kI86EB7q1JOf3as%j zItlc+0KWYz?%KTqxhDiagsj9e_18`I<=jR!7%J=)+_h_3#q)L*bU4;%OM8$q5F5V4 z+1>07nFY>fn4}li=0|Ou#gc8dsTSVN`|J^qT<)HXLDAAzTKYoc17fExOj4zH zc*x|umZ`iXz-!vTFOF4$$L#Tp>jt;-OQ*;2g0V=Q8xaMdi5Q9F;I|F50`4L+zeIPW z^1KF3!r=NTlhuUY1`zD(`qfHnt>g<&j`Mut4m5djPf_mbyWD_wx{io@L~5RYyIko$ zM8xyF!uDg|1L;86)i_*4yOyx`wJ+FH*DhOnT*1hx)=S|=F}g1Cx;O=lUXY}GZ4Q>r zzn?ocLVSw<^hMFv#K?pMYm6<%{GQ5`a;aDazpFshMXlF=fs^hzl&XY?t<*6*;g1tA zRxH&SrF}{{DyRPv7C)1O+%MdCW5ixiNhJYhv&+UG*^AUDa4azD5G7>Us!k@58o!P3 zKZ#(0(h|!OL=qfstTnzFDU*P|jTy2P$lH%DNESP)i#HzSy>km@mY#e6cuP^vC;s~} z@LMNrNV!2Mh~woVah<>nm6l8?^QHog{LT*<1Ruh(FJyvVA@DV7pJm#Iv=0C8J152` zqJ9SN7P=%9Rgd&MAnPxCPPR~{Ocs)EdzbHHT6%*M^fOF8-RGvrO^P$-(9)q$$;9_! zDex4Rl<<`C`%caQ&c>b0`@5VTIEy?u?Gkp^%K0g3xJclW)Pv3<1?QJVhf7+~!RUBY z+wn8`)n_&$S8+m5E=61AUP9(O;mY30URRQO2gA={%(`eUJd^7FH|;!6K3SQv4dPpq z4}zStbu-j&G>kPKcli~27l#+?^@Q|P z_jpdzrlqDQd)R^0Y?EyD>_s>Uz8ok}ak%1mMRY}PVA~I)kGM(ZguvqaMd69B?beH= zpZSZ@KiFODc11m?4*%fx)`}IT^3zFvuwIfO{!0lx?G7U zdDqO{nefb}=l6;;i|c|iN&ON-67dH+4lX*9d$gw3rv#@mrglslEMb>amPku&3e9`P z6uOSkkA%|bfz3fgYUO0Xpw643x}rA|u0HZUw*#^lbfxbeOK1{H3rdrABo$sQB;N{Y zN*R@#spxq2aWOyhWoBRT7t*J%&4{;Q57z87GvyoI-yqngKWCRQLuZ?ZvkNl|UoRw# zLrw>sc00XRwa?*cmTFEHl+@5$cXFVr>6{1L2!UU1o!~KgXT*IgK<9Mkf{VaW1y^A&Cw&qh6Hy2-Y?ZuH^zvr|dAC?~x zO~g%QmPeG|FTcRJ{L6AKO^hzSUts#mNL_aw;>vIU_c$>_J8LAvDV2^Z8STq^Aw4$H z+LRM)=%(wI5UL-2Q!MR?@n{st3c#`BB3gW7#e# zOZs1rgqg4UUUIMse5WnofL3EB%HDXPykO^I(e;hh_T}ss4TI#Y7BR`c*^m7i(nhfA|U#qx94N9E6uj((%x z4)I%zYbkAc-@>Dd)tx@s{G8Q0fBSI$Qb_iB_a>K(;s<5bUsQX#YQ6@aTM&*?kUa8@ zojg_fOpW2{Uu7A#NbZ=4{2DLkDPK`D7XG!|I@sZDPW-t$=XNexvM2rM6k^}Qnwlp9 zB=q6y`;c(zXl4YZCv!R@_!;%YA>r4iqp$wzzZ-gP81?;j>zlqeE&b`|%NF@3kxaD? zcugQnBcGIuxLw8mel0&+;k1Hvb=g)pTWc5>Sg#xJnv;L8w>)vveip5_+OViT9 zf-|;#?jiAvhwIfn8$Wigiu^cVy7?GiOB(p)QR~t6#!ZAREO0qzGkNRd<-rc?X6sI6 zE9L9)*@}wtLUL8}Uad)kg-;5_+unz}Y%wPT9*p;I46Pk&!>o7D?pld$t0`d?EzsBx ziXOu2mFpENTbYQtyX(cRyl zfyy4vU!^SF5<_>Sc+-QiG(2GHMe)RgY)DuiJQ|PnVxDcp8v+2&0fG~Tj`52eqS`<9!Lp5E|Yw#NG)P z;*T@%0vj8F3>k0^0SQmXf*2$sIRMT;fdA%&bLQJ-2pIIY3*8?9{!daEI~2&ALc@df zG_^EvP$(3nXP{|-!{Kzi@CMrIAQ%(|gFv+*S~?n9I&i2S90mjZ^ME-4XV=XASKoXuz|BdzfFV^6X*lj_OsGP_acp4!H?`1`!kU)Q*8cz6g zE{Fff_YctwkVxqU~jM$gT021gqUQzu4G@{M*u0JNJscx&sUsS|WQGSu1sqq8nbHuoAsbjO^> zL+qA^xW`lM8t+c=S8g^D*9;`p1ZVn?S_-PfYrHQmbDD92L_H%j0|UdYo$Gf4DaPU;cPEB*=VV?2IV|apzK#qG8~eHcB(eheYymzY zuK)l42QotsU9JOCoCO|{#S9GG!XV7ZFl&wkP|(lQ#W6(UvTn~t&I1Y}tp18M8z&`{ z74%$LDRWX$Mj`gvufVj(?r|yrRjw in@l4XGcL=2!v5kn=L-v`q_04u89ZJ6T-G@yGywpki9o#o diff --git a/assets/icons/Common/Loading_24/frame_06.png b/assets/icons/Common/Loading_24/frame_06.png index 3354ecda423dfc60a6836f8541f78b8f0bdde6bf..b768a7875f6fd1e259b30d9212e21df882a9da52 100644 GIT binary patch literal 3650 zcmaJ@c{r5q+kR|?vLuWp86)1xGG-7aV;jpT%QUu8DPs%SeuF^6)ve7Q}kzJzboS5Ofy%oOZS7MIFx*RwB zrrcljzk@0_+`+8f?&yU z&P!jR*8ngpz+#3o9+x=~ixGM%s|FAU?0(y#*`$0fY{;pzSAdU~n*lV+g-|RWy>2e;c z$zS&p$YYy9v<2%*`6Aq(!fp5?s)c}%cwC}{nI{mDVWHUqfDQQp)b5?F0$@9VJe|(k z!Qzv&=n6C+P{&DaO+VbJD_xQLRw4BJ?BKA<@XNr57I@G;Ngt6>NOpRb>Q3~8fL+^m z08m)&c(GwvINIJB0dryvybqmlM_#On; z1{5CydR+m(fn^WfK9RhmqHn{NV_Al4X1jB5Vj7K=c8PA=HlyZsvsz~)*5sG&5Opv% ze3AEeqc3b0IF)IZQBqeBwSEdu2`R%zbB@yCkeIzs@n@OiDP z3fqzZNnbrUYY707YnKzuH28ql^uiGUsQMyz{7wqU?u{@2SmvGI|G<3f_7~FZI`Qlm zN>z0re*6|ov+aB8j3q6$j7IDdy(yPwF7I52=n;JKKtLgHN9K@Z*$bGV*udyyANxZNi|8ctHprt#>V=5Ih+peFXBlkzUAOY~i2e zfmZ#lMVB^;J8rg;*w+Y#Us=0SWdln&|LBOod;VavXLpnpuDr<$>R{+ectoV-2XrWu z?M6mC%`fUW{3VzHoV^lHi0FWc`&|8qKYsO+mFH!gf_j52VGO75nxIcm!Wo3fDAwiT zxx#z+V3!k_k`7$svG0_HRheO>_n^rB8suXq;iMjxL`4=Slj$@fxnACDT(+lx1 z5ogU-|E98AC0FglU*bDYCZqR=H(eWb5LHo2gxhYj4M6vywF;dIO*$n>*>>tviR7lw zqr#6O*x>Y}@s8!JQHk0H_TJnQVGAczrMeVjqf1BPJ@MY`d z#AMWu(CuOu#iAO}UVG&OgnGOOT6c7whge=X)*^_fEK;y>0FC7&B5V@?Q2{SFw`I^Wp=gZP-w3 z0;c`Q$%2}b>yax2u}2r9t@AFT3!Dk%Z{*`tWZ%Gvb2y7`x~ssHX25lOuVasvr|m+7 zRuw~_r|q0jL3e%FK1n_~PO|0#-mVlP2*28Z95}%Ur5`*5b z-kM&o8TyRu%v3Kon3iLfqnWdSAS0H7MJf+e9;uA3>ks%0Q$=9=5{C>=;#R_NR$tR84_k&5(!@du9GS{W-kog*}?IvOse-Q=&&vLt3v(T zCEpQ!CdkBxP2J_i*85EC4=~1ik>GuW^@XoTYxcFK1Z4VDc9gwiw6rv8_OpA~P1Es4 zUD*M-_?nMZeQR;ix2&>XABsH?+mP0qc7`LAW}mjizV2$`%5q(B{lK>EK0c*6MecSB z#3;IDZO=kvah~2O$ttN2$s!L(4@)QP>)f~CMCpZ1uT6_iXHIXKFqy@@}CZ>v>jx$w%`0Pc6vTXYZ}rYiB7odAve$&40`;;f7DOjN}w$6}_BK zoPeGPIpKa{wR*SX<81ZZZXI%CU;VMcYR+j-gb9+k(l#kz^2UV!M%ax@HMeUZ1IQZH z@b2)8@U3gPs|Qy&>j^(=hgjcb=NyDQ`Cjmi@l~H!IR986KtNeAL-5vCeW5s^=UbrL zO=K*#i-@@^)03%npzn&y1l@jL&CCv&X5k!}qlzm!E$Vi=yLZH2Y!@Do45!{+wwr8u zDjYLt6BtvWOp?z4EuWR%w;z62`|FW1C&nqpl4du1)P2>rI({yp`0BHReg04BA--(? zKx`mkI;$e0;%>!x=B1xjbLmoyoqI%PE|1pt)FUsC1o2MOdMI5mjtR(qs&s68_T`jvmv)ezO`lw};lAV%WfE6R9m1%s? zDc@V}=%b;LEH=s-CpRl5Uus?&Rb396?~@6Pw(BS;!Tajxj6H)##(| zbq9PlzAme7iiwYH>;vhf@0E=re*0KGoZW>!03r%=O%UQ0hrGjeV!| z=L74C@nJWIlU-*PSmfT`&xgvJXQt3og;Nyvl6&p_L)HG~U2iYWij^qN#f>SRBp>?B zxEbcZ5Z_wX+T1FjkJq0$*7B6y_xSm^^$w#H6PV`yK6s%o}L$vQj$6N znVT|Q^+bc|7Eo<f|p`t?Rfa73Y$>J*SQI&Z=K${XvLlKXHWzC@7LBo z5+P#`#O+2SXk%Fs)ZVO_%+M#aqx;2QnvcEsYvA^o(<7KKH``wIziJ)GI9I+PJcVXy zbRuel*;)nUJmk%4?w6|tIZ7v#Y--AXg>zvegy07K1h?G0oW01o<)zk9bO4;4Ks+S%S5?)r;06?AW6V10P?a64|TXLj3iY9J;G*l~R>|Hb4z|4275E_c!Ixd+^oY`1|E?t;k zjWAN%!Mjz;Gpuk7C#nx46i+7t=H659H4+3jx z{W~0Qg@pJq7&HVF8X6j^9jdEMrTao*Mn***m#CuVL8Au2(+5c2Qru{=p3HrTLygh?5@iZt*TW7PXKaTeH|Gz7l{Ev4K z155nheE%zPkTZ)$gkp(7)L=S+*E=88%}_K1icZ8csB~v4HSo_yV*IEKYLFk528Qcu z>w@>%;|V0nre)vX5PN%sEhUJ7rx1v?mPiPXM4LqNM(A7Wn#1)CP*(an1~8Zv%G^R< z*UB1YU6`MMv(qJ7xRDR`;GPfFS-1#!{T4DP+l_7&EEc>UjH%i1hhH*N4&hnKk_G1c$%m4 z#QoHuZ}VVn!Pq%l{fgW?BUhs5=6Hjnt);m$v)9X04pY|{gSwi;huQ)W++z;hl&d%I zd?D;~l`Y^d?8I*g%kSfJX^Wv4Nqe1=xo{b^)!`uRndm*!*_B;~aWE;+upR*LZ2>}@ W0n(a=Iq%{Q0Jc^RmZcV+k^ckPJzkpt delta 168 zcmX>kvx9MhL_H%j0|UdYo$Gf4DaPU;cPEB*=VV?2IV|apzK#qG8~eHcB(eheYymzY zuK)l42QotsU9JOCoCO|{#S9GG!XV7ZFl&wkP|(`b#W6(Ua`FK-A&DCjOcFaJ9!b_2 zvX~SZvRE)~pJh_c&^*oSP1Y-@dE%LV2LzE zu}6uWmzRtE{aD!E0s#CbcoP#lOA`|inL_f!`{4k9-k)V3h)!G;(;r&J?Q=5jn=eWA zy9|KknY>LxF1bRt0L&F3VZ-{!D1Ijq(fyf7$GY$yeq>hEXwH#xFQe$F(=m=`b-v3D z7Ca9LV$IEMeB7v<%ADHlV07*a+b^t`Fq!KE=%OO^;C*s&w#d5XsxVGbg7Z32imznR$Mu1-8I97 z=gE=fNDiR3HMu?YWVgCVdGb4{z{UCD(LqmX=w(mR%tbb@>XuI+TCpREu)5+>TKQYnEMQ-GH;$P!i zcn0Wq0=$RTT-68oa!&KV3tEd|=xiFwX5Y1I(vvyJzh}>!g8SVnwXqoeU+N>I;h4}B z_U`sT&^&M<-7u}FHZNl90)`k+jEbFVIlzFuwz zwr*s+L?xIWYEB*%p1uTIkW1O(OAHhMm{)CUZC>nt-s)Ey`kjL_MiAW{02qcYsoap- zlK=>LX}}n(0FYR-7H6o$0ko&)j{!jCSBbL^lEkeVcmcpP=kl>9M!WaE7Gc&3X1@qdnd$?9l$avRy*g^ig5-CQK4z=(;?&nXqq;mGBj|i2%hUy4R4GW*WJVO@W zbm z2z!xR&~@^wKMe?pj>U#`K?OZ;e8QZ)am~!_I$BDxQ4BkQ)^v)~#LA$x14N~3voS2* z!<;c;2WENCT@iZY7akvPfwn@MJW!aGFBPufb>@q>0)6urIPrmPsX~zOS{>aTUJ{Qs zXDWU_Bzq`Z;oM(>2hJxV4+}Qm8n@v;q!16Y++*pB96+k%+vn?d3*j@Z6ldZI&0ofO zpN26(sR?EA`{HeHZ8X0fFB5^+M~zzX#2HL*-@5}dPRn_Cs=YA#1MkBq z_?^?1gq#37i2b#~0~-G63hfzUCaw7@c|Gsa@m}~t-js`u9hkG0zIqrLO&MD-+x#Kgtu|mENVvl+XWgK4>Y87{&0#R{x zou|&{RiEDqU&jhOy&7qra}}BAfGul~ym?5h0ft*Z8~0M2xMq}nZ(F;cdAc@h6~MD0 z9RRs#Wp6@#=*jd<@XVUL(9R*)P%=EP`ziB8$Ds~^j*BW>Dh4Vgy*@>rMWIF7{XzZJ z{qA#=IkCB!ewIHu%P>nhYZ*>}uln;bP=iB13Uwv=m%e&^Uj6B%i>Rpjg=bhJOnfF(@;`eJ_ zW14hveNQIopgU9J3vSR?595x94dmD5*N;~pZBOz|_pInDeNSs^Yf>I$_A#4hV|9Bn zeX}vupDG77Z${oT%d9^UqZQMb(w`FC%9CQ9vdX;er0>LVT6X%#wCp`QqdY_Cb@sE9 zcFx$F0nccC@t`Q9s4gIbFeEZ65_h!w=(0VrA3D1^%RiewyK7E&1+${CLRjgPX*(z^ z(|eqDJeWfBZwv4vSI*>*XuK_~D||cc>?Q4WmzuStDSrQCe5-J3K&rSsp&+_|cqgbe zc|z)YMfdaf%Xt~EG6su25k7owL)3>n+OSs5kZyK;i(nc3m|sPYUT7Q3D#$2!vlKrC zITvuw<=jS?>}LH6p4 z8t>&3aFL@Vl4`{lrPr|PgI>z%U7{_#S)!+<*VWn-tz>)m$6oE^9TEy9-CwhsZhOHS zHEiJ*RW65@OcP%V5jlDc_E7cPsZx8|1=^}|FLT^w!>cNGA+GSo%i{w+FDLFTKcRPPGRrA> zMd$PJ5R-N9tG4F;4eEThC?!UMy;F?%H@A7d{bs0wvORd~?x^W7n>-mOnlw(LgH zD91$~#^7QsDx&+|JrkvHXN}~-q~=y)@sHClv7(q{4@Z_yYR?&`OUJ~M&ojx)2gN_1 zn3qqEI@_G@30`Ip`uo3}C~KLULC)mQ5SgnkHIGkJ`55)QyE-pWB)xERLi#-6#24D# zAfM&f_R{v2b}mhf=G>XK7tDdhyIOfGL0OkvTb;Iw9+g#pQta=o`5bt0Niaf2^!OK6 z(ro2(CAzb3m08F#vHN@Y=Qt^M>57`k(9h)-fwuM8aTo7h+`VGPn(?8L{01M_)I8-Q zptNqvBH`qTj4)Dv#$0;fbMon9f^Uo_UjH?8KltL9-PgMvZwKGD52alyTjrfXGL*XE zHU3PMJVFlQZWZh6jl3+Gb21jyWxqmM&@rrkqh_3Qc23q2#KPKmc;Z-rM?rR$jRE3A z+8|@qYBSB(^^|Lsmq}-~fjI5ERoVH~=A|!Fajx@~AXT;K(UCY(@U-ASXG^HlFUAb@(bUk^=*G!T^k(1up0$|Hnqo%b5{31s z@G-nmzEQ5SgMnDMzgg5V5W*^FRSY#&$)z3HG~BjZ>RQJ(7QC}v)t?I9-h`}PS=tEG zRoKt|tCXafp=tIcPg)>`f&+{^NbWe0B?04wL*XzUj0?>;JpkZ3f_FgE(AHLPEQz3s z+3``O6Ub~d0O%Re$r!9Jjs|kadEto&FzZzf7=-sgfSon1)vU=TIBz^Mh=Q{ZvT?u$ z`C@fFzy|stJvy9CK)}&3AUeU1NQKi8;Juv0tWryF2{x`157y()xxoI2g|L%>?DY13_4>DoEufw0zv5*t{*^zD$ksfCEpAzOP9ghZ?6R|R zF#8q0b4Q{h7Z%uqgQcmF1HC`#)@wlk#A_V#>(_fiv6gj7{ar4eB#(fw<*?A*@AVe- zx_3|5zGdB;cucP`Fo+h3mfzrU7fR89b`^xfIlF+Tk{;L_*4vv=KN}Qk0pIHYn&S~Q Qb0?0anT=_&v0M260R4Sy)&Kwi delta 187 zcmX>ubDD92L_H%j0|UdYo$Gf4DaPU;cPEB*=VV?2IV|apzK#qG8~eHcB(eheYymzY zuK)l42QotsU9JOCoCO|{#S9GG!XV7ZFl&wkP|(lQ#W6(Uvh10SybT6CE*JfmoDiGZ zn$X@eah8^HDhJzwWZnKljvv3Qw$^CyoEczZ{e#zV$-%ONg{#iTpFW@~$)_1V`^_dV h-n$w5UbIa)$9+|pODR`h`8UvL22WQ%mvv4FO#s@bK Date: Sun, 17 Jul 2022 12:21:56 +0300 Subject: [PATCH 09/37] [FL-2601] Move Infrared unit test data to assets (#1396) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Move samsung raw data to assets * Add more assets and fix bugs * Clean up code * Implement all raw data as assets * Remove input data from old test files * Better signal names * Better file opening logic * Implement loading parsed data from files * Move most of RC5 tests into assets * Add more test cases * Add more test cases * Eliminate RUN_DECODER macro * Better code structure * Implement run_encoder function * More encoder tests * Move all encoder tests to assets * Move all test data to assets * Normalise function names * Rename code files * Uncomment other tests * Swich test order to avoid weird memory leaks * UnitTests: cleanup output and redirect it into stdout * UnitTests: selectable tests and better reporting Co-authored-by: あく --- .../unit_tests/{ => furi}/furi_memmgr_test.c | 2 +- .../unit_tests/{ => furi}/furi_pubsub_test.c | 2 +- .../unit_tests/{ => furi}/furi_record_test.c | 2 +- .../{minunit_test.c => furi/furi_test.c} | 5 +- .../{ => furi}/furi_valuemutex_test.c | 2 +- .../unit_tests/infrared/infrared_test.c | 520 ++++++++ .../infrared_decoder_encoder_test.c | 331 ----- .../test_data/infrared_nec_test_data.srcdata | 341 ------ .../infrared_necext_test_data.srcdata | 255 ---- .../test_data/infrared_rc5_test_data.srcdata | 160 --- .../test_data/infrared_rc6_test_data.srcdata | 162 --- .../infrared_samsung_test_data.srcdata | 254 ---- .../test_data/infrared_sirc_test_data.srcdata | 479 -------- applications/unit_tests/test_index.c | 88 +- assets/unit_tests/infrared/test_nec.irtest | 511 ++++++++ assets/unit_tests/infrared/test_nec42.irtest | 137 +++ .../unit_tests/infrared/test_nec42ext.irtest | 163 +++ assets/unit_tests/infrared/test_necext.irtest | 684 +++++++++++ assets/unit_tests/infrared/test_rc5.irtest | 341 ++++++ assets/unit_tests/infrared/test_rc5x.irtest | 29 + assets/unit_tests/infrared/test_rc6.irtest | 341 ++++++ .../unit_tests/infrared/test_samsung32.irtest | 535 +++++++++ assets/unit_tests/infrared/test_sirc.irtest | 1060 +++++++++++++++++ 23 files changed, 4385 insertions(+), 2019 deletions(-) rename applications/unit_tests/{ => furi}/furi_memmgr_test.c (99%) rename applications/unit_tests/{ => furi}/furi_pubsub_test.c (98%) rename applications/unit_tests/{ => furi}/furi_record_test.c (94%) rename applications/unit_tests/{minunit_test.c => furi/furi_test.c} (93%) rename applications/unit_tests/{ => furi}/furi_valuemutex_test.c (97%) create mode 100644 applications/unit_tests/infrared/infrared_test.c delete mode 100644 applications/unit_tests/infrared_decoder_encoder/infrared_decoder_encoder_test.c delete mode 100644 applications/unit_tests/infrared_decoder_encoder/test_data/infrared_nec_test_data.srcdata delete mode 100644 applications/unit_tests/infrared_decoder_encoder/test_data/infrared_necext_test_data.srcdata delete mode 100644 applications/unit_tests/infrared_decoder_encoder/test_data/infrared_rc5_test_data.srcdata delete mode 100644 applications/unit_tests/infrared_decoder_encoder/test_data/infrared_rc6_test_data.srcdata delete mode 100644 applications/unit_tests/infrared_decoder_encoder/test_data/infrared_samsung_test_data.srcdata delete mode 100644 applications/unit_tests/infrared_decoder_encoder/test_data/infrared_sirc_test_data.srcdata create mode 100644 assets/unit_tests/infrared/test_nec.irtest create mode 100644 assets/unit_tests/infrared/test_nec42.irtest create mode 100644 assets/unit_tests/infrared/test_nec42ext.irtest create mode 100644 assets/unit_tests/infrared/test_necext.irtest create mode 100644 assets/unit_tests/infrared/test_rc5.irtest create mode 100644 assets/unit_tests/infrared/test_rc5x.irtest create mode 100644 assets/unit_tests/infrared/test_rc6.irtest create mode 100644 assets/unit_tests/infrared/test_samsung32.irtest create mode 100644 assets/unit_tests/infrared/test_sirc.irtest diff --git a/applications/unit_tests/furi_memmgr_test.c b/applications/unit_tests/furi/furi_memmgr_test.c similarity index 99% rename from applications/unit_tests/furi_memmgr_test.c rename to applications/unit_tests/furi/furi_memmgr_test.c index 732856ec..b0fd060c 100644 --- a/applications/unit_tests/furi_memmgr_test.c +++ b/applications/unit_tests/furi/furi_memmgr_test.c @@ -1,4 +1,4 @@ -#include "minunit.h" +#include "../minunit.h" #include #include #include diff --git a/applications/unit_tests/furi_pubsub_test.c b/applications/unit_tests/furi/furi_pubsub_test.c similarity index 98% rename from applications/unit_tests/furi_pubsub_test.c rename to applications/unit_tests/furi/furi_pubsub_test.c index 57c970b8..ddaeb746 100644 --- a/applications/unit_tests/furi_pubsub_test.c +++ b/applications/unit_tests/furi/furi_pubsub_test.c @@ -1,7 +1,7 @@ #include #include #include -#include "minunit.h" +#include "../minunit.h" const uint32_t context_value = 0xdeadbeef; const uint32_t notify_value_0 = 0x12345678; diff --git a/applications/unit_tests/furi_record_test.c b/applications/unit_tests/furi/furi_record_test.c similarity index 94% rename from applications/unit_tests/furi_record_test.c rename to applications/unit_tests/furi/furi_record_test.c index e7eebe4b..512ddfdc 100644 --- a/applications/unit_tests/furi_record_test.c +++ b/applications/unit_tests/furi/furi_record_test.c @@ -1,7 +1,7 @@ #include #include #include -#include "minunit.h" +#include "../minunit.h" void test_furi_create_open() { // 1. Create record diff --git a/applications/unit_tests/minunit_test.c b/applications/unit_tests/furi/furi_test.c similarity index 93% rename from applications/unit_tests/minunit_test.c rename to applications/unit_tests/furi/furi_test.c index 9d564df6..eed9e420 100644 --- a/applications/unit_tests/minunit_test.c +++ b/applications/unit_tests/furi/furi_test.c @@ -1,6 +1,7 @@ #include #include -#include "minunit.h" +#include +#include "../minunit.h" // v2 tests void test_furi_create_open(); @@ -55,7 +56,7 @@ MU_TEST_SUITE(test_suite) { MU_RUN_TEST(mu_test_furi_memmgr); } -int run_minunit() { +int run_minunit_test_furi() { MU_RUN_SUITE(test_suite); return MU_EXIT_CODE; diff --git a/applications/unit_tests/furi_valuemutex_test.c b/applications/unit_tests/furi/furi_valuemutex_test.c similarity index 97% rename from applications/unit_tests/furi_valuemutex_test.c rename to applications/unit_tests/furi/furi_valuemutex_test.c index 12613239..ed98be32 100644 --- a/applications/unit_tests/furi_valuemutex_test.c +++ b/applications/unit_tests/furi/furi_valuemutex_test.c @@ -3,7 +3,7 @@ #include #include "furi_hal_delay.h" -#include "minunit.h" +#include "../minunit.h" void test_furi_valuemutex() { const int init_value = 0xdeadbeef; diff --git a/applications/unit_tests/infrared/infrared_test.c b/applications/unit_tests/infrared/infrared_test.c new file mode 100644 index 00000000..312305b6 --- /dev/null +++ b/applications/unit_tests/infrared/infrared_test.c @@ -0,0 +1,520 @@ +#include +#include +#include +#include +#include "../minunit.h" + +#define IR_TEST_FILES_DIR "/ext/unit_tests/infrared/" +#define IR_TEST_FILE_PREFIX "test_" +#define IR_TEST_FILE_SUFFIX ".irtest" + +typedef struct { + InfraredDecoderHandler* decoder_handler; + InfraredEncoderHandler* encoder_handler; + string_t file_path; + FlipperFormat* ff; +} InfraredTest; + +static InfraredTest* test; + +static void infrared_test_alloc() { + Storage* storage = furi_record_open("storage"); + test = malloc(sizeof(InfraredTest)); + test->decoder_handler = infrared_alloc_decoder(); + test->encoder_handler = infrared_alloc_encoder(); + test->ff = flipper_format_file_alloc(storage); + string_init(test->file_path); +} + +static void infrared_test_free() { + furi_assert(test); + infrared_free_decoder(test->decoder_handler); + infrared_free_encoder(test->encoder_handler); + flipper_format_free(test->ff); + string_clear(test->file_path); + furi_record_close("storage"); + free(test); + test = NULL; +} + +static bool infrared_test_prepare_file(const char* protocol_name) { + string_t file_type; + string_init(file_type); + bool success = false; + + string_printf( + test->file_path, + "%s%s%s%s", + IR_TEST_FILES_DIR, + IR_TEST_FILE_PREFIX, + protocol_name, + IR_TEST_FILE_SUFFIX); + + do { + uint32_t format_version; + if(!flipper_format_file_open_existing(test->ff, string_get_cstr(test->file_path))) break; + if(!flipper_format_read_header(test->ff, file_type, &format_version)) break; + if(string_cmp_str(file_type, "IR tests file") || format_version != 1) break; + success = true; + } while(false); + + string_clear(file_type); + return success; +} + +static bool infrared_test_load_raw_signal( + FlipperFormat* ff, + const char* signal_name, + uint32_t** timings, + uint32_t* timings_count) { + string_t buf; + string_init(buf); + bool success = false; + + do { + bool is_name_found = false; + for(; !is_name_found && flipper_format_read_string(ff, "name", buf); + is_name_found = !string_cmp_str(buf, signal_name)) + ; + + if(!is_name_found) break; + if(!flipper_format_read_string(ff, "type", buf) || string_cmp_str(buf, "raw")) break; + if(!flipper_format_get_value_count(ff, "data", timings_count)) break; + if(!*timings_count) break; + + *timings = malloc(*timings_count * sizeof(uint32_t*)); + if(!flipper_format_read_uint32(ff, "data", *timings, *timings_count)) { + free(*timings); + break; + } + success = true; + } while(false); + + string_clear(buf); + return success; +} + +static bool infrared_test_read_message(FlipperFormat* ff, InfraredMessage* message) { + string_t buf; + string_init(buf); + bool success = false; + + do { + if(!flipper_format_read_string(ff, "protocol", buf)) break; + message->protocol = infrared_get_protocol_by_name(string_get_cstr(buf)); + if(!infrared_is_protocol_valid(message->protocol)) break; + if(!flipper_format_read_hex(ff, "address", (uint8_t*)&message->address, sizeof(uint32_t))) + break; + if(!flipper_format_read_hex(ff, "command", (uint8_t*)&message->command, sizeof(uint32_t))) + break; + if(!flipper_format_read_bool(ff, "repeat", &message->repeat, 1)) break; + success = true; + } while(false); + + string_clear(buf); + return success; +} + +static bool infrared_test_load_messages( + FlipperFormat* ff, + const char* signal_name, + InfraredMessage** messages, + uint32_t* messages_count) { + string_t buf; + string_init(buf); + bool success = false; + + do { + bool is_name_found = false; + for(; !is_name_found && flipper_format_read_string(ff, "name", buf); + is_name_found = !string_cmp_str(buf, signal_name)) + ; + + if(!is_name_found) break; + if(!flipper_format_read_string(ff, "type", buf) || string_cmp_str(buf, "parsed_array")) + break; + if(!flipper_format_read_uint32(ff, "count", messages_count, 1)) break; + if(!*messages_count) break; + + *messages = malloc(*messages_count * sizeof(InfraredMessage)); + uint32_t i; + for(i = 0; i < *messages_count; ++i) { + if(!infrared_test_read_message(ff, (*messages) + i)) { + break; + } + } + if(*messages_count != i) { + free(*messages); + break; + } + success = true; + } while(false); + + string_clear(buf); + return success; +} + +static void infrared_test_compare_message_results( + const InfraredMessage* message_decoded, + const InfraredMessage* message_expected) { + mu_check(message_decoded->protocol == message_expected->protocol); + mu_check(message_decoded->command == message_expected->command); + mu_check(message_decoded->address == message_expected->address); + if((message_expected->protocol == InfraredProtocolSIRC) || + (message_expected->protocol == InfraredProtocolSIRC15) || + (message_expected->protocol == InfraredProtocolSIRC20)) { + mu_check(message_decoded->repeat == false); + } else { + mu_check(message_decoded->repeat == message_expected->repeat); + } +} + +/* Encodes signal and merges same levels (high+high, low+low) */ +static void infrared_test_run_encoder_fill_array( + InfraredEncoderHandler* handler, + uint32_t* timings, + uint32_t* timings_len, + bool* start_level) { + uint32_t duration = 0; + bool level = false; + bool level_read; + InfraredStatus status = InfraredStatusError; + size_t i = 0; + bool first = true; + + while(1) { + status = infrared_encode(handler, &duration, &level_read); + if(first) { + if(start_level) *start_level = level_read; + first = false; + timings[0] = 0; + } else if(level_read != level) { + ++i; + furi_check(i < *timings_len); + timings[i] = 0; + } + level = level_read; + timings[i] += duration; + + furi_check((status == InfraredStatusOk) || (status == InfraredStatusDone)); + if(status == InfraredStatusDone) break; + } + + *timings_len = i + 1; +} + +// messages in input array for encoder should have one protocol +static void infrared_test_run_encoder(InfraredProtocol protocol, uint32_t test_index) { + uint32_t* timings; + uint32_t timings_count = 200; + uint32_t* expected_timings; + uint32_t expected_timings_count; + InfraredMessage* input_messages; + uint32_t input_messages_count; + + string_t buf; + string_init(buf); + + const char* protocol_name = infrared_get_protocol_name(protocol); + mu_assert(infrared_test_prepare_file(protocol_name), "Failed to prepare test file"); + + string_printf(buf, "encoder_input%d", test_index); + mu_assert( + infrared_test_load_messages( + test->ff, string_get_cstr(buf), &input_messages, &input_messages_count), + "Failed to load messages from file"); + + string_printf(buf, "encoder_expected%d", test_index); + mu_assert( + infrared_test_load_raw_signal( + test->ff, string_get_cstr(buf), &expected_timings, &expected_timings_count), + "Failed to load raw signal from file"); + + flipper_format_file_close(test->ff); + string_clear(buf); + + uint32_t j = 0; + timings = malloc(sizeof(uint32_t) * timings_count); + + for(uint32_t message_counter = 0; message_counter < input_messages_count; ++message_counter) { + const InfraredMessage* message = &input_messages[message_counter]; + if(!message->repeat) { + infrared_reset_encoder(test->encoder_handler, message); + } + + timings_count = 200; + infrared_test_run_encoder_fill_array(test->encoder_handler, timings, &timings_count, NULL); + furi_check(timings_count <= 200); + + for(size_t i = 0; i < timings_count; ++i, ++j) { + mu_check(MATCH_TIMING(timings[i], expected_timings[j], 120)); + mu_assert(j < expected_timings_count, "encoded more timings than expected"); + } + } + + free(input_messages); + free(expected_timings); + free(timings); + + mu_assert(j == expected_timings_count, "encoded less timings than expected"); +} + +static void infrared_test_run_encoder_decoder(InfraredProtocol protocol, uint32_t test_index) { + uint32_t* timings = 0; + uint32_t timings_count = 200; + InfraredMessage* input_messages; + uint32_t input_messages_count; + bool level = false; + + string_t buf; + string_init(buf); + + timings = malloc(sizeof(uint32_t) * timings_count); + + const char* protocol_name = infrared_get_protocol_name(protocol); + mu_assert(infrared_test_prepare_file(protocol_name), "Failed to prepare test file"); + + string_printf(buf, "encoder_decoder_input%d", test_index); + mu_assert( + infrared_test_load_messages( + test->ff, string_get_cstr(buf), &input_messages, &input_messages_count), + "Failed to load messages from file"); + + flipper_format_file_close(test->ff); + string_clear(buf); + + for(uint32_t message_counter = 0; message_counter < input_messages_count; ++message_counter) { + const InfraredMessage* message_encoded = &input_messages[message_counter]; + if(!message_encoded->repeat) { + infrared_reset_encoder(test->encoder_handler, message_encoded); + } + + timings_count = 200; + infrared_test_run_encoder_fill_array( + test->encoder_handler, timings, &timings_count, &level); + furi_check(timings_count <= 200); + + const InfraredMessage* message_decoded = 0; + for(size_t i = 0; i < timings_count; ++i) { + message_decoded = infrared_decode(test->decoder_handler, level, timings[i]); + if((i == timings_count - 2) && level && message_decoded) { + /* In case we end with space timing - message can be decoded at last mark */ + break; + } else if(i < timings_count - 1) { + mu_check(!message_decoded); + } else { + if(!message_decoded) { + message_decoded = infrared_check_decoder_ready(test->decoder_handler); + } + mu_check(message_decoded); + } + level = !level; + } + if(message_decoded) { + infrared_test_compare_message_results(message_decoded, message_encoded); + } else { + mu_check(0); + } + } + free(input_messages); + free(timings); +} + +static void infrared_test_run_decoder(InfraredProtocol protocol, uint32_t test_index) { + uint32_t* timings; + uint32_t timings_count; + InfraredMessage* messages; + uint32_t messages_count; + + string_t buf; + string_init(buf); + + mu_assert( + infrared_test_prepare_file(infrared_get_protocol_name(protocol)), + "Failed to prepare test file"); + + string_printf(buf, "decoder_input%d", test_index); + mu_assert( + infrared_test_load_raw_signal(test->ff, string_get_cstr(buf), &timings, &timings_count), + "Failed to load raw signal from file"); + + string_printf(buf, "decoder_expected%d", test_index); + mu_assert( + infrared_test_load_messages(test->ff, string_get_cstr(buf), &messages, &messages_count), + "Failed to load messages from file"); + + flipper_format_file_close(test->ff); + string_clear(buf); + + InfraredMessage message_decoded_check_local; + bool level = 0; + uint32_t message_counter = 0; + const InfraredMessage* message_decoded = 0; + + for(uint32_t i = 0; i < timings_count; ++i) { + const InfraredMessage* message_decoded_check = 0; + + if(timings[i] > INFRARED_RAW_RX_TIMING_DELAY_US) { + message_decoded_check = infrared_check_decoder_ready(test->decoder_handler); + if(message_decoded_check) { + /* infrared_decode() can reset message, but we have to call infrared_decode() to perform real + * simulation: infrared_check() by timeout, then infrared_decode() when meet edge */ + message_decoded_check_local = *message_decoded_check; + message_decoded_check = &message_decoded_check_local; + } + } + + message_decoded = infrared_decode(test->decoder_handler, level, timings[i]); + + if(message_decoded_check || message_decoded) { + mu_assert( + !(message_decoded_check && message_decoded), + "both messages decoded: check_ready() and infrared_decode()"); + + if(message_decoded_check) { + message_decoded = message_decoded_check; + } + + mu_assert(message_counter < messages_count, "decoded more than expected"); + infrared_test_compare_message_results(message_decoded, &messages[message_counter]); + + ++message_counter; + } + level = !level; + } + + message_decoded = infrared_check_decoder_ready(test->decoder_handler); + if(message_decoded) { + infrared_test_compare_message_results(message_decoded, &messages[message_counter]); + ++message_counter; + } + + free(timings); + free(messages); + + mu_assert(message_counter == messages_count, "decoded less than expected"); +} + +MU_TEST(infrared_test_decoder_samsung32) { + infrared_test_run_decoder(InfraredProtocolSamsung32, 1); +} + +MU_TEST(infrared_test_decoder_mixed) { + infrared_test_run_decoder(InfraredProtocolRC5, 2); + infrared_test_run_decoder(InfraredProtocolSIRC, 1); + infrared_test_run_decoder(InfraredProtocolNECext, 1); + infrared_test_run_decoder(InfraredProtocolRC6, 2); + infrared_test_run_decoder(InfraredProtocolSamsung32, 1); + infrared_test_run_decoder(InfraredProtocolRC6, 1); + infrared_test_run_decoder(InfraredProtocolSamsung32, 1); + infrared_test_run_decoder(InfraredProtocolRC5, 1); + infrared_test_run_decoder(InfraredProtocolSIRC, 2); + infrared_test_run_decoder(InfraredProtocolNECext, 1); + infrared_test_run_decoder(InfraredProtocolSIRC, 4); + infrared_test_run_decoder(InfraredProtocolNEC, 2); + infrared_test_run_decoder(InfraredProtocolRC6, 1); + infrared_test_run_decoder(InfraredProtocolNECext, 1); + infrared_test_run_decoder(InfraredProtocolSIRC, 5); + infrared_test_run_decoder(InfraredProtocolNEC, 3); + infrared_test_run_decoder(InfraredProtocolRC5, 5); + infrared_test_run_decoder(InfraredProtocolSamsung32, 1); + infrared_test_run_decoder(InfraredProtocolSIRC, 3); +} + +MU_TEST(infrared_test_decoder_nec) { + infrared_test_run_decoder(InfraredProtocolNEC, 1); + infrared_test_run_decoder(InfraredProtocolNEC, 2); + infrared_test_run_decoder(InfraredProtocolNEC, 3); +} + +MU_TEST(infrared_test_decoder_unexpected_end_in_sequence) { + infrared_test_run_decoder(InfraredProtocolNEC, 1); + infrared_test_run_decoder(InfraredProtocolNEC, 1); + infrared_test_run_decoder(InfraredProtocolNEC, 2); + infrared_test_run_decoder(InfraredProtocolNEC, 2); +} + +MU_TEST(infrared_test_decoder_necext1) { + infrared_test_run_decoder(InfraredProtocolNECext, 1); + infrared_test_run_decoder(InfraredProtocolNECext, 1); +} + +MU_TEST(infrared_test_decoder_long_packets_with_nec_start) { + infrared_test_run_decoder(InfraredProtocolNEC42ext, 1); + infrared_test_run_decoder(InfraredProtocolNEC42ext, 2); +} + +MU_TEST(infrared_test_encoder_sirc) { + infrared_test_run_encoder(InfraredProtocolSIRC, 1); + infrared_test_run_encoder(InfraredProtocolSIRC, 2); +} + +MU_TEST(infrared_test_decoder_sirc) { + infrared_test_run_decoder(InfraredProtocolSIRC, 3); + infrared_test_run_decoder(InfraredProtocolSIRC, 1); + infrared_test_run_decoder(InfraredProtocolSIRC, 2); + infrared_test_run_decoder(InfraredProtocolSIRC, 4); + infrared_test_run_decoder(InfraredProtocolSIRC, 5); +} + +MU_TEST(infrared_test_decoder_rc5) { + infrared_test_run_decoder(InfraredProtocolRC5X, 1); + infrared_test_run_decoder(InfraredProtocolRC5, 1); + infrared_test_run_decoder(InfraredProtocolRC5, 2); + infrared_test_run_decoder(InfraredProtocolRC5, 3); + infrared_test_run_decoder(InfraredProtocolRC5, 4); + infrared_test_run_decoder(InfraredProtocolRC5, 5); + infrared_test_run_decoder(InfraredProtocolRC5, 6); + infrared_test_run_decoder(InfraredProtocolRC5, 7); +} + +MU_TEST(infrared_test_encoder_rc5x) { + infrared_test_run_encoder(InfraredProtocolRC5X, 1); +} + +MU_TEST(infrared_test_encoder_rc5) { + infrared_test_run_encoder(InfraredProtocolRC5, 1); +} + +MU_TEST(infrared_test_decoder_rc6) { + infrared_test_run_decoder(InfraredProtocolRC6, 1); +} + +MU_TEST(infrared_test_encoder_rc6) { + infrared_test_run_encoder(InfraredProtocolRC6, 1); +} + +MU_TEST(infrared_test_encoder_decoder_all) { + infrared_test_run_encoder_decoder(InfraredProtocolNEC, 1); + infrared_test_run_encoder_decoder(InfraredProtocolNECext, 1); + infrared_test_run_encoder_decoder(InfraredProtocolNEC42, 1); + infrared_test_run_encoder_decoder(InfraredProtocolNEC42ext, 1); + infrared_test_run_encoder_decoder(InfraredProtocolSamsung32, 1); + infrared_test_run_encoder_decoder(InfraredProtocolRC6, 1); + infrared_test_run_encoder_decoder(InfraredProtocolRC5, 1); + infrared_test_run_encoder_decoder(InfraredProtocolSIRC, 1); +} + +MU_TEST_SUITE(infrared_test) { + MU_SUITE_CONFIGURE(&infrared_test_alloc, &infrared_test_free); + + MU_RUN_TEST(infrared_test_encoder_sirc); + MU_RUN_TEST(infrared_test_decoder_sirc); + MU_RUN_TEST(infrared_test_encoder_rc5x); + MU_RUN_TEST(infrared_test_encoder_rc5); + MU_RUN_TEST(infrared_test_decoder_rc5); + MU_RUN_TEST(infrared_test_decoder_rc6); + MU_RUN_TEST(infrared_test_encoder_rc6); + MU_RUN_TEST(infrared_test_decoder_unexpected_end_in_sequence); + MU_RUN_TEST(infrared_test_decoder_long_packets_with_nec_start); + MU_RUN_TEST(infrared_test_decoder_nec); + MU_RUN_TEST(infrared_test_decoder_samsung32); + MU_RUN_TEST(infrared_test_decoder_necext1); + MU_RUN_TEST(infrared_test_decoder_mixed); + MU_RUN_TEST(infrared_test_encoder_decoder_all); +} + +int run_minunit_test_infrared() { + MU_RUN_SUITE(infrared_test); + return MU_EXIT_CODE; +} diff --git a/applications/unit_tests/infrared_decoder_encoder/infrared_decoder_encoder_test.c b/applications/unit_tests/infrared_decoder_encoder/infrared_decoder_encoder_test.c deleted file mode 100644 index 0c3e685d..00000000 --- a/applications/unit_tests/infrared_decoder_encoder/infrared_decoder_encoder_test.c +++ /dev/null @@ -1,331 +0,0 @@ -#include -#include "../minunit.h" -#include "infrared.h" -#include "common/infrared_common_i.h" -#include "test_data/infrared_nec_test_data.srcdata" -#include "test_data/infrared_necext_test_data.srcdata" -#include "test_data/infrared_samsung_test_data.srcdata" -#include "test_data/infrared_rc6_test_data.srcdata" -#include "test_data/infrared_rc5_test_data.srcdata" -#include "test_data/infrared_sirc_test_data.srcdata" - -#define RUN_ENCODER(data, expected) \ - run_encoder((data), COUNT_OF(data), (expected), COUNT_OF(expected)) - -#define RUN_DECODER(data, expected) \ - run_decoder((data), COUNT_OF(data), (expected), COUNT_OF(expected)) - -#define RUN_ENCODER_DECODER(data) run_encoder_decoder((data), COUNT_OF(data)) - -static InfraredDecoderHandler* decoder_handler; -static InfraredEncoderHandler* encoder_handler; - -static void test_setup(void) { - decoder_handler = infrared_alloc_decoder(); - encoder_handler = infrared_alloc_encoder(); -} - -static void test_teardown(void) { - infrared_free_decoder(decoder_handler); - infrared_free_encoder(encoder_handler); -} - -static void compare_message_results( - const InfraredMessage* message_decoded, - const InfraredMessage* message_expected) { - mu_check(message_decoded->protocol == message_expected->protocol); - mu_check(message_decoded->command == message_expected->command); - mu_check(message_decoded->address == message_expected->address); - if((message_expected->protocol == InfraredProtocolSIRC) || - (message_expected->protocol == InfraredProtocolSIRC15) || - (message_expected->protocol == InfraredProtocolSIRC20)) { - mu_check(message_decoded->repeat == false); - } else { - mu_check(message_decoded->repeat == message_expected->repeat); - } -} - -/* Encodes signal and merges same levels (high+high, low+low) */ -static void run_encoder_fill_array( - InfraredEncoderHandler* handler, - uint32_t* timings, - uint32_t* timings_len, - bool* start_level) { - uint32_t duration = 0; - bool level = false; - bool level_read; - InfraredStatus status = InfraredStatusError; - size_t i = 0; - bool first = true; - - while(1) { - status = infrared_encode(handler, &duration, &level_read); - if(first) { - if(start_level) *start_level = level_read; - first = false; - timings[0] = 0; - } else if(level_read != level) { - ++i; - furi_check(i < *timings_len); - timings[i] = 0; - } - level = level_read; - timings[i] += duration; - - furi_check((status == InfraredStatusOk) || (status == InfraredStatusDone)); - if(status == InfraredStatusDone) break; - } - - *timings_len = i + 1; -} - -// messages in input array for encoder should have one protocol -static void run_encoder( - const InfraredMessage input_messages[], - uint32_t input_messages_len, - const uint32_t expected_timings[], - uint32_t expected_timings_len) { - uint32_t* timings = 0; - uint32_t timings_len = 200; - uint32_t j = 0; - timings = malloc(sizeof(uint32_t) * timings_len); - - for(uint32_t message_counter = 0; message_counter < input_messages_len; ++message_counter) { - const InfraredMessage* message = &input_messages[message_counter]; - if(!message->repeat) { - infrared_reset_encoder(encoder_handler, message); - } - - timings_len = 200; - run_encoder_fill_array(encoder_handler, timings, &timings_len, NULL); - furi_check(timings_len <= 200); - - for(size_t i = 0; i < timings_len; ++i, ++j) { - mu_check(MATCH_TIMING(timings[i], expected_timings[j], 120)); - mu_assert(j < expected_timings_len, "encoded more timings than expected"); - } - } - free(timings); - mu_assert(j == expected_timings_len, "encoded less timings than expected"); -} - -static void - run_encoder_decoder(const InfraredMessage input_messages[], uint32_t input_messages_len) { - uint32_t* timings = 0; - uint32_t timings_len = 200; - bool level = false; - timings = malloc(sizeof(uint32_t) * timings_len); - - for(uint32_t message_counter = 0; message_counter < input_messages_len; ++message_counter) { - const InfraredMessage* message_encoded = &input_messages[message_counter]; - if(!message_encoded->repeat) { - infrared_reset_encoder(encoder_handler, message_encoded); - } - - timings_len = 200; - run_encoder_fill_array(encoder_handler, timings, &timings_len, &level); - furi_check(timings_len <= 200); - - const InfraredMessage* message_decoded = 0; - for(size_t i = 0; i < timings_len; ++i) { - message_decoded = infrared_decode(decoder_handler, level, timings[i]); - if((i == timings_len - 2) && level && message_decoded) { - /* In case we end with space timing - message can be decoded at last mark */ - break; - } else if(i < timings_len - 1) { - mu_check(!message_decoded); - } else { - if(!message_decoded) { - message_decoded = infrared_check_decoder_ready(decoder_handler); - } - mu_check(message_decoded); - } - level = !level; - } - if(message_decoded) { - compare_message_results(message_decoded, message_encoded); - } else { - mu_check(0); - } - } - free(timings); -} - -static void run_decoder( - const uint32_t* input_delays, - uint32_t input_delays_len, - const InfraredMessage* message_expected, - uint32_t message_expected_len) { - InfraredMessage message_decoded_check_local; - bool level = 0; - uint32_t message_counter = 0; - const InfraredMessage* message_decoded = 0; - - for(uint32_t i = 0; i < input_delays_len; ++i) { - const InfraredMessage* message_decoded_check = 0; - - if(input_delays[i] > INFRARED_RAW_RX_TIMING_DELAY_US) { - message_decoded_check = infrared_check_decoder_ready(decoder_handler); - if(message_decoded_check) { - /* infrared_decode() can reset message, but we have to call infrared_decode() to perform real - * simulation: infrared_check() by timeout, then infrared_decode() when meet edge */ - message_decoded_check_local = *message_decoded_check; - message_decoded_check = &message_decoded_check_local; - } - } - - message_decoded = infrared_decode(decoder_handler, level, input_delays[i]); - - if(message_decoded_check || message_decoded) { - mu_assert( - !(message_decoded_check && message_decoded), - "both messages decoded: check_ready() and infrared_decode()"); - - if(message_decoded_check) { - message_decoded = message_decoded_check; - } - - mu_assert(message_counter < message_expected_len, "decoded more than expected"); - compare_message_results(message_decoded, &message_expected[message_counter]); - - ++message_counter; - } - level = !level; - } - - message_decoded = infrared_check_decoder_ready(decoder_handler); - if(message_decoded) { - compare_message_results(message_decoded, &message_expected[message_counter]); - ++message_counter; - } - - mu_assert(message_counter == message_expected_len, "decoded less than expected"); -} - -MU_TEST(test_decoder_samsung32) { - RUN_DECODER(test_decoder_samsung32_input1, test_decoder_samsung32_expected1); -} - -MU_TEST(test_mix) { - RUN_DECODER(test_decoder_rc5_input2, test_decoder_rc5_expected2); - RUN_DECODER(test_decoder_sirc_input1, test_decoder_sirc_expected1); - RUN_DECODER(test_decoder_necext_input1, test_decoder_necext_expected1); - // can use encoder data for decoding, but can't do opposite - RUN_DECODER(test_encoder_rc6_expected1, test_encoder_rc6_input1); - RUN_DECODER(test_decoder_samsung32_input1, test_decoder_samsung32_expected1); - RUN_DECODER(test_decoder_rc6_input1, test_decoder_rc6_expected1); - RUN_DECODER(test_decoder_samsung32_input1, test_decoder_samsung32_expected1); - RUN_DECODER(test_decoder_rc5_input1, test_decoder_rc5_expected1); - RUN_DECODER(test_decoder_sirc_input2, test_decoder_sirc_expected2); - RUN_DECODER(test_decoder_necext_input1, test_decoder_necext_expected1); - RUN_DECODER(test_decoder_sirc_input4, test_decoder_sirc_expected4); - RUN_DECODER(test_decoder_nec_input2, test_decoder_nec_expected2); - RUN_DECODER(test_decoder_rc6_input1, test_decoder_rc6_expected1); - RUN_DECODER(test_decoder_necext_input1, test_decoder_necext_expected1); - RUN_DECODER(test_decoder_sirc_input5, test_decoder_sirc_expected5); - RUN_DECODER(test_decoder_nec_input3, test_decoder_nec_expected3); - RUN_DECODER(test_decoder_rc5_input5, test_decoder_rc5_expected5); - RUN_DECODER(test_decoder_samsung32_input1, test_decoder_samsung32_expected1); - RUN_DECODER(test_decoder_sirc_input3, test_decoder_sirc_expected3); -} - -MU_TEST(test_decoder_nec) { - RUN_DECODER(test_decoder_nec_input1, test_decoder_nec_expected1); - RUN_DECODER(test_decoder_nec_input2, test_decoder_nec_expected2); - RUN_DECODER(test_decoder_nec_input3, test_decoder_nec_expected3); -} - -MU_TEST(test_decoder_unexpected_end_in_sequence) { - // test_decoder_nec_input1 and test_decoder_nec_input2 shuts unexpected - RUN_DECODER(test_decoder_nec_input1, test_decoder_nec_expected1); - RUN_DECODER(test_decoder_nec_input1, test_decoder_nec_expected1); - RUN_DECODER(test_decoder_nec_input2, test_decoder_nec_expected2); - RUN_DECODER(test_decoder_nec_input2, test_decoder_nec_expected2); -} - -MU_TEST(test_decoder_necext1) { - RUN_DECODER(test_decoder_necext_input1, test_decoder_necext_expected1); - RUN_DECODER(test_decoder_necext_input1, test_decoder_necext_expected1); -} - -MU_TEST(test_decoder_long_packets_with_nec_start) { - RUN_DECODER(test_decoder_nec42ext_input1, test_decoder_nec42ext_expected1); - RUN_DECODER(test_decoder_nec42ext_input2, test_decoder_nec42ext_expected2); -} - -MU_TEST(test_encoder_sirc) { - RUN_ENCODER(test_encoder_sirc_input1, test_encoder_sirc_expected1); - RUN_ENCODER(test_encoder_sirc_input2, test_encoder_sirc_expected2); -} - -MU_TEST(test_decoder_sirc) { - RUN_DECODER(test_decoder_sirc_input3, test_decoder_sirc_expected3); - RUN_DECODER(test_decoder_sirc_input1, test_decoder_sirc_expected1); - RUN_DECODER(test_decoder_sirc_input2, test_decoder_sirc_expected2); - RUN_DECODER(test_decoder_sirc_input4, test_decoder_sirc_expected4); - RUN_DECODER(test_decoder_sirc_input5, test_decoder_sirc_expected5); - RUN_ENCODER_DECODER(test_sirc); -} - -MU_TEST(test_decoder_rc5) { - RUN_DECODER(test_decoder_rc5x_input1, test_decoder_rc5x_expected1); - RUN_DECODER(test_decoder_rc5_input1, test_decoder_rc5_expected1); - RUN_DECODER(test_decoder_rc5_input2, test_decoder_rc5_expected2); - RUN_DECODER(test_decoder_rc5_input3, test_decoder_rc5_expected3); - RUN_DECODER(test_decoder_rc5_input4, test_decoder_rc5_expected4); - RUN_DECODER(test_decoder_rc5_input5, test_decoder_rc5_expected5); - RUN_DECODER(test_decoder_rc5_input6, test_decoder_rc5_expected6); - RUN_DECODER(test_decoder_rc5_input_all_repeats, test_decoder_rc5_expected_all_repeats); -} - -MU_TEST(test_encoder_rc5x) { - RUN_ENCODER(test_decoder_rc5x_expected1, test_decoder_rc5x_input1); -} - -MU_TEST(test_encoder_rc5) { - RUN_ENCODER(test_decoder_rc5_expected_all_repeats, test_decoder_rc5_input_all_repeats); -} - -MU_TEST(test_decoder_rc6) { - RUN_DECODER(test_decoder_rc6_input1, test_decoder_rc6_expected1); -} - -MU_TEST(test_encoder_rc6) { - RUN_ENCODER(test_encoder_rc6_input1, test_encoder_rc6_expected1); -} - -MU_TEST(test_encoder_decoder_all) { - RUN_ENCODER_DECODER(test_nec); - RUN_ENCODER_DECODER(test_necext); - RUN_ENCODER_DECODER(test_nec42); - RUN_ENCODER_DECODER(test_nec42ext); - RUN_ENCODER_DECODER(test_samsung32); - RUN_ENCODER_DECODER(test_rc6); - RUN_ENCODER_DECODER(test_rc5); - RUN_ENCODER_DECODER(test_sirc); -} - -MU_TEST_SUITE(test_infrared_decoder_encoder) { - MU_SUITE_CONFIGURE(&test_setup, &test_teardown); - - MU_RUN_TEST(test_encoder_sirc); - MU_RUN_TEST(test_decoder_sirc); - MU_RUN_TEST(test_encoder_rc5x); - MU_RUN_TEST(test_encoder_rc5); - MU_RUN_TEST(test_decoder_rc5); - MU_RUN_TEST(test_decoder_rc6); - MU_RUN_TEST(test_encoder_rc6); - MU_RUN_TEST(test_decoder_unexpected_end_in_sequence); - MU_RUN_TEST(test_decoder_long_packets_with_nec_start); - MU_RUN_TEST(test_decoder_nec); - MU_RUN_TEST(test_decoder_samsung32); - MU_RUN_TEST(test_decoder_necext1); - MU_RUN_TEST(test_mix); - MU_RUN_TEST(test_encoder_decoder_all); -} - -int run_minunit_test_infrared_decoder_encoder() { - MU_RUN_SUITE(test_infrared_decoder_encoder); - - return MU_EXIT_CODE; -} diff --git a/applications/unit_tests/infrared_decoder_encoder/test_data/infrared_nec_test_data.srcdata b/applications/unit_tests/infrared_decoder_encoder/test_data/infrared_nec_test_data.srcdata deleted file mode 100644 index ec9a86a6..00000000 --- a/applications/unit_tests/infrared_decoder_encoder/test_data/infrared_nec_test_data.srcdata +++ /dev/null @@ -1,341 +0,0 @@ -const uint32_t test_decoder_nec_input1[] = { -/* message */ -2640671, 9071, 4445, 601, 497, 578, 500, 604, 501, 603, 502, 581, 496, 615, 498, 606, 499, 584, 493, 610, 1630, 576, 1640, 601, 1615, 605, 1638, 581, 1634, 606, 1610, 610, 1633, 577, 1639, 601, 504, 580, 498, 604, 501, 603, 500, 582, 496, 607, 498, 606, 499, 585, 485, 610, 1633, 576, 1640, 596, 1615, 605, 1638, 582, 1634, 605, 1610, 609, 1634, 586, 1630, 600, -/* repeat */ -40015, 9077, 2208, 593, - -/* message */ -1457713, 9076, 4440, 607, 508, 585, 493, 610, 494, 598, 506, 577, 501, 603, 502, 601, 504, 580, 498, 605, 1638, 582, 1634, 606, 1610, 610, 1633, 577, 1639, 600, 1616, 605, 1638, 582, 1634, 606, 499, 585, 493, 609, 495, 608, 496, 586, 502, 612, 493, 601, 504, 579, 498, 605, 1638, 582, 1633, 606, 1610, 610, 1633, 577, 1639, 602, 1614, 574, 1668, 582, 1634, 606, - -/* message */ -1415838, 9080, 4436, 611, 494, 600, 505, 578, 500, 608, 501, 602, 502, 580, 498, 606, 508, 605, 500, 583, 1633, 608, 1608, 611, 1631, 578, 1638, 602, 1614, 606, 1637, 583, 1633, 607, 1609, 611, 494, 600, 505, 570, 500, 604, 501, 602, 502, 581, 497, 606, 499, 605, 499, 583, 1633, 617, 1608, 611, 1631, 579, 1638, 602}; - -const InfraredMessage test_decoder_nec_expected1[] = { - {InfraredProtocolNEC, 0x00, 0, false}, - {InfraredProtocolNEC, 0x00, 0, true}, - {InfraredProtocolNEC, 0x00, 0, false}, -}; - -const uint32_t test_decoder_nec_input2[] = { -18372093,9030,4495,559,524,585,526,613,496,560,522,595,524,605,504,553,530,578,524,608,1614,581,1668,557,1665,581,1641,585,1664,551,1671,605,1616,578,1670,555,528,581,1668,553,526,582,528,612,498,559,524,585,526,604,507,552,1670,597,504,553,1667,608,1613,582,1667,559,1663,613,1608,586,1662,552, -40067,9026,2219,579, - - -3060767,9079,4445,606,505,554,530,578,532,608,502,555,528,581,530,610,500,588,495,614,1635,580,1641,604,1617,618,1621,584,1637,608,1612,612,1636,589,1637,602,507,581,1641,605,505,582,501,609,502,607,503,585,498,611,499,609,1612,613,498,612,1610,615,1633,561,1661,606,1615,609,1639,585,1636,610, -40011,9072,2200,588, -96480,9075,2198,560, -96509,9047,2226,552, -96517,9049,2224,555, -96514,9042,2222,556, -96512,9053,2220,558, -96511,9045,2227,561, -96507,9048,2225,554, -96515,9061,2231,565, -96522,9053,2219,559, -96510,9044,2229,560, -96508,9046,2226,562, -96506,9027,2245,553, -96511,9030,2243,555, -96513,9031,2237,557, -96512,9054,2219,559, - - -570349,9027,4495,608,476,583,529,580,529,558,525,584,527,582,528,560,523,596,524,584,1636,578,1669,555,1667,578,1643,581,1666,558,1663,582,1639,586,1662,552,531,577,1670,554,1667,578,532,563,527,582,528,580,529,558,525,584,1665,561,523,586,525,584,1637,577,1670,554,1668,578,1642,582,1667,558, -40062,9021,2233,585, - - -172411,9020,4502,559,524,585,526,583,527,551,532,586,523,575,535,553,530,579,532,577,1643,581,1668,557,1664,581,1639,585,1664,552,1670,575,1637,579,1669,556,527,581,529,580,1642,584,536,581,528,560,523,585,524,584,526,552,1670,576,1645,579,530,578,1643,582,1667,558,1663,582,1639,586,1662,545, -40068,9026,2220,578, - - -226896,9054,4468,578,500,608,502,607,503,585,498,611,500,610,501,588,496,612,497,602,1610,615,1633,581,1640,606,1616,609,1639,585,1635,610,1612,614,1635,580,504,615,495,604,506,582,1639,606,503,585,499,610,501,609,502,587,1635,610,1610,614,1634,581,502,616,1632,582,1648,606,1615,610,1638,587, -40033,9050,2195,614, - -249594,9020,4502,560,524,594,525,603,506,552,532,587,521,606,504,554,529,579,532,609,1612,582,1667,557,1654,612,1608,585,1663,552,1670,606,1615,579,1669,554,527,582,529,611,500,558,1663,612,497,560,523,585,524,598,505,552,1670,606,1614,580,1668,557,526,582,1665,558,1662,603,1618,587,1661,553, -40067,9058,2187,621, - - -97567,9054,4467,584,500,609,501,601,502,586,497,611,499,610,501,588,496,614,497,612,1609,615,1632,582,1640,606,1615,609,1639,586,1636,611,1611,614,1634,581,503,608,493,605,505,583,1639,607,503,586,498,611,500,609,501,588,1634,611,1609,615,1634,582,502,608,1641,553,1668,608,1613,581,1668,558, - -112307,9078,4443,608,502,606,504,584,498,610,501,608,502,587,497,612,498,610,499,589,1633,603,1619,607,1642,583,1638,607,1614,611,1638,597,1634,611,1610,615,495,603,506,581,502,607,1642,584,500,609,501,607,503,585,498,611,1637,588,1634,611,1610,615,495,603,1618,607,1641,584,1638,607,1605,611, - - -112281,9076,4445,606,505,584,499,610,501,608,502,586,497,612,498,610,500,581,494,614,1635,581,1641,604,1617,608,1640,585,1637,609,1610,613,1636,589,1632,603,507,581,503,607,504,604,1617,608,502,607,503,585,498,611,500,609,1613,613,1636,590,1632,603,507,581,1641,605,1616,609,1640,585,1636,609, - - -94207,9075,4446,605,506,582,501,607,502,606,504,584,500,610,501,608,502,587,497,611,1636,588,1633,612,1610,616,1633,583,1639,604,1615,610,1638,587,1635,610,500,588,495,606,496,602,1619,616,495,605,506,583,501,609,502,606,1614,610,1638,587,1635,611,499,590,1632,603,1618,607,1641,583,1638,608, - - -103762,9076,4446,605,505,553,531,579,532,607,503,555,528,580,530,609,500,557,527,583,1666,559,1662,603,1609,587,1661,553,1669,608,1614,580,1659,557,1665,612,498,580,504,585,526,604,1617,607,503,606,504,584,499,610,500,609,1613,612,1636,588,1633,602,507,573,1641,605,1617,608,1640,585,1636,619, - - -76134,9056,4466,585,525,604,506,552,532,577,533,606,504,553,529,579,531,608,501,556,1665,611,1611,584,1665,561,1661,605,1616,578,1671,555,1667,609,1612,582,528,611,499,559,525,584,1664,551,533,586,524,605,505,553,530,578,1670,555,1667,610,1612,582,528,611,1610,584,1664,551,1671,606,1616,578, - - -112997,9073,4447,603,507,560,523,586,524,605,505,552,531,578,533,607,503,555,529,580,1668,548,1665,611,1611,584,1665,551,1671,615,1616,578,1670,555,1667,610,501,556,527,582,528,611,1609,584,518,604,506,551,533,586,524,606,1615,579,1669,555,1666,610,500,558,1664,612,1609,585,1663,551,1670,606, - - -84870,9053,4470,582,529,611,500,559,525,583,526,602,507,560,523,586,525,574,536,543,1669,608,1614,580,1668,556,1665,620,1610,585,1664,550,1671,605,1616,578,533,608,503,555,529,580,1677,557,526,582,528,612,498,559,525,585,1664,551,1671,605,1615,578,531,608,1614,581,1668,558,1664,611,1609,585, - - -76184,9025,4496,555,529,579,531,609,502,556,528,582,529,610,500,559,525,583,526,603,1619,586,1663,552,1669,606,1614,580,1668,556,1665,611,1610,584,1664,550,533,586,524,605,504,553,1669,608,503,555,529,580,530,609,501,557,1664,605,1609,585,1664,551,532,586,1661,553,1668,608,1614,581,1666,558, - - -96145,9073,4449,612,499,559,524,584,526,603,506,552,532,587,523,606,504,584,499,570,1669,556,1666,610,1611,614,1634,580,1641,605,1617,608,1640,584,1636,609,501,587,497,612,498,611,1611,615,496,602,508,580,503,595,535,614,1627,617,1650,594,1646,604,502,586,1635,611,1618,614,1634,581,1641,604, - - -86183,9080,4442,610,501,607,502,586,498,611,499,610,501,588,496,613,497,611,498,579,1642,604,1617,608,1641,583,1637,608,1613,611,1637,588,1634,611,1608,615,494,604,506,582,501,617,1641,584,499,610,493,608,502,586,497,612,1636,588,1633,602,1619,615,494,604,1617,608,1640,585,1637,608,1613,613, - - -234570,9078,4437,607,503,606,505,584,500,608,501,614,502,585,497,611,499,610,509,588,1634,612,1609,616,1633,582,1639,606,1616,610,1639,587,1635,610,1611,614,1634,581,503,606,504,604,1617,608,502,607,503,585,498,611,500,609,501,597,1634,611,1610,615,495,603,1618,607,1642,584,1638,607,1614,611, - - -112281,9076,4446,605,505,583,501,609,493,606,503,585,498,610,500,609,501,587,497,613,1636,579,1643,602,1618,606,1641,583,1639,607,1614,610,1638,554,1665,611,1611,584,526,603,507,551,1671,597,504,583,500,578,532,607,502,555,528,581,1668,556,1664,611,498,559,1663,604,1618,587,1662,553,1668,608, - - -130332,9076,4446,615,496,605,507,582,502,608,503,605,512,584,499,609,501,608,502,586,1636,610,1611,613,1635,579,1641,604,1617,608,1641,584,1637,608,1613,611,1636,588,495,614,497,613,1609,616,494,604,506,590,500,608,502,607,503,585,1635,609,1613,612,498,610,1610,614,1634,581,1641,604,1617,608, - - -886079,9020,4501,560,523,585,525,583,527,552,532,587,523,576,534,554,529,580,531,577,1644,582,1667,559,1663,582,1639,586,1663,553,1669,576,1645,581,1668,557,521,582,529,581,530,559,1663,582,527,551,532,587,523,575,535,553,1669,577,1644,581,1667,557,526,584,1665,560,1662,582,1637,588,1661,554, - - -76188,9053,4469,583,528,560,523,586,524,585,525,552,531,578,533,576,534,554,528,581,1668,557,1665,581,1631,585,1664,551,1670,575,1646,579,1678,555,1666,579,531,558,1664,581,528,559,1662,584,527,552,532,588,523,575,535,553,1668,578,532,556,1666,580,531,567,1663,582,1639,585,1662,552,1670,575, - - -76165,9054,4468,583,527,581,529,559,524,585,525,583,526,547,531,587,524,576,535,554,1668,577,1644,581,1667,558,1664,582,1640,586,1663,551,1670,576,1645,579,531,578,533,556,527,582,1666,559,525,583,526,582,528,560,523,586,1663,553,1669,576,1645,580,522,578,1642,582,1666,559,1663,582,1639,586, -40034,9049,2224,585, - - -114557,9051,4471,581,529,558,525,584,527,582,528,561,522,586,524,585,525,552,531,578,1670,555,1667,579,1643,577,1666,559,1662,583,1638,587,1662,563,1678,587,543,565,537,591,539,589,1651,592,537,591,539,569,533,595,535,593,1647,597,1670,563,1678,587,542,565,1675,589,1651,593,1675,569,1671,593, -40045,9047,2225,553, - - -114589,9029,4492,559,525,585,526,582,528,550,533,586,524,575,535,553,530,578,532,577,1645,581,1668,557,1664,581,1640,585,1664,552,1670,575,1646,579,1669,556,527,582,529,580,531,557,1663,582,528,560,523,586,524,585,525,552,1669,576,1645,580,1668,556,526,582,1667,559,1663,582,1639,593,1662,553, - - -40067,9026,4495,556,528,581,529,579,531,557,526,575,527,581,528,561,523,585,525,584,1638,588,1661,554,1667,578,1644,582,1667,559,1663,582,1639,586,1663,552,530,578,1671,555,529,581,1668,556,526,582,529,581,529,559,524,584,1664,550,533,587,1662,553,530,578,1669,555,1667,578,1642,582,1668,559, - - -58109,9049,4473,578,533,576,534,555,529,580,531,578,532,556,527,582,528,580,529,559,1663,583,1639,586,1662,553,1669,580,1644,581,1668,558,1664,581,1640,582,525,584,527,552,531,588,1670,554,529,579,531,578,532,556,527,582,1666,558,1663,582,1639,587,524,584,1636,578,1671,564,1676,588,1652,592, - - -263241,9028,4503,557,526,582,528,581,529,559,523,594,526,584,527,552,532,588,527,575,1646,579,1670,556,1666,579,1642,583,1665,560,1662,584,1638,578,1671,554,529,580,1669,559,527,582,1667,559,525,584,526,582,528,560,523,586,1662,552,530,578,1671,555,529,580,1668,556,1665,581,1640,584,1664,551, -40069,9025,2221,588 -}; - -const InfraredMessage test_decoder_nec_expected2[] = { - {InfraredProtocolNEC, 0x00, 0x02, false}, - {InfraredProtocolNEC, 0x00, 0x02, true}, - {InfraredProtocolNEC, 0x00, 0x02, false}, - {InfraredProtocolNEC, 0x00, 0x02, true}, - {InfraredProtocolNEC, 0x00, 0x02, true}, - {InfraredProtocolNEC, 0x00, 0x02, true}, - {InfraredProtocolNEC, 0x00, 0x02, true}, - {InfraredProtocolNEC, 0x00, 0x02, true}, - {InfraredProtocolNEC, 0x00, 0x02, true}, - {InfraredProtocolNEC, 0x00, 0x02, true}, - {InfraredProtocolNEC, 0x00, 0x02, true}, - {InfraredProtocolNEC, 0x00, 0x02, true}, - {InfraredProtocolNEC, 0x00, 0x02, true}, - {InfraredProtocolNEC, 0x00, 0x02, true}, - {InfraredProtocolNEC, 0x00, 0x02, true}, - {InfraredProtocolNEC, 0x00, 0x02, true}, - {InfraredProtocolNEC, 0x00, 0x02, true}, - {InfraredProtocolNEC, 0x00, 0x02, true}, - {InfraredProtocolNEC, 0x00, 0x02, true}, - {InfraredProtocolNEC, 0x00, 0x06, false}, - {InfraredProtocolNEC, 0x00, 0x06, true}, - {InfraredProtocolNEC, 0x00, 0x04, false}, - {InfraredProtocolNEC, 0x00, 0x04, true}, - {InfraredProtocolNEC, 0x00, 0x08, false}, - {InfraredProtocolNEC, 0x00, 0x08, true}, - {InfraredProtocolNEC, 0x00, 0x08, false}, - {InfraredProtocolNEC, 0x00, 0x08, true}, - {InfraredProtocolNEC, 0x00, 0x08, false}, - {InfraredProtocolNEC, 0x00, 0x08, false}, - {InfraredProtocolNEC, 0x00, 0x08, false}, - {InfraredProtocolNEC, 0x00, 0x08, false}, - {InfraredProtocolNEC, 0x00, 0x08, false}, - {InfraredProtocolNEC, 0x00, 0x08, false}, - {InfraredProtocolNEC, 0x00, 0x08, false}, - {InfraredProtocolNEC, 0x00, 0x08, false}, - {InfraredProtocolNEC, 0x00, 0x08, false}, - {InfraredProtocolNEC, 0x00, 0x08, false}, - {InfraredProtocolNEC, 0x00, 0x08, false}, - {InfraredProtocolNEC, 0x00, 0x09, false}, - {InfraredProtocolNEC, 0x00, 0x09, false}, - {InfraredProtocolNEC, 0x00, 0x09, false}, - {InfraredProtocolNEC, 0x00, 0x08, false}, - {InfraredProtocolNEC, 0x00, 0x0A, false}, - {InfraredProtocolNEC, 0x00, 0x08, false}, - {InfraredProtocolNEC, 0x00, 0x08, true}, - {InfraredProtocolNEC, 0x00, 0x08, false}, - {InfraredProtocolNEC, 0x00, 0x08, true}, - {InfraredProtocolNEC, 0x00, 0x08, false}, - {InfraredProtocolNEC, 0x00, 0x0A, false}, - {InfraredProtocolNEC, 0x00, 0x08, false}, - {InfraredProtocolNEC, 0x00, 0x0A, false}, - {InfraredProtocolNEC, 0x00, 0x0A, true}, -}; - -const uint32_t test_decoder_nec_input3[] = { -200000, 8862, 4452, 562, 563, 559, 1681, 563, 1646, 567, 586, 556, 569, 563, 583, 559, 571, 561, 1675, 559, 565, 567, 1673, 561, 561, 561, 592, 561, 565, 567, 579, 563, 567, 565, 584, 558, 1652, 561, 592, 561, 561, 561, 1679, 565, 560, 562, 584, 558, 1659, 564, 585, 557, 566, 566, 1675, 559, 1649, 564, 589, 564, 1649, 564, 1668, 566, 565, 567, 1669, 565, - 43470, 8896, 4432, 561, 561, 561, 1679, 565, 1648, 565, 581, 561, 568, 564, 586, 567, 558, 564, 1676, 558, 564, 558, 1681, 563, 563, 559, 587, 566, 565, 567, 582, 561, 564, 558, 595, 558, 1650, 563, 590, 563, 563, 559, 1674, 560, 570, 562, 587, 566, 1645, 568, 586, 556, 565, 567, 1672, 562, 1651, 562, 584, 558, 1658, 566, 1671, 563, 561, 561, 1679, 565, -200000, 8881, 4383, 569, 549, 573, 548, 574, 541, 571, 550, 572, 547, 575, 539, 573, 551, 571, 1651, 573, 545, 567, 554, 568, 548, 574, 1652, 572, 547, 575, 1645, 568, 1661, 573, 545, 567, 1657, 567, 554, 568, 547, 575, 1652, 572, 547, 575, 539, 573, 1657, 567, 550, 572, 545, 577, 1651, 573, 1648, 576, 545, 567, 1659, 575, 1645, 568, 555, 567, 1657, 567, - 38995, 8883, 4369, 573, 543, 569, 552, 570, 549, 573, 541, 571, 553, 569, 548, 574, 543, 569, 1658, 566, 550, 572, 548, 574, 546, 566, 1653, 571, 553, 569, 1654, 570, 1654, 570, 551, 571, 1651, 573, 547, 575, 545, 567, 1653, 571, 552, 570, 547, 575, 1649, 564, 556, 566, 550, 572, 1655, 569, 1656, 568, 546, 566, 1664, 570, 1653, 571, 547, 565, 1663, 571, -200000, 8987, 4504, 561, 593, 539, 589, 533, 596, 515, 586, 536, 592, 540, 588, 534, 595, 517, 1713, 541, 1664, 570, 1686, 558, 596, 515, 587, 535, 593, 539, 1691, 543, 1689, 565, 588, 513, 1691, 563, 1668, 617, 1613, 641, 1615, 567, 587, 535, 593, 519, 610, 512, 590, 542, 1714, 510, 593, 539, 1691, 563, 591, 510, 1720, 535, 594, 518, 584, 538, 591, 541, - 39546, 8990, 4501, 565, 590, 542, 586, 536, 593, 508, 593, 539, 589, 543, 585, 537, 592, 509, 1720, 545, 1660, 615, 1642, 561, 567, 534, 594, 538, 590, 542, 1688, 535, 1696, 558, 595, 517, 1687, 567, 1664, 621, 1635, 619, 1611, 561, 594, 538, 590, 511, 617, 515, 586, 536, 1721, 513, 589, 543, 1687, 568, 587, 514, 1691, 563, 590, 511, 591, 541, 587, 535, -200000, 8986, 4505, 560, 594, 538, 590, 542, 586, 515, 586, 536, 593, 539, 589, 533, 595, 517, 1714, 540, 587, 535, 594, 518, 1713, 542, 586, 515, 587, 535, 1722, 543, 1662, 562, 592, 540, 1664, 570, 585, 537, 591, 541, 1689, 545, 584, 538, 590, 542, 1688, 536, 593, 539, 589, 512, 590, 542, 586, 536, 1720, 514, 588, 544, 585, 537, 591, 541, 587, 514, - 40671, 8986, 4505, 560, 594, 538, 590, 542, 586, 515, 587, 535, 593, 539, 589, 533, 595, 516, 1714, 541, 587, 535, 594, 518, 1712, 542, 586, 515, 587, 535, 1722, 543, 1662, 561, 592, 540, 1664, 570, 585, 537, 591, 541, 1689, 545, 584, 538, 590, 542, 1688, 536, 593, 539, 589, 512, 590, 542, 586, 536, 1720, 514, 588, 544, 585, 537, 591, 541, 587, 514, -200000, 8990, 4500, 566, 1692, 562, 1668, 566, 588, 534, 594, 518, 584, 538, 591, 541, 587, 535, 1669, 565, 589, 543, 1688, 536, 592, 540, 1691, 563, 1667, 567, 1664, 621, 1635, 568, 586, 515, 587, 535, 593, 539, 589, 543, 1662, 562, 592, 540, 588, 534, 594, 518, 585, 537, 591, 541, 587, 514, 587, 535, 594, 538, 590, 542, 586, 515, 586, 536, 593, 539, - 39544, 8993, 4498, 567, 1690, 564, 1666, 568, 586, 536, 593, 508, 593, 539, 589, 543, 585, 537, 1668, 566, 588, 544, 1687, 537, 591, 541, 1690, 564, 1666, 568, 1663, 561, 1696, 569, 585, 516, 586, 536, 593, 539, 589, 543, 1661, 562, 592, 540, 588, 534, 594, 517, 584, 538, 591, 541, 587, 514, 587, 535, 593, 539, 589, 543, 585, 516, 586, 536, 592, 540, -200000, 8894, 4456, 589, 1676, 589, 571, 582, 574, 589, 571, 582, 1683, 582, 1677, 588, 1682, 583, 574, 589, 568, 585, 1682, 583, 1678, 587, 1680, 585, 574, 589, 565, 588, 575, 588, 1675, 590, 567, 586, 1681, 584, 571, 582, 1685, 590, 568, 585, 569, 584, 1685, 590, 567, 586, 1678, 587, 574, 589, 1672, 582, 578, 585, 1679, 586, 1674, 591, 572, 591, 1672, 582, - 39632, 8912, 4464, 560, 1703, 562, 598, 565, 594, 559, 594, 559, 1711, 564, 1698, 567, 1697, 568, 593, 560, 595, 568, 1698, 567, 1698, 567, 1693, 561, 602, 561, 596, 567, 590, 563, 1704, 561, 594, 559, 1707, 568, 591, 562, 1697, 568, 596, 567, 590, 563, 1700, 565, 596, 567, 1693, 561, 599, 564, 1701, 564, 589, 564, 1706, 559, 1704, 561, 597, 566, 1700, 565, -200000, 9018, 4500, 565, 1666, 568, 1689, 565, 588, 513, 1691, 615, 1616, 618, 1639, 564, 1667, 567, 587, 535, 594, 538, 563, 538, 590, 542, 586, 536, 593, 508, 593, 539, 589, 543, 1688, 535, 592, 540, 588, 544, 585, 537, 591, 510, 1694, 560, 1670, 564, 1693, 562, 1669, 565, 1692, 542, 1689, 565, 588, 534, 595, 517, 585, 537, 591, 541, 587, 535, 568, 544, 584, 538, 591, 541, 1663, 560, 1696, 569, 1662, 562, 1695, 539, 1692, 614, 1616, 566, 1691, 563, 1667, 567, - 23184, 9012, 4505, 560, 1697, 537, 1693, 561, 593, 508, 1696, 569, 1662, 562, 1695, 560, 1671, 563, 591, 541, 587, 535, 594, 518, 584, 538, 590, 542, 586, 515, 613, 509, 593, 539, 1692, 542, 585, 537, 592, 540, 588, 534, 594, 518, 1687, 567, 1663, 560, 1697, 568, 1662, 562, 1695, 539, 1692, 563, 591, 541, 587, 514, 588, 544, 584, 538, 590, 542, 586, 515, 587, 535, 593, 539, 1666, 568, 1689, 565, 1665, 569, 1688, 536, 1695, 570, 1661, 562, 1694, 561, 1670, 564, -200000, 8835, 4446, 537, 562, 539, 562, 539, 1663, 540, 1667, 536, 1669, 534, 560, 531, 573, 539, 559, 532, 1672, 531, 570, 531, 564, 537, 563, 538, 561, 540, 1660, 533, 1677, 536, 561, 540, 557, 534, 567, 534, 1668, 535, 1672, 531, 1675, 538, 555, 536, 1674, 539, 1665, 538, 1666, 537, 1671, 532, 563, 538, 1669, 534, 566, 535, 558, 533, 1677, 536, 562, 539, 558, 533, 568, 533, 1668, 535, 566, 535, 1670, 533, 1667, 536, 568, 533, 1671, 532, 1672, 531, 1676, 537, - 22779, 8870, 4437, 535, - 92592, 8861, 4414, 538, -}; - -const InfraredMessage test_decoder_nec_expected3[] = { - {InfraredProtocolNECext, 0x286, 0xB649, false}, - {InfraredProtocolNECext, 0x286, 0xB649, false}, - {InfraredProtocolNECext, 0x6880, 0xB649, false}, - {InfraredProtocolNECext, 0x6880, 0xB649, false}, - {InfraredProtocolNECext, 0x6380, 0x150F, false}, - {InfraredProtocolNECext, 0x6380, 0x150F, false}, - {InfraredProtocolNECext, 0x6480, 0x849, false}, - {InfraredProtocolNECext, 0x6480, 0x849, false}, - {InfraredProtocolNECext, 0x7A83, 0x8, false}, - {InfraredProtocolNECext, 0x7A83, 0x8, false}, - {InfraredProtocolNEC, 0x71, 0x4A, false}, - {InfraredProtocolNEC, 0x71, 0x4A, false}, - {InfraredProtocolNEC42, 0x7B, 0x0, false}, - {InfraredProtocolNEC42, 0x7B, 0x0, false}, - {InfraredProtocolNEC42, 0x11C, 0x12, false}, -}; - - -const InfraredMessage test_nec[] = { - {InfraredProtocolNEC, 0x00, 0x00, false}, - {InfraredProtocolNEC, 0x01, 0x00, false}, - {InfraredProtocolNEC, 0x01, 0x80, false}, - {InfraredProtocolNEC, 0x00, 0x80, false}, - {InfraredProtocolNEC, 0x00, 0x00, false}, - {InfraredProtocolNEC, 0x00, 0x00, true}, - {InfraredProtocolNEC, 0x00, 0x00, false}, - {InfraredProtocolNEC, 0x00, 0x00, true}, - {InfraredProtocolNEC, 0xFF, 0xFF, false}, - {InfraredProtocolNEC, 0xFE, 0xFF, false}, - {InfraredProtocolNEC, 0xFE, 0x7F, false}, - {InfraredProtocolNEC, 0xFF, 0x7F, false}, - {InfraredProtocolNEC, 0xFF, 0xFF, false}, - {InfraredProtocolNEC, 0xFF, 0xFF, true}, - {InfraredProtocolNEC, 0xAA, 0x55, false}, - {InfraredProtocolNEC, 0x55, 0xAA, false}, - {InfraredProtocolNEC, 0x55, 0x55, false}, - {InfraredProtocolNEC, 0xAA, 0xAA, false}, - {InfraredProtocolNEC, 0xAA, 0xAA, true}, - - {InfraredProtocolNEC, 0xAA, 0xAA, false}, - {InfraredProtocolNEC, 0xAA, 0xAA, true}, - {InfraredProtocolNEC, 0xAA, 0xAA, true}, - - {InfraredProtocolNEC, 0x55, 0x55, false}, - {InfraredProtocolNEC, 0x55, 0x55, true}, - {InfraredProtocolNEC, 0x55, 0x55, true}, - {InfraredProtocolNEC, 0x55, 0x55, true}, -}; - -const InfraredMessage test_nec42[] = { - {InfraredProtocolNEC42, 0x0000, 0x00, false}, - {InfraredProtocolNEC42, 0x0001, 0x00, false}, - {InfraredProtocolNEC42, 0x0001, 0x80, false}, - {InfraredProtocolNEC42, 0x0000, 0x80, false}, - {InfraredProtocolNEC42, 0x0000, 0x00, false}, - {InfraredProtocolNEC42, 0x0000, 0x00, true}, - {InfraredProtocolNEC42, 0x0000, 0x00, false}, - {InfraredProtocolNEC42, 0x0000, 0x00, true}, - {InfraredProtocolNEC42, 0x1FFF, 0xFF, false}, - {InfraredProtocolNEC42, 0x1FFE, 0xFF, false}, - {InfraredProtocolNEC42, 0x1FFE, 0x7F, false}, - {InfraredProtocolNEC42, 0x1FFF, 0x7F, false}, - {InfraredProtocolNEC42, 0x1FFF, 0xFF, false}, - {InfraredProtocolNEC42, 0x1FFF, 0xFF, true}, - {InfraredProtocolNEC42, 0x0AAA, 0x55, false}, - {InfraredProtocolNEC42, 0x1555, 0xAA, false}, - {InfraredProtocolNEC42, 0x1555, 0x55, false}, - {InfraredProtocolNEC42, 0x0AAA, 0xAA, false}, - {InfraredProtocolNEC42, 0x0AAA, 0xAA, true}, - {InfraredProtocolNEC42, 0x0AAA, 0xAA, false}, - {InfraredProtocolNEC42, 0x0AAA, 0xAA, true}, - {InfraredProtocolNEC42, 0x0AAA, 0xAA, true}, - {InfraredProtocolNEC42, 0x1555, 0x55, false}, - {InfraredProtocolNEC42, 0x1555, 0x55, true}, - {InfraredProtocolNEC42, 0x1555, 0x55, true}, - {InfraredProtocolNEC42, 0x1555, 0x55, true}, -}; - -const InfraredMessage test_nec42ext[] = { - {InfraredProtocolNEC42ext, 0x0000000, 0x0000, false}, - {InfraredProtocolNEC42ext, 0x0000001, 0x0000, false}, - {InfraredProtocolNEC42ext, 0x0000001, 0x8000, false}, - {InfraredProtocolNEC42ext, 0x0000000, 0x8000, false}, - {InfraredProtocolNEC42ext, 0x0000000, 0x0000, false}, - {InfraredProtocolNEC42ext, 0x0000000, 0x0000, true}, - {InfraredProtocolNEC42ext, 0x0000000, 0x0000, false}, - {InfraredProtocolNEC42ext, 0x0000000, 0x0000, true}, - {InfraredProtocolNEC42ext, 0x3F000FF, 0xF00F, false}, - {InfraredProtocolNEC42ext, 0x3F000FE, 0xF00F, false}, - {InfraredProtocolNEC42ext, 0x3F000FE, 0x700F, false}, - {InfraredProtocolNEC42ext, 0x3F000FF, 0x700F, false}, - {InfraredProtocolNEC42ext, 0x3F000FF, 0xF00F, false}, - {InfraredProtocolNEC42ext, 0x3F000FF, 0xF00F, true}, - {InfraredProtocolNEC42ext, 0x2AAAAAA, 0x5555, false}, - {InfraredProtocolNEC42ext, 0x1555555, 0xAAAA, false}, - {InfraredProtocolNEC42ext, 0x1555555, 0x5555, false}, - {InfraredProtocolNEC42ext, 0x2AAAAAA, 0xAAAA, false}, - {InfraredProtocolNEC42ext, 0x2AAAAAA, 0xAAAA, true}, - {InfraredProtocolNEC42ext, 0x2AAAAAA, 0xAAAA, false}, - {InfraredProtocolNEC42ext, 0x2AAAAAA, 0xAAAA, true}, - {InfraredProtocolNEC42ext, 0x2AAAAAA, 0xAAAA, true}, - {InfraredProtocolNEC42ext, 0x1555555, 0x5555, false}, - {InfraredProtocolNEC42ext, 0x1555555, 0x5555, true}, - {InfraredProtocolNEC42ext, 0x1555555, 0x5555, true}, - {InfraredProtocolNEC42ext, 0x1555555, 0x5555, true}, -}; - -const uint32_t test_decoder_nec42ext_input1[] = { -2000000, 9000, 4500, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, // 8 - 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, // 16 - 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, // 24 - 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, // 32 - 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, // 40 - 560, 560, 560, 560, 560, // 42 -}; - -const uint32_t test_decoder_nec42ext_input2[] = { -2000000, 9000, 4500, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, // 8 - 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, // 16 - 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, // 24 - 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, // 32 - 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, // 40 - 560, 560, 560, 560, 560, 560, 560, // 43 - failed - -2000000, 9000, 4500, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, // 8 - 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, // 16 - 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, // 24 - 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, // 32 - 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, // 40 - 560, 560, 560, 560, 560, 10000, 560, // 42 OK + 1 failed -}; - -const InfraredMessage test_decoder_nec42ext_expected1[] = { - {InfraredProtocolNEC42ext, 0x00, 0, false}, -}; - -const InfraredMessage test_decoder_nec42ext_expected2[] = { - {InfraredProtocolNEC42ext, 0x00, 0, false}, -}; - diff --git a/applications/unit_tests/infrared_decoder_encoder/test_data/infrared_necext_test_data.srcdata b/applications/unit_tests/infrared_decoder_encoder/test_data/infrared_necext_test_data.srcdata deleted file mode 100644 index 22ccf40b..00000000 --- a/applications/unit_tests/infrared_decoder_encoder/test_data/infrared_necext_test_data.srcdata +++ /dev/null @@ -1,255 +0,0 @@ -const uint32_t test_decoder_necext_input1[] = { -1915384, 8967, 4463, 587, 527, 590, 524, 584, 1647, 590, 524, 583, 531, 586, 527, 590, 524, 583, 1646, 589, 1640, 586, 527, 590, 524, 583, 1647, 590, 1640, 587, 1644, 582, 1647, 589, 524, 583, 531, 586, 1644, 593, 521, 586, 527, 589, 1641, 586, 528, 589, 525, 592, 521, 585, 1644, 592, 522, 585, 1645, 592, 1638, 589, 524, 592, 1637, 588, 1641, 585, 1645, 592, -41082, 8965, 2220, 591, -409594, 8972, 4458, 591, 523, 584, 530, 587, 1642, 584, 529, 588, 526, 591, 522, 583, 530, 587, 1643, 584, 1646, 590, 523, 584, 530, 587, 1643, 584, 1647, 590, 1640, 586, 1643, 583, 531, 586, 527, 589, 1641, 586, 528, 589, 524, 593, 1637, 589, 524, 593, 521, 586, 529, 589, 1641, 585, 528, 589, 1640, 586, 1644, 592, 521, 585, 1645, 592, 1638, 588, 1641, 585, -41088, 8968, 2218, 582, -95791, 8971, 2214, 587, -95787, 8965, 2220, 591, -95783, 8971, 2215, 585, -95787, 8964, 2221, 590, -95783, 8971, 2215, 586, -95788, 8965, 2220, 591, -95783, 8969, 2216, 585, -95789, 8965, 2220, 590, -95782, 8970, 2215, 586, -95788, 9047, 2139, 591, -95782, 8970, 2216, 585, -95788, 8966, 2220, 591, -95782, 8972, 2214, 588, -95786, 8964, 2222, 590, -95784, 8971, 2214, 586, -95787, 8967, 2218, 583, -95791, 8964, 2222, 588, -95785, 8969, 2217, 584, -333740, 8967, 4464, 586, 528, 590, 524, 592, 1637, 589, 525, 592, 521, 586, 528, 589, 525, 593, 1637, 588, 1640, 585, 528, 589, 525, 592, 1638, 589, 1641, 586, 1644, 592, 1638, 588, 525, 592, 522, 585, 1644, 592, 522, 585, 528, 588, 1642, 585, 529, 588, 526, 591, 522, 585, 1645, 591, 522, 584, 1646, 591, 1639, 587, 526, 591, 1639, 588, 1642, 583, 1646, 590, -41082, 8963, 2223, 588, -95785, 8967, 2219, 591, -95782, 8968, 2217, 584, -246369, 8972, 4459, 591, 523, 583, 530, 587, 1643, 583, 530, 587, 527, 590, 523, 584, 530, 586, 1643, 583, 1647, 590, 524, 583, 530, 586, 1643, 583, 1646, 589, 1641, 586, 1644, 583, 531, 586, 528, 589, 1640, 585, 528, 588, 525, 592, 1638, 588, 525, 592, 522, 585, 529, 589, 1641, 584, 529, 588, 1642, 585, 1645, 591, 522, 585, 1645, 590, 1639, 587, 1642, 584, -41090, 8966, 2220, 591, -95782, 8966, 2220, 592, -95782, 8967, 2218, 583, -165604, 9017, 4413, 586, 527, 590, 524, 583, 1647, 589, 523, 582, 531, 586, 528, 589, 525, 593, 1637, 589, 1640, 585, 527, 588, 525, 592, 1638, 589, 1641, 585, 1644, 592, 1638, 588, 525, 591, 523, 585, 1645, 591, 522, 584, 529, 588, 1642, 584, 530, 587, 527, 591, 523, 584, 1646, 591, 523, 584, 1646, 591, 1640, 586, 527, 590, 1640, 586, 1643, 583, 1646, 589, -41084, 8972, 2214, 587, -95787, 8967, 2219, 581, -95792, 8971, 2215, 586, -208929, 9016, 4414, 584, 529, 588, 526, 591, 1638, 588, 525, 591, 522, 584, 529, 587, 526, 591, 1639, 587, 1642, 584, 529, 588, 526, 591, 1638, 587, 1643, 584, 1646, 591, 1639, 587, 526, 590, 523, 584, 1646, 590, 524, 583, 530, 587, 1643, 583, 530, 587, 527, 590, 524, 583, 1647, 590, 524, 583, 1647, 590, 1640, 586, 527, 589, 1640, 586, 1644, 592, 1637, 589, -41085, 8972, 2214, 587, -95787, 8964, 2221, 590, -95784, 8965, 2221, 590, -167378, 8969, 4460, 589, 525, 582, 532, 586, 1644, 592, 521, 586, 528, 589, 524, 592, 522, 585, 1645, 592, 1638, 589, 525, 592, 522, 585, 1644, 591, 1639, 588, 1642, 585, 1645, 591, 522, 585, 529, 587, 1641, 584, 530, 587, 526, 591, 1639, 588, 526, 591, 522, 584, 530, 587, 1643, 584, 530, 587, 1642, 584, 1646, 591, 523, 584, 1647, 590, 1640, 587, 1643, 583, -41090, 9017, 2169, 591, -95781, 8969, 2216, 585, -95788, 8964, 2223, 588, -192781, 8969, 4461, 589, 525, 592, 522, 586, 1644, 592, 521, 586, 528, 589, 525, 592, 522, 585, 1644, 592, 1638, 589, 524, 592, 521, 586, 1645, 591, 1638, 588, 1642, 585, 1645, 590, 522, 584, 530, 587, 1642, 584, 530, 587, 526, 591, 1639, 588, 526, 590, 524, 583, 530, 587, 1643, 584, 530, 587, 1643, 584, 1646, 590, 524, 583, 1646, 590, 1640, 587, 1643, 583, -41090, 8967, 2219, 591, -95782, 8970, 2215, 586, -95788, 8963, 2222, 589, -179978, 8967, 4464, 586, 528, 589, 524, 593, 1637, 588, 525, 592, 522, 585, 529, 589, 525, 592, 1638, 589, 1641, 585, 529, 588, 526, 591, 1638, 588, 1641, 585, 1645, 590, 1639, 587, 527, 590, 523, 584, 1646, 591, 523, 584, 530, 587, 1643, 583, 530, 586, 527, 590, 524, 583, 1646, 590, 523, 584, 1646, 589, 1640, 586, 528, 589, 1640, 586, 1644, 593, 1638, 589, -41084, 8971, 2214, 587, -95787, 8964, 2221, 589, -95785, 8966, 2219, 592, -196616, 8967, 4463, 585, 527, 590, 525, 592, 1637, 589, 525, 592, 521, 586, 528, 589, 524, 592, 1638, 588, 1641, 585, 528, 589, 525, 592, 1637, 589, 1641, 585, 1645, 591, 1638, 588, 526, 591, 522, 585, 1645, 591, 522, 584, 530, 587, 1642, 584, 529, 588, 526, 591, 523, 583, 1645, 590, 523, 584, 1646, 590, 1639, 587, 527, 590, 1639, 586, 1644, 583, 1647, 589, -41084, 8971, 2214, 587, -95787, 8964, 2222, 589, -2112164, 8969, 4462, 588, 525, 592, 522, 585, 1645, 591, 523, 584, 529, 588, 526, 591, 523, 584, 1645, 591, 1639, 587, 527, 590, 524, 583, 1646, 590, 1639, 587, 1643, 584, 1673, 563, 524, 583, 531, 586, 1643, 593, 521, 586, 528, 589, 1641, 585, 528, 589, 525, 592, 521, 585, 1644, 592, 522, 584, 1645, 591, 1639, 588, 526, 591, 1639, 588, 1642, 583, 1646, 590, -41082, 8962, 2223, 588, -95785, 8965, 2220, 591, -95783, 8968, 2217, 583, -164778, 8969, 4462, 588, 525, 591, 522, 585, 1645, 591, 522, 585, 530, 587, 527, 591, 523, 584, 1646, 591, 1639, 588, 526, 591, 523, 583, 1646, 590, 1639, 587, 1643, 584, 1672, 564, 523, 584, 531, 586, 1643, 583, 530, 587, 527, 590, 1639, 587, 527, 589, 524, 583, 531, 586, 1644, 583, 531, 586, 1643, 583, 1647, 590, 525, 582, 1647, 589, 1639, 586, 1644, 593, -41081, 8965, 2220, 590, -95784, 8968, 2217, 583, -95790, 8970, 2215, 586, -161053, 8963, 4468, 592, 521, 586, 528, 589, 1641, 585, 529, 588, 526, 591, 522, 585, 529, 588, 1642, 585, 1645, 591, 523, 584, 530, 587, 1642, 584, 1646, 591, 1639, 586, 1669, 557, 531, 586, 527, 590, 1640, 586, 527, 590, 525, 592, 1638, 589, 525, 592, 522, 585, 528, 588, 1641, 585, 528, 588, 1642, 584, 1645, 591, 523, 584, 1645, 591, 1639, 587, 1643, 583, -41090, 8964, 2221, 590, -95784, 8963, 2222, 589, -95785, 8965, 2220, 590, -139334, 8968, 4463, 587, 527, 590, 523, 584, 1646, 590, 523, 583, 531, 586, 527, 589, 524, 583, 1647, 590, 1640, 586, 527, 590, 525, 592, 1637, 589, 1641, 585, 1644, 592, 1665, 562, 524, 591, 522, 584, 1645, 591, 523, 584, 529, 588, 1642, 584, 529, 587, 527, 590, 523, 584, 1646, 590, 523, 584, 1646, 590, 1639, 587, 527, 589, 1640, 586, 1644, 592, 1637, 589, -41085, 8970, 2217, 584, -95789, 8972, 2213, 586, -95787, 8965, 2221, 590, -141444, 8969, 4461, 589, 525, 592, 522, 584, 1644, 591, 522, 585, 529, 588, 526, 591, 522, 585, 1645, 592, 1638, 587, 526, 591, 523, 584, 1646, 591, 1639, 588, 1642, 583, 1672, 564, 523, 584, 530, 587, 1643, 584, 530, 587, 527, 590, 1640, 587, 527, 590, 524, 584, 530, 587, 1643, 584, 530, 586, 1644, 583, 1647, 589, 524, 583, 1647, 590, 1640, 586, 1645, 592, -41081, 8964, 2222, 589, -95784, 8968, 2218, 583, -95790, 8971, 2214, 586, -154119, 8969, 4462, 588, 526, 591, 522, 585, 1645, 592, 522, 585, 529, 589, 526, 591, 522, 584, 1646, 591, 1639, 588, 526, 591, 523, 583, 1645, 590, 1639, 587, 1642, 584, 1671, 564, 523, 584, 529, 587, 1643, 583, 530, 587, 527, 590, 1639, 587, 526, 590, 523, 583, 530, 586, 1643, 583, 529, 586, 1643, 583, 1646, 590, 524, 583, 1648, 589, 1641, 586, 1644, 592, -41081, 8965, 2220, 590, -95784, 8969, 2216, 585, -95790, 8964, 2221, 590, -147134, 8966, 4464, 586, 528, 589, 525, 593, 1637, 589, 524, 593, 522, 585, 529, 589, 525, 592, 1638, 589, 1641, 586, 528, 589, 525, 591, 1638, 588, 1641, 585, 1645, 592, 1664, 561, 525, 592, 523, 584, 1646, 591, 523, 584, 530, 588, 1642, 585, 526, 587, 527, 590, 523, 584, 1646, 591, 523, 584, 1646, 591, 1639, 586, 526, 590, 1640, 587, 1643, 583, 1646, 590, -41083, 8963, 2223, 587, -95786, 8965, 2221, 590, -95784, 8968, 2217, 584, -158330, 8965, 4465, 585, 529, 588, 526, 590, 1639, 587, 526, 590, 523, 584, 530, 586, 526, 590, 1639, 587, 1643, 583, 530, 587, 527, 590, 1639, 587, 1643, 584, 1647, 590, 1666, 561, 527, 589, 523, 583, 1646, 590, 523, 583, 531, 586, 1643, 583, 530, 586, 527, 590, 524, 582, 1646, 590, 525, 582, 1647, 589, 1640, 586, 528, 589, 1640, 586, 1644, 592, 1638, 589, -41085, 8971, 2214, 586, -95787, 8962, 2223, 588, -95786, 8965, 2222, 589, -206063, 8962, 4467, 591, 521, 585, 529, 588, 1642, 585, 529, 588, 525, 591, 522, 584, 530, 587, 1642, 584, 1646, 591, 523, 584, 529, 588, 1642, 583, 1646, 590, 1640, 587, 1668, 558, 530, 587, 526, 589, 1639, 586, 528, 589, 524, 583, 1647, 589, 524, 593, 521, 585, 528, 589, 1641, 585, 529, 589, 1641, 585, 1645, 592, 522, 585, 1644, 591, 1639, 587, 1642, 584, -41090, 8965, 2221, 590, -95784, 8963, 2223, 588, -95785, 8964, 2222, 589, -183026, 8970, 4460, 590, 524, 583, 531, 586, 1643, 583, 530, 587, 528, 589, 525, 592, 522, 586, 1644, 592, 1637, 588, 525, 591, 522, 585, 1645, 592, 1638, 588, 1641, 585, 1672, 565, 522, 584, 530, 588, 1642, 584, 529, 588, 526, 591, 1639, 587, 527, 590, 523, 584, 530, 587, 1642, 584, 530, 587, 1642, 583, 1647, 590, 524, 583, 1647, 590, 1640, 587, 1643, 582, -41090, 8965, 2221, 590, -95783, 8970, 2216, 584, -95789, 8962, 2223, 587, -184104, 8964, 4467, 583, 530, 587, 527, 590, 1640, 587, 527, 590, 523, 582, 531, 586, 528, 589, 1640, 586, 1644, 593, 521, 586, 528, 589, 1640, 585, 1644, 592, 1638, 589, 1667, 558, 528, 589, 526, 591, 1638, 588, 526, 591, 522, 585, 1645, 591, 522, 585, 530, 587, 527, 591, 1639, 587, 526, 591, 1639, 587, 1642, 584, 530, 587, 1643, 583, 1646, 590, 1639, 587, -41087, 9020, 2166, 584, -95790, 8972, 2213, 587, -95787, 8963, 2222, 589, -169833, 8964, 4465, 583, 529, 587, 527, 590, 1639, 587, 527, 591, 523, 584, 530, 586, 527, 590, 1640, 587, 1643, 583, 531, 587, 527, 590, 1640, 586, 1644, 583, 1647, 590, 1666, 560, 527, 590, 524, 582, 1647, 589, 525, 592, 521, 586, 1644, 592, 521, 586, 528, 589, 526, 592, 1638, 588, 525, 592, 1638, 589, 1641, 585, 528, 589, 1641, 585, 1645, 591, 1638, 588, -41086, 8971, 2215, 585, -95789, 8964, 2222, 588, -95785, 8967, 2218, 583, -185701, 8971, 4460, 590, 523, 584, 530, 587, 1642, 584, 530, 587, 527, 590, 524, 583, 531, 586, 1644, 583, 1647, 590, 524, 592, 521, 585, 1644, 592, 1638, 589, 1641, 585, 1671, 565, 522, 586, 529, 588, 1642, 585, 529, 588, 526, 591, 1638, 588, 525, 590, 523, 584, 530, 587, 1642, 584, 530, 587, 1642, 584, 1646, 590, 524, 583, 1646, 590, 1640, 586, 1643, 583, -41091, 8965, 2222, 589, -95784, 8965, 2221, 589, -95784, 8968, 2217, 583, -146332, 8969, 4461, 669, 445, 591, 522, 584, 1644, 591, 523, 584, 529, 588, 526, 591, 522, 585, 1645, 591, 1638, 587, 527, 590, 524, 584, 1646, 590, 1639, 587, 1642, 583, 1673, 564, 524, 583, 531, 586, 1643, 583, 531, 586, 528, 589, 1641, 585, 528, 589, 525, 592, 522, 585, 1644, 591, 521, 585, 1645, 592, 1638, 588, 525, 592, 1638, 588, 1641, 584, 1646, 591, -41083, 8963, 2222, 589, -95785, 8966, 2220, 592, -261924, 8965, 4465, 585, 529, 588, 525, 592, 1638, 588, 525, 592, 523, 584, 530, 587, 526, 591, 1639, 587, 1642, 583, 529, 587, 527, 590, 1639, 587, 1643, 584, 1646, 590, -}; - -const InfraredMessage test_decoder_necext_expected1[] = { - {InfraredProtocolNECext, 0x7984, 0xed12, false}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, false}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, false}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, false}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, false}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, false}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, false}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, false}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, false}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, false}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, false}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, false}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, false}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, false}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, false}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, false}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, false}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, false}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, false}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, false}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, false}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, false}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, false}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, false}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, - {InfraredProtocolNECext, 0x7984, 0xed12, true}, -}; - -const InfraredMessage test_necext[] = { - {InfraredProtocolNECext, 0x0000, 0x0000, false}, - {InfraredProtocolNECext, 0x0001, 0x0000, false}, - {InfraredProtocolNECext, 0x0001, 0x8000, false}, - {InfraredProtocolNECext, 0x0000, 0x8000, false}, - {InfraredProtocolNECext, 0x0000, 0x0000, false}, - {InfraredProtocolNECext, 0x0000, 0x0000, true}, - {InfraredProtocolNECext, 0x0000, 0x0000, false}, - {InfraredProtocolNECext, 0x0000, 0x0000, true}, - {InfraredProtocolNECext, 0xFFFF, 0xFFFF, false}, - {InfraredProtocolNECext, 0xFFFE, 0xFFFF, false}, - {InfraredProtocolNECext, 0xFFFE, 0x7FFF, false}, - {InfraredProtocolNECext, 0xFFFF, 0x7FFF, false}, - {InfraredProtocolNECext, 0xFFFF, 0xFFFF, false}, - {InfraredProtocolNECext, 0xFFFF, 0xFFFF, true}, - {InfraredProtocolNECext, 0xAAAA, 0x5555, false}, - {InfraredProtocolNECext, 0x5555, 0xAAAA, false}, - {InfraredProtocolNECext, 0x5555, 0x5555, false}, - {InfraredProtocolNECext, 0xAAAA, 0xAAAA, false}, - {InfraredProtocolNECext, 0xAAAA, 0xAAAA, true}, - - {InfraredProtocolNECext, 0xAAAA, 0xAAAA, false}, - {InfraredProtocolNECext, 0xAAAA, 0xAAAA, true}, - {InfraredProtocolNECext, 0xAAAA, 0xAAAA, true}, - - {InfraredProtocolNECext, 0x5555, 0x5555, false}, - {InfraredProtocolNECext, 0x5555, 0x5555, true}, - {InfraredProtocolNECext, 0x5555, 0x5555, true}, - {InfraredProtocolNECext, 0x5555, 0x5555, true}, -}; - - diff --git a/applications/unit_tests/infrared_decoder_encoder/test_data/infrared_rc5_test_data.srcdata b/applications/unit_tests/infrared_decoder_encoder/test_data/infrared_rc5_test_data.srcdata deleted file mode 100644 index 07241555..00000000 --- a/applications/unit_tests/infrared_decoder_encoder/test_data/infrared_rc5_test_data.srcdata +++ /dev/null @@ -1,160 +0,0 @@ -/* -_______----__--____----__--____--__----____----__--__--__--__ - | 1 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | - s1 s2 t | address | command | -*/ - -const uint32_t test_decoder_rc5x_input1[] = { -27000 + 888, 1776, 888, 888, 1776, 1776, 888, 888, 1776, 888, 888, 1776, 1776, 1776, 888, 888, 888, 888, 888, 888, -}; - -const InfraredMessage test_decoder_rc5x_expected1[] = { - {InfraredProtocolRC5X, 0x13, 0x10, false}, // toggle 0 -}; - -/* -_______--__----____----__--____--__----____----__--__--__--__ - | 1 | 1 | 0 | 1 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | - s1 s2 t | address | command | -*/ - -const uint32_t test_decoder_rc5_input1[] = { -27000 + 888, 888, 888, 1776, 1776, 1776, 888, 888, 1776, 888, 888, 1776, 1776, 1776, 888, 888, 888, 888, 888, 888, -}; - -const InfraredMessage test_decoder_rc5_expected1[] = { - {InfraredProtocolRC5, 0x13, 0x10, false}, // toggle 0 -}; - - -/* -_______--__--__--__----__--____--__----____----__--__--__--__ - | 1 | 1 | 1 | 1 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | - s1 s2 t | address | command | -*/ - -const uint32_t test_decoder_rc5_input2[] = { -27000 + 888, 888, 888, 888, 888, 888, 888, 1776, 888, 888, 1776, 888, 888, 1776, 1776, 1776, 888, 888, 888, 888, 888, 888, -}; - -const InfraredMessage test_decoder_rc5_expected2[] = { - {InfraredProtocolRC5, 0x13, 0x10, false}, // toggle 1 -}; - -/* -_______--__----____----__--____--__----____----__--__--____-- - | 1 | 1 | 0 | 1 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 0 | 0 | 1 | - s1 s2 t | address | command | -*/ - -const uint32_t test_decoder_rc5_input3[] = { -27000 + 888, 888, 888, 1776, 1776, 1776, 888, 888, 1776, 888, 888, 1776, 1776, 1776, 888, 888, 888, 888, 1776, 888, -}; - -const InfraredMessage test_decoder_rc5_expected3[] = { - {InfraredProtocolRC5, 0x13, 0x11, false}, // toggle 0 -}; - - -/* -_______--__--__--__----__--____--__----____----__--__--____-- - | 1 | 1 | 1 | 1 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 0 | 0 | 1 | - s1 s2 t | address | command | -*/ - -const uint32_t test_decoder_rc5_input4[] = { -27000 + 888, 888, 888, 888, 888, 888, 888, 1776, 888, 888, 1776, 888, 888, 1776, 1776, 1776, 888, 888, 888, 888, 1776, 888, -}; - -const InfraredMessage test_decoder_rc5_expected4[] = { - {InfraredProtocolRC5, 0x13, 0x11, false}, // toggle 1 -}; - -/* -_______--__----____--__--__--__--__--__--__--__--__--__--__-- - | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | - s1 s2 t | address | command | -*/ - -const uint32_t test_decoder_rc5_input5[] = { -27000 + 888, 888, 888, 1776, 1776, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, -}; - -const InfraredMessage test_decoder_rc5_expected5[] = { - {InfraredProtocolRC5, 0x1F, 0x3F, false}, // toggle 0 -}; - -/* -_______--__--__--__--__--__--__--__--__--__--__--__--__--__-- - | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | - s1 s2 t | address | command | -*/ - -const uint32_t test_decoder_rc5_input6[] = { -27000 + 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, -}; - -const InfraredMessage test_decoder_rc5_expected6[] = { - {InfraredProtocolRC5, 0x1F, 0x3F, false}, // toggle 1 -}; - - -const uint32_t test_decoder_rc5_input_all_repeats[] = { -27000 + 888, 888, 888, 1776, 1776, 1776, 888, 888, 1776, 888, 888, 1776, 1776, 1776, 888, 888, 888, 888, 1776, 888, -27000 + 888, 888, 888, 888, 888, 888, 888, 1776, 888, 888, 1776, 888, 888, 1776, 1776, 1776, 888, 888, 888, 888, 1776, 888, -27000 + 888, 888, 888, 888, 888, 888, 888, 1776, 888, 888, 1776, 888, 888, 1776, 1776, 1776, 888, 888, 888, 888, 1776, 888, -27000 + 888, 888, 888, 888, 888, 888, 888, 1776, 888, 888, 1776, 888, 888, 1776, 1776, 1776, 888, 888, 888, 888, 1776, 888, -27000 + 888, 888, 888, 1776, 1776, 1776, 888, 888, 1776, 888, 888, 1776, 1776, 1776, 888, 888, 888, 888, 1776, 888, -27000 + 888, 888, 888, 888, 888, 888, 888, 1776, 888, 888, 1776, 888, 888, 1776, 1776, 1776, 888, 888, 888, 888, 888, 888, -27000 + 888, 888, 888, 1776, 1776, 1776, 888, 888, 1776, 888, 888, 1776, 1776, 1776, 888, 888, 888, 888, 888, 888, -27000 + 888, 888, 888, 1776, 1776, 1776, 888, 888, 1776, 888, 888, 1776, 1776, 1776, 888, 888, 888, 888, 888, 888, -27000 + 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, -27000 + 888, 888, 888, 1776, 1776, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, -27000 + 888, 888, 888, 1776, 1776, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, -}; - -const InfraredMessage test_decoder_rc5_expected_all_repeats[] = { - {InfraredProtocolRC5, 0x13, 0x11, false}, // toggle 0 - {InfraredProtocolRC5, 0x13, 0x11, false}, // toggle 1 - {InfraredProtocolRC5, 0x13, 0x11, true}, // toggle 1 - {InfraredProtocolRC5, 0x13, 0x11, true}, // toggle 1 - {InfraredProtocolRC5, 0x13, 0x11, false}, // toggle 0 - {InfraredProtocolRC5, 0x13, 0x10, false}, // toggle 1 - {InfraredProtocolRC5, 0x13, 0x10, false}, // toggle 0 - {InfraredProtocolRC5, 0x13, 0x10, true}, // toggle 0 - {InfraredProtocolRC5, 0x1F, 0x3F, false}, // toggle 1 - {InfraredProtocolRC5, 0x1F, 0x3F, false}, // toggle 0 - {InfraredProtocolRC5, 0x1F, 0x3F, true}, // toggle 0 -}; - - -const InfraredMessage test_rc5[] = { - {InfraredProtocolRC5, 0x1F, 0x3F, false}, - {InfraredProtocolRC5, 0x00, 0x00, false}, - {InfraredProtocolRC5, 0x10, 0x01, false}, - {InfraredProtocolRC5, 0x01, 0x20, false}, - {InfraredProtocolRC5, 0x01, 0x20, false}, - {InfraredProtocolRC5, 0x01, 0x20, true}, - {InfraredProtocolRC5, 0x01, 0x20, true}, - {InfraredProtocolRC5, 0x01, 0x20, true}, - {InfraredProtocolRC5, 0x01, 0x20, true}, - {InfraredProtocolRC5, 0x1F, 0x3F, false}, - {InfraredProtocolRC5, 0x0A, 0x2A, false}, - {InfraredProtocolRC5, 0x15, 0x15, false}, - {InfraredProtocolRC5, 0x15, 0x15, true}, - - {InfraredProtocolRC5X, 0x1F, 0x3F, false}, - {InfraredProtocolRC5X, 0x00, 0x00, false}, - {InfraredProtocolRC5X, 0x10, 0x01, false}, - {InfraredProtocolRC5X, 0x01, 0x20, false}, - {InfraredProtocolRC5X, 0x01, 0x20, false}, - {InfraredProtocolRC5X, 0x01, 0x20, true}, - {InfraredProtocolRC5X, 0x01, 0x20, true}, - {InfraredProtocolRC5X, 0x01, 0x20, true}, - {InfraredProtocolRC5X, 0x01, 0x20, true}, - {InfraredProtocolRC5X, 0x1F, 0x3F, false}, - {InfraredProtocolRC5X, 0x0A, 0x2A, false}, - {InfraredProtocolRC5X, 0x15, 0x15, false}, - {InfraredProtocolRC5X, 0x15, 0x15, true}, -}; - diff --git a/applications/unit_tests/infrared_decoder_encoder/test_data/infrared_rc6_test_data.srcdata b/applications/unit_tests/infrared_decoder_encoder/test_data/infrared_rc6_test_data.srcdata deleted file mode 100644 index 94b9be5a..00000000 --- a/applications/unit_tests/infrared_decoder_encoder/test_data/infrared_rc6_test_data.srcdata +++ /dev/null @@ -1,162 +0,0 @@ -/* -_____---------______--____--__--__--____------____--__----____--__----__--__--____----____--__--__--__--__--___________ - | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 93 A0 0 - s m2 m1 m0 T | address | command | -// 93 A0 0 -27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 444 + 444, 888 + 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, -//27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 444 + 444, 888 + 444, 888, 444, 444, 888, 888, -// --__----__--__-- -// 0 | 0 | 1 | 1 | 1 -//444, 444, 888, 444, 444, 444, 444, -//888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, - -_____---------______--____--__--__------____--____--__----____--__----__--__--____----____--__--__--__--__--___________ - | 1 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 93 A0 1 -// 93 A0 1 -27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444 + 888, 888, 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, -//27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444 + 888, 888, 444, 888, 444, 444, 888, 888, -//444, 444, 888, 444, 444, 444, 444, -//888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, - -_____---------______--____--__--__--____------____--__----____----____--__----____----____--__--__--__--__--___________ - | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 94 A0 0 -// 94 A0 0 -27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 444 + 444, 888 + 444, 888, 444, 444, 888, 888, 888, 888, 444, 444, 888, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, -//27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 444 + 444, 888 + 444, 888, 444, 444, 888, 888, -//----____--__---- -//0 | 1 | 0 | 0 | 1 -//888, 888, 444, 444, 888, -//888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, - -_____---------______--____--__--__------____--____--__----____----____--__----____----____--__--__--__--__--___________ - | 1 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 94 A0 1 -// 94 A0 1 -27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444 + 888, 888, 444, 888, 444, 444, 888, 888, 888, 888, 444, 444, 888, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, -//27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444 + 888, 888, 444, 888, 444, 444, 888, 888, -//888, 888, 444, 444, 888, -//888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, - -_____---------______--____--__--__--____------____--__----____----____----__--____----____--__--__--__--__--___________ - | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 95 A0 0 -// 95 A0 0 -27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 444 + 444, 888 + 444, 888, 444, 444, 888, 888, 888, 888, 888, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, -//27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 444 + 444, 888 + 444, 888, 444, 444, 888, 888, -//----____----__-- -//0 | 1 | 0 | 1 | 1 -//888, 888, 888, 444, 444, -//888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, - -_____---------______--____--__--__------____--____--__----____----____----__--____----____--__--__--__--__--___________ - | 1 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 95 A0 1 -// 95 A0 1 -27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444 + 888, 888, 444, 888, 444, 444, 888, 888, 888, 888, 888, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, -//27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444 + 888, 888, 444, 888, 444, 444, 888, 888, -//888, 888, 888, 444, 444, -//888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, - -*/ - -const uint32_t test_decoder_rc6_input1[] = { -// 94 A0 0 -27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 444 + 444, 888 + 444, 888, 444, 444, 888, 888, 888, 888, 444, 444, 888, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, -// 93 A0 1 -27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444 + 888, 888, 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, - // failed 95 - 27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444 + 888, 888, 444, 888, 444, 444, 888, 888, 888, 888, 888, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 888, -// 93 A0 0 -27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 444 + 444, 888 + 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, -// 94 A0 1 -27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444 + 888, 888, 444, 888, 444, 444, 888, 888, 888, 888, 444, 444, 888, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, -// 95 A0 0 -27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 444 + 444, 888 + 444, 888, 444, 444, 888, 888, 888, 888, 888, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, - // failed 93 + 1 sample - 27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444 + 888, 888, 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, 444, 444, 444, 444, - // failed 93 - 27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444 + 888, 888, 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 888, 444, 444, - // failed 93 - 27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444 + 888, 888, 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 888, -// 95 A0 1 -27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444 + 888, 888, 444, 888, 444, 444, 888, 888, 888, 888, 888, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, -}; - -const InfraredMessage test_decoder_rc6_expected1[] = { - {InfraredProtocolRC6, 0x94, 0xA0, false}, // toggle 0 - {InfraredProtocolRC6, 0x93, 0xA0, false}, // toggle 1 -// {InfraredProtocolRC6, 0x95, 0xA0, false}, failed - {InfraredProtocolRC6, 0x93, 0xA0, false}, // toggle 0 - {InfraredProtocolRC6, 0x94, 0xA0, false}, // toggle 1 - {InfraredProtocolRC6, 0x95, 0xA0, false}, // toggle 0 -// {InfraredProtocolRC6, 0x93, 0xA0, false}, failed -// {InfraredProtocolRC6, 0x93, 0xA0, false}, failed -// {InfraredProtocolRC6, 0x93, 0xA0, false}, failed - {InfraredProtocolRC6, 0x95, 0xA0, false}, // toggle 1 -}; - -const InfraredMessage test_encoder_rc6_input1[] = { - {InfraredProtocolRC6, 0x93, 0xA0, false}, // Toggle 0 - {InfraredProtocolRC6, 0x93, 0xA0, true}, // Toggle 0 - {InfraredProtocolRC6, 0x93, 0xA1, false}, // Toggle 1 - {InfraredProtocolRC6, 0x93, 0xA1, true}, // Toggle 1 - {InfraredProtocolRC6, 0x93, 0xA1, true}, // Toggle 1 - {InfraredProtocolRC6, 0x93, 0xA0, false}, // Toggle 0 - {InfraredProtocolRC6, 0x93, 0xA0, false}, // Toggle 1 - {InfraredProtocolRC6, 0x93, 0xA0, true}, // Toggle 1 -}; - -const uint32_t test_encoder_rc6_expected1[] = { -27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 888, 888+444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, -27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 888, 888+444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, -27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444+888, 888, 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 888, -27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444+888, 888, 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 888, -27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444+888, 888, 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 888, -27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 888, 888+444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, -27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444+888, 888, 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, -27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444+888, 888, 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, -}; - - -const InfraredMessage test_rc6[] = { - {InfraredProtocolRC6, 0x00, 0x00, false}, // t 0 - {InfraredProtocolRC6, 0x80, 0x00, false}, // t 1 - {InfraredProtocolRC6, 0x80, 0x01, false}, // t 0 - {InfraredProtocolRC6, 0x00, 0x01, false}, // t 1 - {InfraredProtocolRC6, 0x00, 0x00, false}, // t 0 - {InfraredProtocolRC6, 0x00, 0x00, true}, // t 0 - {InfraredProtocolRC6, 0x00, 0x00, false}, // t 1 - {InfraredProtocolRC6, 0x00, 0x00, true}, // t 1 - {InfraredProtocolRC6, 0xFF, 0xFF, false}, // t 0 - {InfraredProtocolRC6, 0x7F, 0xFF, false}, // t 1 - {InfraredProtocolRC6, 0x7F, 0xFE, false}, // t 0 - {InfraredProtocolRC6, 0xFF, 0xFE, false}, // t 1 - {InfraredProtocolRC6, 0xFF, 0xFF, false}, // t 0 - {InfraredProtocolRC6, 0xFF, 0xFF, true}, // t 0 - {InfraredProtocolRC6, 0xAA, 0x55, false}, // t 1 - {InfraredProtocolRC6, 0x55, 0xAA, false}, // t 0 - {InfraredProtocolRC6, 0x55, 0x55, false}, // t 1 - {InfraredProtocolRC6, 0xAA, 0xAA, false}, // t 0 - {InfraredProtocolRC6, 0xAA, 0xAA, true}, // t 0 -// same with inverted toggle bit - {InfraredProtocolRC6, 0x00, 0x00, false}, // t 1 - {InfraredProtocolRC6, 0x80, 0x00, false}, // t 0 - {InfraredProtocolRC6, 0x80, 0x01, false}, // t 1 - {InfraredProtocolRC6, 0x00, 0x01, false}, // t 0 - {InfraredProtocolRC6, 0x00, 0x00, false}, // t 1 - {InfraredProtocolRC6, 0x00, 0x00, true}, // t 1 - {InfraredProtocolRC6, 0x00, 0x00, false}, // t 0 - {InfraredProtocolRC6, 0x00, 0x00, true}, // t 0 - {InfraredProtocolRC6, 0xFF, 0xFF, false}, // t 1 - {InfraredProtocolRC6, 0x7F, 0xFF, false}, // t 0 - {InfraredProtocolRC6, 0x7F, 0xFE, false}, // t 1 - {InfraredProtocolRC6, 0xFF, 0xFE, false}, // t 0 - {InfraredProtocolRC6, 0xFF, 0xFF, false}, // t 1 - {InfraredProtocolRC6, 0xFF, 0xFF, true}, // t 1 - {InfraredProtocolRC6, 0xAA, 0x55, false}, // t 0 - {InfraredProtocolRC6, 0x55, 0xAA, false}, // t 1 - {InfraredProtocolRC6, 0x55, 0x55, false}, // t 0 - {InfraredProtocolRC6, 0xAA, 0xAA, false}, // t 1 - {InfraredProtocolRC6, 0xAA, 0xAA, true}, // t 1 - - {InfraredProtocolRC6, 0x93, 0xA0, false}, // t 0 - {InfraredProtocolRC6, 0x93, 0xA1, false}, // t 1 -}; - diff --git a/applications/unit_tests/infrared_decoder_encoder/test_data/infrared_samsung_test_data.srcdata b/applications/unit_tests/infrared_decoder_encoder/test_data/infrared_samsung_test_data.srcdata deleted file mode 100644 index aea867b9..00000000 --- a/applications/unit_tests/infrared_decoder_encoder/test_data/infrared_samsung_test_data.srcdata +++ /dev/null @@ -1,254 +0,0 @@ -const uint32_t test_decoder_samsung32_input1[] = { - 3129767, 4513, 4483, 565, 530, 586, 1670, 563, 1664, 588, 1666, 566, 530, 586, - 535, 560, 535, 591, 531, 565, 531, 585, 1669, 563, 1666, 587, 1640, 593, - 531, 566, 530, 587, 536, 559, 562, 564, 531, 585, 537, 558, 1670, 562, - 1665, 587, 534, 561, 534, 592, 530, 566, 529, 587, 1668, 564, 1664, 589, - 533, 563, 533, 594, 1661, 560, 1667, 565, 1661, 591, 1664, 558, 46325, 4517, - 4480, 558, 1668, 595, - - 679127, 4511, 4485, 562, 532, 584, 1671, 561, 1666, 587, 1668, 564, 532, 585, - 537, 559, 537, 589, 533, 562, 533, 593, 1661, 561, 1667, 586, 1642, 590, - 532, 563, 531, 585, 537, 559, 564, 563, 1666, 567, 528, 588, 535, 613, - 483, 593, 530, 586, 536, 559, 536, 590, 1637, 584, 537, 558, 1669, 594, - 1661, 561, 1667, 586, 1642, 591, 1664, 559, 1670, 583, 534, 567, 46429, 4515, - 4480, 558, 1671, 593, - - 618571, 4508, 4488, 560, 561, 566, 1663, 559, 1667, 583, 1670, 562, 534, 582, - 540, 565, 531, 587, 536, 560, 536, 590, 1664, 558, 1670, 583, 1644, 588, - 535, 561, 534, 592, 530, 566, 557, 610, 1616, 616, 479, 585, 537, 558, - 537, 589, 534, 584, 539, 567, 529, 587, 534, 561, 534, 592, 1663, 559, - 1668, 564, 1664, 588, 1666, 566, 1661, 581, 1646, 585, 1669, 563, 46106, 4511, - 4485, 563, 1664, 589, - - 514897, 4514, 4482, 556, 564, 614, 1616, 565, 1664, 589, 1666, 557, 538, 588, - 534, 562, 534, 592, 529, 566, 529, 587, 1667, 565, 1663, 590, 1638, 584, - 538, 568, 527, 590, 534, 562, 562, 566, 530, 587, 1642, 590, 532, 563, - 530, 586, 537, 589, 533, 563, 533, 583, 539, 566, 1661, 561, 561, 566, - 1663, 559, 1668, 584, 1671, 563, 1666, 556, 1671, 591, 1663, 559, 46210, 4508, - 4488, 560, 1668, 585, - - 683922, 4509, 4487, 561, 560, 565, 1662, 559, 1669, 585, 1670, 562, 534, 583, - 540, 566, 529, 586, 535, 560, 535, 591, 1663, 559, 1669, 584, 1644, 588, - 534, 561, 533, 593, 529, 556, 567, 561, 1668, 564, 1664, 590, 534, 563, - 532, 584, 538, 557, 537, 589, 534, 562, 534, 593, 530, 566, 555, 561, - 1667, 564, 1662, 589, 1665, 557, 1671, 581, 1647, 586, 1669, 564, 46686, 4514, - 4481, 556, 1672, 592, - - 1088255, 4514, 4481, 557, 564, 562, 1667, 565, 1663, 591, 1665, 558, 538, 590, - 533, 564, 532, 583, 539, 567, 528, 588, 1666, 566, 1663, 580, 1648, 585, - 537, 559, 537, 589, 533, 562, 560, 618, 478, 589, 535, 562, 1667, 565, - 1662, 588, 531, 565, 531, 585, 537, 558, 536, 590, 1666, 566, 1661, 592, - 530, 566, 530, 586, 1669, 564, 1664, 558, 1669, 594, 1662, 560, 46291, 4510, - 4485, 563, 1663, 589, 97349, 4510, 4487, 561, 1666, 586, 97560, 4513, 4482, 566, - 1662, 591, 97123, 4510, 4485, 563, 1664, 588, 97605, 4508, 4487, 561, 1666, 586, - 97371, 4518, 4478, 560, 1668, 595, 97514, 4518, 4478, 560, 1667, 586, 97014, 4515, - 4480, 568, 1660, 593, 96719, 4516, 4481, 567, 1660, 593, 97528, 4515, 4480, 568, - 1659, 593, 97453, 4510, 4485, 563, 1665, 587, 97351, 4518, 4477, 561, 1668, 585, - 97216, 4511, 4484, 564, 1664, 589, 97708, 4518, 4477, 561, 1667, 586, 96718, 4516, - 4479, 559, 1669, 594, 97070, 4515, 4480, 568, 1660, 593, 97500, 4511, 4484, 564, - 1662, 590, 97425, 4515, 4481, 567, 1660, 593, 97025, 4515, 4482, 566, 1660, 592, - 96796, 4509, 4487, 561, 1666, 587, 97399, 4512, 4484, 565, 1662, 591, 97486, 4516, - 4480, 567, 1658, 594, 97425, 4515, 4481, 567, 1659, 593, 97511, 4510, 4485, 563, - 1664, 650, 96969, 4511, 4485, 562, 1665, 588, 97243, 4512, 4484, 564, 1663, 590, - 97031, 4519, 4478, 560, 1666, 586, 97548, 4514, 4482, 566, 1661, 591, 97302, 4515, - 4480, 568, 1659, 593, 97726, 4510, 4486, 562, 1665, 588, 97396, 4514, 4482, 566, - 1661, 592, 97301, 4515, 4480, 568, 1661, 593, 97453, 4518, 4477, 560, 1667, 585, - 97430, 4518, 4477, 561, 1665, 587, 97521, 4511, 4484, 564, 1664, 589, 97182, 4512, - 4484, 564, 1663, 590, 97760, 4516, 4479, 559, 1668, 595, 97268, 4516, 4479, 559, - 1668, 595, 97243, 4512, 4485, 563, 1663, 589, 97695, 4510, 4486, 562, 1664, 588, - 374205, 4513, 4483, 565, 530, 586, 1669, 564, 1665, 589, 1667, 567, 529, 587, - 535, 560, 535, 591, 531, 565, 530, 585, 1669, 563, 1664, 588, 1639, 593, - 529, 566, 529, 587, 536, 560, 563, 565, 532, 585, 537, 560, 1669, 563, - 1664, 587, 534, 561, 534, 592, 529, 566, 529, 586, 1668, 564, 1663, 589, - 532, 563, 534, 593, 1661, 562, 1666, 566, 1662, 591, 1664, 558, - - 149343, 4512, 4483, 565, 530, 586, 1669, 563, 1664, 588, 1667, 565, 530, 586, - 536, 560, 536, 590, 532, 563, 531, 586, 1670, 563, 1666, 567, 1660, 592, - 530, 565, 529, 586, 537, 558, 563, 563, 532, 584, 538, 568, 1661, 561, - 1665, 587, 535, 560, 535, 592, 532, 565, 531, 587, 1669, 563, 1665, 587, - 534, 561, 534, 592, 1663, 559, 1668, 564, 1662, 590, 1666, 566, - - 116399, 4514, 4482, 566, 531, 587, 1669, 564, 1664, 589, 1666, 566, 529, 587, - 535, 561, 535, 592, 531, 565, 529, 587, 1668, 564, 1664, 558, 1670, 595, - 529, 566, 528, 589, 535, 560, 562, 565, 531, 585, 536, 559, 1668, 564, - 1664, 589, 534, 561, 533, 593, 530, 565, 528, 588, 1668, 564, 1665, 590, - 533, 564, 532, 594, 1661, 561, 1666, 566, 1661, 592, 1663, 558, - - 121946, 4517, 4478, 559, 537, 590, 1664, 568, 1660, 593, 1661, 560, 536, 590, - 531, 564, 531, 585, 537, 559, 536, 590, 1665, 568, 1661, 561, 1666, 587, - 537, 559, 529, 591, 531, 564, 558, 558, 537, 588, 533, 562, 1665, 567, - 1659, 593, 530, 565, 529, 587, 536, 561, 535, 592, 1664, 559, 1671, 593, - 530, 566, 528, 587, 1667, 565, 1662, 558, 1668, 595, 1660, 561, 46509, 4516, - 4479, 558, 1668, 594, - - 88785, 4512, 4484, 564, 530, 585, 1669, 563, 1664, 588, 1666, 566, 530, 587, - 536, 560, 535, 592, 532, 565, 531, 585, 1669, 563, 1665, 557, 1669, 594, - 530, 566, 530, 586, 535, 560, 562, 564, 530, 585, 537, 558, 1669, 563, - 1664, 589, 535, 561, 534, 593, 529, 566, 529, 586, 1668, 564, 1664, 589, - 533, 562, 532, 594, 1661, 561, 1666, 565, 1662, 591, 1665, 558, - - 289651, 4512, 4483, 564, 531, 586, 1669, 563, 1665, 588, 1667, 565, 529, 587, - 536, 560, 536, 590, 531, 563, 531, 584, 1670, 562, 1666, 556, 1671, 592, - 529, 566, 531, 586, 536, 561, 562, 564, 532, 585, 537, 558, 1669, 563, - 1665, 588, 535, 561, 536, 590, 530, 565, 531, 585, 1669, 563, 1664, 587, - 534, 561, 533, 593, 1662, 561, 1669, 564, 1663, 590, 1665, 567, 46302, 4509, - 4487, 561, 1667, 585, - - 97097, 4513, 4483, 565, 529, 587, 1668, 564, 1663, 589, 1666, 567, 529, 587, - 536, 560, 535, 591, 530, 565, 529, 587, 1669, 563, 1664, 558, 1669, 594, - 529, 566, 527, 587, 535, 561, 561, 563, 530, 586, 537, 560, 1669, 563, - 1663, 589, 534, 561, 532, 594, 529, 566, 528, 587, 1668, 564, 1663, 589, - 532, 563, 532, 594, 1660, 561, 1667, 566, 1661, 592, 1663, 558, 46311, 4510, - 4485, 562, 1665, 589, - - 99001, 4514, 4481, 566, 528, 587, 1667, 565, 1662, 589, 1664, 568, 528, 588, - 535, 561, 535, 593, 529, 567, 528, 589, 1668, 564, 1663, 559, 1668, 595, - 528, 567, 527, 589, 534, 562, 561, 565, 530, 586, 536, 560, 1668, 564, - 1663, 590, 533, 563, 532, 595, 524, 567, 527, 588, 1667, 565, 1662, 590, - 532, 563, 531, 595, 1659, 562, 1666, 566, 1661, 593, 1664, 559, - - 300259, 4514, 4482, 556, 565, 561, 1668, 564, 1663, 589, 1664, 556, 539, 588, - 535, 561, 535, 643, 478, 568, 530, 587, 1668, 564, 1664, 589, 1636, 594, - 529, 567, 528, 588, 534, 561, 561, 565, 1662, 560, 536, 590, 532, 564, - 531, 586, 537, 589, 532, 564, 533, 584, 538, 568, 528, 588, 1667, 565, - 1662, 560, 1669, 584, 1670, 562, 1666, 587, 1641, 591, 1664, 559, 46271, 4561, - 4435, 562, 1666, 586, - - 81421, 4514, 4482, 556, 565, 561, 1667, 565, 1662, 589, 1664, 558, 538, 588, - 534, 562, 534, 593, 530, 567, 530, 587, 1669, 564, 1663, 589, 1637, 594, - 529, 567, 528, 588, 534, 561, 560, 566, 1663, 559, 535, 591, 531, 565, - 530, 587, 538, 589, 533, 563, 533, 583, 539, 567, 529, 587, 1667, 565, - 1662, 560, 1669, 584, 1669, 563, 1666, 587, 1640, 592, 1663, 560, 46296, 4516, - 4480, 558, 1669, 594, - - 80690, 4508, 4489, 560, 561, 565, 1663, 558, 1670, 593, 1660, 561, 534, 592, - 530, 565, 530, 586, 537, 560, 536, 591, 1664, 558, 1670, 583, 1644, 587, - 535, 560, 534, 592, 530, 566, 556, 559, 1669, 563, 532, 584, 538, 558, - 537, 588, 534, 582, 540, 567, 530, 588, 535, 562, 535, 591, 1663, 559, - 1669, 564, 1665, 588, 1666, 566, 1662, 560, 1668, 585, 1669, 563, - - 136483, 4511, 4485, 563, 531, 585, 1671, 561, 1666, 587, 1668, 564, 531, 585, - 536, 559, 537, 589, 532, 563, 532, 584, 1670, 562, 1666, 587, 1642, 591, - 531, 566, 531, 585, 536, 559, 563, 563, 1665, 567, 528, 588, 535, 561, - 534, 593, 529, 567, 556, 560, 535, 591, 530, 565, 531, 585, 1670, 563, - 1665, 568, 1660, 593, 1662, 560, 1668, 564, 1663, 590, 1666, 566, - - 129038, 4511, 4484, 564, 533, 583, 1670, 562, 1666, 587, 1668, 565, 532, 586, - 537, 559, 536, 591, 532, 564, 532, 594, 1660, 562, 1666, 566, 1660, 593, - 531, 565, 530, 586, 537, 558, 563, 563, 1664, 568, 528, 589, 535, 562, - 533, 595, 530, 567, 556, 560, 535, 591, 531, 565, 531, 584, 1669, 563, - 1664, 567, 1661, 592, 1662, 559, 1668, 564, 1663, 590, 1666, 566, 46187, 4511, - 4486, 562, 1665, 589, - - 110663, 4517, 4478, 558, 536, 590, 1665, 568, 1660, 593, 1661, 560, 536, 590, - 531, 564, 531, 584, 537, 558, 536, 590, 1665, 567, 1661, 561, 1666, 587, - 536, 560, 535, 591, 532, 564, 559, 557, 1670, 562, 532, 594, 529, 567, - 528, 649, 473, 561, 561, 565, 531, 585, 536, 559, 536, 589, 1665, 567, - 1660, 562, 1666, 587, 1668, 564, 1663, 558, 1669, 594, 1661, 561, - - 143736, 4517, 4479, 559, 536, 591, 1664, 558, 1670, 593, 1661, 559, 536, 590, - 531, 564, 531, 585, 536, 559, 537, 589, 1665, 567, 1661, 561, 1666, 587, - 536, 560, 536, 590, 530, 564, 557, 558, 1669, 562, 533, 593, 528, 568, - 530, 586, 534, 561, 560, 566, 530, 586, 536, 560, 536, 591, 1664, 558, - 1671, 562, 1666, 587, 1667, 565, 1663, 559, 1668, 594, 1660, 562, 46234, 4514, - 4482, 566, 1661, 591, - - 120661, 4564, 4432, 565, 530, 586, 1669, 563, 1665, 587, 1666, 566, 531, 585, - 536, 559, 536, 591, 532, 564, 532, 586, 1670, 563, 1666, 557, 1666, 592, - 530, 565, 530, 586, 536, 560, 562, 563, 1664, 558, 538, 588, 533, 562, - 533, 593, 528, 558, 565, 561, 534, 582, 541, 566, 530, 586, 1670, 563, - 1664, 567, 1660, 593, 1662, 560, 1668, 564, 1663, 590, 1665, 567, 46472, 4513, - 4484, 564, 1664, 588, - - 125301, 4511, 4484, 564, 532, 584, 1670, 562, 1666, 587, 1668, 565, 531, 586, - 537, 560, 537, 591, 532, 565, 533, 584, 1671, 562, 1666, 566, 1661, 591, - 530, 565, 532, 584, 536, 559, 562, 564, 1665, 567, 529, 587, 534, 563, - 535, 593, 529, 568, 556, 561, 535, 592, 531, 565, 531, 585, 1669, 563, - 1665, 567, 1660, 593, 1663, 559, 1668, 564, 1664, 589, 1666, 567, - - 200253, 4517, 4479, 558, 562, 615, 1613, 558, 1670, 592, 1661, 560, 536, 591, - 531, 616, 480, 585, 537, 559, 537, 641, 1613, 568, 1661, 582, 1646, 586, - 536, 559, 535, 591, 532, 564, 558, 558, 1670, 562, 533, 592, 530, 566, - 529, 588, 536, 581, 542, 617, 479, 587, 537, 560, 536, 590, 1665, 557, - 1670, 562, 1666, 587, 1668, 564, 1664, 558, 1669, 593, 1662, 561, 46230, 4570, - 4426, 561, 1667, 586, - - 115418, 4514, 4483, 565, 557, 561, 1669, 563, 1664, 589, 1666, 566, 529, 587, - 534, 561, 534, 592, 530, 566, 530, 586, 1668, 564, 1664, 589, 1639, 594, - 529, 567, 528, 587, 534, 561, 561, 565, 1663, 559, 535, 590, 532, 563, - 532, 584, -}; - -const InfraredMessage test_decoder_samsung32_expected1[] = { - {InfraredProtocolSamsung32, 0x0E, 0x0C, false}, {InfraredProtocolSamsung32, 0x0E, 0x0C, true}, - {InfraredProtocolSamsung32, 0x0E, 0x81, false}, {InfraredProtocolSamsung32, 0x0E, 0x81, true}, - {InfraredProtocolSamsung32, 0x0E, 0x01, false}, {InfraredProtocolSamsung32, 0x0E, 0x01, true}, - {InfraredProtocolSamsung32, 0x0E, 0x02, false}, {InfraredProtocolSamsung32, 0x0E, 0x02, true}, - {InfraredProtocolSamsung32, 0x0E, 0x03, false}, {InfraredProtocolSamsung32, 0x0E, 0x03, true}, - {InfraredProtocolSamsung32, 0x0E, 0x0C, false}, {InfraredProtocolSamsung32, 0x0E, 0x0C, true}, - {InfraredProtocolSamsung32, 0x0E, 0x0C, true}, {InfraredProtocolSamsung32, 0x0E, 0x0C, true}, - {InfraredProtocolSamsung32, 0x0E, 0x0C, true}, {InfraredProtocolSamsung32, 0x0E, 0x0C, true}, - {InfraredProtocolSamsung32, 0x0E, 0x0C, true}, {InfraredProtocolSamsung32, 0x0E, 0x0C, true}, - {InfraredProtocolSamsung32, 0x0E, 0x0C, true}, {InfraredProtocolSamsung32, 0x0E, 0x0C, true}, - {InfraredProtocolSamsung32, 0x0E, 0x0C, true}, {InfraredProtocolSamsung32, 0x0E, 0x0C, true}, - {InfraredProtocolSamsung32, 0x0E, 0x0C, true}, {InfraredProtocolSamsung32, 0x0E, 0x0C, true}, - {InfraredProtocolSamsung32, 0x0E, 0x0C, true}, {InfraredProtocolSamsung32, 0x0E, 0x0C, true}, - {InfraredProtocolSamsung32, 0x0E, 0x0C, true}, {InfraredProtocolSamsung32, 0x0E, 0x0C, true}, - {InfraredProtocolSamsung32, 0x0E, 0x0C, true}, {InfraredProtocolSamsung32, 0x0E, 0x0C, true}, - {InfraredProtocolSamsung32, 0x0E, 0x0C, true}, {InfraredProtocolSamsung32, 0x0E, 0x0C, true}, - {InfraredProtocolSamsung32, 0x0E, 0x0C, true}, {InfraredProtocolSamsung32, 0x0E, 0x0C, true}, - {InfraredProtocolSamsung32, 0x0E, 0x0C, true}, {InfraredProtocolSamsung32, 0x0E, 0x0C, true}, - {InfraredProtocolSamsung32, 0x0E, 0x0C, true}, {InfraredProtocolSamsung32, 0x0E, 0x0C, true}, - {InfraredProtocolSamsung32, 0x0E, 0x0C, true}, {InfraredProtocolSamsung32, 0x0E, 0x0C, true}, - {InfraredProtocolSamsung32, 0x0E, 0x0C, true}, {InfraredProtocolSamsung32, 0x0E, 0x0C, true}, - {InfraredProtocolSamsung32, 0x0E, 0x0C, true}, {InfraredProtocolSamsung32, 0x0E, 0x0C, true}, - {InfraredProtocolSamsung32, 0x0E, 0x0C, true}, {InfraredProtocolSamsung32, 0x0E, 0x0C, true}, - {InfraredProtocolSamsung32, 0x0E, 0x0C, true}, {InfraredProtocolSamsung32, 0x0E, 0x0C, true}, - {InfraredProtocolSamsung32, 0x0E, 0x0C, true}, {InfraredProtocolSamsung32, 0x0E, 0x0C, true}, - {InfraredProtocolSamsung32, 0x0E, 0x0C, true}, {InfraredProtocolSamsung32, 0x0E, 0x0C, false}, - {InfraredProtocolSamsung32, 0x0E, 0x0C, false}, {InfraredProtocolSamsung32, 0x0E, 0x0C, false}, - {InfraredProtocolSamsung32, 0x0E, 0x0C, false}, {InfraredProtocolSamsung32, 0x0E, 0x0C, true}, - {InfraredProtocolSamsung32, 0x0E, 0x0C, false}, {InfraredProtocolSamsung32, 0x0E, 0x0C, false}, - {InfraredProtocolSamsung32, 0x0E, 0x0C, true}, {InfraredProtocolSamsung32, 0x0E, 0x0C, false}, - {InfraredProtocolSamsung32, 0x0E, 0x0C, true}, {InfraredProtocolSamsung32, 0x0E, 0x0C, false}, - {InfraredProtocolSamsung32, 0x0E, 0x01, false}, {InfraredProtocolSamsung32, 0x0E, 0x01, true}, - {InfraredProtocolSamsung32, 0x0E, 0x01, false}, {InfraredProtocolSamsung32, 0x0E, 0x01, true}, - {InfraredProtocolSamsung32, 0x0E, 0x01, false}, {InfraredProtocolSamsung32, 0x0E, 0x01, false}, - {InfraredProtocolSamsung32, 0x0E, 0x01, false}, {InfraredProtocolSamsung32, 0x0E, 0x01, true}, - {InfraredProtocolSamsung32, 0x0E, 0x01, false}, {InfraredProtocolSamsung32, 0x0E, 0x01, false}, - {InfraredProtocolSamsung32, 0x0E, 0x01, true}, {InfraredProtocolSamsung32, 0x0E, 0x01, false}, - {InfraredProtocolSamsung32, 0x0E, 0x01, true}, {InfraredProtocolSamsung32, 0x0E, 0x01, false}, - {InfraredProtocolSamsung32, 0x0E, 0x01, false}, {InfraredProtocolSamsung32, 0x0E, 0x01, true}, -}; - -const InfraredMessage test_samsung32[] = { - {InfraredProtocolSamsung32, 0x00, 0x00, false}, - {InfraredProtocolSamsung32, 0x01, 0x00, false}, - {InfraredProtocolSamsung32, 0x01, 0x80, false}, - {InfraredProtocolSamsung32, 0x00, 0x80, false}, - {InfraredProtocolSamsung32, 0x00, 0x00, false}, - {InfraredProtocolSamsung32, 0x00, 0x00, true}, - {InfraredProtocolSamsung32, 0x00, 0x00, false}, - {InfraredProtocolSamsung32, 0x00, 0x00, true}, - {InfraredProtocolSamsung32, 0xFF, 0xFF, false}, - {InfraredProtocolSamsung32, 0xFE, 0xFF, false}, - {InfraredProtocolSamsung32, 0xFE, 0x7F, false}, - {InfraredProtocolSamsung32, 0xFF, 0x7F, false}, - {InfraredProtocolSamsung32, 0xFF, 0xFF, false}, - {InfraredProtocolSamsung32, 0xFF, 0xFF, true}, - {InfraredProtocolSamsung32, 0xAA, 0x55, false}, - {InfraredProtocolSamsung32, 0x55, 0xAA, false}, - {InfraredProtocolSamsung32, 0x55, 0x55, false}, - {InfraredProtocolSamsung32, 0xAA, 0xAA, false}, - {InfraredProtocolSamsung32, 0xAA, 0xAA, true}, - - {InfraredProtocolSamsung32, 0xAA, 0xAA, false}, - {InfraredProtocolSamsung32, 0xAA, 0xAA, true}, - {InfraredProtocolSamsung32, 0xAA, 0xAA, true}, - - {InfraredProtocolSamsung32, 0x55, 0x55, false}, - {InfraredProtocolSamsung32, 0x55, 0x55, true}, - {InfraredProtocolSamsung32, 0x55, 0x55, true}, - {InfraredProtocolSamsung32, 0x55, 0x55, true}, -}; - diff --git a/applications/unit_tests/infrared_decoder_encoder/test_data/infrared_sirc_test_data.srcdata b/applications/unit_tests/infrared_decoder_encoder/test_data/infrared_sirc_test_data.srcdata deleted file mode 100644 index 52cc1533..00000000 --- a/applications/unit_tests/infrared_decoder_encoder/test_data/infrared_sirc_test_data.srcdata +++ /dev/null @@ -1,479 +0,0 @@ -const uint32_t test_decoder_sirc_input1[] = { /* 121 timings */ -1000000, 2420, 608, 1194, 608, 596, 604, 1198, 603, 591, 610, 1192, 609, 596, 605, 599, 601, 593, 607, 597, 604, 590, 610, 594, 606, 1196, - 25957, 2426, 603, 1199, 603, 591, 610, 1192, 610, 594, 606, 1196, 606, 599, 603, 591, 609, 595, 606, 598, 602, 592, 609, 596, 605, 1197, - 25960, 2423, 606, 1196, 606, 599, 602, 1200, 602, 592, 609, 1193, 609, 596, 606, 599, 602, 592, 609, 595, 605, 600, 601, 593, 608, 1194, -1000000, 2422, 607, 1195, 607, 598, 603, 1199, 604, 590, 610, 1192, 610, 594, 606, 598, 603, 591, 609, 595, 605, 600, 601, 593, 607, 1195, - 25955, 2418, 610, 1192, 610, 594, 606, 1196, 606, 599, 602, 1200, 602, 592, 608, 596, 604, 590, 611, 594, 607, 597, 603, 591, 609, 1193, - 25959, 2424, 604, 1198, 604, 590, 610, 1192, 610, 594, 606, 1196, 605, 600, 601, 593, 608, 597, 603, 591, 610, 595, 606, 598, 602, 1200, -1000000, 2424, 605, 599, 601, 593, 607, 597, 603, 591, 610, 594, 606, 1196, 606, 1196, 605, 600, 601, 593, 608, 597, 604, 590, 611, 1191, - 26586, 2425, 604, 590, 611, 593, 607, 598, 603, 591, 610, 595, 606, 1196, 606, 1196, 606, 599, 602, 592, 608, 596, 604, 590, 611, 1191, - 26586, 2424, 604, 590, 611, 593, 607, 598, 603, 591, 609, 595, 605, 1197, 605, 1197, 604, 590, 611, 593, 607, 597, 603, 591, 610, 1192, -1000000, 2424, 604, 1198, 604, 590, 611, 1191, 610, 594, 606, 598, 603, 1199, 602, 1200, 602, 592, 609, 595, 605, 600, 601, 593, 608, 1194, - 25386, 2419, 610, 1192, 610, 594, 606, 1196, 607, 597, 603, 591, 610, 1192, 609, 1193, 610, 594, 606, 598, 602, 592, 609, 595, 605, 1197, - 25385, 2421, 608, 1194, 608, 596, 605, 1197, 605, 599, 601, 593, 608, 1194, 608, 1194, 608, 596, 605, 589, 611, 594, 607, 597, 604, 1198, -1000000, 2426, 603, 1199, 602, 1200, 602, 1200, 602, 592, 608, 1194, 608, 596, 604, 590, 611, 594, 607, 597, 603, 591, 610, 594, 606, 1196, 605, 600, 601, 593, 608, 596, 604, 590, 610, 594, 607, 1195, 606, 598, 603, 591, - 15078, 2419, 610, 1192, 610, 1192, 610, 1192, 610, 594, 606, 1196, 605, 600, 601, 593, 608, 597, 604, 590, 610, 595, 606, 598, 602, 1200, 602, 592, 608, 597, 604, 590, 611, 594, 607, 597, 603, 1199, 603, 591, 609, 595, - 15075, 2422, 607, 1195, 607, 1195, 607, 1195, 607, 597, 604, 1198, 603, 591, 610, 594, 606, 598, 603, 591, 609, 595, 605, 600, 601, 1191, 611, 594, 607, 597, 603, 591, 610, 594, 606, 598, 602, 1200, 602, 592, 608, 596, -1000000, 2422, 607, 1195, 606, 599, 602, 592, 608, 596, 604, 590, 610, 1192, 610, 594, 606, 599, 602, 592, 608, 596, 604, 590, 610, 1192, - 26585, 2426, 602, 1200, 602, 592, 608, 596, 604, 590, 611, 594, 607, 1195, 607, 598, 603, 591, 610, 594, 606, 598, 603, 591, 609, 1193, - 26586, 2425, 604, 1198, 603, 591, 610, 594, 606, 598, 602, 592, 609, 1193, 608, 597, 605, 600, 601, 593, 607, 597, 604, 590, 610, 1192, -1000000, 2418, 610, 594, 606, 598, 603, 1199, 603, 1199, 603, 1199, 603, 1199, 603, 1199, 603, 591, 610, 1192, 610, 594, 606, 1196, 606, 1196, 606, 1196, 606, 598, 602, 592, 609, 1193, 609, 1193, 609, 1193, 609, 595, 605, 599, - 11557, 2418, 611, 594, 607, 598, 603, 1199, 603, 1199, 603, 1199, 602, 1200, 602, 1200, 601, 593, 608, 1194, 607, 597, 604, 1198, 603, 1199, 603, 1199, 602, 592, 608, 596, 604, 1198, 603, 1199, 603, 1199, 603, 591, 609, 595, - 11561, 2424, 604, 590, 610, 594, 607, 1195, 606, 1196, 606, 1196, 606, 1196, 606, 1196, 605, 600, 601, 1191, 611, 594, 607, 1195, 607, 1195, 607, 1195, 607, 597, 603, 591, 610, 1192, 610, 1192, 610, 1192, 610, 594, 606, 598, -1000000, 2424, 604, 590, 611, 594, 607, 1195, 607, 1195, 607, 1195, 607, 1195, 607, 1195, 606, 598, 603, 1199, 602, 592, 609, 1193, 608, 1194, 608, 1194, 608, 596, 604, 590, 611, 1191, 611, 1191, 611, 1191, 611, 594, 607, 598, - 11559, 2427, 602, 592, 608, 596, 605, 1197, 604, 1198, 604, 1198, 604, 1198, 604, 1198, 604, 590, 610, 1192, 610, 595, 606, 1196, 606, 1196, 606, 1196, 606, 599, 603, 591, 609, 1193, 609, 1193, 609, 1193, 608, 597, 605, 589, - 11567, 2418, 610, 595, 607, 597, 603, 1199, 603, 1199, 602, 1200, 602, 1200, 601, 1201, 601, 593, 608, 1194, 607, 598, 603, 1199, 603, 1199, 603, 1199, 603, 591, 609, 595, 605, 1197, 605, 1197, 605, 1197, 604, 590, 611, 594, -1000000, 2421, 608, 597, 604, 590, 610, 1192, 610, 1192, 609, 1193, 609, 1193, 609, 1193, 608, 596, 605, 1197, 604, 590, 610, 1192, 611, 1191, 610, 1192, 610, 594, 606, 598, 603, 1199, 603, 1199, 602, 1200, 602, 592, 608, 596, - 11561, 2424, 604, 590, 610, 594, 606, 1196, 606, 1196, 606, 1196, 606, 1196, 605, 1197, 605, 600, 601, 1201, 601, 593, 607, 1195, 607, 1195, 606, 1196, 606, 598, 602, 592, 608, 1194, 608, 1194, 607, 1195, 607, 597, 603, 591, - 11564, 2421, 607, 597, 604, 590, 610, 1192, 610, 1192, 610, 1192, 610, 1192, 610, 1192, 609, 595, 606, 1196, 606, 598, 602, 1200, 601, 1201, 601, 1201, 601, 593, 607, 598, 603, 1199, 603, 1199, 602, 1200, 602, 592, 608, 596, -1000000, 2420, 609, 595, 606, 598, 602, 1200, 602, 1200, 602, 1200, 602, 1200, 602, 1200, 602, 592, 608, 1194, 608, 596, 604, 1198, 603, 1199, 603, 1199, 603, 591, 610, 594, 606, 1196, 606, 1196, 606, 1196, 606, 598, 602, 592, - 11565, 2420, 609, 595, 605, 600, 601, 1201, 601, 1201, 601, 1201, 601, 1201, 601, 1201, 601, 593, 607, 1195, 607, 597, 603, 1199, 603, 1199, 603, 1199, 603, 591, 609, 595, 605, 1197, 605, 1197, 605, 1197, 605, 599, 601, 593, - 11563, 2422, 607, 597, 603, 591, 609, 1193, 609, 1193, 608, 1194, 608, 1194, 608, 1194, 582, 623, 603, 1199, 603, 591, 610, 1202, 599, 1203, 599, 1203, 599, 595, 581, 623, 577, 1225, 601, 1201, 601, 1201, 601, 593, 582, 623, -1000000, 2425, 602, 1200, 602, 1200, 602, 592, 608, 1194, 608, 1194, 607, 1195, 607, 1195, 607, 597, 603, 1199, 602, 592, 609, 1193, 608, 1194, 608, 1194, 607, 597, 603, 601, 575, 1227, 599, 1203, 599, 1203, 573, 621, 580, 625, - 10931, 2426, 578, 1224, 578, 1224, 578, 616, 585, 1217, 585, 1217, 585, 1217, 585, 1217, 585, 620, 580, 1222, 580, 624, 577, 1225, 577, 1225, 577, 1225, 577, 617, 583, 622, 580, 1222, 580, 1222, 579, 1223, 579, 625, 576, 618, - 10936, 2421, 583, 1219, 583, 1219, 582, 622, 579, 1223, 578, 1224, 578, 1224, 578, 1224, 578, 616, 584, 1218, 584, 621, 580, 1222, 579, 1223, 579, 1223, 579, 625, 576, 618, 583, 1219, 582, 1220, 582, 1220, 582, 622, 578, 616, -1000000, 2419, 584, 620, 580, 1222, 580, 624, 576, 1226, 576, 1226, 576, 1226, 576, 1226, 576, 618, 582, 1220, 582, 622, 579, 1223, 578, 1224, 579, 1223, 578, 616, 585, 619, 581, 1221, 581, 1221, 581, 1221, 580, 624, 576, 618, - 11563, 2422, 582, 622, 579, 1223, 578, 616, 585, 1217, 585, 1217, 584, 1218, 584, 1218, 583, 622, 579, 1223, 579, 625, 575, 1216, 585, 1217, 585, 1217, 585, 619, 581, 623, 577, 1225, 577, 1225, 577, 1225, 576, 618, 583, 621, - 11558, 2427, 577, 617, 584, 1218, 583, 621, 579, 1223, 579, 1223, 578, 1224, 578, 1224, 578, 647, 553, 1249, 553, 651, 549, 1253, 548, 1254, 549, 1253, 549, 645, 555, 649, 551, 1251, 551, 1251, 551, 1251, 550, 654, 546, 648, -1000000, 2456, 548, 646, 554, 650, 551, 653, 547, 1255, 547, 1255, 547, 1255, 547, 1255, 547, 647, 554, 1248, 554, 650, 551, 1251, 551, 1251, 551, 1251, 551, 653, 547, 647, 554, 1248, 554, 1248, 554, 1248, 553, 651, 550, 644, - 12112, 2449, 555, 649, 551, 654, 547, 647, 554, 1248, 554, 1248, 553, 1249, 553, 1249, 553, 651, 549, 1253, 549, 645, 555, 1247, 555, 1247, 555, 1247, 554, 650, 550, 655, 547, 1244, 557, 1224, 578, 1224, 579, 615, 585, 619, - 12139, 2423, 580, 624, 576, 618, 582, 622, 578, 1224, 578, 1224, 578, 1224, 578, 1224, 578, 616, 584, 1218, 584, 620, 580, 1222, 580, 1222, 581, 1221, 580, 624, 577, 617, 584, 1218, 584, 1218, 584, 1218, 584, 620, 581, 623, -1000000, 2422, 582, 1220, 581, 623, 578, 616, 584, 1218, 584, 1218, 584, 1218, 584, 1218, 584, 620, 580, 1222, 580, 624, 576, 1226, 577, 1225, 576, 1226, 576, 618, 583, 622, 579, 1223, 578, 1224, 577, 1225, 577, 617, 585, 619, - 11559, 2426, 577, 1225, 577, 617, 583, 621, 579, 1223, 579, 1223, 578, 1224, 578, 1224, 578, 616, 584, 1218, 584, 620, 580, 1222, 580, 1222, 579, 1223, 579, 625, 575, 650, 550, 1252, 550, 1252, 549, 1253, 549, 645, 556, 648, - 11531, 2453, 549, 1253, 548, 646, 555, 649, 551, 1251, 551, 1251, 550, 1252, 549, 1253, 549, 645, 556, 1246, 555, 649, 552, 1219, 582, 1220, 582, 1220, 582, 622, 578, 616, 585, 1217, 584, 1218, 584, 1218, 584, 620, 581, 623, -1000000, 2428, 576, 618, 582, 1220, 583, 622, 579, 1223, 578, 1224, 578, 1224, 578, 1224, 578, 616, 585, 1217, 585, 619, 582, 1220, 582, 1220, 582, 1220, 582, 622, 578, 616, 585, 1217, 585, 1217, 584, 1218, 584, 620, 581, 623, - 11557, 2427, 577, 617, 584, 1218, 583, 621, 580, 1222, 580, 1222, 580, 1222, 580, 1222, 580, 624, 576, 1246, 555, 649, 552, 1250, 552, 1250, 551, 1251, 551, 653, 548, 646, 554, 1248, 555, 1247, 555, 1247, 555, 649, 551, 653, - 11528, 2447, 556, 648, 552, 1250, 552, 653, 548, 1254, 548, 1254, 547, 1245, 557, 1245, 557, 647, 553, 1249, 552, 652, 549, 1253, 548, 1254, 548, 1254, 548, 646, 555, 649, 551, 1251, 551, 1251, 551, 1251, 551, 643, 557, 647, -1000000, 2418, 610, 594, 606, 598, 603, 1199, 603, 1199, 602, 1200, 602, 1200, 602, 1200, 602, 592, 608, 1194, 608, 596, 604, 1198, 604, 1198, 604, 1198, 603, 591, 610, 594, 606, 1196, 606, 1196, 605, 1197, 605, 599, 601, 593, - 11563, 2422, 606, 598, 602, 592, 608, 1194, 608, 1194, 608, 1194, 607, 1195, 607, 1195, 607, 597, 603, 1199, 603, 591, 609, 1193, 609, 1193, 609, 1193, 608, 596, 605, 599, 601, 1201, 600, 1191, 611, 1191, 611, 593, 606, 598, - 11558, 2427, 601, 593, 607, 597, 603, 1199, 603, 1199, 603, 1199, 602, 1200, 602, 1200, 601, 593, 607, 1195, 607, 597, 603, 1199, 603, 1199, 602, 1200, 602, 592, 608, 596, 604, 1198, 604, 1198, 604, 1198, 603, 591, 609, 595, -1000000, 2424, 605, 1197, 604, 600, 600, 1191, 610, 1192, 610, 1192, 610, 1192, 609, 1193, 609, 595, 605, 1197, 606, 598, 602, 1200, 602, 1200, 601, 1201, 601, 593, 607, 597, 603, 1199, 603, 1199, 603, 1199, 603, 591, 609, 595, - 10937, 2420, 609, 1193, 609, 595, 605, 1197, 605, 1197, 605, 1197, 605, 1197, 605, 1197, 605, 600, 601, 1201, 601, 593, 608, 1194, 608, 1194, 608, 1194, 609, 595, 605, 599, 601, 1201, 601, 1201, 601, 1201, 601, 593, 608, 596, - 10936, 2420, 608, 1194, 608, 596, 604, 1198, 605, 1197, 605, 1197, 605, 1197, 605, 1197, 605, 600, 601, 1201, 601, 593, 607, 1195, 608, 1194, 608, 1194, 608, 596, 604, 600, 600, 1202, 601, 1201, 601, 1201, 601, 593, 607, 597, -1000000, 2420, 609, 1193, 608, 1194, 608, 596, 579, 625, 600, 1202, 600, 1202, 600, 1202, 600, 594, 607, 1195, 607, 597, 603, 1199, 603, 1199, 602, 1200, 602, 592, 609, 595, 605, 1197, 605, 1197, 605, 1197, 604, 600, 600, 594, - 11561, 2423, 605, 1197, 605, 1197, 605, 599, 601, 593, 607, 1195, 607, 1195, 607, 1195, 607, 597, 604, 1198, 603, 591, 610, 1192, 610, 1192, 610, 1192, 610, 594, 607, 597, 603, 1199, 603, 1199, 603, 1199, 603, 591, 610, 594, - 11563, 2421, 608, 1194, 608, 1194, 608, 596, 605, 599, 601, 1201, 602, 1200, 602, 1200, 602, 592, 609, 1193, 609, 595, 605, 1197, 606, 1196, 606, 1196, 606, 598, 602, 592, 609, 1193, 609, 1193, 610, 1192, 610, 594, 607, 597, -1000000, 2428, 576, 1226, 600, 1192, 610, 594, 606, 598, 602, 1200, 602, 592, 609, 595, 605, 600, 601, 593, 607, 597, 603, 591, 609, 1193, - 25955, 2427, 601, 1190, 610, 1192, 610, 594, 606, 598, 602, 1200, 601, 593, 607, 597, 603, 591, 610, 594, 606, 598, 602, 592, 608, 1194, - 25957, 2425, 604, 1198, 603, 1199, 603, 591, 609, 595, 605, 1197, 605, 599, 601, 593, 607, 598, 603, 591, 610, 594, 606, 598, 602, 1200, - 25952, 2420, 608, 1194, 608, 1194, 608, 596, 604, 601, 600, 1191, 610, 594, 606, 598, 603, 591, 609, 595, 605, 599, 601, 593, 608, 1194, -1000000, 2421, 607, 597, 603, 1199, 603, 591, 610, 594, 606, 1196, 605, 600, 576, 618, 583, 621, 604, 601, 575, 619, 606, 598, 603, 1199, - 26576, 2424, 605, 600, 576, 1226, 601, 593, 608, 596, 604, 1198, 604, 600, 600, 594, 607, 597, 603, 591, 609, 595, 606, 598, 602, 1200, - 26579, 2420, 583, 621, 605, 1197, 604, 600, 601, 593, 607, 1195, 607, 597, 604, 590, 610, 594, 607, 597, 603, 591, 610, 594, 606, 1196, - 26584, 2426, 603, 591, 609, 1193, 609, 595, 605, 599, 601, 1201, 601, 593, 607, 597, 603, 591, 610, 594, 606, 598, 603, 591, 609, 1193, -1000000, 2418, 610, 594, 606, 598, 602, 592, 609, 595, 605, 1197, 605, 1197, 605, 600, 602, 592, 608, 1194, 608, 596, 605, 1197, 605, 1197, 604, 1198, 604, 600, 601, 593, 607, 1195, 607, 1195, 607, 1195, 607, 597, 603, 591, - 13368, 2419, 610, 594, 606, 598, 602, 592, 608, 596, 605, 1197, 604, 1198, 604, 600, 601, 593, 607, 1195, 607, 597, 603, 1199, 603, 1199, 603, 1199, 603, 591, 609, 595, 605, 1197, 605, 1197, 605, 1197, 604, 601, 600, 594, - 13362, 2425, 604, 601, 600, 594, 607, 597, 603, 591, 610, 1192, 610, 1192, 610, 594, 606, 598, 603, 1199, 602, 592, 609, 1193, 609, 1193, 608, 1194, 608, 596, 604, 601, 600, 1191, 610, 1192, 610, 1192, 610, 594, 607, 597, -1000000, 2427, 601, 1201, 601, 593, 582, 623, 603, 1199, 578, 1224, 603, 1199, 577, 617, 584, 620, 605, 1197, 605, 600, 601, 1201, 601, 1201, 601, 1201, 601, 593, 582, 622, 603, 1199, 603, 1199, 578, 1224, 603, 591, 610, 594, - 12139, 2423, 605, 1197, 605, 600, 601, 593, 608, 1194, 608, 1194, 607, 1195, 607, 597, 604, 600, 601, 1201, 601, 593, 607, 1195, 608, 1194, 608, 1194, 583, 622, 604, 601, 600, 1202, 575, 1227, 601, 1201, 576, 618, 607, 597, - 12137, 2424, 604, 1198, 604, 590, 610, 594, 607, 1195, 607, 1195, 607, 1195, 607, 597, 604, 601, 600, 1202, 600, 594, 607, 1195, 606, 1196, 581, 1221, 607, 597, 603, 591, 610, 1202, 600, 1202, 576, 1226, 602, 592, 609, 595, -1000000, 2422, 607, 1195, 607, 597, 603, 591, 585, 619, 606, 1196, 606, 1196, 581, 624, 577, 617, 609, 1193, 584, 621, 605, 1197, 604, 1198, 604, 1198, 604, 590, 610, 595, 581, 1221, 605, 1197, 605, 1197, 605, 599, 601, 593, - 12763, 2427, 603, 1199, 603, 591, 609, 595, 605, 599, 577, 1225, 602, 1200, 601, 593, 583, 622, 604, 1198, 604, 590, 610, 1192, 610, 1192, 610, 1192, 610, 594, 606, 598, 603, 1199, 603, 1199, 603, 1199, 603, 591, 610, 594, - 12763, 2427, 602, 1200, 601, 593, 608, 596, 604, 600, 600, 1202, 601, 1201, 601, 593, 607, 597, 604, 1198, 604, 590, 610, 1192, 610, 1192, 611, 1191, 610, 594, 607, 598, 578, 1224, 603, 1199, 603, 1199, 603, 591, 610, 594, -1000000, 2422, 607, 597, 603, 591, 610, 1192, 610, 594, 606, 1196, 580, 1222, 605, 600, 601, 593, 583, 1219, 608, 596, 579, 1223, 604, 1198, 604, 1198, 604, 590, 610, 594, 606, 1196, 606, 1196, 606, 1196, 606, 599, 602, 592, - 12765, 2425, 603, 591, 610, 594, 606, 1196, 606, 598, 602, 1200, 601, 1201, 601, 593, 582, 623, 604, 1198, 604, 590, 610, 1192, 610, 1192, 609, 1193, 609, 596, 605, 599, 601, 1201, 601, 1201, 601, 1201, 600, 594, 607, 597, - 12758, 2421, 607, 597, 603, 591, 609, 1193, 609, 595, 605, 1197, 605, 1197, 605, 599, 601, 593, 607, 1195, 607, 597, 603, 1199, 603, 1199, 603, 1199, 603, 591, 609, 595, 580, 1222, 605, 1197, 605, 1197, 605, 600, 600, 594, -1000000, 2422, 580, 625, 601, 1201, 601, 593, 608, 596, 604, 1198, 604, 1198, 604, 600, 600, 594, 607, 1195, 607, 597, 603, 1199, 603, 1199, 603, 1199, 578, 616, 609, 595, 606, 1196, 606, 1196, 606, 1196, 581, 624, 602, 592, - 12766, 2424, 605, 599, 601, 1201, 601, 593, 608, 596, 604, 1198, 604, 1198, 579, 625, 601, 593, 608, 1194, 608, 596, 604, 1198, 580, 1222, 605, 1197, 605, 599, 602, 592, 608, 1194, 609, 1193, 609, 1193, 609, 596, 605, 599, - 12759, 2420, 608, 597, 604, 1198, 604, 590, 610, 594, 606, 1196, 606, 1196, 606, 598, 602, 592, 608, 1194, 607, 597, 604, 1198, 603, 1199, 603, 1199, 602, 592, 609, 595, 605, 1197, 605, 1197, 605, 1197, 604, 600, 601, 593, -1000000, 2429, 600, 1202, 575, 1227, 599, 595, 606, 598, 602, 1200, 602, 1200, 602, 592, 609, 595, 605, 1197, 605, 599, 601, 1201, 601, 1201, 601, 1201, 601, 593, 607, 597, 603, 1199, 603, 1199, 603, 1199, 603, 591, 609, 595, - 12136, 2425, 603, 1199, 603, 1199, 603, 591, 609, 595, 605, 1197, 605, 1197, 605, 599, 601, 593, 608, 1194, 608, 596, 604, 1198, 604, 1198, 603, 1199, 603, 591, 609, 595, 606, 1196, 606, 1196, 605, 1197, 605, 599, 601, 593, - 12137, 2424, 604, 1198, 603, 1199, 603, 591, 609, 595, 606, 1196, 605, 1197, 605, 599, 601, 593, 607, 1195, 607, 597, 603, 1199, 603, 1199, 603, 1199, 602, 592, 609, 595, 605, 1197, 605, 1197, 604, 1198, 604, 600, 600, 594, -1000000, 2429, 574, 1228, 573, 1229, 573, 1229, 573, 1229, 573, 621, 581, 624, 577, 617, 583, 622, 580, 1222, 579, 625, 576, 1226, 577, 1225, 576, 1226, 577, 617, 584, 620, 581, 1221, 580, 1222, 579, 1223, 579, 625, 577, 617, - 12142, 2419, 584, 1218, 584, 1218, 583, 1219, 583, 1219, 582, 623, 578, 616, 585, 619, 581, 623, 578, 1224, 577, 617, 584, 1218, 584, 1218, 584, 1218, 584, 620, 580, 624, 576, 1226, 575, 1227, 500, 1353, 523, 620, 582, 622, /* failed, noise pollution 500, 1353 timings */ - 12134, 2427, 576, 1226, 576, 1226, 576, 1226, 576, 1226, 576, 618, 583, 622, 579, 625, 576, 618, 583, 1219, 583, 673, 527, 1223, 579, 1223, 579, 1223, 579, 625, 576, 618, 582, 1220, 582, 1220, 582, 1220, 582, 622, 578, 616, - 12140, 2421, 582, 1220, 581, 1221, 581, 1221, 580, 1222, 580, 624, 576, 618, 582, 622, 578, 616, 585, 1217, 584, 620, 581, 1221, 580, 1222, 580, 1222, 580, 624, 576, 618, 582, 1220, 582, 1220, 582, 1220, 582, 623, 578, 616, -1000000, 2419, 584, 672, 528, 625, 577, 617, 583, 1219, 582, 1220, 581, 1221, 582, 622, 578, 616, 585, 1217, 583, 621, 580, 1222, 580, 1222, 580, 1222, 580, 624, 576, 618, 583, 1219, 583, 1219, 582, 1220, 583, 621, 580, 624, - 12732, 2427, 577, 617, 584, 672, 528, 676, 524, 1226, 576, 1226, 576, 1226, 576, 618, 583, 621, 579, 1223, 579, 625, 575, 1227, 575, 1227, 575, 1227, 575, 671, 529, 675, 526, 1224, 578, 1224, 578, 1224, 578, 616, 585, 619, - 12738, 2421, 583, 621, 580, 624, 576, 618, 582, 1220, 582, 1220, 583, 1219, 583, 621, 579, 625, 576, 1226, 576, 670, 530, 1220, 582, 1220, 582, 1220, 581, 624, 577, 617, 584, 1218, 583, 1219, 583, 1219, 583, 622, 580, 624, -1000000, 2430, 599, 1192, 609, 595, 605, 1197, 580, 624, 601, 1201, 601, 593, 607, 597, 603, 591, 610, 594, 606, 598, 602, 592, 608, 1194, - 25958, 2423, 605, 1197, 604, 600, 575, 1227, 600, 594, 606, 1196, 606, 598, 602, 592, 608, 596, 604, 601, 600, 594, 607, 597, 603, 1199, - 25949, 2422, 607, 1195, 606, 598, 603, 1199, 602, 592, 608, 1194, 608, 596, 604, 600, 601, 593, 607, 597, 604, 600, 600, 594, 607, 1195, - 25958, 2423, 606, 1196, 606, 598, 602, 1200, 602, 592, 608, 1194, 608, 596, 605, 600, 601, 593, 607, 597, 603, 591, 610, 594, 606, 1196, - 25957, 2425, 604, 1198, 603, 591, 610, 1192, 610, 594, 606, 1196, 606, 598, 602, 592, 609, 595, 605, 599, 602, 592, 608, 596, 604, 1198, - 25956, 2426, 604, 1198, 603, 591, 610, 1192, 610, 594, 606, 1196, 606, 598, 602, 592, 608, 597, 605, 599, 601, 593, 607, 597, 603, 1199, - 25952, 2420, 609, 1193, 608, 596, 604, 1198, 604, 590, 610, 1192, 610, 594, 606, 598, 602, 592, 608, 596, 605, 599, 601, 593, 607, 1195, -1000000, 2422, 583, 1219, 608, 596, 605, 1197, 580, 624, 601, 1201, 601, 593, 608, 596, 604, 600, 601, 593, 607, 597, 604, 590, 610, 1202, - 25955, 2427, 603, 1199, 603, 591, 609, 1193, 610, 594, 606, 1196, 607, 597, 603, 591, 609, 595, 606, 598, 602, 592, 609, 595, 605, 1197, - 25957, 2425, 604, 1198, 604, 590, 610, 1192, 610, 594, 581, 1221, 606, 598, 602, 592, 608, 596, 605, 599, 601, 593, 607, 597, 604, 1198, - 25954, 2418, 610, 1192, 610, 594, 606, 1196, 605, 599, 601, 1201, 601, 593, 608, 596, 604, 590, 610, 594, 606, 598, 603, 591, 609, 1193, - 25958, 2424, 604, 1198, 604, 590, 610, 1192, 610, 594, 606, 1196, 606, 598, 602, 592, 609, 595, 605, 600, 601, 593, 607, 597, 603, 1199, - 25953, 2419, 610, 1192, 609, 595, 605, 1197, 605, 600, 601, 1201, 600, 594, 607, 597, 603, 591, 609, 595, 605, 599, 601, 593, 608, 1194, - 25954, 2418, 611, 1191, 610, 594, 606, 1196, 606, 598, 602, 1200, 602, 592, 608, 596, 604, 601, 600, 594, 607, 597, 603, 591, 609, 1193, - 25958, 2424, 605, 1197, 605, 599, 601, 1201, 600, 594, 607, 1195, 607, 597, 603, 591, 609, 596, 605, 599, 602, 592, 608, 596, 605, 1197, - 25954, 2428, 601, 1190, 610, 594, 607, 1195, 606, 598, 602, 1200, 602, 592, 608, 596, 604, 590, 610, 594, 606, 598, 603, 591, 609, 1193, - 25960, 2422, 607, 1195, 606, 598, 602, 1200, 602, 592, 609, 1193, 609, 595, 605, 599, 601, 593, 607, 597, 604, 590, 610, 594, 606, 1196, - 25957, 2424, 605, 1197, 604, 600, 600, 1202, 601, 593, 607, 1195, 607, 597, 603, 591, 610, 594, 606, 598, 603, 591, 609, 595, 606, 1196, -1000000, 2421, 608, 1194, 608, 596, 604, 1198, 604, 601, 575, 1227, 601, 593, 607, 598, 604, 600, 600, 594, 607, 598, 604, 601, 600, 1202, - 25953, 2419, 609, 1193, 609, 596, 605, 1197, 605, 600, 601, 1201, 601, 593, 607, 597, 603, 591, 610, 594, 606, 599, 602, 592, 608, 1194, - 25958, 2424, 605, 1197, 605, 600, 601, 1201, 600, 594, 607, 1195, 606, 598, 602, 592, 609, 595, 605, 600, 601, 593, 608, 596, 604, 1198, -1000000, 2423, 606, 1196, 606, 598, 602, 1200, 602, 592, 608, 1194, 608, 597, 604, 590, 610, 594, 607, 597, 603, 591, 610, 594, 606, 1196, - 25958, 2424, 605, 1197, 604, 600, 601, 1201, 601, 593, 607, 1195, 607, 597, 604, 590, 610, 595, 607, 597, 603, 591, 610, 594, 607, 1195, - 25961, 2421, 608, 1194, 608, 596, 605, 1197, 605, 600, 601, 1201, 601, 593, 607, 597, 603, 591, 610, 594, 606, 598, 602, 592, 609, 1193, -1000000, 2429, 601, 1201, 601, 593, 607, 1195, 608, 596, 604, 1198, 604, 600, 601, 593, 607, 597, 604, 590, 611, 593, 607, 597, 604, 1198, - 25959, 2422, 607, 1195, 607, 597, 603, 1199, 603, 591, 609, 1193, 610, 594, 606, 598, 602, 592, 609, 595, 605, 599, 602, 592, 608, 1194, - 25959, 2421, 608, 1194, 607, 597, 603, 1199, 603, 591, 610, 1192, 610, 594, 606, 598, 603, 591, 609, 595, 605, 599, 602, 592, 608, 1194, - 25959, 2422, 608, 1194, 608, 596, 604, 1198, 604, 590, 611, 1201, 601, 593, 607, 597, 604, 590, 610, 594, 607, 597, 603, 591, 609, 1193, - 25962, 2418, 610, 1192, 610, 594, 606, 1196, 607, 597, 603, 1199, 603, 591, 609, 595, 605, 599, 602, 592, 608, 596, 605, 599, 601, 1201, - -1000000, 2357, 610, 1183, 592, 1191, 614, 1179, 595, 1188, 618, 584, 613, 1180, 593, 588, 613, 1190, 612, 590, 605, 587, 613, 589, 605, 587, - 25398, 2355, 623, 1180, 591, 1181, 627, 1186, 589, 1183, 618, 584, 616, 1187, 587, 584, 614, 1189, 615, 587, 605, 587, 615, 587, 609, 593, -1000000, 2383, 609, 1214, 600, 612, 580, 1213, 608, 614, 583, 1210, 605, 607, 586, 616, 611, 1192, 599, 613, 608, 614, 579, 613, 615, 607, - 26670, 2387, 601, 1212, 600, 612, 589, 1214, 603, 609, 586, 1217, 595, 607, 594, 618, 606, 1187, 602, 610, 609, 613, 588, 614, 610, 612, -1000000, 2445, 582, 1221, 603, 548, 602, 1191, 609, 572, 602, 1191, 609, 542, 607, 544, 631, 1172, 603, 568, 606, 545, 605, 566, 608, 543, - 26263, 2414, 611, 1192, 607, 544, 606, 1197, 602, 569, 606, 1197, 602, 539, 611, 540, 635, 1168, 606, 565, 610, 541, 608, 563, 587, 564, -}; - -const InfraredMessage test_decoder_sirc_expected1[] = { - {InfraredProtocolSIRC, 0x10, 0x15, false}, - {InfraredProtocolSIRC, 0x10, 0x15, false}, - {InfraredProtocolSIRC, 0x10, 0x15, false}, - {InfraredProtocolSIRC, 0x10, 0x15, false}, - {InfraredProtocolSIRC, 0x10, 0x15, false}, - {InfraredProtocolSIRC, 0x10, 0x15, false}, - {InfraredProtocolSIRC, 0x10, 0x60, false}, - {InfraredProtocolSIRC, 0x10, 0x60, false}, - {InfraredProtocolSIRC, 0x10, 0x60, false}, - {InfraredProtocolSIRC, 0x10, 0x65, false}, - {InfraredProtocolSIRC, 0x10, 0x65, false}, - {InfraredProtocolSIRC, 0x10, 0x65, false}, - {InfraredProtocolSIRC20, 0x410, 0x17, false}, - {InfraredProtocolSIRC20, 0x410, 0x17, false}, - {InfraredProtocolSIRC20, 0x410, 0x17, false}, - {InfraredProtocolSIRC, 0x10, 0x21, false}, - {InfraredProtocolSIRC, 0x10, 0x21, false}, - {InfraredProtocolSIRC, 0x10, 0x21, false}, - {InfraredProtocolSIRC20, 0x73A, 0x7C, false}, - {InfraredProtocolSIRC20, 0x73A, 0x7C, false}, - {InfraredProtocolSIRC20, 0x73A, 0x7C, false}, - {InfraredProtocolSIRC20, 0x73A, 0x7C, false}, - {InfraredProtocolSIRC20, 0x73A, 0x7C, false}, - {InfraredProtocolSIRC20, 0x73A, 0x7C, false}, - {InfraredProtocolSIRC20, 0x73A, 0x7C, false}, - {InfraredProtocolSIRC20, 0x73A, 0x7C, false}, - {InfraredProtocolSIRC20, 0x73A, 0x7C, false}, - {InfraredProtocolSIRC20, 0x73A, 0x7C, false}, - {InfraredProtocolSIRC20, 0x73A, 0x7C, false}, - {InfraredProtocolSIRC20, 0x73A, 0x7C, false}, - {InfraredProtocolSIRC20, 0x73A, 0x7B, false}, - {InfraredProtocolSIRC20, 0x73A, 0x7B, false}, - {InfraredProtocolSIRC20, 0x73A, 0x7B, false}, - {InfraredProtocolSIRC20, 0x73A, 0x7A, false}, - {InfraredProtocolSIRC20, 0x73A, 0x7A, false}, - {InfraredProtocolSIRC20, 0x73A, 0x7A, false}, - {InfraredProtocolSIRC20, 0x73A, 0x78, false}, - {InfraredProtocolSIRC20, 0x73A, 0x78, false}, - {InfraredProtocolSIRC20, 0x73A, 0x78, false}, - {InfraredProtocolSIRC20, 0x73A, 0x79, false}, - {InfraredProtocolSIRC20, 0x73A, 0x79, false}, - {InfraredProtocolSIRC20, 0x73A, 0x79, false}, - {InfraredProtocolSIRC20, 0x73A, 0x7A, false}, - {InfraredProtocolSIRC20, 0x73A, 0x7A, false}, - {InfraredProtocolSIRC20, 0x73A, 0x7A, false}, - {InfraredProtocolSIRC20, 0x73A, 0x7C, false}, - {InfraredProtocolSIRC20, 0x73A, 0x7C, false}, - {InfraredProtocolSIRC20, 0x73A, 0x7C, false}, - {InfraredProtocolSIRC20, 0x73A, 0x7D, false}, - {InfraredProtocolSIRC20, 0x73A, 0x7D, false}, - {InfraredProtocolSIRC20, 0x73A, 0x7D, false}, - {InfraredProtocolSIRC20, 0x73A, 0x73, false}, - {InfraredProtocolSIRC20, 0x73A, 0x73, false}, - {InfraredProtocolSIRC20, 0x73A, 0x73, false}, - {InfraredProtocolSIRC, 0x10, 0x13, false}, - {InfraredProtocolSIRC, 0x10, 0x13, false}, - {InfraredProtocolSIRC, 0x10, 0x13, false}, - {InfraredProtocolSIRC, 0x10, 0x13, false}, - {InfraredProtocolSIRC, 0x10, 0x12, false}, - {InfraredProtocolSIRC, 0x10, 0x12, false}, - {InfraredProtocolSIRC, 0x10, 0x12, false}, - {InfraredProtocolSIRC, 0x10, 0x12, false}, - {InfraredProtocolSIRC20, 0x73A, 0x30, false}, - {InfraredProtocolSIRC20, 0x73A, 0x30, false}, - {InfraredProtocolSIRC20, 0x73A, 0x30, false}, - {InfraredProtocolSIRC20, 0x73A, 0x39, false}, - {InfraredProtocolSIRC20, 0x73A, 0x39, false}, - {InfraredProtocolSIRC20, 0x73A, 0x39, false}, - {InfraredProtocolSIRC20, 0x73A, 0x31, false}, - {InfraredProtocolSIRC20, 0x73A, 0x31, false}, - {InfraredProtocolSIRC20, 0x73A, 0x31, false}, - {InfraredProtocolSIRC20, 0x73A, 0x34, false}, - {InfraredProtocolSIRC20, 0x73A, 0x34, false}, - {InfraredProtocolSIRC20, 0x73A, 0x34, false}, - {InfraredProtocolSIRC20, 0x73A, 0x32, false}, - {InfraredProtocolSIRC20, 0x73A, 0x32, false}, - {InfraredProtocolSIRC20, 0x73A, 0x32, false}, - {InfraredProtocolSIRC20, 0x73A, 0x33, false}, - {InfraredProtocolSIRC20, 0x73A, 0x33, false}, - {InfraredProtocolSIRC20, 0x73A, 0x33, false}, - {InfraredProtocolSIRC20, 0x73A, 0x0F, false}, - {InfraredProtocolSIRC20, 0x73A, 0x0F, false}, - {InfraredProtocolSIRC20, 0x73A, 0x0F, false}, - {InfraredProtocolSIRC20, 0x73A, 0x38, false}, - {InfraredProtocolSIRC20, 0x73A, 0x38, false}, - {InfraredProtocolSIRC20, 0x73A, 0x38, false}, - {InfraredProtocolSIRC, 0x10, 0x15, false}, - {InfraredProtocolSIRC, 0x10, 0x15, false}, - {InfraredProtocolSIRC, 0x10, 0x15, false}, - {InfraredProtocolSIRC, 0x10, 0x15, false}, - {InfraredProtocolSIRC, 0x10, 0x15, false}, - {InfraredProtocolSIRC, 0x10, 0x15, false}, - {InfraredProtocolSIRC, 0x10, 0x15, false}, - {InfraredProtocolSIRC, 0x10, 0x15, false}, - {InfraredProtocolSIRC, 0x10, 0x15, false}, - {InfraredProtocolSIRC, 0x10, 0x15, false}, - {InfraredProtocolSIRC, 0x10, 0x15, false}, - {InfraredProtocolSIRC, 0x10, 0x15, false}, - {InfraredProtocolSIRC, 0x10, 0x15, false}, - {InfraredProtocolSIRC, 0x10, 0x15, false}, - {InfraredProtocolSIRC, 0x10, 0x15, false}, - {InfraredProtocolSIRC, 0x10, 0x15, false}, - {InfraredProtocolSIRC, 0x10, 0x15, false}, - {InfraredProtocolSIRC, 0x10, 0x15, false}, - {InfraredProtocolSIRC, 0x10, 0x15, false}, - {InfraredProtocolSIRC, 0x10, 0x15, false}, - {InfraredProtocolSIRC, 0x10, 0x15, false}, - {InfraredProtocolSIRC, 0x10, 0x15, false}, - {InfraredProtocolSIRC, 0x10, 0x15, false}, - {InfraredProtocolSIRC, 0x10, 0x15, false}, - {InfraredProtocolSIRC, 0x10, 0x15, false}, - {InfraredProtocolSIRC, 0x10, 0x15, false}, - {InfraredProtocolSIRC, 0x10, 0x15, false}, - {InfraredProtocolSIRC, 0x10, 0x15, false}, - {InfraredProtocolSIRC, 0x10, 0x15, false}, - {InfraredProtocolSIRC, 0x01, 0x2F, false}, - {InfraredProtocolSIRC, 0x01, 0x2F, false}, - {InfraredProtocolSIRC, 0x01, 0x15, false}, - {InfraredProtocolSIRC, 0x01, 0x15, false}, - {InfraredProtocolSIRC, 0x01, 0x15, false}, - {InfraredProtocolSIRC, 0x01, 0x15, false}, -}; - - -// command (0x55) address (0x0A) SIRC -// 1 0 1 0 1 0 1 0 1 0 1 0 -// 2400, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, -// -// command (0x7F) address (0x1F) SIRC -// 1 1 1 1 1 1 1 1 1 1 1 1 -// 2400, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, -// -// command (0x00) address (0x00) SIRC -// 0 0 0 0 0 0 0 0 0 0 0 0 -// 2400, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, -// -// command (0x53) address (0x0D) SIRC -// 1 1 0 0 1 0 1 1 0 1 1 0 -// 2400, 600, 1200, 600, 1200, 600, 600, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, - -const uint32_t test_decoder_sirc_input2[] = { -1000000, 2400, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, -1000000, 2400, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, -1000000, 2400, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, -1000000, 2400, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 600, /* failed - should be skipped */ - -1000000, 2400, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, -1000000, 2400, 600, 1200, 600, 600, /* failed - should be skipped */ -1000000, 2400, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, -1000000, 2400, 600, 1200, 600, /* failed - should be skipped */ - 2400, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, -1000000, 2400, 600, 1200, 600, 600, /* failed - should be skipped */ -1000000, 2400, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, - -1000000, 2400, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, - -1000000, 2400, 600, 1200, 600, 1200, 600, 600, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, -}; - -const InfraredMessage test_decoder_sirc_expected2[] = { - {InfraredProtocolSIRC, 0xA, 0x55, false}, - {InfraredProtocolSIRC, 0xA, 0x55, false}, - {InfraredProtocolSIRC, 0xA, 0x55, false}, - /* failed - 13 data bits */ - - {InfraredProtocolSIRC, 0x1F, 0x7F, false}, - /* failed - 2 data bits */ - {InfraredProtocolSIRC, 0x1F, 0x7F, false}, - /* failed - sudden end */ - {InfraredProtocolSIRC, 0x1F, 0x7F, false}, - /* failed */ - {InfraredProtocolSIRC, 0x0A, 0x55, false}, - - {InfraredProtocolSIRC, 0x00, 0x00, false}, - - {InfraredProtocolSIRC, 0x0D, 0x53, false}, -}; - - -// command (0x13) address (0xFD) SIRC15 -// 1 1 0 0 1 0 0 1 0 1 1 1 1 1 1 -// 2400, 600, 1200, 600, 1200, 600, 600, 600, 600, 600, 1200, 600, 600, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, -// -// command (0x53) address (0x7D) SIRC15 -// 1 1 0 0 1 0 1 1 0 1 1 1 1 1 0 -// 2400, 600, 1200, 600, 1200, 600, 600, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 600, -// -// command (0x53) address (0x0D) SIRC15 -// 1 1 0 0 1 0 1 1 0 1 1 0 0 0 0 -// 2400, 600, 1200, 600, 1200, 600, 600, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 600, 600, 600, 600, 600, - -const uint32_t test_decoder_sirc_input3[] = { -1000000, 2400, 600, 1200, 600, 1200, 600, 600, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 600, - 10000, 2400, 600, 1200, 600, 1200, 600, 600, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 600, - 10000, 2400, 600, 1200, 600, 1200, 600, 600, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 600, - -1000000, 2400, 600, 1200, 600, 1200, 600, 600, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 600, 600, 600, 600, 600, - 10000, 2400, 600, 1200, 600, 1200, 600, 600, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 600, 600, 600, 600, 600, - 10000, 2400, 600, 1200, 600, 1200, 600, 600, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 600, 600, 600, 600, 600, - -1000000, 2400, 600, 1200, 600, 1200, 600, 600, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 600, 600, 600, 600, 600, -1000000, 2400, 600, 1200, 600, 1200, 600, 600, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 600, 600, 600, 600, 600, - -1000000, 2400, 600, 1200, 600, 1200, 600, 600, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 600, -1000000, 2400, 600, 1200, 600, 1200, 600, 600, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 600, - - 10000, 2400, 600, 1200, 600, 1200, 600, 600, 600, 600, 600, 1200, 600, 600, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, -}; - -const InfraredMessage test_decoder_sirc_expected3[] = { - {InfraredProtocolSIRC15, 0x7D, 0x53, false}, - {InfraredProtocolSIRC15, 0x7D, 0x53, false}, - {InfraredProtocolSIRC15, 0x7D, 0x53, false}, - {InfraredProtocolSIRC15, 0x0D, 0x53, false}, - {InfraredProtocolSIRC15, 0x0D, 0x53, false}, - {InfraredProtocolSIRC15, 0x0D, 0x53, false}, - {InfraredProtocolSIRC15, 0x0D, 0x53, false}, - {InfraredProtocolSIRC15, 0x0D, 0x53, false}, - {InfraredProtocolSIRC15, 0x7D, 0x53, false}, - {InfraredProtocolSIRC15, 0x7D, 0x53, false}, - {InfraredProtocolSIRC15, 0xFD, 0x13, false}, -}; - -const uint32_t test_decoder_sirc_input4[] = { -1000000, 2400, 600, 1200, 600, 1200, 600, 600, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 600, -10000, 2400, 600, 1200, 600, 1200, 600, 600, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 600, -10000, 2400, 600, 1200, 600, 1200, 600, 600, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 600, -1000000, 2400, 600, 1200, 600, 1200, 600, 600, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 600, -1000000, 2400, 600, 1200, 600, 1200, 600, 600, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 600, -1000000, 2400, 600, 1200, 600, 1200, 600, 600, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 600, -}; - -const InfraredMessage test_decoder_sirc_expected4[] = { - {InfraredProtocolSIRC20, 0xFB5, 0x53, false}, // {InfraredProtocolSIRC20, 0x15, 0x3ED3, false}, - {InfraredProtocolSIRC20, 0xFB5, 0x53, false}, - {InfraredProtocolSIRC20, 0xFB5, 0x53, false}, - {InfraredProtocolSIRC20, 0xFB5, 0x53, false}, - {InfraredProtocolSIRC20, 0xFB5, 0x53, false}, - {InfraredProtocolSIRC20, 0xFB5, 0x53, false}, -}; - -const uint32_t test_decoder_sirc_input5[] = { -1000000, 2400, 600, 1200, 600, 1200, 600, 600, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 600, -1000000, 2400, 600, 1200, 600, 1200, 600, 600, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 600, -1000000, 2400, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, -1000000, 2400, 600, 1200, 600, 1200, 600, 600, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 600, -1000000, 2400, 600, 1200, 600, 1200, 600, 600, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 600, -1000000, 2400, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, - -10000, 2400, 600, 1200, 600, 1200, 600, 600, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 600, -10000, 2400, 600, 1200, 600, 1200, 600, 600, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 600, -10000, 2400, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, -10000, 2400, 600, 1200, 600, 1200, 600, 600, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 600, -10000, 2400, 600, 1200, 600, 1200, 600, 600, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 600, -10000, 2400, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, - -10000, 2400, 600, 1200, 600, 1200, 600, 600, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 600, -10000, 2400, 600, 1200, 600, 1200, 600, 600, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 600, -10000, 2400, 600, 1200, 600, 1200, 600, 600, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 600, -10000, 2400, 600, 1200, 600, 1200, 600, 600, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 600, -10000, 2400, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, -10000, 2400, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, - -10000, 2400, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, -10000, 2400, 600, 1200, 600, 1200, 600, 600, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 600, -10000, 2400, 600, 1200, 600, 1200, 600, 600, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 600, -10000, 2400, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, -10000, 2400, 600, 1200, 600, 1200, 600, 600, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 600, -10000, 2400, 600, 1200, 600, 1200, 600, 600, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 600, -}; - -const InfraredMessage test_decoder_sirc_expected5[] = { - {InfraredProtocolSIRC20, 0xFB5, 0x53, false}, - {InfraredProtocolSIRC15, 0x7D, 0x53, false}, - {InfraredProtocolSIRC, 0xA, 0x55, false}, - {InfraredProtocolSIRC20, 0xFB5, 0x53, false}, - {InfraredProtocolSIRC15, 0x7D, 0x53, false}, - {InfraredProtocolSIRC, 0xA, 0x55, false}, - - {InfraredProtocolSIRC20, 0xFB5, 0x53, false}, - {InfraredProtocolSIRC15, 0x7D, 0x53, false}, - {InfraredProtocolSIRC, 0xA, 0x55, false}, - {InfraredProtocolSIRC20, 0xFB5, 0x53, false}, - {InfraredProtocolSIRC15, 0x7D, 0x53, false}, - {InfraredProtocolSIRC, 0xA, 0x55, false}, - - {InfraredProtocolSIRC20, 0xFB5, 0x53, false}, - {InfraredProtocolSIRC20, 0xFB5, 0x53, false}, - {InfraredProtocolSIRC15, 0x7D, 0x53, false}, - {InfraredProtocolSIRC15, 0x7D, 0x53, false}, - {InfraredProtocolSIRC, 0xA, 0x55, false}, - {InfraredProtocolSIRC, 0xA, 0x55, false}, - - {InfraredProtocolSIRC, 0xA, 0x55, false}, - {InfraredProtocolSIRC15, 0x7D, 0x53, false}, - {InfraredProtocolSIRC20, 0xFB5, 0x53, false}, - {InfraredProtocolSIRC, 0xA, 0x55, false}, - {InfraredProtocolSIRC15, 0x7D, 0x53, false}, - {InfraredProtocolSIRC20, 0xFB5, 0x53, false}, -}; - -const InfraredMessage test_encoder_sirc_input1[] = { - {InfraredProtocolSIRC, 0xA, 0x55, false}, -}; - -const uint32_t test_encoder_sirc_expected1[] = { -10000, 2400, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, -}; - -const InfraredMessage test_encoder_sirc_input2[] = { - {InfraredProtocolSIRC15, 0x7D, 0x53, false}, - {InfraredProtocolSIRC15, 0x7D, 0x53, true}, - {InfraredProtocolSIRC15, 0x7D, 0x53, true}, -}; - -const uint32_t test_encoder_sirc_expected2[] = { - 10000, 2400, 600, 1200, 600, 1200, 600, 600, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 600, - 18600, 2400, 600, 1200, 600, 1200, 600, 600, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 600, - 18600, 2400, 600, 1200, 600, 1200, 600, 600, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 600, -}; - -const InfraredMessage test_sirc[] = { - {InfraredProtocolSIRC20, 0x1FFF, 0x7F, false}, - {InfraredProtocolSIRC20, 0x1FFF, 0x7F, true}, - {InfraredProtocolSIRC20, 0x1FFF, 0x7F, true}, - {InfraredProtocolSIRC, 0x00, 0x00, false}, - {InfraredProtocolSIRC, 0x00, 0x00, true}, - {InfraredProtocolSIRC, 0x00, 0x00, true}, - - {InfraredProtocolSIRC, 0x1A, 0x22, false}, - {InfraredProtocolSIRC, 0x1A, 0x22, true}, - {InfraredProtocolSIRC, 0x1A, 0x22, true}, - {InfraredProtocolSIRC, 0x17, 0x0A, false}, - - {InfraredProtocolSIRC15, 0x7D, 0x53, false}, - {InfraredProtocolSIRC15, 0x7D, 0x53, true}, - {InfraredProtocolSIRC15, 0x7D, 0x53, true}, - {InfraredProtocolSIRC15, 0x71, 0x0, false}, - {InfraredProtocolSIRC15, 0x15, 0x01, false}, - {InfraredProtocolSIRC15, 0x01, 0x15, false}, - - {InfraredProtocolSIRC20, 0xAA, 0x55, false}, - {InfraredProtocolSIRC20, 0x331, 0x71, false}, - - {InfraredProtocolSIRC, 0x00, 0x00, false}, - {InfraredProtocolSIRC, 0x1F, 0x7F, false}, - {InfraredProtocolSIRC15, 0x00, 0x00, false}, - {InfraredProtocolSIRC15, 0xFF, 0x7F, false}, - {InfraredProtocolSIRC20, 0x00, 0x00, false}, - {InfraredProtocolSIRC20, 0x1FFF, 0x7F, false}, -}; - diff --git a/applications/unit_tests/test_index.c b/applications/unit_tests/test_index.c index 8ff27b4d..9f12adae 100644 --- a/applications/unit_tests/test_index.c +++ b/applications/unit_tests/test_index.c @@ -10,8 +10,8 @@ #define TAG "UnitTests" -int run_minunit(); -int run_minunit_test_infrared_decoder_encoder(); +int run_minunit_test_furi(); +int run_minunit_test_infrared(); int run_minunit_test_rpc(); int run_minunit_test_flipper_format(); int run_minunit_test_flipper_format_string(); @@ -21,14 +21,35 @@ int run_minunit_test_subghz(); int run_minunit_test_dirwalk(); int run_minunit_test_nfc(); -void minunit_print_progress(void) { - static char progress[] = {'\\', '|', '/', '-'}; +typedef int (*UnitTestEntry)(); + +typedef struct { + const char* name; + const UnitTestEntry entry; +} UnitTest; + +const UnitTest unit_tests[] = { + {.name = "furi", .entry = run_minunit_test_furi}, + {.name = "storage", .entry = run_minunit_test_storage}, + {.name = "stream", .entry = run_minunit_test_stream}, + {.name = "dirwalk", .entry = run_minunit_test_dirwalk}, + {.name = "flipper_format", .entry = run_minunit_test_flipper_format}, + {.name = "flipper_format_string", .entry = run_minunit_test_flipper_format_string}, + {.name = "rpc", .entry = run_minunit_test_rpc}, + {.name = "subghz", .entry = run_minunit_test_subghz}, + {.name = "infrared", .entry = run_minunit_test_infrared}, + {.name = "nfc", .entry = run_minunit_test_nfc}, +}; + +void minunit_print_progress() { + static const char progress[] = {'\\', '|', '/', '-'}; static uint8_t progress_counter = 0; static TickType_t last_tick = 0; TickType_t current_tick = xTaskGetTickCount(); if(current_tick - last_tick > 20) { last_tick = current_tick; printf("[%c]\033[3D", progress[++progress_counter % COUNT_OF(progress)]); + fflush(stdout); } } @@ -40,7 +61,7 @@ void unit_tests_cli(Cli* cli, string_t args, void* context) { UNUSED(cli); UNUSED(args); UNUSED(context); - uint32_t test_result = 0; + uint32_t failed_tests = 0; minunit_run = 0; minunit_assert = 0; minunit_fail = 0; @@ -51,7 +72,7 @@ void unit_tests_cli(Cli* cli, string_t args, void* context) { // TODO: lock device while test running if(loader_is_locked(loader)) { - FURI_LOG_E(TAG, "RPC: stop all applications to run tests"); + printf("RPC: stop all applications to run tests\r\n"); notification_message(notification, &sequence_blink_magenta_100); } else { notification_message_block(notification, &sequence_set_only_blue_255); @@ -59,34 +80,39 @@ void unit_tests_cli(Cli* cli, string_t args, void* context) { uint32_t heap_before = memmgr_get_free_heap(); uint32_t cycle_counter = furi_hal_get_tick(); - test_result |= run_minunit(); - test_result |= run_minunit_test_storage(); - test_result |= run_minunit_test_stream(); - test_result |= run_minunit_test_dirwalk(); - test_result |= run_minunit_test_flipper_format(); - test_result |= run_minunit_test_flipper_format_string(); - test_result |= run_minunit_test_infrared_decoder_encoder(); - test_result |= run_minunit_test_rpc(); - test_result |= run_minunit_test_subghz(); - test_result |= run_minunit_test_nfc(); - - cycle_counter = (furi_hal_get_tick() - cycle_counter); - - FURI_LOG_I(TAG, "Consumed: %u us", cycle_counter); - - if(test_result == 0) { - furi_hal_delay_ms(200); /* wait for tested services and apps to deallocate */ - uint32_t heap_after = memmgr_get_free_heap(); - notification_message(notification, &sequence_success); - if(heap_after != heap_before) { - FURI_LOG_E(TAG, "Leaked: %d", heap_before - heap_after); - } else { - FURI_LOG_I(TAG, "No leaks"); + for(size_t i = 0; i < COUNT_OF(unit_tests); i++) { + if(cli_cmd_interrupt_received(cli)) { + break; } - FURI_LOG_I(TAG, "PASSED"); + + if(string_size(args)) { + if(string_cmp_str(args, unit_tests[i].name) == 0) { + failed_tests += unit_tests[i].entry(); + } else { + printf("Skipping %s\r\n", unit_tests[i].name); + } + } else { + failed_tests += unit_tests[i].entry(); + } + } + printf("\r\nFailed tests: %lu\r\n", failed_tests); + + // Time report + cycle_counter = (furi_hal_get_tick() - cycle_counter); + printf("Consumed: %lu ms\r\n", cycle_counter); + + // Wait for tested services and apps to deallocate memory + furi_hal_delay_ms(200); + uint32_t heap_after = memmgr_get_free_heap(); + printf("Leaked: %ld\r\n", heap_before - heap_after); + + // Final Report + if(failed_tests == 0) { + notification_message(notification, &sequence_success); + printf("Status: PASSED\r\n"); } else { notification_message(notification, &sequence_error); - FURI_LOG_E(TAG, "FAILED"); + printf("Status: FAILED\r\n"); } } diff --git a/assets/unit_tests/infrared/test_nec.irtest b/assets/unit_tests/infrared/test_nec.irtest new file mode 100644 index 00000000..8b1d59e7 --- /dev/null +++ b/assets/unit_tests/infrared/test_nec.irtest @@ -0,0 +1,511 @@ +Filetype: IR tests file +Version: 1 +# +name: decoder_input1 +type: raw +data: 2640671 9071 4445 601 497 578 500 604 501 603 502 581 496 615 498 606 499 584 493 610 1630 576 1640 601 1615 605 1638 581 1634 606 1610 610 1633 577 1639 601 504 580 498 604 501 603 500 582 496 607 498 606 499 585 485 610 1633 576 1640 596 1615 605 1638 582 1634 605 1610 609 1634 586 1630 600 40015 9077 2208 593 1457713 9076 4440 607 508 585 493 610 494 598 506 577 501 603 502 601 504 580 498 605 1638 582 1634 606 1610 610 1633 577 1639 600 1616 605 1638 582 1634 606 499 585 493 609 495 608 496 586 502 612 493 601 504 579 498 605 1638 582 1633 606 1610 610 1633 577 1639 602 1614 574 1668 582 1634 606 1415838 9080 4436 611 494 600 505 578 500 608 501 602 502 580 498 606 508 605 500 583 1633 608 1608 611 1631 578 1638 602 1614 606 1637 583 1633 607 1609 611 494 600 505 570 500 604 501 602 502 581 497 606 499 605 499 583 1633 617 1608 611 1631 579 1638 602 +# +name: decoder_expected1 +type: parsed_array +count: 3 +# +protocol: NEC +address: 00 00 00 00 +command: 00 00 00 00 +repeat: false +# +protocol: NEC +address: 00 00 00 00 +command: 00 00 00 00 +repeat: true +# +protocol: NEC +address: 00 00 00 00 +command: 00 00 00 00 +repeat: false +# +name: decoder_input2 +type: raw +data: 18372093 9030 4495 559 524 585 526 613 496 560 522 595 524 605 504 553 530 578 524 608 1614 581 1668 557 1665 581 1641 585 1664 551 1671 605 1616 578 1670 555 528 581 1668 553 526 582 528 612 498 559 524 585 526 604 507 552 1670 597 504 553 1667 608 1613 582 1667 559 1663 613 1608 586 1662 552 40067 9026 2219 579 3060767 9079 4445 606 505 554 530 578 532 608 502 555 528 581 530 610 500 588 495 614 1635 580 1641 604 1617 618 1621 584 1637 608 1612 612 1636 589 1637 602 507 581 1641 605 505 582 501 609 502 607 503 585 498 611 499 609 1612 613 498 612 1610 615 1633 561 1661 606 1615 609 1639 585 1636 610 40011 9072 2200 588 96480 9075 2198 560 96509 9047 2226 552 96517 9049 2224 555 96514 9042 2222 556 96512 9053 2220 558 96511 9045 2227 561 96507 9048 2225 554 96515 9061 2231 565 96522 9053 2219 559 96510 9044 2229 560 96508 9046 2226 562 96506 9027 2245 553 96511 9030 2243 555 96513 9031 2237 557 96512 9054 2219 559 570349 9027 4495 608 476 583 529 580 529 558 525 584 527 582 528 560 523 596 524 584 1636 578 1669 555 1667 578 1643 581 1666 558 1663 582 1639 586 1662 552 531 577 1670 554 1667 578 532 563 527 582 528 580 529 558 525 584 1665 561 523 586 525 584 1637 577 1670 554 1668 578 1642 582 1667 558 40062 9021 2233 585 172411 9020 4502 559 524 585 526 583 527 551 532 586 523 575 535 553 530 579 532 577 1643 581 1668 557 1664 581 1639 585 1664 552 1670 575 1637 579 1669 556 527 581 529 580 1642 584 536 581 528 560 523 585 524 584 526 552 1670 576 1645 579 530 578 1643 582 1667 558 1663 582 1639 586 1662 545 40068 9026 2220 578 226896 9054 4468 578 500 608 502 607 503 585 498 611 500 610 501 588 496 612 497 602 1610 615 1633 581 1640 606 1616 609 1639 585 1635 610 1612 614 1635 580 504 615 495 604 506 582 1639 606 503 585 499 610 501 609 502 587 1635 610 1610 614 1634 581 502 616 1632 582 1648 606 1615 610 1638 587 40033 9050 2195 614 249594 9020 4502 560 524 594 525 603 506 552 532 587 521 606 504 554 529 579 532 609 1612 582 1667 557 1654 612 1608 585 1663 552 1670 606 1615 579 1669 554 527 582 529 611 500 558 1663 612 497 560 523 585 524 598 505 552 1670 606 1614 580 1668 557 526 582 1665 558 1662 603 1618 587 1661 553 40067 9058 2187 621 97567 9054 4467 584 500 609 501 601 502 586 497 611 499 610 501 588 496 614 497 612 1609 615 1632 582 1640 606 1615 609 1639 586 1636 611 1611 614 1634 581 503 608 493 605 505 583 1639 607 503 586 498 611 500 609 501 588 1634 611 1609 615 1634 582 502 608 1641 553 1668 608 1613 581 1668 558 112307 9078 4443 608 502 606 504 584 498 610 501 608 502 587 497 612 498 610 499 589 1633 603 1619 607 1642 583 1638 607 1614 611 1638 597 1634 611 1610 615 495 603 506 581 502 607 1642 584 500 609 501 607 503 585 498 611 1637 588 1634 611 1610 615 495 603 1618 607 1641 584 1638 607 1605 611 112281 9076 4445 606 505 584 499 610 501 608 502 586 497 612 498 610 500 581 494 614 1635 581 1641 604 1617 608 1640 585 1637 609 1610 613 1636 589 1632 603 507 581 503 607 504 604 1617 608 502 607 503 585 498 611 500 609 1613 613 1636 590 1632 603 507 581 1641 605 1616 609 1640 585 1636 609 94207 9075 4446 605 506 582 501 607 502 606 504 584 500 610 501 608 502 587 497 611 1636 588 1633 612 1610 616 1633 583 1639 604 1615 610 1638 587 1635 610 500 588 495 606 496 602 1619 616 495 605 506 583 501 609 502 606 1614 610 1638 587 1635 611 499 590 1632 603 1618 607 1641 583 1638 608 103762 9076 4446 605 505 553 531 579 532 607 503 555 528 580 530 609 500 557 527 583 1666 559 1662 603 1609 587 1661 553 1669 608 1614 580 1659 557 1665 612 498 580 504 585 526 604 1617 607 503 606 504 584 499 610 500 609 1613 612 1636 588 1633 602 507 573 1641 605 1617 608 1640 585 1636 619 76134 9056 4466 585 525 604 506 552 532 577 533 606 504 553 529 579 531 608 501 556 1665 611 1611 584 1665 561 1661 605 1616 578 1671 555 1667 609 1612 582 528 611 499 559 525 584 1664 551 533 586 524 605 505 553 530 578 1670 555 1667 610 1612 582 528 611 1610 584 1664 551 1671 606 1616 578 112997 9073 4447 603 507 560 523 586 524 605 505 552 531 578 533 607 503 555 529 580 1668 548 1665 611 1611 584 1665 551 1671 615 1616 578 1670 555 1667 610 501 556 527 582 528 611 1609 584 518 604 506 551 533 586 524 606 1615 579 1669 555 1666 610 500 558 1664 612 1609 585 1663 551 1670 606 84870 9053 4470 582 529 611 500 559 525 583 526 602 507 560 523 586 525 574 536 543 1669 608 1614 580 1668 556 1665 620 1610 585 1664 550 1671 605 1616 578 533 608 503 555 529 580 1677 557 526 582 528 612 498 559 525 585 1664 551 1671 605 1615 578 531 608 1614 581 1668 558 1664 611 1609 585 76184 9025 4496 555 529 579 531 609 502 556 528 582 529 610 500 559 525 583 526 603 1619 586 1663 552 1669 606 1614 580 1668 556 1665 611 1610 584 1664 550 533 586 524 605 504 553 1669 608 503 555 529 580 530 609 501 557 1664 605 1609 585 1664 551 532 586 1661 553 1668 608 1614 581 1666 558 96145 9073 4449 612 499 559 524 584 526 603 506 552 532 587 523 606 504 584 499 570 1669 556 1666 610 1611 614 1634 580 1641 605 1617 608 1640 584 1636 609 501 587 497 612 498 611 1611 615 496 602 508 580 503 595 535 614 1627 617 1650 594 1646 604 502 586 1635 611 1618 614 1634 581 1641 604 86183 9080 4442 610 501 607 502 586 498 611 499 610 501 588 496 613 497 611 498 579 1642 604 1617 608 1641 583 1637 608 1613 611 1637 588 1634 611 1608 615 494 604 506 582 501 617 1641 584 499 610 493 608 502 586 497 612 1636 588 1633 602 1619 615 494 604 1617 608 1640 585 1637 608 1613 613 234570 9078 4437 607 503 606 505 584 500 608 501 614 502 585 497 611 499 610 509 588 1634 612 1609 616 1633 582 1639 606 1616 610 1639 587 1635 610 1611 614 1634 581 503 606 504 604 1617 608 502 607 503 585 498 611 500 609 501 597 1634 611 1610 615 495 603 1618 607 1642 584 1638 607 1614 611 112281 9076 4446 605 505 583 501 609 493 606 503 585 498 610 500 609 501 587 497 613 1636 579 1643 602 1618 606 1641 583 1639 607 1614 610 1638 554 1665 611 1611 584 526 603 507 551 1671 597 504 583 500 578 532 607 502 555 528 581 1668 556 1664 611 498 559 1663 604 1618 587 1662 553 1668 608 130332 9076 4446 615 496 605 507 582 502 608 503 605 512 584 499 609 501 608 502 586 1636 610 1611 613 1635 579 1641 604 1617 608 1641 584 1637 608 1613 611 1636 588 495 614 497 613 1609 616 494 604 506 590 500 608 502 607 503 585 1635 609 1613 612 498 610 1610 614 1634 581 1641 604 1617 608 886079 9020 4501 560 523 585 525 583 527 552 532 587 523 576 534 554 529 580 531 577 1644 582 1667 559 1663 582 1639 586 1663 553 1669 576 1645 581 1668 557 521 582 529 581 530 559 1663 582 527 551 532 587 523 575 535 553 1669 577 1644 581 1667 557 526 584 1665 560 1662 582 1637 588 1661 554 76188 9053 4469 583 528 560 523 586 524 585 525 552 531 578 533 576 534 554 528 581 1668 557 1665 581 1631 585 1664 551 1670 575 1646 579 1678 555 1666 579 531 558 1664 581 528 559 1662 584 527 552 532 588 523 575 535 553 1668 578 532 556 1666 580 531 567 1663 582 1639 585 1662 552 1670 575 76165 9054 4468 583 527 581 529 559 524 585 525 583 526 547 531 587 524 576 535 554 1668 577 1644 581 1667 558 1664 582 1640 586 1663 551 1670 576 1645 579 531 578 533 556 527 582 1666 559 525 583 526 582 528 560 523 586 1663 553 1669 576 1645 580 522 578 1642 582 1666 559 1663 582 1639 586 40034 9049 2224 585 114557 9051 4471 581 529 558 525 584 527 582 528 561 522 586 524 585 525 552 531 578 1670 555 1667 579 1643 577 1666 559 1662 583 1638 587 1662 563 1678 587 543 565 537 591 539 589 1651 592 537 591 539 569 533 595 535 593 1647 597 1670 563 1678 587 542 565 1675 589 1651 593 1675 569 1671 593 40045 9047 2225 553 114589 9029 4492 559 525 585 526 582 528 550 533 586 524 575 535 553 530 578 532 577 1645 581 1668 557 1664 581 1640 585 1664 552 1670 575 1646 579 1669 556 527 582 529 580 531 557 1663 582 528 560 523 586 524 585 525 552 1669 576 1645 580 1668 556 526 582 1667 559 1663 582 1639 593 1662 553 40067 9026 4495 556 528 581 529 579 531 557 526 575 527 581 528 561 523 585 525 584 1638 588 1661 554 1667 578 1644 582 1667 559 1663 582 1639 586 1663 552 530 578 1671 555 529 581 1668 556 526 582 529 581 529 559 524 584 1664 550 533 587 1662 553 530 578 1669 555 1667 578 1642 582 1668 559 58109 9049 4473 578 533 576 534 555 529 580 531 578 532 556 527 582 528 580 529 559 1663 583 1639 586 1662 553 1669 580 1644 581 1668 558 1664 581 1640 582 525 584 527 552 531 588 1670 554 529 579 531 578 532 556 527 582 1666 558 1663 582 1639 587 524 584 1636 578 1671 564 1676 588 1652 592 263241 9028 4503 557 526 582 528 581 529 559 523 594 526 584 527 552 532 588 527 575 1646 579 1670 556 1666 579 1642 583 1665 560 1662 584 1638 578 1671 554 529 580 1669 559 527 582 1667 559 525 584 526 582 528 560 523 586 1662 552 530 578 1671 555 529 580 1668 556 1665 581 1640 584 1664 551 40069 9025 2221 588 +# +name: decoder_expected2 +type: parsed_array +count: 52 +# +protocol: NEC +address: 00 00 00 00 +command: 02 00 00 00 +repeat: false +# +protocol: NEC +address: 00 00 00 00 +command: 02 00 00 00 +repeat: true +# +protocol: NEC +address: 00 00 00 00 +command: 02 00 00 00 +repeat: false +# +protocol: NEC +address: 00 00 00 00 +command: 02 00 00 00 +repeat: true +# +protocol: NEC +address: 00 00 00 00 +command: 02 00 00 00 +repeat: true +# +protocol: NEC +address: 00 00 00 00 +command: 02 00 00 00 +repeat: true +# +protocol: NEC +address: 00 00 00 00 +command: 02 00 00 00 +repeat: true +# +protocol: NEC +address: 00 00 00 00 +command: 02 00 00 00 +repeat: true +# +protocol: NEC +address: 00 00 00 00 +command: 02 00 00 00 +repeat: true +# +protocol: NEC +address: 00 00 00 00 +command: 02 00 00 00 +repeat: true +# +protocol: NEC +address: 00 00 00 00 +command: 02 00 00 00 +repeat: true +# +protocol: NEC +address: 00 00 00 00 +command: 02 00 00 00 +repeat: true +# +protocol: NEC +address: 00 00 00 00 +command: 02 00 00 00 +repeat: true +# +protocol: NEC +address: 00 00 00 00 +command: 02 00 00 00 +repeat: true +# +protocol: NEC +address: 00 00 00 00 +command: 02 00 00 00 +repeat: true +# +protocol: NEC +address: 00 00 00 00 +command: 02 00 00 00 +repeat: true +# +protocol: NEC +address: 00 00 00 00 +command: 02 00 00 00 +repeat: true +# +protocol: NEC +address: 00 00 00 00 +command: 02 00 00 00 +repeat: true +# +protocol: NEC +address: 00 00 00 00 +command: 02 00 00 00 +repeat: true +# +protocol: NEC +address: 00 00 00 00 +command: 06 00 00 00 +repeat: false +# +protocol: NEC +address: 00 00 00 00 +command: 06 00 00 00 +repeat: true +# +protocol: NEC +address: 00 00 00 00 +command: 04 00 00 00 +repeat: false +# +protocol: NEC +address: 00 00 00 00 +command: 04 00 00 00 +repeat: true +# +protocol: NEC +address: 00 00 00 00 +command: 08 00 00 00 +repeat: false +# +protocol: NEC +address: 00 00 00 00 +command: 08 00 00 00 +repeat: true +# +protocol: NEC +address: 00 00 00 00 +command: 08 00 00 00 +repeat: false +# +protocol: NEC +address: 00 00 00 00 +command: 08 00 00 00 +repeat: true +# +protocol: NEC +address: 00 00 00 00 +command: 08 00 00 00 +repeat: false +# +protocol: NEC +address: 00 00 00 00 +command: 08 00 00 00 +repeat: false +# +protocol: NEC +address: 00 00 00 00 +command: 08 00 00 00 +repeat: false +# +protocol: NEC +address: 00 00 00 00 +command: 08 00 00 00 +repeat: false +# +protocol: NEC +address: 00 00 00 00 +command: 08 00 00 00 +repeat: false +# +protocol: NEC +address: 00 00 00 00 +command: 08 00 00 00 +repeat: false +# +protocol: NEC +address: 00 00 00 00 +command: 08 00 00 00 +repeat: false +# +protocol: NEC +address: 00 00 00 00 +command: 08 00 00 00 +repeat: false +# +protocol: NEC +address: 00 00 00 00 +command: 08 00 00 00 +repeat: false +# +protocol: NEC +address: 00 00 00 00 +command: 08 00 00 00 +repeat: false +# +protocol: NEC +address: 00 00 00 00 +command: 08 00 00 00 +repeat: false +# +protocol: NEC +address: 00 00 00 00 +command: 09 00 00 00 +repeat: false +# +protocol: NEC +address: 00 00 00 00 +command: 09 00 00 00 +repeat: false +# +protocol: NEC +address: 00 00 00 00 +command: 09 00 00 00 +repeat: false +# +protocol: NEC +address: 00 00 00 00 +command: 08 00 00 00 +repeat: false +# +protocol: NEC +address: 00 00 00 00 +command: 0A 00 00 00 +repeat: false +# +protocol: NEC +address: 00 00 00 00 +command: 08 00 00 00 +repeat: false +# +protocol: NEC +address: 00 00 00 00 +command: 08 00 00 00 +repeat: true +# +protocol: NEC +address: 00 00 00 00 +command: 08 00 00 00 +repeat: false +# +protocol: NEC +address: 00 00 00 00 +command: 08 00 00 00 +repeat: true +# +protocol: NEC +address: 00 00 00 00 +command: 08 00 00 00 +repeat: false +# +protocol: NEC +address: 00 00 00 00 +command: 0A 00 00 00 +repeat: false +# +protocol: NEC +address: 00 00 00 00 +command: 08 00 00 00 +repeat: false +# +protocol: NEC +address: 00 00 00 00 +command: 0A 00 00 00 +repeat: false +# +protocol: NEC +address: 00 00 00 00 +command: 0A 00 00 00 +repeat: true +# +name: decoder_input3 +type: raw +data: 200000 8862 4452 562 563 559 1681 563 1646 567 586 556 569 563 583 559 571 561 1675 559 565 567 1673 561 561 561 592 561 565 567 579 563 567 565 584 558 1652 561 592 561 561 561 1679 565 560 562 584 558 1659 564 585 557 566 566 1675 559 1649 564 589 564 1649 564 1668 566 565 567 1669 565 43470 8896 4432 561 561 561 1679 565 1648 565 581 561 568 564 586 567 558 564 1676 558 564 558 1681 563 563 559 587 566 565 567 582 561 564 558 595 558 1650 563 590 563 563 559 1674 560 570 562 587 566 1645 568 586 556 565 567 1672 562 1651 562 584 558 1658 566 1671 563 561 561 1679 565 200000 8881 4383 569 549 573 548 574 541 571 550 572 547 575 539 573 551 571 1651 573 545 567 554 568 548 574 1652 572 547 575 1645 568 1661 573 545 567 1657 567 554 568 547 575 1652 572 547 575 539 573 1657 567 550 572 545 577 1651 573 1648 576 545 567 1659 575 1645 568 555 567 1657 567 38995 8883 4369 573 543 569 552 570 549 573 541 571 553 569 548 574 543 569 1658 566 550 572 548 574 546 566 1653 571 553 569 1654 570 1654 570 551 571 1651 573 547 575 545 567 1653 571 552 570 547 575 1649 564 556 566 550 572 1655 569 1656 568 546 566 1664 570 1653 571 547 565 1663 571 200000 8987 4504 561 593 539 589 533 596 515 586 536 592 540 588 534 595 517 1713 541 1664 570 1686 558 596 515 587 535 593 539 1691 543 1689 565 588 513 1691 563 1668 617 1613 641 1615 567 587 535 593 519 610 512 590 542 1714 510 593 539 1691 563 591 510 1720 535 594 518 584 538 591 541 39546 8990 4501 565 590 542 586 536 593 508 593 539 589 543 585 537 592 509 1720 545 1660 615 1642 561 567 534 594 538 590 542 1688 535 1696 558 595 517 1687 567 1664 621 1635 619 1611 561 594 538 590 511 617 515 586 536 1721 513 589 543 1687 568 587 514 1691 563 590 511 591 541 587 535 200000 8986 4505 560 594 538 590 542 586 515 586 536 593 539 589 533 595 517 1714 540 587 535 594 518 1713 542 586 515 587 535 1722 543 1662 562 592 540 1664 570 585 537 591 541 1689 545 584 538 590 542 1688 536 593 539 589 512 590 542 586 536 1720 514 588 544 585 537 591 541 587 514 40671 8986 4505 560 594 538 590 542 586 515 587 535 593 539 589 533 595 516 1714 541 587 535 594 518 1712 542 586 515 587 535 1722 543 1662 561 592 540 1664 570 585 537 591 541 1689 545 584 538 590 542 1688 536 593 539 589 512 590 542 586 536 1720 514 588 544 585 537 591 541 587 514 200000 8990 4500 566 1692 562 1668 566 588 534 594 518 584 538 591 541 587 535 1669 565 589 543 1688 536 592 540 1691 563 1667 567 1664 621 1635 568 586 515 587 535 593 539 589 543 1662 562 592 540 588 534 594 518 585 537 591 541 587 514 587 535 594 538 590 542 586 515 586 536 593 539 39544 8993 4498 567 1690 564 1666 568 586 536 593 508 593 539 589 543 585 537 1668 566 588 544 1687 537 591 541 1690 564 1666 568 1663 561 1696 569 585 516 586 536 593 539 589 543 1661 562 592 540 588 534 594 517 584 538 591 541 587 514 587 535 593 539 589 543 585 516 586 536 592 540 200000 8894 4456 589 1676 589 571 582 574 589 571 582 1683 582 1677 588 1682 583 574 589 568 585 1682 583 1678 587 1680 585 574 589 565 588 575 588 1675 590 567 586 1681 584 571 582 1685 590 568 585 569 584 1685 590 567 586 1678 587 574 589 1672 582 578 585 1679 586 1674 591 572 591 1672 582 39632 8912 4464 560 1703 562 598 565 594 559 594 559 1711 564 1698 567 1697 568 593 560 595 568 1698 567 1698 567 1693 561 602 561 596 567 590 563 1704 561 594 559 1707 568 591 562 1697 568 596 567 590 563 1700 565 596 567 1693 561 599 564 1701 564 589 564 1706 559 1704 561 597 566 1700 565 200000 9018 4500 565 1666 568 1689 565 588 513 1691 615 1616 618 1639 564 1667 567 587 535 594 538 563 538 590 542 586 536 593 508 593 539 589 543 1688 535 592 540 588 544 585 537 591 510 1694 560 1670 564 1693 562 1669 565 1692 542 1689 565 588 534 595 517 585 537 591 541 587 535 568 544 584 538 591 541 1663 560 1696 569 1662 562 1695 539 1692 614 1616 566 1691 563 1667 567 23184 9012 4505 560 1697 537 1693 561 593 508 1696 569 1662 562 1695 560 1671 563 591 541 587 535 594 518 584 538 590 542 586 515 613 509 593 539 1692 542 585 537 592 540 588 534 594 518 1687 567 1663 560 1697 568 1662 562 1695 539 1692 563 591 541 587 514 588 544 584 538 590 542 586 515 587 535 593 539 1666 568 1689 565 1665 569 1688 536 1695 570 1661 562 1694 561 1670 564 200000 8835 4446 537 562 539 562 539 1663 540 1667 536 1669 534 560 531 573 539 559 532 1672 531 570 531 564 537 563 538 561 540 1660 533 1677 536 561 540 557 534 567 534 1668 535 1672 531 1675 538 555 536 1674 539 1665 538 1666 537 1671 532 563 538 1669 534 566 535 558 533 1677 536 562 539 558 533 568 533 1668 535 566 535 1670 533 1667 536 568 533 1671 532 1672 531 1676 537 22779 8870 4437 535 92592 8861 4414 538 +# +name: decoder_expected3 +type: parsed_array +count: 15 +# +protocol: NECext +address: 86 02 00 00 +command: 49 B6 00 00 +repeat: false +# +protocol: NECext +address: 86 02 00 00 +command: 49 B6 00 00 +repeat: false +# +protocol: NECext +address: 80 68 00 00 +command: 49 B6 00 00 +repeat: false +# +protocol: NECext +address: 80 68 00 00 +command: 49 B6 00 00 +repeat: false +# +protocol: NECext +address: 80 63 00 00 +command: 0F 15 00 00 +repeat: false +# +protocol: NECext +address: 80 63 00 00 +command: 0F 15 00 00 +repeat: false +# +protocol: NECext +address: 80 64 00 00 +command: 49 08 00 00 +repeat: false +# +protocol: NECext +address: 80 64 00 00 +command: 49 08 00 00 +repeat: false +# +protocol: NECext +address: 83 7A 00 00 +command: 08 00 00 00 +repeat: false +# +protocol: NECext +address: 83 7A 00 00 +command: 08 00 00 00 +repeat: false +# +protocol: NEC +address: 71 00 00 00 +command: 4A 00 00 00 +repeat: false +# +protocol: NEC +address: 71 00 00 00 +command: 4A 00 00 00 +repeat: false +# +protocol: NEC42 +address: 7B 00 00 00 +command: 00 00 00 00 +repeat: false +# +protocol: NEC42 +address: 7B 00 00 00 +command: 00 00 00 00 +repeat: false +# +protocol: NEC42 +address: 1C 01 00 00 +command: 12 00 00 00 +repeat: false +# +name: encoder_decoder_input1 +type: parsed_array +count: 26 +# +protocol: NEC +address: 00 00 00 00 +command: 00 00 00 00 +repeat: false +# +protocol: NEC +address: 01 00 00 00 +command: 00 00 00 00 +repeat: false +# +protocol: NEC +address: 01 00 00 00 +command: 80 00 00 00 +repeat: false +# +protocol: NEC +address: 00 00 00 00 +command: 80 00 00 00 +repeat: false +# +protocol: NEC +address: 00 00 00 00 +command: 00 00 00 00 +repeat: false +# +protocol: NEC +address: 00 00 00 00 +command: 00 00 00 00 +repeat: true +# +protocol: NEC +address: 00 00 00 00 +command: 00 00 00 00 +repeat: false +# +protocol: NEC +address: 00 00 00 00 +command: 00 00 00 00 +repeat: true +# +protocol: NEC +address: FF 00 00 00 +command: FF 00 00 00 +repeat: false +# +protocol: NEC +address: FE 00 00 00 +command: FF 00 00 00 +repeat: false +# +protocol: NEC +address: FE 00 00 00 +command: 7F 00 00 00 +repeat: false +# +protocol: NEC +address: FF 00 00 00 +command: 7F 00 00 00 +repeat: false +# +protocol: NEC +address: FF 00 00 00 +command: FF 00 00 00 +repeat: false +# +protocol: NEC +address: FF 00 00 00 +command: FF 00 00 00 +repeat: true +# +protocol: NEC +address: AA 00 00 00 +command: 55 00 00 00 +repeat: false +# +protocol: NEC +address: 55 00 00 00 +command: AA 00 00 00 +repeat: false +# +protocol: NEC +address: 55 00 00 00 +command: 55 00 00 00 +repeat: false +# +protocol: NEC +address: AA 00 00 00 +command: AA 00 00 00 +repeat: false +# +protocol: NEC +address: AA 00 00 00 +command: AA 00 00 00 +repeat: true +# +protocol: NEC +address: AA 00 00 00 +command: AA 00 00 00 +repeat: false +# +protocol: NEC +address: AA 00 00 00 +command: AA 00 00 00 +repeat: true +# +protocol: NEC +address: AA 00 00 00 +command: AA 00 00 00 +repeat: true +# +protocol: NEC +address: 55 00 00 00 +command: 55 00 00 00 +repeat: false +# +protocol: NEC +address: 55 00 00 00 +command: 55 00 00 00 +repeat: true +# +protocol: NEC +address: 55 00 00 00 +command: 55 00 00 00 +repeat: true +# +protocol: NEC +address: 55 00 00 00 +command: 55 00 00 00 +repeat: true +# diff --git a/assets/unit_tests/infrared/test_nec42.irtest b/assets/unit_tests/infrared/test_nec42.irtest new file mode 100644 index 00000000..960e60ee --- /dev/null +++ b/assets/unit_tests/infrared/test_nec42.irtest @@ -0,0 +1,137 @@ +Filetype: IR tests file +Version: 1 +# +name: encoder_decoder_input1 +type: parsed_array +count: 26 +# +protocol: NEC42 +address: 00 00 00 00 +command: 00 00 00 00 +repeat: false +# +protocol: NEC42 +address: 01 00 00 00 +command: 00 00 00 00 +repeat: false +# +protocol: NEC42 +address: 01 00 00 00 +command: 80 00 00 00 +repeat: false +# +protocol: NEC42 +address: 00 00 00 00 +command: 80 00 00 00 +repeat: false +# +protocol: NEC42 +address: 00 00 00 00 +command: 00 00 00 00 +repeat: false +# +protocol: NEC42 +address: 00 00 00 00 +command: 00 00 00 00 +repeat: true +# +protocol: NEC42 +address: 00 00 00 00 +command: 00 00 00 00 +repeat: false +# +protocol: NEC42 +address: 00 00 00 00 +command: 00 00 00 00 +repeat: true +# +protocol: NEC42 +address: FF 1F 00 00 +command: FF 00 00 00 +repeat: false +# +protocol: NEC42 +address: FE 1F 00 00 +command: FF 00 00 00 +repeat: false +# +protocol: NEC42 +address: FE 1F 00 00 +command: 7F 00 00 00 +repeat: false +# +protocol: NEC42 +address: FF 1F 00 00 +command: 7F 00 00 00 +repeat: false +# +protocol: NEC42 +address: FF 1F 00 00 +command: FF 00 00 00 +repeat: false +# +protocol: NEC42 +address: FF 1F 00 00 +command: FF 00 00 00 +repeat: true +# +protocol: NEC42 +address: AA 0A 00 00 +command: 55 00 00 00 +repeat: false +# +protocol: NEC42 +address: 55 15 00 00 +command: AA 00 00 00 +repeat: false +# +protocol: NEC42 +address: 55 15 00 00 +command: 55 00 00 00 +repeat: false +# +protocol: NEC42 +address: AA 0A 00 00 +command: AA 00 00 00 +repeat: false +# +protocol: NEC42 +address: AA 0A 00 00 +command: AA 00 00 00 +repeat: true +# +protocol: NEC42 +address: AA 0A 00 00 +command: AA 00 00 00 +repeat: false +# +protocol: NEC42 +address: AA 0A 00 00 +command: AA 00 00 00 +repeat: true +# +protocol: NEC42 +address: AA 0A 00 00 +command: AA 00 00 00 +repeat: true +# +protocol: NEC42 +address: 55 15 00 00 +command: 55 00 00 00 +repeat: false +# +protocol: NEC42 +address: 55 15 00 00 +command: 55 00 00 00 +repeat: true +# +protocol: NEC42 +address: 55 15 00 00 +command: 55 00 00 00 +repeat: true +# +protocol: NEC42 +address: 55 15 00 00 +command: 55 00 00 00 +repeat: true +# diff --git a/assets/unit_tests/infrared/test_nec42ext.irtest b/assets/unit_tests/infrared/test_nec42ext.irtest new file mode 100644 index 00000000..d7271fce --- /dev/null +++ b/assets/unit_tests/infrared/test_nec42ext.irtest @@ -0,0 +1,163 @@ +Filetype: IR tests file +Version: 1 +# +name: decoder_input1 +type: raw +data: 2000000 9000 4500 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 +# +name: decoder_expected1 +type: parsed_array +count: 1 +# +protocol: NEC42ext +address: 00 00 00 00 +command: 00 00 00 00 +repeat: false +# +name: decoder_input2 +type: raw +data: 2000000 9000 4500 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 2000000 9000 4500 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 560 10000 560 +# +name: decoder_expected2 +type: parsed_array +count: 1 +# +protocol: NEC42ext +address: 00 00 00 00 +command: 00 00 00 00 +repeat: false +# +name: encoder_decoder_input1 +type: parsed_array +count: 26 +# +protocol: NEC42ext +address: 00 00 00 00 +command: 00 00 00 00 +repeat: false +# +protocol: NEC42ext +address: 01 00 00 00 +command: 00 00 00 00 +repeat: false +# +protocol: NEC42ext +address: 01 00 00 00 +command: 00 80 00 00 +repeat: false +# +protocol: NEC42ext +address: 00 00 00 00 +command: 00 80 00 00 +repeat: false +# +protocol: NEC42ext +address: 00 00 00 00 +command: 00 00 00 00 +repeat: false +# +protocol: NEC42ext +address: 00 00 00 00 +command: 00 00 00 00 +repeat: true +# +protocol: NEC42ext +address: 00 00 00 00 +command: 00 00 00 00 +repeat: false +# +protocol: NEC42ext +address: 00 00 00 00 +command: 00 00 00 00 +repeat: true +# +protocol: NEC42ext +address: FF 00 F0 03 +command: 0F F0 00 00 +repeat: false +# +protocol: NEC42ext +address: FE 00 F0 03 +command: 0F F0 00 00 +repeat: false +# +protocol: NEC42ext +address: FE 00 F0 03 +command: 0F 70 00 00 +repeat: false +# +protocol: NEC42ext +address: FF 00 F0 03 +command: 0F 70 00 00 +repeat: false +# +protocol: NEC42ext +address: FF 00 F0 03 +command: 0F F0 00 00 +repeat: false +# +protocol: NEC42ext +address: FF 00 F0 03 +command: 0F F0 00 00 +repeat: true +# +protocol: NEC42ext +address: AA AA AA 02 +command: 55 55 00 00 +repeat: false +# +protocol: NEC42ext +address: 55 55 55 01 +command: AA AA 00 00 +repeat: false +# +protocol: NEC42ext +address: 55 55 55 01 +command: 55 55 00 00 +repeat: false +# +protocol: NEC42ext +address: AA AA AA 02 +command: AA AA 00 00 +repeat: false +# +protocol: NEC42ext +address: AA AA AA 02 +command: AA AA 00 00 +repeat: true +# +protocol: NEC42ext +address: AA AA AA 02 +command: AA AA 00 00 +repeat: false +# +protocol: NEC42ext +address: AA AA AA 02 +command: AA AA 00 00 +repeat: true +# +protocol: NEC42ext +address: AA AA AA 02 +command: AA AA 00 00 +repeat: true +# +protocol: NEC42ext +address: 55 55 55 01 +command: 55 55 00 00 +repeat: false +# +protocol: NEC42ext +address: 55 55 55 01 +command: 55 55 00 00 +repeat: true +# +protocol: NEC42ext +address: 55 55 55 01 +command: 55 55 00 00 +repeat: true +# +protocol: NEC42ext +address: 55 55 55 01 +command: 55 55 00 00 +repeat: true +# diff --git a/assets/unit_tests/infrared/test_necext.irtest b/assets/unit_tests/infrared/test_necext.irtest new file mode 100644 index 00000000..ffe663b7 --- /dev/null +++ b/assets/unit_tests/infrared/test_necext.irtest @@ -0,0 +1,684 @@ +Filetype: IR tests file +Version: 1 +# +name: decoder_input1 +type: raw +data: 1915384 8967 4463 587 527 590 524 584 1647 590 524 583 531 586 527 590 524 583 1646 589 1640 586 527 590 524 583 1647 590 1640 587 1644 582 1647 589 524 583 531 586 1644 593 521 586 527 589 1641 586 528 589 525 592 521 585 1644 592 522 585 1645 592 1638 589 524 592 1637 588 1641 585 1645 592 41082 8965 2220 591 409594 8972 4458 591 523 584 530 587 1642 584 529 588 526 591 522 583 530 587 1643 584 1646 590 523 584 530 587 1643 584 1647 590 1640 586 1643 583 531 586 527 589 1641 586 528 589 524 593 1637 589 524 593 521 586 529 589 1641 585 528 589 1640 586 1644 592 521 585 1645 592 1638 588 1641 585 41088 8968 2218 582 95791 8971 2214 587 95787 8965 2220 591 95783 8971 2215 585 95787 8964 2221 590 95783 8971 2215 586 95788 8965 2220 591 95783 8969 2216 585 95789 8965 2220 590 95782 8970 2215 586 95788 9047 2139 591 95782 8970 2216 585 95788 8966 2220 591 95782 8972 2214 588 95786 8964 2222 590 95784 8971 2214 586 95787 8967 2218 583 95791 8964 2222 588 95785 8969 2217 584 333740 8967 4464 586 528 590 524 592 1637 589 525 592 521 586 528 589 525 593 1637 588 1640 585 528 589 525 592 1638 589 1641 586 1644 592 1638 588 525 592 522 585 1644 592 522 585 528 588 1642 585 529 588 526 591 522 585 1645 591 522 584 1646 591 1639 587 526 591 1639 588 1642 583 1646 590 41082 8963 2223 588 95785 8967 2219 591 95782 8968 2217 584 246369 8972 4459 591 523 583 530 587 1643 583 530 587 527 590 523 584 530 586 1643 583 1647 590 524 583 530 586 1643 583 1646 589 1641 586 1644 583 531 586 528 589 1640 585 528 588 525 592 1638 588 525 592 522 585 529 589 1641 584 529 588 1642 585 1645 591 522 585 1645 590 1639 587 1642 584 41090 8966 2220 591 95782 8966 2220 592 95782 8967 2218 583 165604 9017 4413 586 527 590 524 583 1647 589 523 582 531 586 528 589 525 593 1637 589 1640 585 527 588 525 592 1638 589 1641 585 1644 592 1638 588 525 591 523 585 1645 591 522 584 529 588 1642 584 530 587 527 591 523 584 1646 591 523 584 1646 591 1640 586 527 590 1640 586 1643 583 1646 589 41084 8972 2214 587 95787 8967 2219 581 95792 8971 2215 586 208929 9016 4414 584 529 588 526 591 1638 588 525 591 522 584 529 587 526 591 1639 587 1642 584 529 588 526 591 1638 587 1643 584 1646 591 1639 587 526 590 523 584 1646 590 524 583 530 587 1643 583 530 587 527 590 524 583 1647 590 524 583 1647 590 1640 586 527 589 1640 586 1644 592 1637 589 41085 8972 2214 587 95787 8964 2221 590 95784 8965 2221 590 167378 8969 4460 589 525 582 532 586 1644 592 521 586 528 589 524 592 522 585 1645 592 1638 589 525 592 522 585 1644 591 1639 588 1642 585 1645 591 522 585 529 587 1641 584 530 587 526 591 1639 588 526 591 522 584 530 587 1643 584 530 587 1642 584 1646 591 523 584 1647 590 1640 587 1643 583 41090 9017 2169 591 95781 8969 2216 585 95788 8964 2223 588 192781 8969 4461 589 525 592 522 586 1644 592 521 586 528 589 525 592 522 585 1644 592 1638 589 524 592 521 586 1645 591 1638 588 1642 585 1645 590 522 584 530 587 1642 584 530 587 526 591 1639 588 526 590 524 583 530 587 1643 584 530 587 1643 584 1646 590 524 583 1646 590 1640 587 1643 583 41090 8967 2219 591 95782 8970 2215 586 95788 8963 2222 589 179978 8967 4464 586 528 589 524 593 1637 588 525 592 522 585 529 589 525 592 1638 589 1641 585 529 588 526 591 1638 588 1641 585 1645 590 1639 587 527 590 523 584 1646 591 523 584 530 587 1643 583 530 586 527 590 524 583 1646 590 523 584 1646 589 1640 586 528 589 1640 586 1644 593 1638 589 41084 8971 2214 587 95787 8964 2221 589 95785 8966 2219 592 196616 8967 4463 585 527 590 525 592 1637 589 525 592 521 586 528 589 524 592 1638 588 1641 585 528 589 525 592 1637 589 1641 585 1645 591 1638 588 526 591 522 585 1645 591 522 584 530 587 1642 584 529 588 526 591 523 583 1645 590 523 584 1646 590 1639 587 527 590 1639 586 1644 583 1647 589 41084 8971 2214 587 95787 8964 2222 589 2112164 8969 4462 588 525 592 522 585 1645 591 523 584 529 588 526 591 523 584 1645 591 1639 587 527 590 524 583 1646 590 1639 587 1643 584 1673 563 524 583 531 586 1643 593 521 586 528 589 1641 585 528 589 525 592 521 585 1644 592 522 584 1645 591 1639 588 526 591 1639 588 1642 583 1646 590 41082 8962 2223 588 95785 8965 2220 591 95783 8968 2217 583 164778 8969 4462 588 525 591 522 585 1645 591 522 585 530 587 527 591 523 584 1646 591 1639 588 526 591 523 583 1646 590 1639 587 1643 584 1672 564 523 584 531 586 1643 583 530 587 527 590 1639 587 527 589 524 583 531 586 1644 583 531 586 1643 583 1647 590 525 582 1647 589 1639 586 1644 593 41081 8965 2220 590 95784 8968 2217 583 95790 8970 2215 586 161053 8963 4468 592 521 586 528 589 1641 585 529 588 526 591 522 585 529 588 1642 585 1645 591 523 584 530 587 1642 584 1646 591 1639 586 1669 557 531 586 527 590 1640 586 527 590 525 592 1638 589 525 592 522 585 528 588 1641 585 528 588 1642 584 1645 591 523 584 1645 591 1639 587 1643 583 41090 8964 2221 590 95784 8963 2222 589 95785 8965 2220 590 139334 8968 4463 587 527 590 523 584 1646 590 523 583 531 586 527 589 524 583 1647 590 1640 586 527 590 525 592 1637 589 1641 585 1644 592 1665 562 524 591 522 584 1645 591 523 584 529 588 1642 584 529 587 527 590 523 584 1646 590 523 584 1646 590 1639 587 527 589 1640 586 1644 592 1637 589 41085 8970 2217 584 95789 8972 2213 586 95787 8965 2221 590 141444 8969 4461 589 525 592 522 584 1644 591 522 585 529 588 526 591 522 585 1645 592 1638 587 526 591 523 584 1646 591 1639 588 1642 583 1672 564 523 584 530 587 1643 584 530 587 527 590 1640 587 527 590 524 584 530 587 1643 584 530 586 1644 583 1647 589 524 583 1647 590 1640 586 1645 592 41081 8964 2222 589 95784 8968 2218 583 95790 8971 2214 586 154119 8969 4462 588 526 591 522 585 1645 592 522 585 529 589 526 591 522 584 1646 591 1639 588 526 591 523 583 1645 590 1639 587 1642 584 1671 564 523 584 529 587 1643 583 530 587 527 590 1639 587 526 590 523 583 530 586 1643 583 529 586 1643 583 1646 590 524 583 1648 589 1641 586 1644 592 41081 8965 2220 590 95784 8969 2216 585 95790 8964 2221 590 147134 8966 4464 586 528 589 525 593 1637 589 524 593 522 585 529 589 525 592 1638 589 1641 586 528 589 525 591 1638 588 1641 585 1645 592 1664 561 525 592 523 584 1646 591 523 584 530 588 1642 585 526 587 527 590 523 584 1646 591 523 584 1646 591 1639 586 526 590 1640 587 1643 583 1646 590 41083 8963 2223 587 95786 8965 2221 590 95784 8968 2217 584 158330 8965 4465 585 529 588 526 590 1639 587 526 590 523 584 530 586 526 590 1639 587 1643 583 530 587 527 590 1639 587 1643 584 1647 590 1666 561 527 589 523 583 1646 590 523 583 531 586 1643 583 530 586 527 590 524 582 1646 590 525 582 1647 589 1640 586 528 589 1640 586 1644 592 1638 589 41085 8971 2214 586 95787 8962 2223 588 95786 8965 2222 589 206063 8962 4467 591 521 585 529 588 1642 585 529 588 525 591 522 584 530 587 1642 584 1646 591 523 584 529 588 1642 583 1646 590 1640 587 1668 558 530 587 526 589 1639 586 528 589 524 583 1647 589 524 593 521 585 528 589 1641 585 529 589 1641 585 1645 592 522 585 1644 591 1639 587 1642 584 41090 8965 2221 590 95784 8963 2223 588 95785 8964 2222 589 183026 8970 4460 590 524 583 531 586 1643 583 530 587 528 589 525 592 522 586 1644 592 1637 588 525 591 522 585 1645 592 1638 588 1641 585 1672 565 522 584 530 588 1642 584 529 588 526 591 1639 587 527 590 523 584 530 587 1642 584 530 587 1642 583 1647 590 524 583 1647 590 1640 587 1643 582 41090 8965 2221 590 95783 8970 2216 584 95789 8962 2223 587 184104 8964 4467 583 530 587 527 590 1640 587 527 590 523 582 531 586 528 589 1640 586 1644 593 521 586 528 589 1640 585 1644 592 1638 589 1667 558 528 589 526 591 1638 588 526 591 522 585 1645 591 522 585 530 587 527 591 1639 587 526 591 1639 587 1642 584 530 587 1643 583 1646 590 1639 587 41087 9020 2166 584 95790 8972 2213 587 95787 8963 2222 589 169833 8964 4465 583 529 587 527 590 1639 587 527 591 523 584 530 586 527 590 1640 587 1643 583 531 587 527 590 1640 586 1644 583 1647 590 1666 560 527 590 524 582 1647 589 525 592 521 586 1644 592 521 586 528 589 526 592 1638 588 525 592 1638 589 1641 585 528 589 1641 585 1645 591 1638 588 41086 8971 2215 585 95789 8964 2222 588 95785 8967 2218 583 185701 8971 4460 590 523 584 530 587 1642 584 530 587 527 590 524 583 531 586 1644 583 1647 590 524 592 521 585 1644 592 1638 589 1641 585 1671 565 522 586 529 588 1642 585 529 588 526 591 1638 588 525 590 523 584 530 587 1642 584 530 587 1642 584 1646 590 524 583 1646 590 1640 586 1643 583 41091 8965 2222 589 95784 8965 2221 589 95784 8968 2217 583 146332 8969 4461 669 445 591 522 584 1644 591 523 584 529 588 526 591 522 585 1645 591 1638 587 527 590 524 584 1646 590 1639 587 1642 583 1673 564 524 583 531 586 1643 583 531 586 528 589 1641 585 528 589 525 592 522 585 1644 591 521 585 1645 592 1638 588 525 592 1638 588 1641 584 1646 591 41083 8963 2222 589 95785 8966 2220 592 261924 8965 4465 585 529 588 525 592 1638 588 525 592 523 584 530 587 526 591 1639 587 1642 583 529 587 527 590 1639 587 1643 584 1646 590 +# +name: decoder_expected1 +type: parsed_array +count: 108 +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: false +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: false +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: false +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: false +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: false +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: false +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: false +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: false +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: false +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: false +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: false +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: false +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: false +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: false +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: false +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: false +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: false +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: false +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: false +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: false +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: false +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: false +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: false +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: false +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +protocol: NECext +address: 84 79 00 00 +command: 12 ED 00 00 +repeat: true +# +name: encoder_decoder_input1 +type: parsed_array +count: 26 +protocol: NECext +address: 00 00 00 00 +command: 00 00 00 00 +repeat: false +# +protocol: NECext +address: 01 00 00 00 +command: 00 00 00 00 +repeat: false +# +protocol: NECext +address: 01 00 00 00 +command: 00 80 00 00 +repeat: false +# +protocol: NECext +address: 00 00 00 00 +command: 00 80 00 00 +repeat: false +# +protocol: NECext +address: 00 00 00 00 +command: 00 00 00 00 +repeat: false +# +protocol: NECext +address: 00 00 00 00 +command: 00 00 00 00 +repeat: true +# +protocol: NECext +address: 00 00 00 00 +command: 00 00 00 00 +repeat: false +# +protocol: NECext +address: 00 00 00 00 +command: 00 00 00 00 +repeat: true +# +protocol: NECext +address: FF FF 00 00 +command: FF FF 00 00 +repeat: false +# +protocol: NECext +address: FE FF 00 00 +command: FF FF 00 00 +repeat: false +# +protocol: NECext +address: FE FF 00 00 +command: FF 7F 00 00 +repeat: false +# +protocol: NECext +address: FF FF 00 00 +command: FF 7F 00 00 +repeat: false +# +protocol: NECext +address: FF FF 00 00 +command: FF FF 00 00 +repeat: false +# +protocol: NECext +address: FF FF 00 00 +command: FF FF 00 00 +repeat: true +# +protocol: NECext +address: AA AA 00 00 +command: 55 55 00 00 +repeat: false +# +protocol: NECext +address: 55 55 00 00 +command: AA AA 00 00 +repeat: false +# +protocol: NECext +address: 55 55 00 00 +command: 55 55 00 00 +repeat: false +# +protocol: NECext +address: AA AA 00 00 +command: AA AA 00 00 +repeat: false +# +protocol: NECext +address: AA AA 00 00 +command: AA AA 00 00 +repeat: true +# +protocol: NECext +address: AA AA 00 00 +command: AA AA 00 00 +repeat: false +# +protocol: NECext +address: AA AA 00 00 +command: AA AA 00 00 +repeat: true +# +protocol: NECext +address: AA AA 00 00 +command: AA AA 00 00 +repeat: true +# +protocol: NECext +address: 55 55 00 00 +command: 55 55 00 00 +repeat: false +# +protocol: NECext +address: 55 55 00 00 +command: 55 55 00 00 +repeat: true +# +protocol: NECext +address: 55 55 00 00 +command: 55 55 00 00 +repeat: true +# +protocol: NECext +address: 55 55 00 00 +command: 55 55 00 00 +repeat: true +# diff --git a/assets/unit_tests/infrared/test_rc5.irtest b/assets/unit_tests/infrared/test_rc5.irtest new file mode 100644 index 00000000..6935faa6 --- /dev/null +++ b/assets/unit_tests/infrared/test_rc5.irtest @@ -0,0 +1,341 @@ +Filetype: IR tests file +Version: 1 +# +name: decoder_input1 +type: raw +data: 27888 888 888 1776 1776 1776 888 888 1776 888 888 1776 1776 1776 888 888 888 888 888 888 +# +name: decoder_expected1 +type: parsed_array +count: 1 +# +protocol: RC5 +address: 13 00 00 00 +command: 10 00 00 00 +repeat: false +# +name: decoder_input2 +type: raw +data: 27888 888 888 888 888 888 888 1776 888 888 1776 888 888 1776 1776 1776 888 888 888 888 888 888 +# +name: decoder_expected2 +type: parsed_array +count: 1 +# +protocol: RC5 +address: 13 00 00 00 +command: 10 00 00 00 +repeat: false +# +name: decoder_input3 +type: raw +data: 27888 888 888 1776 1776 1776 888 888 1776 888 888 1776 1776 1776 888 888 888 888 1776 888 +# +name: decoder_expected3 +type: parsed_array +count: 1 +# +protocol: RC5 +address: 13 00 00 00 +command: 11 00 00 00 +repeat: false +# +name: decoder_input4 +type: raw +data: 27888 888 888 888 888 888 888 1776 888 888 1776 888 888 1776 1776 1776 888 888 888 888 1776 888 +# +name: decoder_expected4 +type: parsed_array +count: 1 +# +protocol: RC5 +address: 13 00 00 00 +command: 11 00 00 00 +repeat: false +# +name: decoder_input5 +type: raw +data: 27888 888 888 1776 1776 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 +# +name: decoder_expected5 +type: parsed_array +count: 1 +# +protocol: RC5 +address: 1F 00 00 00 +command: 3F 00 00 00 +repeat: false +# +name: decoder_input6 +type: raw +data: 27888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 +# +name: decoder_expected6 +type: parsed_array +count: 1 +# +protocol: RC5 +address: 1F 00 00 00 +command: 3F 00 00 00 +repeat: false +# +name: decoder_input7 +type: raw +data: 27888 888 888 1776 1776 1776 888 888 1776 888 888 1776 1776 1776 888 888 888 888 1776 888 27888 888 888 888 888 888 888 1776 888 888 1776 888 888 1776 1776 1776 888 888 888 888 1776 888 27888 888 888 888 888 888 888 1776 888 888 1776 888 888 1776 1776 1776 888 888 888 888 1776 888 27888 888 888 888 888 888 888 1776 888 888 1776 888 888 1776 1776 1776 888 888 888 888 1776 888 27888 888 888 1776 1776 1776 888 888 1776 888 888 1776 1776 1776 888 888 888 888 1776 888 27888 888 888 888 888 888 888 1776 888 888 1776 888 888 1776 1776 1776 888 888 888 888 888 888 27888 888 888 1776 1776 1776 888 888 1776 888 888 1776 1776 1776 888 888 888 888 888 888 27888 888 888 1776 1776 1776 888 888 1776 888 888 1776 1776 1776 888 888 888 888 888 888 27888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 27888 888 888 1776 1776 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 27888 888 888 1776 1776 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 +# +name: decoder_expected7 +type: parsed_array +count: 11 +# +protocol: RC5 +address: 13 00 00 00 +command: 11 00 00 00 +repeat: false +# +protocol: RC5 +address: 13 00 00 00 +command: 11 00 00 00 +repeat: false +# +protocol: RC5 +address: 13 00 00 00 +command: 11 00 00 00 +repeat: true +# +protocol: RC5 +address: 13 00 00 00 +command: 11 00 00 00 +repeat: true +# +protocol: RC5 +address: 13 00 00 00 +command: 11 00 00 00 +repeat: false +# +protocol: RC5 +address: 13 00 00 00 +command: 10 00 00 00 +repeat: false +# +protocol: RC5 +address: 13 00 00 00 +command: 10 00 00 00 +repeat: false +# +protocol: RC5 +address: 13 00 00 00 +command: 10 00 00 00 +repeat: true +# +protocol: RC5 +address: 1F 00 00 00 +command: 3F 00 00 00 +repeat: false +# +protocol: RC5 +address: 1F 00 00 00 +command: 3F 00 00 00 +repeat: false +# +protocol: RC5 +address: 1F 00 00 00 +command: 3F 00 00 00 +repeat: true +# +name: encoder_input1 +type: parsed_array +count: 11 +# +protocol: RC5 +address: 13 00 00 00 +command: 11 00 00 00 +repeat: false +# +protocol: RC5 +address: 13 00 00 00 +command: 11 00 00 00 +repeat: false +# +protocol: RC5 +address: 13 00 00 00 +command: 11 00 00 00 +repeat: true +# +protocol: RC5 +address: 13 00 00 00 +command: 11 00 00 00 +repeat: true +# +protocol: RC5 +address: 13 00 00 00 +command: 11 00 00 00 +repeat: false +# +protocol: RC5 +address: 13 00 00 00 +command: 10 00 00 00 +repeat: false +# +protocol: RC5 +address: 13 00 00 00 +command: 10 00 00 00 +repeat: false +# +protocol: RC5 +address: 13 00 00 00 +command: 10 00 00 00 +repeat: true +# +protocol: RC5 +address: 1F 00 00 00 +command: 3F 00 00 00 +repeat: false +# +protocol: RC5 +address: 1F 00 00 00 +command: 3F 00 00 00 +repeat: false +# +protocol: RC5 +address: 1F 00 00 00 +command: 3F 00 00 00 +repeat: true +# +name: encoder_expected1 +type: raw +data: 27888 888 888 1776 1776 1776 888 888 1776 888 888 1776 1776 1776 888 888 888 888 1776 888 27888 888 888 888 888 888 888 1776 888 888 1776 888 888 1776 1776 1776 888 888 888 888 1776 888 27888 888 888 888 888 888 888 1776 888 888 1776 888 888 1776 1776 1776 888 888 888 888 1776 888 27888 888 888 888 888 888 888 1776 888 888 1776 888 888 1776 1776 1776 888 888 888 888 1776 888 27888 888 888 1776 1776 1776 888 888 1776 888 888 1776 1776 1776 888 888 888 888 1776 888 27888 888 888 888 888 888 888 1776 888 888 1776 888 888 1776 1776 1776 888 888 888 888 888 888 27888 888 888 1776 1776 1776 888 888 1776 888 888 1776 1776 1776 888 888 888 888 888 888 27888 888 888 1776 1776 1776 888 888 1776 888 888 1776 1776 1776 888 888 888 888 888 888 27888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 27888 888 888 1776 1776 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 27888 888 888 1776 1776 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 +# +name: encoder_decoder_input1 +type: parsed_array +count: 26 +# +protocol: RC5 +address: 1F 00 00 00 +command: 3F 00 00 00 +repeat: false +# +protocol: RC5 +address: 00 00 00 00 +command: 00 00 00 00 +repeat: false +# +protocol: RC5 +address: 10 00 00 00 +command: 01 00 00 00 +repeat: false +# +protocol: RC5 +address: 01 00 00 00 +command: 20 00 00 00 +repeat: false +# +protocol: RC5 +address: 01 00 00 00 +command: 20 00 00 00 +repeat: false +# +protocol: RC5 +address: 01 00 00 00 +command: 20 00 00 00 +repeat: true +# +protocol: RC5 +address: 01 00 00 00 +command: 20 00 00 00 +repeat: true +# +protocol: RC5 +address: 01 00 00 00 +command: 20 00 00 00 +repeat: true +# +protocol: RC5 +address: 01 00 00 00 +command: 20 00 00 00 +repeat: true +# +protocol: RC5 +address: 1F 00 00 00 +command: 3F 00 00 00 +repeat: false +# +protocol: RC5 +address: 0A 00 00 00 +command: 2A 00 00 00 +repeat: false +# +protocol: RC5 +address: 15 00 00 00 +command: 15 00 00 00 +repeat: false +# +protocol: RC5 +address: 15 00 00 00 +command: 15 00 00 00 +repeat: true +# +protocol: RC5X +address: 1F 00 00 00 +command: 3F 00 00 00 +repeat: false +# +protocol: RC5X +address: 00 00 00 00 +command: 00 00 00 00 +repeat: false +# +protocol: RC5X +address: 10 00 00 00 +command: 01 00 00 00 +repeat: false +# +protocol: RC5X +address: 01 00 00 00 +command: 20 00 00 00 +repeat: false +# +protocol: RC5X +address: 01 00 00 00 +command: 20 00 00 00 +repeat: false +# +protocol: RC5X +address: 01 00 00 00 +command: 20 00 00 00 +repeat: true +# +protocol: RC5X +address: 01 00 00 00 +command: 20 00 00 00 +repeat: true +# +protocol: RC5X +address: 01 00 00 00 +command: 20 00 00 00 +repeat: true +# +protocol: RC5X +address: 01 00 00 00 +command: 20 00 00 00 +repeat: true +# +protocol: RC5X +address: 1F 00 00 00 +command: 3F 00 00 00 +repeat: false +# +protocol: RC5X +address: 0A 00 00 00 +command: 2A 00 00 00 +repeat: false +# +protocol: RC5X +address: 15 00 00 00 +command: 15 00 00 00 +repeat: false +# +protocol: RC5X +address: 15 00 00 00 +command: 15 00 00 00 +repeat: true +# diff --git a/assets/unit_tests/infrared/test_rc5x.irtest b/assets/unit_tests/infrared/test_rc5x.irtest new file mode 100644 index 00000000..65731eae --- /dev/null +++ b/assets/unit_tests/infrared/test_rc5x.irtest @@ -0,0 +1,29 @@ +Filetype: IR tests file +Version: 1 +# +name: decoder_input1 +type: raw +data: 27888 1776 888 888 1776 1776 888 888 1776 888 888 1776 1776 1776 888 888 888 888 888 888 +# +name: decoder_expected1 +type: parsed_array +count: 1 +# +protocol: RC5X +address: 13 00 00 00 +command: 10 00 00 00 +repeat: false +# +name: encoder_input1 +type: parsed_array +count: 1 +# +protocol: RC5X +address: 13 00 00 00 +command: 10 00 00 00 +repeat: false +# +name: encoder_expected1 +type: raw +data: 27888 1776 888 888 1776 1776 888 888 1776 888 888 1776 1776 1776 888 888 888 888 888 888 +# diff --git a/assets/unit_tests/infrared/test_rc6.irtest b/assets/unit_tests/infrared/test_rc6.irtest new file mode 100644 index 00000000..cb2e4393 --- /dev/null +++ b/assets/unit_tests/infrared/test_rc6.irtest @@ -0,0 +1,341 @@ +Filetype: IR tests file +Version: 1 +# +name: decoder_input1 +type: raw +data: 27000 2666 889 444 888 444 444 444 444 444 888 1332 888 444 444 888 888 888 888 444 444 888 888 888 888 444 444 444 444 444 444 444 444 444 27000 2666 889 444 888 444 444 444 444 1332 888 444 888 444 444 888 888 444 444 888 444 444 444 444 888 888 888 444 444 444 444 444 444 444 444 444 27000 2666 889 444 888 444 444 444 444 1332 888 444 888 444 444 888 888 888 888 888 444 444 888 888 888 444 444 444 444 444 444 444 444 888 27000 2666 889 444 888 444 444 444 444 444 888 1332 888 444 444 888 888 444 444 888 444 444 444 444 888 888 888 444 444 444 444 444 444 444 444 444 27000 2666 889 444 888 444 444 444 444 1332 888 444 888 444 444 888 888 888 888 444 444 888 888 888 888 444 444 444 444 444 444 444 444 444 27000 2666 889 444 888 444 444 444 444 444 888 1332 888 444 444 888 888 888 888 888 444 444 888 888 888 444 444 444 444 444 444 444 444 444 27000 2666 889 444 888 444 444 444 444 1332 888 444 888 444 444 888 888 444 444 888 444 444 444 444 888 888 888 444 444 444 444 444 444 444 444 444 444 444 444 444 27000 2666 889 444 888 444 444 444 444 1332 888 444 888 444 444 888 888 444 444 888 444 444 444 444 888 888 888 444 444 444 444 444 444 444 444 888 444 444 27000 2666 889 444 888 444 444 444 444 1332 888 444 888 444 444 888 888 444 444 888 444 444 444 444 888 888 888 444 444 444 444 444 444 444 444 888 27000 2666 889 444 888 444 444 444 444 1332 888 444 888 444 444 888 888 888 888 888 444 444 888 888 888 444 444 444 444 444 444 444 444 444 +# +name: decoder_expected1 +type: parsed_array +count: 6 +# +protocol: RC6 +address: 94 00 00 00 +command: A0 00 00 00 +repeat: false +# +protocol: RC6 +address: 93 00 00 00 +command: A0 00 00 00 +repeat: false +# +protocol: RC6 +address: 93 00 00 00 +command: A0 00 00 00 +repeat: false +# +protocol: RC6 +address: 94 00 00 00 +command: A0 00 00 00 +repeat: false +# +protocol: RC6 +address: 95 00 00 00 +command: A0 00 00 00 +repeat: false +# +protocol: RC6 +address: 95 00 00 00 +command: A0 00 00 00 +repeat: false +# +name: decoder_input2 +type: raw +data: 27000 2666 889 444 888 444 444 444 444 444 888 1332 888 444 444 888 888 444 444 888 444 444 444 444 888 888 888 444 444 444 444 444 444 444 444 444 27000 2666 889 444 888 444 444 444 444 444 888 1332 888 444 444 888 888 444 444 888 444 444 444 444 888 888 888 444 444 444 444 444 444 444 444 444 27000 2666 889 444 888 444 444 444 444 1332 888 444 888 444 444 888 888 444 444 888 444 444 444 444 888 888 888 444 444 444 444 444 444 888 27000 2666 889 444 888 444 444 444 444 1332 888 444 888 444 444 888 888 444 444 888 444 444 444 444 888 888 888 444 444 444 444 444 444 888 27000 2666 889 444 888 444 444 444 444 1332 888 444 888 444 444 888 888 444 444 888 444 444 444 444 888 888 888 444 444 444 444 444 444 888 27000 2666 889 444 888 444 444 444 444 444 888 1332 888 444 444 888 888 444 444 888 444 444 444 444 888 888 888 444 444 444 444 444 444 444 444 444 27000 2666 889 444 888 444 444 444 444 1332 888 444 888 444 444 888 888 444 444 888 444 444 444 444 888 888 888 444 444 444 444 444 444 444 444 444 27000 2666 889 444 888 444 444 444 444 1332 888 444 888 444 444 888 888 444 444 888 444 444 444 444 888 888 888 444 444 444 444 444 444 444 444 444 +# +name: decoder_expected2 +type: parsed_array +count: 8 +# +protocol: RC6 +address: 93 00 00 00 +command: A0 00 00 00 +repeat: false +# +protocol: RC6 +address: 93 00 00 00 +command: A0 00 00 00 +repeat: true +# +protocol: RC6 +address: 93 00 00 00 +command: A1 00 00 00 +repeat: false +# +protocol: RC6 +address: 93 00 00 00 +command: A1 00 00 00 +repeat: true +# +protocol: RC6 +address: 93 00 00 00 +command: A1 00 00 00 +repeat: true +# +protocol: RC6 +address: 93 00 00 00 +command: A0 00 00 00 +repeat: false +# +protocol: RC6 +address: 93 00 00 00 +command: A0 00 00 00 +repeat: false +# +protocol: RC6 +address: 93 00 00 00 +command: A0 00 00 00 +repeat: true +# +name: encoder_input1 +type: parsed_array +count: 8 +# +protocol: RC6 +address: 93 00 00 00 +command: A0 00 00 00 +repeat: false +# +protocol: RC6 +address: 93 00 00 00 +command: A0 00 00 00 +repeat: true +# +protocol: RC6 +address: 93 00 00 00 +command: A1 00 00 00 +repeat: false +# +protocol: RC6 +address: 93 00 00 00 +command: A1 00 00 00 +repeat: true +# +protocol: RC6 +address: 93 00 00 00 +command: A1 00 00 00 +repeat: true +# +protocol: RC6 +address: 93 00 00 00 +command: A0 00 00 00 +repeat: false +# +protocol: RC6 +address: 93 00 00 00 +command: A0 00 00 00 +repeat: false +# +protocol: RC6 +address: 93 00 00 00 +command: A0 00 00 00 +repeat: true +# +name: encoder_expected1 +type: raw +data: 27000 2666 889 444 888 444 444 444 444 444 888 1332 888 444 444 888 888 444 444 888 444 444 444 444 888 888 888 444 444 444 444 444 444 444 444 444 27000 2666 889 444 888 444 444 444 444 444 888 1332 888 444 444 888 888 444 444 888 444 444 444 444 888 888 888 444 444 444 444 444 444 444 444 444 27000 2666 889 444 888 444 444 444 444 1332 888 444 888 444 444 888 888 444 444 888 444 444 444 444 888 888 888 444 444 444 444 444 444 888 27000 2666 889 444 888 444 444 444 444 1332 888 444 888 444 444 888 888 444 444 888 444 444 444 444 888 888 888 444 444 444 444 444 444 888 27000 2666 889 444 888 444 444 444 444 1332 888 444 888 444 444 888 888 444 444 888 444 444 444 444 888 888 888 444 444 444 444 444 444 888 27000 2666 889 444 888 444 444 444 444 444 888 1332 888 444 444 888 888 444 444 888 444 444 444 444 888 888 888 444 444 444 444 444 444 444 444 444 27000 2666 889 444 888 444 444 444 444 1332 888 444 888 444 444 888 888 444 444 888 444 444 444 444 888 888 888 444 444 444 444 444 444 444 444 444 27000 2666 889 444 888 444 444 444 444 1332 888 444 888 444 444 888 888 444 444 888 444 444 444 444 888 888 888 444 444 444 444 444 444 444 444 444 +# +name: encoder_decoder_input1 +type: parsed_array +count: 40 +# +protocol: RC6 +address: 00 00 00 00 +command: 00 00 00 00 +repeat: false +# +protocol: RC6 +address: 80 00 00 00 +command: 00 00 00 00 +repeat: false +# +protocol: RC6 +address: 80 00 00 00 +command: 01 00 00 00 +repeat: false +# +protocol: RC6 +address: 00 00 00 00 +command: 01 00 00 00 +repeat: false +# +protocol: RC6 +address: 00 00 00 00 +command: 00 00 00 00 +repeat: false +# +protocol: RC6 +address: 00 00 00 00 +command: 00 00 00 00 +repeat: true +# +protocol: RC6 +address: 00 00 00 00 +command: 00 00 00 00 +repeat: false +# +protocol: RC6 +address: 00 00 00 00 +command: 00 00 00 00 +repeat: true +# +protocol: RC6 +address: FF 00 00 00 +command: FF 00 00 00 +repeat: false +# +protocol: RC6 +address: 7F 00 00 00 +command: FF 00 00 00 +repeat: false +# +protocol: RC6 +address: 7F 00 00 00 +command: FE 00 00 00 +repeat: false +# +protocol: RC6 +address: FF 00 00 00 +command: FE 00 00 00 +repeat: false +# +protocol: RC6 +address: FF 00 00 00 +command: FF 00 00 00 +repeat: false +# +protocol: RC6 +address: FF 00 00 00 +command: FF 00 00 00 +repeat: true +# +protocol: RC6 +address: AA 00 00 00 +command: 55 00 00 00 +repeat: false +# +protocol: RC6 +address: 55 00 00 00 +command: AA 00 00 00 +repeat: false +# +protocol: RC6 +address: 55 00 00 00 +command: 55 00 00 00 +repeat: false +# +protocol: RC6 +address: AA 00 00 00 +command: AA 00 00 00 +repeat: false +# +protocol: RC6 +address: AA 00 00 00 +command: AA 00 00 00 +repeat: true +# +protocol: RC6 +address: 00 00 00 00 +command: 00 00 00 00 +repeat: false +# +protocol: RC6 +address: 80 00 00 00 +command: 00 00 00 00 +repeat: false +# +protocol: RC6 +address: 80 00 00 00 +command: 01 00 00 00 +repeat: false +# +protocol: RC6 +address: 00 00 00 00 +command: 01 00 00 00 +repeat: false +# +protocol: RC6 +address: 00 00 00 00 +command: 00 00 00 00 +repeat: false +# +protocol: RC6 +address: 00 00 00 00 +command: 00 00 00 00 +repeat: true +# +protocol: RC6 +address: 00 00 00 00 +command: 00 00 00 00 +repeat: false +# +protocol: RC6 +address: 00 00 00 00 +command: 00 00 00 00 +repeat: true +# +protocol: RC6 +address: FF 00 00 00 +command: FF 00 00 00 +repeat: false +# +protocol: RC6 +address: 7F 00 00 00 +command: FF 00 00 00 +repeat: false +# +protocol: RC6 +address: 7F 00 00 00 +command: FE 00 00 00 +repeat: false +# +protocol: RC6 +address: FF 00 00 00 +command: FE 00 00 00 +repeat: false +# +protocol: RC6 +address: FF 00 00 00 +command: FF 00 00 00 +repeat: false +# +protocol: RC6 +address: FF 00 00 00 +command: FF 00 00 00 +repeat: true +# +protocol: RC6 +address: AA 00 00 00 +command: 55 00 00 00 +repeat: false +# +protocol: RC6 +address: 55 00 00 00 +command: AA 00 00 00 +repeat: false +# +protocol: RC6 +address: 55 00 00 00 +command: 55 00 00 00 +repeat: false +# +protocol: RC6 +address: AA 00 00 00 +command: AA 00 00 00 +repeat: false +# +protocol: RC6 +address: AA 00 00 00 +command: AA 00 00 00 +repeat: true +# +protocol: RC6 +address: 93 00 00 00 +command: A0 00 00 00 +repeat: false +# +protocol: RC6 +address: 93 00 00 00 +command: A1 00 00 00 +repeat: false +# diff --git a/assets/unit_tests/infrared/test_samsung32.irtest b/assets/unit_tests/infrared/test_samsung32.irtest new file mode 100644 index 00000000..2b5536a5 --- /dev/null +++ b/assets/unit_tests/infrared/test_samsung32.irtest @@ -0,0 +1,535 @@ +Filetype: IR tests file +Version: 1 +# +name: decoder_input1 +type: raw +data: 3129767 4513 4483 565 530 586 1670 563 1664 588 1666 566 530 586 535 560 535 591 531 565 531 585 1669 563 1666 587 1640 593 531 566 530 587 536 559 562 564 531 585 537 558 1670 562 1665 587 534 561 534 592 530 566 529 587 1668 564 1664 589 533 563 533 594 1661 560 1667 565 1661 591 1664 558 46325 4517 4480 558 1668 595 679127 4511 4485 562 532 584 1671 561 1666 587 1668 564 532 585 537 559 537 589 533 562 533 593 1661 561 1667 586 1642 590 532 563 531 585 537 559 564 563 1666 567 528 588 535 613 483 593 530 586 536 559 536 590 1637 584 537 558 1669 594 1661 561 1667 586 1642 591 1664 559 1670 583 534 567 46429 4515 4480 558 1671 593 618571 4508 4488 560 561 566 1663 559 1667 583 1670 562 534 582 540 565 531 587 536 560 536 590 1664 558 1670 583 1644 588 535 561 534 592 530 566 557 610 1616 616 479 585 537 558 537 589 534 584 539 567 529 587 534 561 534 592 1663 559 1668 564 1664 588 1666 566 1661 581 1646 585 1669 563 46106 4511 4485 563 1664 589 514897 4514 4482 556 564 614 1616 565 1664 589 1666 557 538 588 534 562 534 592 529 566 529 587 1667 565 1663 590 1638 584 538 568 527 590 534 562 562 566 530 587 1642 590 532 563 530 586 537 589 533 563 533 583 539 566 1661 561 561 566 1663 559 1668 584 1671 563 1666 556 1671 591 1663 559 46210 4508 4488 560 1668 585 683922 4509 4487 561 560 565 1662 559 1669 585 1670 562 534 583 540 566 529 586 535 560 535 591 1663 559 1669 584 1644 588 534 561 533 593 529 556 567 561 1668 564 1664 590 534 563 532 584 538 557 537 589 534 562 534 593 530 566 555 561 1667 564 1662 589 1665 557 1671 581 1647 586 1669 564 46686 4514 4481 556 1672 592 1088255 4514 4481 557 564 562 1667 565 1663 591 1665 558 538 590 533 564 532 583 539 567 528 588 1666 566 1663 580 1648 585 537 559 537 589 533 562 560 618 478 589 535 562 1667 565 1662 588 531 565 531 585 537 558 536 590 1666 566 1661 592 530 566 530 586 1669 564 1664 558 1669 594 1662 560 46291 4510 4485 563 1663 589 97349 4510 4487 561 1666 586 97560 4513 4482 566 1662 591 97123 4510 4485 563 1664 588 97605 4508 4487 561 1666 586 97371 4518 4478 560 1668 595 97514 4518 4478 560 1667 586 97014 4515 4480 568 1660 593 96719 4516 4481 567 1660 593 97528 4515 4480 568 1659 593 97453 4510 4485 563 1665 587 97351 4518 4477 561 1668 585 97216 4511 4484 564 1664 589 97708 4518 4477 561 1667 586 96718 4516 4479 559 1669 594 97070 4515 4480 568 1660 593 97500 4511 4484 564 1662 590 97425 4515 4481 567 1660 593 97025 4515 4482 566 1660 592 96796 4509 4487 561 1666 587 97399 4512 4484 565 1662 591 97486 4516 4480 567 1658 594 97425 4515 4481 567 1659 593 97511 4510 4485 563 1664 650 96969 4511 4485 562 1665 588 97243 4512 4484 564 1663 590 97031 4519 4478 560 1666 586 97548 4514 4482 566 1661 591 97302 4515 4480 568 1659 593 97726 4510 4486 562 1665 588 97396 4514 4482 566 1661 592 97301 4515 4480 568 1661 593 97453 4518 4477 560 1667 585 97430 4518 4477 561 1665 587 97521 4511 4484 564 1664 589 97182 4512 4484 564 1663 590 97760 4516 4479 559 1668 595 97268 4516 4479 559 1668 595 97243 4512 4485 563 1663 589 97695 4510 4486 562 1664 588 374205 4513 4483 565 530 586 1669 564 1665 589 1667 567 529 587 535 560 535 591 531 565 530 585 1669 563 1664 588 1639 593 529 566 529 587 536 560 563 565 532 585 537 560 1669 563 1664 587 534 561 534 592 529 566 529 586 1668 564 1663 589 532 563 534 593 1661 562 1666 566 1662 591 1664 558 149343 4512 4483 565 530 586 1669 563 1664 588 1667 565 530 586 536 560 536 590 532 563 531 586 1670 563 1666 567 1660 592 530 565 529 586 537 558 563 563 532 584 538 568 1661 561 1665 587 535 560 535 592 532 565 531 587 1669 563 1665 587 534 561 534 592 1663 559 1668 564 1662 590 1666 566 116399 4514 4482 566 531 587 1669 564 1664 589 1666 566 529 587 535 561 535 592 531 565 529 587 1668 564 1664 558 1670 595 529 566 528 589 535 560 562 565 531 585 536 559 1668 564 1664 589 534 561 533 593 530 565 528 588 1668 564 1665 590 533 564 532 594 1661 561 1666 566 1661 592 1663 558 121946 4517 4478 559 537 590 1664 568 1660 593 1661 560 536 590 531 564 531 585 537 559 536 590 1665 568 1661 561 1666 587 537 559 529 591 531 564 558 558 537 588 533 562 1665 567 1659 593 530 565 529 587 536 561 535 592 1664 559 1671 593 530 566 528 587 1667 565 1662 558 1668 595 1660 561 46509 4516 4479 558 1668 594 88785 4512 4484 564 530 585 1669 563 1664 588 1666 566 530 587 536 560 535 592 532 565 531 585 1669 563 1665 557 1669 594 530 566 530 586 535 560 562 564 530 585 537 558 1669 563 1664 589 535 561 534 593 529 566 529 586 1668 564 1664 589 533 562 532 594 1661 561 1666 565 1662 591 1665 558 289651 4512 4483 564 531 586 1669 563 1665 588 1667 565 529 587 536 560 536 590 531 563 531 584 1670 562 1666 556 1671 592 529 566 531 586 536 561 562 564 532 585 537 558 1669 563 1665 588 535 561 536 590 530 565 531 585 1669 563 1664 587 534 561 533 593 1662 561 1669 564 1663 590 1665 567 46302 4509 4487 561 1667 585 97097 4513 4483 565 529 587 1668 564 1663 589 1666 567 529 587 536 560 535 591 530 565 529 587 1669 563 1664 558 1669 594 529 566 527 587 535 561 561 563 530 586 537 560 1669 563 1663 589 534 561 532 594 529 566 528 587 1668 564 1663 589 532 563 532 594 1660 561 1667 566 1661 592 1663 558 46311 4510 4485 562 1665 589 99001 4514 4481 566 528 587 1667 565 1662 589 1664 568 528 588 535 561 535 593 529 567 528 589 1668 564 1663 559 1668 595 528 567 527 589 534 562 561 565 530 586 536 560 1668 564 1663 590 533 563 532 595 524 567 527 588 1667 565 1662 590 532 563 531 595 1659 562 1666 566 1661 593 1664 559 300259 4514 4482 556 565 561 1668 564 1663 589 1664 556 539 588 535 561 535 643 478 568 530 587 1668 564 1664 589 1636 594 529 567 528 588 534 561 561 565 1662 560 536 590 532 564 531 586 537 589 532 564 533 584 538 568 528 588 1667 565 1662 560 1669 584 1670 562 1666 587 1641 591 1664 559 46271 4561 4435 562 1666 586 81421 4514 4482 556 565 561 1667 565 1662 589 1664 558 538 588 534 562 534 593 530 567 530 587 1669 564 1663 589 1637 594 529 567 528 588 534 561 560 566 1663 559 535 591 531 565 530 587 538 589 533 563 533 583 539 567 529 587 1667 565 1662 560 1669 584 1669 563 1666 587 1640 592 1663 560 46296 4516 4480 558 1669 594 80690 4508 4489 560 561 565 1663 558 1670 593 1660 561 534 592 530 565 530 586 537 560 536 591 1664 558 1670 583 1644 587 535 560 534 592 530 566 556 559 1669 563 532 584 538 558 537 588 534 582 540 567 530 588 535 562 535 591 1663 559 1669 564 1665 588 1666 566 1662 560 1668 585 1669 563 136483 4511 4485 563 531 585 1671 561 1666 587 1668 564 531 585 536 559 537 589 532 563 532 584 1670 562 1666 587 1642 591 531 566 531 585 536 559 563 563 1665 567 528 588 535 561 534 593 529 567 556 560 535 591 530 565 531 585 1670 563 1665 568 1660 593 1662 560 1668 564 1663 590 1666 566 129038 4511 4484 564 533 583 1670 562 1666 587 1668 565 532 586 537 559 536 591 532 564 532 594 1660 562 1666 566 1660 593 531 565 530 586 537 558 563 563 1664 568 528 589 535 562 533 595 530 567 556 560 535 591 531 565 531 584 1669 563 1664 567 1661 592 1662 559 1668 564 1663 590 1666 566 46187 4511 4486 562 1665 589 110663 4517 4478 558 536 590 1665 568 1660 593 1661 560 536 590 531 564 531 584 537 558 536 590 1665 567 1661 561 1666 587 536 560 535 591 532 564 559 557 1670 562 532 594 529 567 528 649 473 561 561 565 531 585 536 559 536 589 1665 567 1660 562 1666 587 1668 564 1663 558 1669 594 1661 561 143736 4517 4479 559 536 591 1664 558 1670 593 1661 559 536 590 531 564 531 585 536 559 537 589 1665 567 1661 561 1666 587 536 560 536 590 530 564 557 558 1669 562 533 593 528 568 530 586 534 561 560 566 530 586 536 560 536 591 1664 558 1671 562 1666 587 1667 565 1663 559 1668 594 1660 562 46234 4514 4482 566 1661 591 120661 4564 4432 565 530 586 1669 563 1665 587 1666 566 531 585 536 559 536 591 532 564 532 586 1670 563 1666 557 1666 592 530 565 530 586 536 560 562 563 1664 558 538 588 533 562 533 593 528 558 565 561 534 582 541 566 530 586 1670 563 1664 567 1660 593 1662 560 1668 564 1663 590 1665 567 46472 4513 4484 564 1664 588 125301 4511 4484 564 532 584 1670 562 1666 587 1668 565 531 586 537 560 537 591 532 565 533 584 1671 562 1666 566 1661 591 530 565 532 584 536 559 562 564 1665 567 529 587 534 563 535 593 529 568 556 561 535 592 531 565 531 585 1669 563 1665 567 1660 593 1663 559 1668 564 1664 589 1666 567 200253 4517 4479 558 562 615 1613 558 1670 592 1661 560 536 591 531 616 480 585 537 559 537 641 1613 568 1661 582 1646 586 536 559 535 591 532 564 558 558 1670 562 533 592 530 566 529 588 536 581 542 617 479 587 537 560 536 590 1665 557 1670 562 1666 587 1668 564 1664 558 1669 593 1662 561 46230 4570 4426 561 1667 586 115418 4514 4483 565 557 561 1669 563 1664 589 1666 566 529 587 534 561 534 592 530 566 530 586 1668 564 1664 589 1639 594 529 567 528 587 534 561 561 565 1663 559 535 590 532 563 532 584 +# +name: decoder_expected1 +type: parsed_array +count: 78 +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 0C 00 00 00 +repeat: false +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 0C 00 00 00 +repeat: true +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 81 00 00 00 +repeat: false +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 81 00 00 00 +repeat: true +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 01 00 00 00 +repeat: false +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 01 00 00 00 +repeat: true +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 02 00 00 00 +repeat: false +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 02 00 00 00 +repeat: true +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 03 00 00 00 +repeat: false +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 03 00 00 00 +repeat: true +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 0C 00 00 00 +repeat: false +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 0C 00 00 00 +repeat: true +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 0C 00 00 00 +repeat: true +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 0C 00 00 00 +repeat: true +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 0C 00 00 00 +repeat: true +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 0C 00 00 00 +repeat: true +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 0C 00 00 00 +repeat: true +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 0C 00 00 00 +repeat: true +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 0C 00 00 00 +repeat: true +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 0C 00 00 00 +repeat: true +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 0C 00 00 00 +repeat: true +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 0C 00 00 00 +repeat: true +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 0C 00 00 00 +repeat: true +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 0C 00 00 00 +repeat: true +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 0C 00 00 00 +repeat: true +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 0C 00 00 00 +repeat: true +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 0C 00 00 00 +repeat: true +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 0C 00 00 00 +repeat: true +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 0C 00 00 00 +repeat: true +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 0C 00 00 00 +repeat: true +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 0C 00 00 00 +repeat: true +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 0C 00 00 00 +repeat: true +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 0C 00 00 00 +repeat: true +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 0C 00 00 00 +repeat: true +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 0C 00 00 00 +repeat: true +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 0C 00 00 00 +repeat: true +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 0C 00 00 00 +repeat: true +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 0C 00 00 00 +repeat: true +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 0C 00 00 00 +repeat: true +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 0C 00 00 00 +repeat: true +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 0C 00 00 00 +repeat: true +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 0C 00 00 00 +repeat: true +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 0C 00 00 00 +repeat: true +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 0C 00 00 00 +repeat: true +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 0C 00 00 00 +repeat: true +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 0C 00 00 00 +repeat: true +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 0C 00 00 00 +repeat: true +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 0C 00 00 00 +repeat: true +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 0C 00 00 00 +repeat: true +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 0C 00 00 00 +repeat: true +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 0C 00 00 00 +repeat: true +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 0C 00 00 00 +repeat: false +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 0C 00 00 00 +repeat: false +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 0C 00 00 00 +repeat: false +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 0C 00 00 00 +repeat: false +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 0C 00 00 00 +repeat: true +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 0C 00 00 00 +repeat: false +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 0C 00 00 00 +repeat: false +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 0C 00 00 00 +repeat: true +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 0C 00 00 00 +repeat: false +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 0C 00 00 00 +repeat: true +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 0C 00 00 00 +repeat: false +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 01 00 00 00 +repeat: false +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 01 00 00 00 +repeat: true +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 01 00 00 00 +repeat: false +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 01 00 00 00 +repeat: true +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 01 00 00 00 +repeat: false +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 01 00 00 00 +repeat: false +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 01 00 00 00 +repeat: false +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 01 00 00 00 +repeat: true +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 01 00 00 00 +repeat: false +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 01 00 00 00 +repeat: false +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 01 00 00 00 +repeat: true +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 01 00 00 00 +repeat: false +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 01 00 00 00 +repeat: true +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 01 00 00 00 +repeat: false +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 01 00 00 00 +repeat: false +# +protocol: Samsung32 +address: 0E 00 00 00 +command: 01 00 00 00 +repeat: true +# +name: encoder_decoder_input1 +type: parsed_array +count: 26 +# +protocol: Samsung32 +address: 00 00 00 00 +command: 00 00 00 00 +repeat: false +# +protocol: Samsung32 +address: 01 00 00 00 +command: 00 00 00 00 +repeat: false +# +protocol: Samsung32 +address: 01 00 00 00 +command: 80 00 00 00 +repeat: false +# +protocol: Samsung32 +address: 00 00 00 00 +command: 80 00 00 00 +repeat: false +# +protocol: Samsung32 +address: 00 00 00 00 +command: 00 00 00 00 +repeat: false +# +protocol: Samsung32 +address: 00 00 00 00 +command: 00 00 00 00 +repeat: true +# +protocol: Samsung32 +address: 00 00 00 00 +command: 00 00 00 00 +repeat: false +# +protocol: Samsung32 +address: 00 00 00 00 +command: 00 00 00 00 +repeat: true +# +protocol: Samsung32 +address: FF 00 00 00 +command: FF 00 00 00 +repeat: false +# +protocol: Samsung32 +address: FE 00 00 00 +command: FF 00 00 00 +repeat: false +# +protocol: Samsung32 +address: FE 00 00 00 +command: 7F 00 00 00 +repeat: false +# +protocol: Samsung32 +address: FF 00 00 00 +command: 7F 00 00 00 +repeat: false +# +protocol: Samsung32 +address: FF 00 00 00 +command: FF 00 00 00 +repeat: false +# +protocol: Samsung32 +address: FF 00 00 00 +command: FF 00 00 00 +repeat: true +# +protocol: Samsung32 +address: AA 00 00 00 +command: 55 00 00 00 +repeat: false +# +protocol: Samsung32 +address: 55 00 00 00 +command: AA 00 00 00 +repeat: false +# +protocol: Samsung32 +address: 55 00 00 00 +command: 55 00 00 00 +repeat: false +# +protocol: Samsung32 +address: AA 00 00 00 +command: AA 00 00 00 +repeat: false +# +protocol: Samsung32 +address: AA 00 00 00 +command: AA 00 00 00 +repeat: true +# +protocol: Samsung32 +address: AA 00 00 00 +command: AA 00 00 00 +repeat: false +# +protocol: Samsung32 +address: AA 00 00 00 +command: AA 00 00 00 +repeat: true +# +protocol: Samsung32 +address: AA 00 00 00 +command: AA 00 00 00 +repeat: true +# +protocol: Samsung32 +address: 55 00 00 00 +command: 55 00 00 00 +repeat: false +# +protocol: Samsung32 +address: 55 00 00 00 +command: 55 00 00 00 +repeat: true +# +protocol: Samsung32 +address: 55 00 00 00 +command: 55 00 00 00 +repeat: true +# +protocol: Samsung32 +address: 55 00 00 00 +command: 55 00 00 00 +repeat: true +# diff --git a/assets/unit_tests/infrared/test_sirc.irtest b/assets/unit_tests/infrared/test_sirc.irtest new file mode 100644 index 00000000..e3fcf5fc --- /dev/null +++ b/assets/unit_tests/infrared/test_sirc.irtest @@ -0,0 +1,1060 @@ +Filetype: IR tests file +Version: 1 +# +name: decoder_input1 +type: raw +data: 1000000 2420 608 1194 608 596 604 1198 603 591 610 1192 609 596 605 599 601 593 607 597 604 590 610 594 606 1196 25957 2426 603 1199 603 591 610 1192 610 594 606 1196 606 599 603 591 609 595 606 598 602 592 609 596 605 1197 25960 2423 606 1196 606 599 602 1200 602 592 609 1193 609 596 606 599 602 592 609 595 605 600 601 593 608 1194 1000000 2422 607 1195 607 598 603 1199 604 590 610 1192 610 594 606 598 603 591 609 595 605 600 601 593 607 1195 25955 2418 610 1192 610 594 606 1196 606 599 602 1200 602 592 608 596 604 590 611 594 607 597 603 591 609 1193 25959 2424 604 1198 604 590 610 1192 610 594 606 1196 605 600 601 593 608 597 603 591 610 595 606 598 602 1200 1000000 2424 605 599 601 593 607 597 603 591 610 594 606 1196 606 1196 605 600 601 593 608 597 604 590 611 1191 26586 2425 604 590 611 593 607 598 603 591 610 595 606 1196 606 1196 606 599 602 592 608 596 604 590 611 1191 26586 2424 604 590 611 593 607 598 603 591 609 595 605 1197 605 1197 604 590 611 593 607 597 603 591 610 1192 1000000 2424 604 1198 604 590 611 1191 610 594 606 598 603 1199 602 1200 602 592 609 595 605 600 601 593 608 1194 25386 2419 610 1192 610 594 606 1196 607 597 603 591 610 1192 609 1193 610 594 606 598 602 592 609 595 605 1197 25385 2421 608 1194 608 596 605 1197 605 599 601 593 608 1194 608 1194 608 596 605 589 611 594 607 597 604 1198 1000000 2426 603 1199 602 1200 602 1200 602 592 608 1194 608 596 604 590 611 594 607 597 603 591 610 594 606 1196 605 600 601 593 608 596 604 590 610 594 607 1195 606 598 603 591 15078 2419 610 1192 610 1192 610 1192 610 594 606 1196 605 600 601 593 608 597 604 590 610 595 606 598 602 1200 602 592 608 597 604 590 611 594 607 597 603 1199 603 591 609 595 15075 2422 607 1195 607 1195 607 1195 607 597 604 1198 603 591 610 594 606 598 603 591 609 595 605 600 601 1191 611 594 607 597 603 591 610 594 606 598 602 1200 602 592 608 596 1000000 2422 607 1195 606 599 602 592 608 596 604 590 610 1192 610 594 606 599 602 592 608 596 604 590 610 1192 26585 2426 602 1200 602 592 608 596 604 590 611 594 607 1195 607 598 603 591 610 594 606 598 603 591 609 1193 26586 2425 604 1198 603 591 610 594 606 598 602 592 609 1193 608 597 605 600 601 593 607 597 604 590 610 1192 1000000 2418 610 594 606 598 603 1199 603 1199 603 1199 603 1199 603 1199 603 591 610 1192 610 594 606 1196 606 1196 606 1196 606 598 602 592 609 1193 609 1193 609 1193 609 595 605 599 11557 2418 611 594 607 598 603 1199 603 1199 603 1199 602 1200 602 1200 601 593 608 1194 607 597 604 1198 603 1199 603 1199 602 592 608 596 604 1198 603 1199 603 1199 603 591 609 595 11561 2424 604 590 610 594 607 1195 606 1196 606 1196 606 1196 606 1196 605 600 601 1191 611 594 607 1195 607 1195 607 1195 607 597 603 591 610 1192 610 1192 610 1192 610 594 606 598 1000000 2424 604 590 611 594 607 1195 607 1195 607 1195 607 1195 607 1195 606 598 603 1199 602 592 609 1193 608 1194 608 1194 608 596 604 590 611 1191 611 1191 611 1191 611 594 607 598 11559 2427 602 592 608 596 605 1197 604 1198 604 1198 604 1198 604 1198 604 590 610 1192 610 595 606 1196 606 1196 606 1196 606 599 603 591 609 1193 609 1193 609 1193 608 597 605 589 11567 2418 610 595 607 597 603 1199 603 1199 602 1200 602 1200 601 1201 601 593 608 1194 607 598 603 1199 603 1199 603 1199 603 591 609 595 605 1197 605 1197 605 1197 604 590 611 594 1000000 2421 608 597 604 590 610 1192 610 1192 609 1193 609 1193 609 1193 608 596 605 1197 604 590 610 1192 611 1191 610 1192 610 594 606 598 603 1199 603 1199 602 1200 602 592 608 596 11561 2424 604 590 610 594 606 1196 606 1196 606 1196 606 1196 605 1197 605 600 601 1201 601 593 607 1195 607 1195 606 1196 606 598 602 592 608 1194 608 1194 607 1195 607 597 603 591 11564 2421 607 597 604 590 610 1192 610 1192 610 1192 610 1192 610 1192 609 595 606 1196 606 598 602 1200 601 1201 601 1201 601 593 607 598 603 1199 603 1199 602 1200 602 592 608 596 1000000 2420 609 595 606 598 602 1200 602 1200 602 1200 602 1200 602 1200 602 592 608 1194 608 596 604 1198 603 1199 603 1199 603 591 610 594 606 1196 606 1196 606 1196 606 598 602 592 11565 2420 609 595 605 600 601 1201 601 1201 601 1201 601 1201 601 1201 601 593 607 1195 607 597 603 1199 603 1199 603 1199 603 591 609 595 605 1197 605 1197 605 1197 605 599 601 593 11563 2422 607 597 603 591 609 1193 609 1193 608 1194 608 1194 608 1194 582 623 603 1199 603 591 610 1202 599 1203 599 1203 599 595 581 623 577 1225 601 1201 601 1201 601 593 582 623 1000000 2425 602 1200 602 1200 602 592 608 1194 608 1194 607 1195 607 1195 607 597 603 1199 602 592 609 1193 608 1194 608 1194 607 597 603 601 575 1227 599 1203 599 1203 573 621 580 625 10931 2426 578 1224 578 1224 578 616 585 1217 585 1217 585 1217 585 1217 585 620 580 1222 580 624 577 1225 577 1225 577 1225 577 617 583 622 580 1222 580 1222 579 1223 579 625 576 618 10936 2421 583 1219 583 1219 582 622 579 1223 578 1224 578 1224 578 1224 578 616 584 1218 584 621 580 1222 579 1223 579 1223 579 625 576 618 583 1219 582 1220 582 1220 582 622 578 616 1000000 2419 584 620 580 1222 580 624 576 1226 576 1226 576 1226 576 1226 576 618 582 1220 582 622 579 1223 578 1224 579 1223 578 616 585 619 581 1221 581 1221 581 1221 580 624 576 618 11563 2422 582 622 579 1223 578 616 585 1217 585 1217 584 1218 584 1218 583 622 579 1223 579 625 575 1216 585 1217 585 1217 585 619 581 623 577 1225 577 1225 577 1225 576 618 583 621 11558 2427 577 617 584 1218 583 621 579 1223 579 1223 578 1224 578 1224 578 647 553 1249 553 651 549 1253 548 1254 549 1253 549 645 555 649 551 1251 551 1251 551 1251 550 654 546 648 1000000 2456 548 646 554 650 551 653 547 1255 547 1255 547 1255 547 1255 547 647 554 1248 554 650 551 1251 551 1251 551 1251 551 653 547 647 554 1248 554 1248 554 1248 553 651 550 644 12112 2449 555 649 551 654 547 647 554 1248 554 1248 553 1249 553 1249 553 651 549 1253 549 645 555 1247 555 1247 555 1247 554 650 550 655 547 1244 557 1224 578 1224 579 615 585 619 12139 2423 580 624 576 618 582 622 578 1224 578 1224 578 1224 578 1224 578 616 584 1218 584 620 580 1222 580 1222 581 1221 580 624 577 617 584 1218 584 1218 584 1218 584 620 581 623 1000000 2422 582 1220 581 623 578 616 584 1218 584 1218 584 1218 584 1218 584 620 580 1222 580 624 576 1226 577 1225 576 1226 576 618 583 622 579 1223 578 1224 577 1225 577 617 585 619 11559 2426 577 1225 577 617 583 621 579 1223 579 1223 578 1224 578 1224 578 616 584 1218 584 620 580 1222 580 1222 579 1223 579 625 575 650 550 1252 550 1252 549 1253 549 645 556 648 11531 2453 549 1253 548 646 555 649 551 1251 551 1251 550 1252 549 1253 549 645 556 1246 555 649 552 1219 582 1220 582 1220 582 622 578 616 585 1217 584 1218 584 1218 584 620 581 623 1000000 2428 576 618 582 1220 583 622 579 1223 578 1224 578 1224 578 1224 578 616 585 1217 585 619 582 1220 582 1220 582 1220 582 622 578 616 585 1217 585 1217 584 1218 584 620 581 623 11557 2427 577 617 584 1218 583 621 580 1222 580 1222 580 1222 580 1222 580 624 576 1246 555 649 552 1250 552 1250 551 1251 551 653 548 646 554 1248 555 1247 555 1247 555 649 551 653 11528 2447 556 648 552 1250 552 653 548 1254 548 1254 547 1245 557 1245 557 647 553 1249 552 652 549 1253 548 1254 548 1254 548 646 555 649 551 1251 551 1251 551 1251 551 643 557 647 1000000 2418 610 594 606 598 603 1199 603 1199 602 1200 602 1200 602 1200 602 592 608 1194 608 596 604 1198 604 1198 604 1198 603 591 610 594 606 1196 606 1196 605 1197 605 599 601 593 11563 2422 606 598 602 592 608 1194 608 1194 608 1194 607 1195 607 1195 607 597 603 1199 603 591 609 1193 609 1193 609 1193 608 596 605 599 601 1201 600 1191 611 1191 611 593 606 598 11558 2427 601 593 607 597 603 1199 603 1199 603 1199 602 1200 602 1200 601 593 607 1195 607 597 603 1199 603 1199 602 1200 602 592 608 596 604 1198 604 1198 604 1198 603 591 609 595 1000000 2424 605 1197 604 600 600 1191 610 1192 610 1192 610 1192 609 1193 609 595 605 1197 606 598 602 1200 602 1200 601 1201 601 593 607 597 603 1199 603 1199 603 1199 603 591 609 595 10937 2420 609 1193 609 595 605 1197 605 1197 605 1197 605 1197 605 1197 605 600 601 1201 601 593 608 1194 608 1194 608 1194 609 595 605 599 601 1201 601 1201 601 1201 601 593 608 596 10936 2420 608 1194 608 596 604 1198 605 1197 605 1197 605 1197 605 1197 605 600 601 1201 601 593 607 1195 608 1194 608 1194 608 596 604 600 600 1202 601 1201 601 1201 601 593 607 597 1000000 2420 609 1193 608 1194 608 596 579 625 600 1202 600 1202 600 1202 600 594 607 1195 607 597 603 1199 603 1199 602 1200 602 592 609 595 605 1197 605 1197 605 1197 604 600 600 594 11561 2423 605 1197 605 1197 605 599 601 593 607 1195 607 1195 607 1195 607 597 604 1198 603 591 610 1192 610 1192 610 1192 610 594 607 597 603 1199 603 1199 603 1199 603 591 610 594 11563 2421 608 1194 608 1194 608 596 605 599 601 1201 602 1200 602 1200 602 592 609 1193 609 595 605 1197 606 1196 606 1196 606 598 602 592 609 1193 609 1193 610 1192 610 594 607 597 1000000 2428 576 1226 600 1192 610 594 606 598 602 1200 602 592 609 595 605 600 601 593 607 597 603 591 609 1193 25955 2427 601 1190 610 1192 610 594 606 598 602 1200 601 593 607 597 603 591 610 594 606 598 602 592 608 1194 25957 2425 604 1198 603 1199 603 591 609 595 605 1197 605 599 601 593 607 598 603 591 610 594 606 598 602 1200 25952 2420 608 1194 608 1194 608 596 604 601 600 1191 610 594 606 598 603 591 609 595 605 599 601 593 608 1194 1000000 2421 607 597 603 1199 603 591 610 594 606 1196 605 600 576 618 583 621 604 601 575 619 606 598 603 1199 26576 2424 605 600 576 1226 601 593 608 596 604 1198 604 600 600 594 607 597 603 591 609 595 606 598 602 1200 26579 2420 583 621 605 1197 604 600 601 593 607 1195 607 597 604 590 610 594 607 597 603 591 610 594 606 1196 26584 2426 603 591 609 1193 609 595 605 599 601 1201 601 593 607 597 603 591 610 594 606 598 603 591 609 1193 1000000 2418 610 594 606 598 602 592 609 595 605 1197 605 1197 605 600 602 592 608 1194 608 596 605 1197 605 1197 604 1198 604 600 601 593 607 1195 607 1195 607 1195 607 597 603 591 13368 2419 610 594 606 598 602 592 608 596 605 1197 604 1198 604 600 601 593 607 1195 607 597 603 1199 603 1199 603 1199 603 591 609 595 605 1197 605 1197 605 1197 604 601 600 594 13362 2425 604 601 600 594 607 597 603 591 610 1192 610 1192 610 594 606 598 603 1199 602 592 609 1193 609 1193 608 1194 608 596 604 601 600 1191 610 1192 610 1192 610 594 607 597 1000000 2427 601 1201 601 593 582 623 603 1199 578 1224 603 1199 577 617 584 620 605 1197 605 600 601 1201 601 1201 601 1201 601 593 582 622 603 1199 603 1199 578 1224 603 591 610 594 12139 2423 605 1197 605 600 601 593 608 1194 608 1194 607 1195 607 597 604 600 601 1201 601 593 607 1195 608 1194 608 1194 583 622 604 601 600 1202 575 1227 601 1201 576 618 607 597 12137 2424 604 1198 604 590 610 594 607 1195 607 1195 607 1195 607 597 604 601 600 1202 600 594 607 1195 606 1196 581 1221 607 597 603 591 610 1202 600 1202 576 1226 602 592 609 595 1000000 2422 607 1195 607 597 603 591 585 619 606 1196 606 1196 581 624 577 617 609 1193 584 621 605 1197 604 1198 604 1198 604 590 610 595 581 1221 605 1197 605 1197 605 599 601 593 12763 2427 603 1199 603 591 609 595 605 599 577 1225 602 1200 601 593 583 622 604 1198 604 590 610 1192 610 1192 610 1192 610 594 606 598 603 1199 603 1199 603 1199 603 591 610 594 12763 2427 602 1200 601 593 608 596 604 600 600 1202 601 1201 601 593 607 597 604 1198 604 590 610 1192 610 1192 611 1191 610 594 607 598 578 1224 603 1199 603 1199 603 591 610 594 1000000 2422 607 597 603 591 610 1192 610 594 606 1196 580 1222 605 600 601 593 583 1219 608 596 579 1223 604 1198 604 1198 604 590 610 594 606 1196 606 1196 606 1196 606 599 602 592 12765 2425 603 591 610 594 606 1196 606 598 602 1200 601 1201 601 593 582 623 604 1198 604 590 610 1192 610 1192 609 1193 609 596 605 599 601 1201 601 1201 601 1201 600 594 607 597 12758 2421 607 597 603 591 609 1193 609 595 605 1197 605 1197 605 599 601 593 607 1195 607 597 603 1199 603 1199 603 1199 603 591 609 595 580 1222 605 1197 605 1197 605 600 600 594 1000000 2422 580 625 601 1201 601 593 608 596 604 1198 604 1198 604 600 600 594 607 1195 607 597 603 1199 603 1199 603 1199 578 616 609 595 606 1196 606 1196 606 1196 581 624 602 592 12766 2424 605 599 601 1201 601 593 608 596 604 1198 604 1198 579 625 601 593 608 1194 608 596 604 1198 580 1222 605 1197 605 599 602 592 608 1194 609 1193 609 1193 609 596 605 599 12759 2420 608 597 604 1198 604 590 610 594 606 1196 606 1196 606 598 602 592 608 1194 607 597 604 1198 603 1199 603 1199 602 592 609 595 605 1197 605 1197 605 1197 604 600 601 593 1000000 2429 600 1202 575 1227 599 595 606 598 602 1200 602 1200 602 592 609 595 605 1197 605 599 601 1201 601 1201 601 1201 601 593 607 597 603 1199 603 1199 603 1199 603 591 609 595 12136 2425 603 1199 603 1199 603 591 609 595 605 1197 605 1197 605 599 601 593 608 1194 608 596 604 1198 604 1198 603 1199 603 591 609 595 606 1196 606 1196 605 1197 605 599 601 593 12137 2424 604 1198 603 1199 603 591 609 595 606 1196 605 1197 605 599 601 593 607 1195 607 597 603 1199 603 1199 603 1199 602 592 609 595 605 1197 605 1197 604 1198 604 600 600 594 1000000 2429 574 1228 573 1229 573 1229 573 1229 573 621 581 624 577 617 583 622 580 1222 579 625 576 1226 577 1225 576 1226 577 617 584 620 581 1221 580 1222 579 1223 579 625 577 617 12142 2419 584 1218 584 1218 583 1219 583 1219 582 623 578 616 585 619 581 623 578 1224 577 617 584 1218 584 1218 584 1218 584 620 580 624 576 1226 575 1227 500 1353 523 620 582 622 12134 2427 576 1226 576 1226 576 1226 576 1226 576 618 583 622 579 625 576 618 583 1219 583 673 527 1223 579 1223 579 1223 579 625 576 618 582 1220 582 1220 582 1220 582 622 578 616 12140 2421 582 1220 581 1221 581 1221 580 1222 580 624 576 618 582 622 578 616 585 1217 584 620 581 1221 580 1222 580 1222 580 624 576 618 582 1220 582 1220 582 1220 582 623 578 616 1000000 2419 584 672 528 625 577 617 583 1219 582 1220 581 1221 582 622 578 616 585 1217 583 621 580 1222 580 1222 580 1222 580 624 576 618 583 1219 583 1219 582 1220 583 621 580 624 12732 2427 577 617 584 672 528 676 524 1226 576 1226 576 1226 576 618 583 621 579 1223 579 625 575 1227 575 1227 575 1227 575 671 529 675 526 1224 578 1224 578 1224 578 616 585 619 12738 2421 583 621 580 624 576 618 582 1220 582 1220 583 1219 583 621 579 625 576 1226 576 670 530 1220 582 1220 582 1220 581 624 577 617 584 1218 583 1219 583 1219 583 622 580 624 1000000 2430 599 1192 609 595 605 1197 580 624 601 1201 601 593 607 597 603 591 610 594 606 598 602 592 608 1194 25958 2423 605 1197 604 600 575 1227 600 594 606 1196 606 598 602 592 608 596 604 601 600 594 607 597 603 1199 25949 2422 607 1195 606 598 603 1199 602 592 608 1194 608 596 604 600 601 593 607 597 604 600 600 594 607 1195 25958 2423 606 1196 606 598 602 1200 602 592 608 1194 608 596 605 600 601 593 607 597 603 591 610 594 606 1196 25957 2425 604 1198 603 591 610 1192 610 594 606 1196 606 598 602 592 609 595 605 599 602 592 608 596 604 1198 25956 2426 604 1198 603 591 610 1192 610 594 606 1196 606 598 602 592 608 597 605 599 601 593 607 597 603 1199 25952 2420 609 1193 608 596 604 1198 604 590 610 1192 610 594 606 598 602 592 608 596 605 599 601 593 607 1195 1000000 2422 583 1219 608 596 605 1197 580 624 601 1201 601 593 608 596 604 600 601 593 607 597 604 590 610 1202 25955 2427 603 1199 603 591 609 1193 610 594 606 1196 607 597 603 591 609 595 606 598 602 592 609 595 605 1197 25957 2425 604 1198 604 590 610 1192 610 594 581 1221 606 598 602 592 608 596 605 599 601 593 607 597 604 1198 25954 2418 610 1192 610 594 606 1196 605 599 601 1201 601 593 608 596 604 590 610 594 606 598 603 591 609 1193 25958 2424 604 1198 604 590 610 1192 610 594 606 1196 606 598 602 592 609 595 605 600 601 593 607 597 603 1199 25953 2419 610 1192 609 595 605 1197 605 600 601 1201 600 594 607 597 603 591 609 595 605 599 601 593 608 1194 25954 2418 611 1191 610 594 606 1196 606 598 602 1200 602 592 608 596 604 601 600 594 607 597 603 591 609 1193 25958 2424 605 1197 605 599 601 1201 600 594 607 1195 607 597 603 591 609 596 605 599 602 592 608 596 605 1197 25954 2428 601 1190 610 594 607 1195 606 598 602 1200 602 592 608 596 604 590 610 594 606 598 603 591 609 1193 25960 2422 607 1195 606 598 602 1200 602 592 609 1193 609 595 605 599 601 593 607 597 604 590 610 594 606 1196 25957 2424 605 1197 604 600 600 1202 601 593 607 1195 607 597 603 591 610 594 606 598 603 591 609 595 606 1196 1000000 2421 608 1194 608 596 604 1198 604 601 575 1227 601 593 607 598 604 600 600 594 607 598 604 601 600 1202 25953 2419 609 1193 609 596 605 1197 605 600 601 1201 601 593 607 597 603 591 610 594 606 599 602 592 608 1194 25958 2424 605 1197 605 600 601 1201 600 594 607 1195 606 598 602 592 609 595 605 600 601 593 608 596 604 1198 1000000 2423 606 1196 606 598 602 1200 602 592 608 1194 608 597 604 590 610 594 607 597 603 591 610 594 606 1196 25958 2424 605 1197 604 600 601 1201 601 593 607 1195 607 597 604 590 610 595 607 597 603 591 610 594 607 1195 25961 2421 608 1194 608 596 605 1197 605 600 601 1201 601 593 607 597 603 591 610 594 606 598 602 592 609 1193 1000000 2429 601 1201 601 593 607 1195 608 596 604 1198 604 600 601 593 607 597 604 590 611 593 607 597 604 1198 25959 2422 607 1195 607 597 603 1199 603 591 609 1193 610 594 606 598 602 592 609 595 605 599 602 592 608 1194 25959 2421 608 1194 607 597 603 1199 603 591 610 1192 610 594 606 598 603 591 609 595 605 599 602 592 608 1194 25959 2422 608 1194 608 596 604 1198 604 590 611 1201 601 593 607 597 604 590 610 594 607 597 603 591 609 1193 25962 2418 610 1192 610 594 606 1196 607 597 603 1199 603 591 609 595 605 599 602 592 608 596 605 599 601 1201 1000000 2357 610 1183 592 1191 614 1179 595 1188 618 584 613 1180 593 588 613 1190 612 590 605 587 613 589 605 587 25398 2355 623 1180 591 1181 627 1186 589 1183 618 584 616 1187 587 584 614 1189 615 587 605 587 615 587 609 593 1000000 2383 609 1214 600 612 580 1213 608 614 583 1210 605 607 586 616 611 1192 599 613 608 614 579 613 615 607 26670 2387 601 1212 600 612 589 1214 603 609 586 1217 595 607 594 618 606 1187 602 610 609 613 588 614 610 612 1000000 2445 582 1221 603 548 602 1191 609 572 602 1191 609 542 607 544 631 1172 603 568 606 545 605 566 608 543 26263 2414 611 1192 607 544 606 1197 602 569 606 1197 602 539 611 540 635 1168 606 565 610 541 608 563 587 564 +# +name: decoder_expected1 +type: parsed_array +count: 121 +# +protocol: SIRC +address: 10 00 00 00 +command: 15 00 00 00 +repeat: false +# +protocol: SIRC +address: 10 00 00 00 +command: 15 00 00 00 +repeat: false +# +protocol: SIRC +address: 10 00 00 00 +command: 15 00 00 00 +repeat: false +# +protocol: SIRC +address: 10 00 00 00 +command: 15 00 00 00 +repeat: false +# +protocol: SIRC +address: 10 00 00 00 +command: 15 00 00 00 +repeat: false +# +protocol: SIRC +address: 10 00 00 00 +command: 15 00 00 00 +repeat: false +# +protocol: SIRC +address: 10 00 00 00 +command: 60 00 00 00 +repeat: false +# +protocol: SIRC +address: 10 00 00 00 +command: 60 00 00 00 +repeat: false +# +protocol: SIRC +address: 10 00 00 00 +command: 60 00 00 00 +repeat: false +# +protocol: SIRC +address: 10 00 00 00 +command: 65 00 00 00 +repeat: false +# +protocol: SIRC +address: 10 00 00 00 +command: 65 00 00 00 +repeat: false +# +protocol: SIRC +address: 10 00 00 00 +command: 65 00 00 00 +repeat: false +# +protocol: SIRC20 +address: 10 04 00 00 +command: 17 00 00 00 +repeat: false +# +protocol: SIRC20 +address: 10 04 00 00 +command: 17 00 00 00 +repeat: false +# +protocol: SIRC20 +address: 10 04 00 00 +command: 17 00 00 00 +repeat: false +# +protocol: SIRC +address: 10 00 00 00 +command: 21 00 00 00 +repeat: false +# +protocol: SIRC +address: 10 00 00 00 +command: 21 00 00 00 +repeat: false +# +protocol: SIRC +address: 10 00 00 00 +command: 21 00 00 00 +repeat: false +# +protocol: SIRC20 +address: 3A 07 00 00 +command: 7C 00 00 00 +repeat: false +# +protocol: SIRC20 +address: 3A 07 00 00 +command: 7C 00 00 00 +repeat: false +# +protocol: SIRC20 +address: 3A 07 00 00 +command: 7C 00 00 00 +repeat: false +# +protocol: SIRC20 +address: 3A 07 00 00 +command: 7C 00 00 00 +repeat: false +# +protocol: SIRC20 +address: 3A 07 00 00 +command: 7C 00 00 00 +repeat: false +# +protocol: SIRC20 +address: 3A 07 00 00 +command: 7C 00 00 00 +repeat: false +# +protocol: SIRC20 +address: 3A 07 00 00 +command: 7C 00 00 00 +repeat: false +# +protocol: SIRC20 +address: 3A 07 00 00 +command: 7C 00 00 00 +repeat: false +# +protocol: SIRC20 +address: 3A 07 00 00 +command: 7C 00 00 00 +repeat: false +# +protocol: SIRC20 +address: 3A 07 00 00 +command: 7C 00 00 00 +repeat: false +# +protocol: SIRC20 +address: 3A 07 00 00 +command: 7C 00 00 00 +repeat: false +# +protocol: SIRC20 +address: 3A 07 00 00 +command: 7C 00 00 00 +repeat: false +# +protocol: SIRC20 +address: 3A 07 00 00 +command: 7B 00 00 00 +repeat: false +# +protocol: SIRC20 +address: 3A 07 00 00 +command: 7B 00 00 00 +repeat: false +# +protocol: SIRC20 +address: 3A 07 00 00 +command: 7B 00 00 00 +repeat: false +# +protocol: SIRC20 +address: 3A 07 00 00 +command: 7A 00 00 00 +repeat: false +# +protocol: SIRC20 +address: 3A 07 00 00 +command: 7A 00 00 00 +repeat: false +# +protocol: SIRC20 +address: 3A 07 00 00 +command: 7A 00 00 00 +repeat: false +# +protocol: SIRC20 +address: 3A 07 00 00 +command: 78 00 00 00 +repeat: false +# +protocol: SIRC20 +address: 3A 07 00 00 +command: 78 00 00 00 +repeat: false +# +protocol: SIRC20 +address: 3A 07 00 00 +command: 78 00 00 00 +repeat: false +# +protocol: SIRC20 +address: 3A 07 00 00 +command: 79 00 00 00 +repeat: false +# +protocol: SIRC20 +address: 3A 07 00 00 +command: 79 00 00 00 +repeat: false +# +protocol: SIRC20 +address: 3A 07 00 00 +command: 79 00 00 00 +repeat: false +# +protocol: SIRC20 +address: 3A 07 00 00 +command: 7A 00 00 00 +repeat: false +# +protocol: SIRC20 +address: 3A 07 00 00 +command: 7A 00 00 00 +repeat: false +# +protocol: SIRC20 +address: 3A 07 00 00 +command: 7A 00 00 00 +repeat: false +# +protocol: SIRC20 +address: 3A 07 00 00 +command: 7C 00 00 00 +repeat: false +# +protocol: SIRC20 +address: 3A 07 00 00 +command: 7C 00 00 00 +repeat: false +# +protocol: SIRC20 +address: 3A 07 00 00 +command: 7C 00 00 00 +repeat: false +# +protocol: SIRC20 +address: 3A 07 00 00 +command: 7D 00 00 00 +repeat: false +# +protocol: SIRC20 +address: 3A 07 00 00 +command: 7D 00 00 00 +repeat: false +# +protocol: SIRC20 +address: 3A 07 00 00 +command: 7D 00 00 00 +repeat: false +# +protocol: SIRC20 +address: 3A 07 00 00 +command: 73 00 00 00 +repeat: false +# +protocol: SIRC20 +address: 3A 07 00 00 +command: 73 00 00 00 +repeat: false +# +protocol: SIRC20 +address: 3A 07 00 00 +command: 73 00 00 00 +repeat: false +# +protocol: SIRC +address: 10 00 00 00 +command: 13 00 00 00 +repeat: false +# +protocol: SIRC +address: 10 00 00 00 +command: 13 00 00 00 +repeat: false +# +protocol: SIRC +address: 10 00 00 00 +command: 13 00 00 00 +repeat: false +# +protocol: SIRC +address: 10 00 00 00 +command: 13 00 00 00 +repeat: false +# +protocol: SIRC +address: 10 00 00 00 +command: 12 00 00 00 +repeat: false +# +protocol: SIRC +address: 10 00 00 00 +command: 12 00 00 00 +repeat: false +# +protocol: SIRC +address: 10 00 00 00 +command: 12 00 00 00 +repeat: false +# +protocol: SIRC +address: 10 00 00 00 +command: 12 00 00 00 +repeat: false +# +protocol: SIRC20 +address: 3A 07 00 00 +command: 30 00 00 00 +repeat: false +# +protocol: SIRC20 +address: 3A 07 00 00 +command: 30 00 00 00 +repeat: false +# +protocol: SIRC20 +address: 3A 07 00 00 +command: 30 00 00 00 +repeat: false +# +protocol: SIRC20 +address: 3A 07 00 00 +command: 39 00 00 00 +repeat: false +# +protocol: SIRC20 +address: 3A 07 00 00 +command: 39 00 00 00 +repeat: false +# +protocol: SIRC20 +address: 3A 07 00 00 +command: 39 00 00 00 +repeat: false +# +protocol: SIRC20 +address: 3A 07 00 00 +command: 31 00 00 00 +repeat: false +# +protocol: SIRC20 +address: 3A 07 00 00 +command: 31 00 00 00 +repeat: false +# +protocol: SIRC20 +address: 3A 07 00 00 +command: 31 00 00 00 +repeat: false +# +protocol: SIRC20 +address: 3A 07 00 00 +command: 34 00 00 00 +repeat: false +# +protocol: SIRC20 +address: 3A 07 00 00 +command: 34 00 00 00 +repeat: false +# +protocol: SIRC20 +address: 3A 07 00 00 +command: 34 00 00 00 +repeat: false +# +protocol: SIRC20 +address: 3A 07 00 00 +command: 32 00 00 00 +repeat: false +# +protocol: SIRC20 +address: 3A 07 00 00 +command: 32 00 00 00 +repeat: false +# +protocol: SIRC20 +address: 3A 07 00 00 +command: 32 00 00 00 +repeat: false +# +protocol: SIRC20 +address: 3A 07 00 00 +command: 33 00 00 00 +repeat: false +# +protocol: SIRC20 +address: 3A 07 00 00 +command: 33 00 00 00 +repeat: false +# +protocol: SIRC20 +address: 3A 07 00 00 +command: 33 00 00 00 +repeat: false +# +protocol: SIRC20 +address: 3A 07 00 00 +command: 0F 00 00 00 +repeat: false +# +protocol: SIRC20 +address: 3A 07 00 00 +command: 0F 00 00 00 +repeat: false +# +protocol: SIRC20 +address: 3A 07 00 00 +command: 0F 00 00 00 +repeat: false +# +protocol: SIRC20 +address: 3A 07 00 00 +command: 38 00 00 00 +repeat: false +# +protocol: SIRC20 +address: 3A 07 00 00 +command: 38 00 00 00 +repeat: false +# +protocol: SIRC20 +address: 3A 07 00 00 +command: 38 00 00 00 +repeat: false +# +protocol: SIRC +address: 10 00 00 00 +command: 15 00 00 00 +repeat: false +# +protocol: SIRC +address: 10 00 00 00 +command: 15 00 00 00 +repeat: false +# +protocol: SIRC +address: 10 00 00 00 +command: 15 00 00 00 +repeat: false +# +protocol: SIRC +address: 10 00 00 00 +command: 15 00 00 00 +repeat: false +# +protocol: SIRC +address: 10 00 00 00 +command: 15 00 00 00 +repeat: false +# +protocol: SIRC +address: 10 00 00 00 +command: 15 00 00 00 +repeat: false +# +protocol: SIRC +address: 10 00 00 00 +command: 15 00 00 00 +repeat: false +# +protocol: SIRC +address: 10 00 00 00 +command: 15 00 00 00 +repeat: false +# +protocol: SIRC +address: 10 00 00 00 +command: 15 00 00 00 +repeat: false +# +protocol: SIRC +address: 10 00 00 00 +command: 15 00 00 00 +repeat: false +# +protocol: SIRC +address: 10 00 00 00 +command: 15 00 00 00 +repeat: false +# +protocol: SIRC +address: 10 00 00 00 +command: 15 00 00 00 +repeat: false +# +protocol: SIRC +address: 10 00 00 00 +command: 15 00 00 00 +repeat: false +# +protocol: SIRC +address: 10 00 00 00 +command: 15 00 00 00 +repeat: false +# +protocol: SIRC +address: 10 00 00 00 +command: 15 00 00 00 +repeat: false +# +protocol: SIRC +address: 10 00 00 00 +command: 15 00 00 00 +repeat: false +# +protocol: SIRC +address: 10 00 00 00 +command: 15 00 00 00 +repeat: false +# +protocol: SIRC +address: 10 00 00 00 +command: 15 00 00 00 +repeat: false +# +protocol: SIRC +address: 10 00 00 00 +command: 15 00 00 00 +repeat: false +# +protocol: SIRC +address: 10 00 00 00 +command: 15 00 00 00 +repeat: false +# +protocol: SIRC +address: 10 00 00 00 +command: 15 00 00 00 +repeat: false +# +protocol: SIRC +address: 10 00 00 00 +command: 15 00 00 00 +repeat: false +# +protocol: SIRC +address: 10 00 00 00 +command: 15 00 00 00 +repeat: false +# +protocol: SIRC +address: 10 00 00 00 +command: 15 00 00 00 +repeat: false +# +protocol: SIRC +address: 10 00 00 00 +command: 15 00 00 00 +repeat: false +# +protocol: SIRC +address: 10 00 00 00 +command: 15 00 00 00 +repeat: false +# +protocol: SIRC +address: 10 00 00 00 +command: 15 00 00 00 +repeat: false +# +protocol: SIRC +address: 10 00 00 00 +command: 15 00 00 00 +repeat: false +# +protocol: SIRC +address: 10 00 00 00 +command: 15 00 00 00 +repeat: false +# +protocol: SIRC +address: 01 00 00 00 +command: 2F 00 00 00 +repeat: false +# +protocol: SIRC +address: 01 00 00 00 +command: 2F 00 00 00 +repeat: false +# +protocol: SIRC +address: 01 00 00 00 +command: 15 00 00 00 +repeat: false +# +protocol: SIRC +address: 01 00 00 00 +command: 15 00 00 00 +repeat: false +# +protocol: SIRC +address: 01 00 00 00 +command: 15 00 00 00 +repeat: false +# +protocol: SIRC +address: 01 00 00 00 +command: 15 00 00 00 +repeat: false +# +name: decoder_input2 +type: raw +data: 1000000 2400 600 1200 600 600 600 1200 600 600 600 1200 600 600 600 1200 600 600 600 1200 600 600 600 1200 600 600 1000000 2400 600 1200 600 600 600 1200 600 600 600 1200 600 600 600 1200 600 600 600 1200 600 600 600 1200 600 600 1000000 2400 600 1200 600 600 600 1200 600 600 600 1200 600 600 600 1200 600 600 600 1200 600 600 600 1200 600 600 1000000 2400 600 1200 600 600 600 1200 600 600 600 1200 600 600 600 1200 600 600 600 1200 600 600 600 1200 600 600 600 600 1000000 2400 600 1200 600 1200 600 1200 600 1200 600 1200 600 1200 600 1200 600 1200 600 1200 600 1200 600 1200 600 1200 1000000 2400 600 1200 600 600 1000000 2400 600 1200 600 1200 600 1200 600 1200 600 1200 600 1200 600 1200 600 1200 600 1200 600 1200 600 1200 600 1200 1000000 2400 600 1200 600 2400 600 1200 600 1200 600 1200 600 1200 600 1200 600 1200 600 1200 600 1200 600 1200 600 1200 600 1200 600 1200 1000000 2400 600 1200 600 600 1000000 2400 600 1200 600 600 600 1200 600 600 600 1200 600 600 600 1200 600 600 600 1200 600 600 600 1200 600 600 1000000 2400 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 1000000 2400 600 1200 600 1200 600 600 600 600 600 1200 600 600 600 1200 600 1200 600 600 600 1200 600 1200 600 600 600 +# +name: decoder_expected2 +type: parsed_array +count: 9 +# +protocol: SIRC +address: 0A 00 00 00 +command: 55 00 00 00 +repeat: false +# +protocol: SIRC +address: 0A 00 00 00 +command: 55 00 00 00 +repeat: false +# +protocol: SIRC +address: 0A 00 00 00 +command: 55 00 00 00 +repeat: false +# +protocol: SIRC +address: 1F 00 00 00 +command: 7F 00 00 00 +repeat: false +# +protocol: SIRC +address: 1F 00 00 00 +command: 7F 00 00 00 +repeat: false +# +protocol: SIRC +address: 1F 00 00 00 +command: 7F 00 00 00 +repeat: false +# +protocol: SIRC +address: 0A 00 00 00 +command: 55 00 00 00 +repeat: false +# +protocol: SIRC +address: 00 00 00 00 +command: 00 00 00 00 +repeat: false +# +protocol: SIRC +address: 0D 00 00 00 +command: 53 00 00 00 +repeat: false +# +name: decoder_input3 +type: raw +data: 1000000 2400 600 1200 600 1200 600 600 600 600 600 1200 600 600 600 1200 600 1200 600 600 600 1200 600 1200 600 1200 600 1200 600 1200 600 600 10000 2400 600 1200 600 1200 600 600 600 600 600 1200 600 600 600 1200 600 1200 600 600 600 1200 600 1200 600 1200 600 1200 600 1200 600 600 10000 2400 600 1200 600 1200 600 600 600 600 600 1200 600 600 600 1200 600 1200 600 600 600 1200 600 1200 600 1200 600 1200 600 1200 600 600 1000000 2400 600 1200 600 1200 600 600 600 600 600 1200 600 600 600 1200 600 1200 600 600 600 1200 600 1200 600 600 600 600 600 600 600 600 10000 2400 600 1200 600 1200 600 600 600 600 600 1200 600 600 600 1200 600 1200 600 600 600 1200 600 1200 600 600 600 600 600 600 600 600 10000 2400 600 1200 600 1200 600 600 600 600 600 1200 600 600 600 1200 600 1200 600 600 600 1200 600 1200 600 600 600 600 600 600 600 600 1000000 2400 600 1200 600 1200 600 600 600 600 600 1200 600 600 600 1200 600 1200 600 600 600 1200 600 1200 600 600 600 600 600 600 600 600 1000000 2400 600 1200 600 1200 600 600 600 600 600 1200 600 600 600 1200 600 1200 600 600 600 1200 600 1200 600 600 600 600 600 600 600 600 1000000 2400 600 1200 600 1200 600 600 600 600 600 1200 600 600 600 1200 600 1200 600 600 600 1200 600 1200 600 1200 600 1200 600 1200 600 600 1000000 2400 600 1200 600 1200 600 600 600 600 600 1200 600 600 600 1200 600 1200 600 600 600 1200 600 1200 600 1200 600 1200 600 1200 600 600 10000 2400 600 1200 600 1200 600 600 600 600 600 1200 600 600 600 600 600 1200 600 600 600 1200 600 1200 600 1200 600 1200 600 1200 600 1200 +# +name: decoder_expected3 +type: parsed_array +count: 11 +# +protocol: SIRC15 +address: 7D 00 00 00 +command: 53 00 00 00 +repeat: false +# +protocol: SIRC15 +address: 7D 00 00 00 +command: 53 00 00 00 +repeat: false +# +protocol: SIRC15 +address: 7D 00 00 00 +command: 53 00 00 00 +repeat: false +# +protocol: SIRC15 +address: 0D 00 00 00 +command: 53 00 00 00 +repeat: false +# +protocol: SIRC15 +address: 0D 00 00 00 +command: 53 00 00 00 +repeat: false +# +protocol: SIRC15 +address: 0D 00 00 00 +command: 53 00 00 00 +repeat: false +# +protocol: SIRC15 +address: 0D 00 00 00 +command: 53 00 00 00 +repeat: false +# +protocol: SIRC15 +address: 0D 00 00 00 +command: 53 00 00 00 +repeat: false +# +protocol: SIRC15 +address: 7D 00 00 00 +command: 53 00 00 00 +repeat: false +# +protocol: SIRC15 +address: 7D 00 00 00 +command: 53 00 00 00 +repeat: false +# +protocol: SIRC15 +address: FD 00 00 00 +command: 13 00 00 00 +repeat: false +# +name: decoder_input4 +type: raw +data: 1000000 2400 600 1200 600 1200 600 600 600 600 600 1200 600 600 600 1200 600 1200 600 600 600 1200 600 600 600 1200 600 1200 600 600 600 1200 600 1200 600 1200 600 1200 600 1200 600 600 10000 2400 600 1200 600 1200 600 600 600 600 600 1200 600 600 600 1200 600 1200 600 600 600 1200 600 600 600 1200 600 1200 600 600 600 1200 600 1200 600 1200 600 1200 600 1200 600 600 10000 2400 600 1200 600 1200 600 600 600 600 600 1200 600 600 600 1200 600 1200 600 600 600 1200 600 600 600 1200 600 1200 600 600 600 1200 600 1200 600 1200 600 1200 600 1200 600 600 1000000 2400 600 1200 600 1200 600 600 600 600 600 1200 600 600 600 1200 600 1200 600 600 600 1200 600 600 600 1200 600 1200 600 600 600 1200 600 1200 600 1200 600 1200 600 1200 600 600 1000000 2400 600 1200 600 1200 600 600 600 600 600 1200 600 600 600 1200 600 1200 600 600 600 1200 600 600 600 1200 600 1200 600 600 600 1200 600 1200 600 1200 600 1200 600 1200 600 600 1000000 2400 600 1200 600 1200 600 600 600 600 600 1200 600 600 600 1200 600 1200 600 600 600 1200 600 600 600 1200 600 1200 600 600 600 1200 600 1200 600 1200 600 1200 600 1200 600 600 +# +name: decoder_expected4 +type: parsed_array +count: 6 +# +protocol: SIRC20 +address: B5 0F 00 00 +command: 53 00 00 00 +repeat: false +# +protocol: SIRC20 +address: B5 0F 00 00 +command: 53 00 00 00 +repeat: false +# +protocol: SIRC20 +address: B5 0F 00 00 +command: 53 00 00 00 +repeat: false +# +protocol: SIRC20 +address: B5 0F 00 00 +command: 53 00 00 00 +repeat: false +# +protocol: SIRC20 +address: B5 0F 00 00 +command: 53 00 00 00 +repeat: false +# +protocol: SIRC20 +address: B5 0F 00 00 +command: 53 00 00 00 +repeat: false +# +name: decoder_input5 +type: raw +data: 1000000 2400 600 1200 600 1200 600 600 600 600 600 1200 600 600 600 1200 600 1200 600 600 600 1200 600 600 600 1200 600 1200 600 600 600 1200 600 1200 600 1200 600 1200 600 1200 600 600 1000000 2400 600 1200 600 1200 600 600 600 600 600 1200 600 600 600 1200 600 1200 600 600 600 1200 600 1200 600 1200 600 1200 600 1200 600 600 1000000 2400 600 1200 600 600 600 1200 600 600 600 1200 600 600 600 1200 600 600 600 1200 600 600 600 1200 600 600 1000000 2400 600 1200 600 1200 600 600 600 600 600 1200 600 600 600 1200 600 1200 600 600 600 1200 600 600 600 1200 600 1200 600 600 600 1200 600 1200 600 1200 600 1200 600 1200 600 600 1000000 2400 600 1200 600 1200 600 600 600 600 600 1200 600 600 600 1200 600 1200 600 600 600 1200 600 1200 600 1200 600 1200 600 1200 600 600 1000000 2400 600 1200 600 600 600 1200 600 600 600 1200 600 600 600 1200 600 600 600 1200 600 600 600 1200 600 600 10000 2400 600 1200 600 1200 600 600 600 600 600 1200 600 600 600 1200 600 1200 600 600 600 1200 600 600 600 1200 600 1200 600 600 600 1200 600 1200 600 1200 600 1200 600 1200 600 600 10000 2400 600 1200 600 1200 600 600 600 600 600 1200 600 600 600 1200 600 1200 600 600 600 1200 600 1200 600 1200 600 1200 600 1200 600 600 10000 2400 600 1200 600 600 600 1200 600 600 600 1200 600 600 600 1200 600 600 600 1200 600 600 600 1200 600 600 10000 2400 600 1200 600 1200 600 600 600 600 600 1200 600 600 600 1200 600 1200 600 600 600 1200 600 600 600 1200 600 1200 600 600 600 1200 600 1200 600 1200 600 1200 600 1200 600 600 10000 2400 600 1200 600 1200 600 600 600 600 600 1200 600 600 600 1200 600 1200 600 600 600 1200 600 1200 600 1200 600 1200 600 1200 600 600 10000 2400 600 1200 600 600 600 1200 600 600 600 1200 600 600 600 1200 600 600 600 1200 600 600 600 1200 600 600 10000 2400 600 1200 600 1200 600 600 600 600 600 1200 600 600 600 1200 600 1200 600 600 600 1200 600 600 600 1200 600 1200 600 600 600 1200 600 1200 600 1200 600 1200 600 1200 600 600 10000 2400 600 1200 600 1200 600 600 600 600 600 1200 600 600 600 1200 600 1200 600 600 600 1200 600 600 600 1200 600 1200 600 600 600 1200 600 1200 600 1200 600 1200 600 1200 600 600 10000 2400 600 1200 600 1200 600 600 600 600 600 1200 600 600 600 1200 600 1200 600 600 600 1200 600 1200 600 1200 600 1200 600 1200 600 600 10000 2400 600 1200 600 1200 600 600 600 600 600 1200 600 600 600 1200 600 1200 600 600 600 1200 600 1200 600 1200 600 1200 600 1200 600 600 10000 2400 600 1200 600 600 600 1200 600 600 600 1200 600 600 600 1200 600 600 600 1200 600 600 600 1200 600 600 10000 2400 600 1200 600 600 600 1200 600 600 600 1200 600 600 600 1200 600 600 600 1200 600 600 600 1200 600 600 10000 2400 600 1200 600 600 600 1200 600 600 600 1200 600 600 600 1200 600 600 600 1200 600 600 600 1200 600 600 10000 2400 600 1200 600 1200 600 600 600 600 600 1200 600 600 600 1200 600 1200 600 600 600 1200 600 1200 600 1200 600 1200 600 1200 600 600 10000 2400 600 1200 600 1200 600 600 600 600 600 1200 600 600 600 1200 600 1200 600 600 600 1200 600 600 600 1200 600 1200 600 600 600 1200 600 1200 600 1200 600 1200 600 1200 600 600 10000 2400 600 1200 600 600 600 1200 600 600 600 1200 600 600 600 1200 600 600 600 1200 600 600 600 1200 600 600 10000 2400 600 1200 600 1200 600 600 600 600 600 1200 600 600 600 1200 600 1200 600 600 600 1200 600 1200 600 1200 600 1200 600 1200 600 600 10000 2400 600 1200 600 1200 600 600 600 600 600 1200 600 600 600 1200 600 1200 600 600 600 1200 600 600 600 1200 600 1200 600 600 600 1200 600 1200 600 1200 600 1200 600 1200 600 600 +# +name: decoder_expected5 +type: parsed_array +count: 24 +# +protocol: SIRC20 +address: B5 0F 00 00 +command: 53 00 00 00 +repeat: false +# +protocol: SIRC15 +address: 7D 00 00 00 +command: 53 00 00 00 +repeat: false +# +protocol: SIRC +address: 0A 00 00 00 +command: 55 00 00 00 +repeat: false +# +protocol: SIRC20 +address: B5 0F 00 00 +command: 53 00 00 00 +repeat: false +# +protocol: SIRC15 +address: 7D 00 00 00 +command: 53 00 00 00 +repeat: false +# +protocol: SIRC +address: 0A 00 00 00 +command: 55 00 00 00 +repeat: false +# +protocol: SIRC20 +address: B5 0F 00 00 +command: 53 00 00 00 +repeat: false +# +protocol: SIRC15 +address: 7D 00 00 00 +command: 53 00 00 00 +repeat: false +# +protocol: SIRC +address: 0A 00 00 00 +command: 55 00 00 00 +repeat: false +# +protocol: SIRC20 +address: B5 0F 00 00 +command: 53 00 00 00 +repeat: false +# +protocol: SIRC15 +address: 7D 00 00 00 +command: 53 00 00 00 +repeat: false +# +protocol: SIRC +address: 0A 00 00 00 +command: 55 00 00 00 +repeat: false +# +protocol: SIRC20 +address: B5 0F 00 00 +command: 53 00 00 00 +repeat: false +# +protocol: SIRC20 +address: B5 0F 00 00 +command: 53 00 00 00 +repeat: false +# +protocol: SIRC15 +address: 7D 00 00 00 +command: 53 00 00 00 +repeat: false +# +protocol: SIRC15 +address: 7D 00 00 00 +command: 53 00 00 00 +repeat: false +# +protocol: SIRC +address: 0A 00 00 00 +command: 55 00 00 00 +repeat: false +# +protocol: SIRC +address: 0A 00 00 00 +command: 55 00 00 00 +repeat: false +# +protocol: SIRC +address: 0A 00 00 00 +command: 55 00 00 00 +repeat: false +# +protocol: SIRC15 +address: 7D 00 00 00 +command: 53 00 00 00 +repeat: false +# +protocol: SIRC20 +address: B5 0F 00 00 +command: 53 00 00 00 +repeat: false +# +protocol: SIRC +address: 0A 00 00 00 +command: 55 00 00 00 +repeat: false +# +protocol: SIRC15 +address: 7D 00 00 00 +command: 53 00 00 00 +repeat: false +# +protocol: SIRC20 +address: B5 0F 00 00 +command: 53 00 00 00 +repeat: false +# +name: encoder_input1 +type: parsed_array +count: 1 +# +protocol: SIRC +address: 0A 00 00 00 +command: 55 00 00 00 +repeat: false +# +name: encoder_expected1 +type: raw +data: +10000 2400 600 1200 600 600 600 1200 600 600 600 1200 600 600 600 1200 600 600 600 1200 600 600 600 1200 600 600 +# +name: encoder_input2 +type: parsed_array +count: 3 +# +protocol: SIRC15 +address: 7D 00 00 00 +command: 53 00 00 00 +repeat: false +# +protocol: SIRC15 +address: 7D 00 00 00 +command: 53 00 00 00 +repeat: true +# +protocol: SIRC15 +address: 7D 00 00 00 +command: 53 00 00 00 +repeat: true +# +name: encoder_expected2 +type: raw +data: +10000 2400 600 1200 600 1200 600 600 600 600 600 1200 600 600 600 1200 600 1200 600 600 600 1200 600 1200 600 1200 600 1200 600 1200 600 600 18600 2400 600 1200 600 1200 600 600 600 600 600 1200 600 600 600 1200 600 1200 600 600 600 1200 600 1200 600 1200 600 1200 600 1200 600 600 18600 2400 600 1200 600 1200 600 600 600 600 600 1200 600 600 600 1200 600 1200 600 600 600 1200 600 1200 600 1200 600 1200 600 1200 600 600 +# +name: encoder_decoder_input1 +type: parsed_array +count: 24 +# +protocol: SIRC20 +address: FF 1F 00 00 +command: 7F 00 00 00 +repeat: false +# +protocol: SIRC20 +address: FF 1F 00 00 +command: 7F 00 00 00 +repeat: true +# +protocol: SIRC20 +address: FF 1F 00 00 +command: 7F 00 00 00 +repeat: true +# +protocol: SIRC +address: 00 00 00 00 +command: 00 00 00 00 +repeat: false +# +protocol: SIRC +address: 00 00 00 00 +command: 00 00 00 00 +repeat: true +# +protocol: SIRC +address: 00 00 00 00 +command: 00 00 00 00 +repeat: true +# +protocol: SIRC +address: 1A 00 00 00 +command: 22 00 00 00 +repeat: false +# +protocol: SIRC +address: 1A 00 00 00 +command: 22 00 00 00 +repeat: true +# +protocol: SIRC +address: 1A 00 00 00 +command: 22 00 00 00 +repeat: true +# +protocol: SIRC +address: 17 00 00 00 +command: 0A 00 00 00 +repeat: false +# +protocol: SIRC15 +address: 7D 00 00 00 +command: 53 00 00 00 +repeat: false +# +protocol: SIRC15 +address: 7D 00 00 00 +command: 53 00 00 00 +repeat: true +# +protocol: SIRC15 +address: 7D 00 00 00 +command: 53 00 00 00 +repeat: true +# +protocol: SIRC15 +address: 71 00 00 00 +command: 00 00 00 00 +repeat: false +# +protocol: SIRC15 +address: 15 00 00 00 +command: 01 00 00 00 +repeat: false +# +protocol: SIRC15 +address: 01 00 00 00 +command: 15 00 00 00 +repeat: false +# +protocol: SIRC20 +address: AA 00 00 00 +command: 55 00 00 00 +repeat: false +# +protocol: SIRC20 +address: 31 03 00 00 +command: 71 00 00 00 +repeat: false +# +protocol: SIRC +address: 00 00 00 00 +command: 00 00 00 00 +repeat: false +# +protocol: SIRC +address: 1F 00 00 00 +command: 7F 00 00 00 +repeat: false +# +protocol: SIRC15 +address: 00 00 00 00 +command: 00 00 00 00 +repeat: false +# +protocol: SIRC15 +address: FF 00 00 00 +command: 7F 00 00 00 +repeat: false +# +protocol: SIRC20 +address: 00 00 00 00 +command: 00 00 00 00 +repeat: false +# +protocol: SIRC20 +address: FF 1F 00 00 +command: 7F 00 00 00 +repeat: false +# From 7741a19244ce3af206c6434fc922f1340a96e547 Mon Sep 17 00:00:00 2001 From: SG Date: Sun, 17 Jul 2022 12:34:13 +0300 Subject: [PATCH 10/37] Better crash handling (#1397) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Core: correct ISR flag check on crash, dump heap and stack info on crash * Core: crash, show task name * Core crash: optimization Co-authored-by: あく --- core/furi/check.c | 47 +++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 41 insertions(+), 6 deletions(-) diff --git a/core/furi/check.c b/core/furi/check.c index ca945ada..3d0cd7a0 100644 --- a/core/furi/check.c +++ b/core/furi/check.c @@ -8,12 +8,39 @@ #include #include +#include -void __furi_print_name() { - if(FURI_IS_ISR()) { - furi_hal_console_puts("[ISR] "); +extern size_t xPortGetTotalHeapSize(void); +extern size_t xPortGetFreeHeapSize(void); +extern size_t xPortGetMinimumEverFreeHeapSize(void); + +static void __furi_put_uint32_as_text(uint32_t data) { + char tmp_str[] = "-2147483648"; + itoa(data, tmp_str, 10); + furi_hal_console_puts(tmp_str); +} + +static void __furi_print_stack_info() { + furi_hal_console_puts("\r\n\tstack watermark: "); + __furi_put_uint32_as_text(uxTaskGetStackHighWaterMark(NULL) * 4); +} + +static void __furi_print_heap_info() { + furi_hal_console_puts("\r\n\t heap total: "); + __furi_put_uint32_as_text(xPortGetTotalHeapSize()); + furi_hal_console_puts("\r\n\t heap free: "); + __furi_put_uint32_as_text(xPortGetFreeHeapSize()); + furi_hal_console_puts("\r\n\t heap watermark: "); + __furi_put_uint32_as_text(xPortGetMinimumEverFreeHeapSize()); +} + +static void __furi_print_name(bool isr) { + if(isr) { + furi_hal_console_puts("[ISR "); + __furi_put_uint32_as_text(__get_IPSR()); + furi_hal_console_puts("] "); } else { - const char* name = pcTaskGetName(xTaskGetCurrentTaskHandle()); + const char* name = pcTaskGetName(NULL); if(name == NULL) { furi_hal_console_puts("[main] "); } else { @@ -39,6 +66,7 @@ static FURI_NORETURN void __furi_halt() { } FURI_NORETURN void furi_crash(const char* message) { + bool isr = FURI_IS_ISR(); __disable_irq(); if(message == NULL) { @@ -46,8 +74,14 @@ FURI_NORETURN void furi_crash(const char* message) { } furi_hal_console_puts("\r\n\033[0;31m[CRASH]"); - __furi_print_name(); + __furi_print_name(isr); furi_hal_console_puts(message); + + if(!isr) { + __furi_print_stack_info(); + } + __furi_print_heap_info(); + #ifdef FURI_DEBUG furi_hal_console_puts("\r\nSystem halted. Connect debugger for more info\r\n"); furi_hal_console_puts("\033[0m\r\n"); @@ -62,6 +96,7 @@ FURI_NORETURN void furi_crash(const char* message) { } FURI_NORETURN void furi_halt(const char* message) { + bool isr = FURI_IS_ISR(); __disable_irq(); if(message == NULL) { @@ -69,7 +104,7 @@ FURI_NORETURN void furi_halt(const char* message) { } furi_hal_console_puts("\r\n\033[0;31m[HALT]"); - __furi_print_name(); + __furi_print_name(isr); furi_hal_console_puts(message); furi_hal_console_puts("\r\nSystem halted. Bye-bye!\r\n"); furi_hal_console_puts("\033[0m\r\n"); From e7c3da1da9bbbd454b1a863e336dce3fbd5e6553 Mon Sep 17 00:00:00 2001 From: Skorpionm <85568270+Skorpionm@users.noreply.github.com> Date: Sun, 17 Jul 2022 13:45:21 +0400 Subject: [PATCH 11/37] [FL-2658, FL-2657] SubGhz: add new protocol (IronLogic, Comunello, Sommer(fsk476), Normstahl, KEY, EcoStar, Gibidi, Mutancode) (#1404) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Subghz: fix cli no load keeloq_mfcodes_user * SubGhz: add new protocol (IronLogic, Comunello, Sommer(fsk476), Normstahl, KEY, EcoStar, Gibidi, Mutancode) * SubGhz: fix syntax * SubGhz: fix error build Co-authored-by: あく --- applications/subghz/subghz_cli.c | 12 ++- assets/resources/subghz/assets/keeloq_mfcodes | 82 ++++++++++--------- 2 files changed, 55 insertions(+), 39 deletions(-) diff --git a/applications/subghz/subghz_cli.c b/applications/subghz/subghz_cli.c index 6c92a5d6..20930df2 100644 --- a/applications/subghz/subghz_cli.c +++ b/applications/subghz/subghz_cli.c @@ -246,6 +246,7 @@ void subghz_cli_command_rx(Cli* cli, string_t args, void* context) { SubGhzEnvironment* environment = subghz_environment_alloc(); subghz_environment_load_keystore(environment, "/ext/subghz/assets/keeloq_mfcodes"); + subghz_environment_load_keystore(environment, "/ext/subghz/assets/keeloq_mfcodes_user"); subghz_environment_set_came_atomo_rainbow_table_file_name( environment, "/ext/subghz/assets/came_atomo"); subghz_environment_set_nice_flor_s_rainbow_table_file_name( @@ -353,9 +354,16 @@ void subghz_cli_command_decode_raw(Cli* cli, string_t args, void* context) { SubGhzEnvironment* environment = subghz_environment_alloc(); if(subghz_environment_load_keystore(environment, "/ext/subghz/assets/keeloq_mfcodes")) { - printf("SubGhz test: Load_keystore \033[0;32mOK\033[0m\r\n"); + printf("SubGhz decode_raw: Load_keystore keeloq_mfcodes \033[0;32mOK\033[0m\r\n"); } else { - printf("SubGhz test: Load_keystore \033[0;31mERROR\033[0m\r\n"); + printf("SubGhz decode_raw: Load_keystore keeloq_mfcodes \033[0;31mERROR\033[0m\r\n"); + } + if(subghz_environment_load_keystore( + environment, "/ext/subghz/assets/keeloq_mfcodes_user")) { + printf("SubGhz decode_raw: Load_keystore keeloq_mfcodes_user \033[0;32mOK\033[0m\r\n"); + } else { + printf( + "SubGhz decode_raw: Load_keystore keeloq_mfcodes_user \033[0;31mERROR\033[0m\r\n"); } subghz_environment_set_came_atomo_rainbow_table_file_name( environment, "/ext/subghz/assets/came_atomo"); diff --git a/assets/resources/subghz/assets/keeloq_mfcodes b/assets/resources/subghz/assets/keeloq_mfcodes index c969b592..f9771285 100644 --- a/assets/resources/subghz/assets/keeloq_mfcodes +++ b/assets/resources/subghz/assets/keeloq_mfcodes @@ -1,40 +1,48 @@ Filetype: Flipper SubGhz Keystore File Version: 0 Encryption: 1 -IV: 2A 44 FE 5A A3 63 F5 11 83 A6 FE DA 1E B7 3D F1 -BF22677F79DF533C83FFE485B5F9CFABA24352FDEBED14B6FFA16EE9F00D6AC4 -B9343EDBB8B8C6EEFDA7AE9934445E27B04950DBB4F31ECCD1735CCB8C1600DE -54CC71AF6794D47FFC49823DA6C4CCAD94EC5540515FD6F537A078BFD736105C -4A3A12125D4F1186369B3B0ECB86B28A6EE4A0AF49DD4C42743A5C2C9BD1F5FC -190D7746CDC7782157E95532070BCFE8637CF9A7BE03F9382A435ACAAA7A5F5E6BEB8E34A320BDB6E492D793E470CAB4 -59ABF9B68B31BF9CCF2CCCC0A6B3182FA2772691A400B2BFB5E2490DA2BCD2A4 -304DF68472EC9C78341218C10242DC3D62887A5281B52061BC0C9D117CDE1185 -D146050F90D30FA166615706FBC8D5B3573BDCB081E2445930CE1B71F5BDB7AE -9386C94D044CCCBEE7972319191933328A06B20138C432B86C76EB909BB06019 -CFC23206853E9D01C3986FD849908686A2442287277C06574928A362F988CE1B -534B351BE03A98B56ED622D37B9BBCD871CA76EB6EF250B1615105FA496E991C8F195293F83EE38AE5831D95F45238E3 -AFF90EC99CF4278D79DA9B1163FF07C83203AD34F9C4228423B4B58FF3F6978C605CC282FB1E37C0946D86C51809222C -44C9EF18971905D2207F62D3365CB4A31D449FA215F950CEB67368D13181959C -0CF10950D8A3EDEEEEA9AA4E41354373584FBFE6BB2E8A52C3149757C133445C -4FBE939E87B8438AFC86773DADA39FE3856A3518A5159C9BF6B2EFA752F5B3F5 -CBFD648024823A33481B8A7381CD28930765265A1CA9BBDE1879F0827273A860 -8D3C70EF2E4ED2EF23752046538BF30F6DA8266F2B10A4BAD8549B3D20298F08EF9E6C21F78DDA9CA6EBB1E3CDF82C78 -D31EBB7C994C397776777D4904661C6F8DF5CDA9F828CA19378CAA397555F8C0 -FDA58BA7B0CD5C9090FE891029A3773EA16DB77EB5FA06A4C443C01B537B2615 -5CEE7A27D0D1B1AB5BAAC93D78121BC6D5FCD589C093A22C71E81C390045C85FDE98C202340FDD2046FF906A035E31E9 -C3121624E5B91EDCF651B8A89C2EEF4379876D0E0D918596F3E5CED9F3C92AB689D609AA1FB5362F57738A0AF62E3C92 -25F715B4CEA880E4879C6C03DC61875A43FB314AB4F21AE1CF7C933172B4A29D -574166A278E2FA4AB8A09078152929E631E4E182E20CCF803250A0A2D4BB62F3 -B0D1C7AA1752135BA7627D8F65EC9651B810EC29BA01C8D9BC5B3EB20B1A0939 -E3E9D30E4F7003E63917DF3B5FC4E03863E37AFD6C5987CCFEC8129C692474EF -67A35F2E3C400953EC1CD1874A35A4734D3E9F116F7E334276BF898E48C21AFE -BC8D612FA363AB364BB9D2701273C4FA587B2F8D8CD039DEFB72BAD00360149F -9A88BBDA111C9185EE5BBA610574D46A4D53EC79B63D5FB57BAB5A6609F2160F -9512A1F77A4C46BD7F79D792B1578AC1FA41F15F6D7C72BC952BD89262C85327 -182685E3E0A23055025F7218AB16F7AE3A7F9DD71761AAE3B5E4AB85E2EFBF929D640258AEBC9F0BB167985A1E4B132D -1DD9156B6BF97424DC639708ACEE21DD1D64FC5BC0DD5252DDDDE7832C2B7B6F -109BB4D660897DB00676093B585535D267426310CDE81F05793ACB46B9F6176E -D7A2D468DF76A8E5C495D5280524B2996254B94458485B11CCAB36CD1EE3918F -9F445C93FF382433015BEAE6D78F70AE2C02E0C961E1B9576D66E64978D984D0 -195CB755E6AC710B5AF10761AC2B13F8CA57355443B593BC59AAF3A819070568028BBAE75C0DA4BA6B90D63E679098B7 -C6ECD39EC47DFFD1ABC55F47AC8E2C26A8DB5EB8184153746F7D9AD5F0015E85 +IV: F2 D4 F5 5A B3 CC 3F 21 28 3A AF ED D1 EB 73 DF +BBFA4D79A73C384D6E07E717F761F32A625F28AA1DB2261B8B19A18261E30AB6 +CE4004AB56111B0B3D486770705FAD8BD616A80957EA2C537BAF1FD09E552DA3 +F974561612C9C751237C64D978F706B41873FDBE38851306574F436CB02D9ECA +E29CAB7C2C2D9853D0F4DF69F582562E8182234E78B355540F6FE3F78C73D518 +97ABE18993A700A607E37DC88E1434F84DDD1C2771693978C9D2FA4CE4F2AB7BBC7C3EB3E8545B37FBBE1C1F1CA03543 +E86ABD0AAE5A4B4A9414C9CB6112CA49B3A8EC29723B14DCA85902F41B05ADDC +C1FBE921035F408C59DA6AD5E76E3887AC9BC90146619B3CAE445BED556E96AC +232C9F86915B927888352797B45F159268FE78956CF09B8D241CDC393D3B0225 +3D9E2A3C701C9D4DD4D72038D4536CA6F515C547CAB0AD18BA71204BD2ABFB74 +4D69A4506D2C97EF8EC68F90CF1AD1065A1EB909793EEB3AF71B0D75E55B9E76 +5A7F4595DFA181C3E946EBEE4974DBD6DA85AF6FCAD0B3725FDD28667175A421D69A2122853E57927C38CCF368732476 +6A946FAEDE134155B5A88EC01AA535E7A778947D360218B560381A64CAF9ACE896079D04C14718D5AD5C0D4EE3005F52 +88AC0C723AAA875A1885C8392A616FA43B205119B0E8D299193979A1921FC8B3 +40588AADA5E1A8BE214B2CCF32D268B48C6B783AE0DD10D88BDF3FF88E921E09 +A7BE05D05DEC9B9A3AE1575D411BF7B12366AD78B726F3E3E843E7BF199961A4 +79F973A155A4367F0EAA078AA0857A2A2A82FC4C8A5AE9E567E7CBF62C2A5CE2 +C38296EEABDA1F95D0C401CC6DDC8656476DC19248588EEF1CB93773D94CDB02A40C902970C4FCB14FABEFFB4F8BC208 +B0B7699B3C3573EE4D88D8CE65FAF3532B5A741D1F20892C0F38BAA2BCE98F2D +6E401D6BDB1B33A404DEB668F3FB353166475487BAADE4A348E3CFDEB3B1B54B +0E44B87878617559783CC6A7C65BE9F99950FE8956ED4BB04894BC53085E3A09CA19915B1E8C143A68D1B7A97F5D1ECB +AC19E55638429C65E6E567C0E96DA9648F8FB80215CF693D7FD5DD86FE7989AC7AC7BAE86BBD4FFF7161AFFB405FFA98 +BCE70C69D90AD639A737813FC8FD26F40F803137BD36E47651C266A671428D6F +F053CF5255AD2E1875A5C38635F7BF203B1DAE1433B162C30AE8695AC8A5589D +B7EFC77FFA98B173E429B3566A27842C4DC5E91B0BC01F07A6A98332C4E1F42A +D7C7950FFB2C5E7D9BCDBC230BF5F1BFFC0FE6F1CF5C8C6013DD90E41AE403FE +50667B2E5909FD5F9D6385788A81DE5F72E56512EAD6BF5EACCA959CB6AF0DEF +6435E07E5E952124B0F80F76E0F68265B8289087387E35C6D51831B299335480 +D7DE1F7748FB8BF90561151CC6AEADC160CA883FE5228768A3737A89F358AF58 +FA206F860C6F981FD4A358FDEA5E1860353406D8416FF2A811D17EBA09C803EA +F2F7B2C6705D1457315F2AAA859AB53592241D63B84C045BC742D220BA110144 +3F0E05E572D1DF5E2B0BBB20EF8F3EB4D198CDF2794F86089E1DB0EF975E9337 +7D54D088C22AA3BA9A97FAB64371B8D512CDEC2A4355116BE2B74BCEC7FEC852 +0FD951F13E19F0FC1A25655DA430640034BE34659C526238E62B6042691998CB +FCA04B0BF98FA89AAEF41A78AE7141EF7783E0D0CBAAB1B6F00C0AD3EAA84A54759D46E1A9BEEDCCE68BA12902802111 +6AD801CE08D58A380B689574BD7FCACC5DF768BDD93AD7EE1AA514A2351EF13A +0A820F47699AFC4A5E3285BF521771FC5B6C5FB7C6C08A1990DA3B3A6766E860 +A7AAC90972DB24D20B57DDD46DC2624FC6169D529426E64B0544AC383799BB2A +AF6088873BC71ED672FA39D50B386523825218C43CDB35D691B0C5895B7EF5C2 +774DFAC8D285241368CB377DA947D7A94951A1520017DF77FE2E6A517D5C6A1FC768BB1E2398F5AF71B10D1806C04CCD +AA788A707E64C40E2A0EB8154FE795EAC68B936FD6BAC5DEF7677A4D5FE344DD +A193EF5D1B223B0FA3C231052EDBDD7A31B0C192BCD8E7E37E11D4D899476ACD +F6986E08949122D46BFA7F218B089E8DB00DCFA6971C5F2468CDDD179E5BBC40 +EDC23A07689EF6229081D1AB9E249E68527BD33EB72C242BA97727E64AF15BCC +70CC64359A2A5DE40D5A30E916DE6532BCC511E7489CD3A2E5DEC269D303FDBD83B7EA14BF13B40E3C960C6D3D12774B From 73711c75e630badf275eb0f11cfc4391ac3d2566 Mon Sep 17 00:00:00 2001 From: t0m1o1 <94725994+t0m1o1@users.noreply.github.com> Date: Sun, 17 Jul 2022 10:56:47 +0100 Subject: [PATCH 12/37] Update bad_usb_script.c to fix incorrect ALT key const #1406 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: あく --- applications/bad_usb/bad_usb_script.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/applications/bad_usb/bad_usb_script.c b/applications/bad_usb/bad_usb_script.c index 38b45acd..322a7292 100644 --- a/applications/bad_usb/bad_usb_script.c +++ b/applications/bad_usb/bad_usb_script.c @@ -171,7 +171,7 @@ static bool ducky_altchar(const char* charcode) { FURI_LOG_I(WORKER_TAG, "char %s", charcode); - furi_hal_hid_kb_press(HID_KEYBOARD_L_ALT); + furi_hal_hid_kb_press(KEY_MOD_LEFT_ALT); while(!ducky_is_line_end(charcode[i])) { state = ducky_numpad_press(charcode[i]); @@ -179,7 +179,7 @@ static bool ducky_altchar(const char* charcode) { i++; } - furi_hal_hid_kb_release(HID_KEYBOARD_L_ALT); + furi_hal_hid_kb_release(KEY_MOD_LEFT_ALT); return state; } From f9c2287ea7dabb0e8275d9a635c4b941516f59bc Mon Sep 17 00:00:00 2001 From: Dom Date: Sun, 17 Jul 2022 03:09:47 -0700 Subject: [PATCH 13/37] Update ReadMe.md (#1409) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Minor correction in grammar for ReadMe. Co-authored-by: あく --- ReadMe.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ReadMe.md b/ReadMe.md index e8b4daab..0d4af039 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -23,7 +23,7 @@ Flipper Zero's firmware consists of two components: - Core2 firmware set - proprietary components by ST: FUS + radio stack. FUS is flashed at factory and you should never update it. - Core1 Firmware - HAL + OS + Drivers + Applications. -They both must be flashed in order described. +They both must be flashed in the order described. ## With offline update package From e3c7201a2065677ad3c96f0bb1f47f7b58cdb819 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=82=E3=81=8F?= Date: Wed, 20 Jul 2022 13:56:33 +0300 Subject: [PATCH 14/37] Furi: core refactoring and CMSIS removal part 2 (#1410) * Furi: rename and move core * Furi: drop CMSIS_OS header and unused api, partially refactor and cleanup the rest * Furi: CMSIS_OS drop and refactoring. * Furi: refactoring, remove cmsis legacy * Furi: fix incorrect assert on queue deallocation, cleanup timer * Furi: improve delay api, get rid of floats * hal: dropped furi_hal_crc * Furi: move DWT based delay to cortex HAL * Furi: update core documentation Co-authored-by: hedger --- .github/CODEOWNERS | 2 +- ReadMe.md | 2 +- .../accessor/accessor_view_manager.cpp | 10 +- applications/accessor/accessor_view_manager.h | 2 +- .../archive/helpers/archive_browser.c | 4 +- applications/bad_usb/bad_usb_script.c | 22 +- applications/bt/bt_cli.c | 8 +- .../bt/bt_debug_app/views/bt_carrier_test.c | 14 +- .../bt/bt_debug_app/views/bt_packet_test.c | 10 +- applications/bt/bt_service/bt.c | 55 +- applications/bt/bt_service/bt_api.c | 13 +- applications/bt/bt_service/bt_i.h | 6 +- applications/cli/cli.c | 36 +- applications/cli/cli_i.h | 4 +- applications/cli/cli_vcp.c | 16 +- applications/debug_tools/blink_test.c | 22 +- .../display_test/view_display_test.c | 10 +- .../scenes/file_browser_scene_browser.c | 4 +- applications/debug_tools/keypad_test.c | 10 +- applications/debug_tools/text_box_test.c | 10 +- applications/debug_tools/uart_echo.c | 4 +- applications/debug_tools/usb_mouse.c | 12 +- applications/debug_tools/vibro_test.c | 10 +- .../desktop/animations/animation_manager.c | 16 +- .../desktop/animations/animation_storage.c | 2 +- .../animations/views/bubble_animation_view.c | 20 +- applications/desktop/desktop.c | 10 +- applications/desktop/desktop_i.h | 2 +- .../scenes/desktop_settings_scene_pin_auth.c | 2 +- .../desktop_settings_scene_pin_disable.c | 2 +- .../scenes/desktop_settings_scene_pin_error.c | 2 +- .../scenes/desktop_settings_scene_pin_setup.c | 2 +- applications/desktop/helpers/slideshow.c | 4 +- .../desktop/scenes/desktop_scene_pin_input.c | 2 +- .../desktop/views/desktop_view_locked.c | 2 +- .../desktop/views/desktop_view_main.c | 2 +- .../desktop/views/desktop_view_pin_input.c | 2 +- applications/dialogs/dialogs.c | 4 +- applications/dialogs/dialogs_api.c | 6 +- applications/dialogs/dialogs_api_lock.h | 10 +- applications/dialogs/dialogs_i.h | 2 +- applications/dialogs/view_holder.c | 2 +- applications/dolphin/dolphin.c | 22 +- applications/dolphin/dolphin.h | 2 +- applications/dolphin/dolphin_i.h | 6 +- applications/dolphin/passport/passport.c | 15 +- applications/gpio/usb_uart_bridge.c | 33 +- applications/gui/gui.c | 14 +- applications/gui/gui_i.h | 4 +- applications/gui/icon_animation.c | 9 +- applications/gui/icon_animation_i.h | 2 +- applications/gui/modules/file_browser.c | 7 +- .../gui/modules/file_browser_worker.c | 9 +- applications/gui/modules/popup.c | 13 +- applications/gui/modules/text_input.c | 12 +- applications/gui/view.c | 8 +- applications/gui/view_dispatcher.c | 20 +- applications/gui/view_dispatcher_i.h | 2 +- applications/gui/view_i.h | 2 +- applications/gui/view_stack.c | 2 +- applications/ibutton/ibutton_cli.c | 27 +- .../ibutton/scenes/ibutton_scene_emulate.c | 2 +- applications/infrared/infrared_cli.c | 2 +- applications/infrared/infrared_remote.c | 2 +- applications/infrared/infrared_signal.c | 2 +- .../infrared/views/infrared_progress_view.c | 2 +- applications/input/input.c | 14 +- applications/input/input_cli.c | 10 +- applications/input/input_i.h | 2 +- applications/lfrfid/helpers/rfid_key.cpp | 2 +- applications/lfrfid/helpers/rfid_reader.cpp | 6 +- applications/lfrfid/helpers/rfid_writer.cpp | 12 +- applications/lfrfid/lfrfid_app.cpp | 2 +- applications/lfrfid/lfrfid_cli.cpp | 4 +- .../lfrfid/scene/lfrfid_app_scene_emulate.cpp | 2 +- .../lfrfid/scene/lfrfid_app_scene_rpc.cpp | 2 +- applications/loader/loader.c | 2 +- applications/loader/loader.h | 2 +- applications/loader/loader_i.h | 2 +- applications/music_player/music_player.c | 32 +- applications/music_player/music_player_cli.c | 2 +- .../music_player/music_player_worker.c | 10 +- applications/nfc/helpers/nfc_debug_pcap.c | 4 +- applications/nfc/nfc_cli.c | 6 +- applications/nfc/nfc_worker.c | 20 +- .../scenes/nfc_scene_emulate_apdu_sequence.c | 2 +- applications/notification/notification_app.c | 42 +- applications/notification/notification_app.h | 6 +- .../notification/notification_app_api.c | 22 +- applications/picopass/picopass_worker.c | 2 +- applications/power/power_cli.c | 2 +- applications/power/power_service/power.c | 10 +- applications/power/power_service/power.h | 2 +- applications/power/power_service/power_api.c | 14 +- applications/power/power_service/power_i.h | 2 +- applications/rpc/rpc.c | 52 +- applications/rpc/rpc_app.c | 15 +- applications/rpc/rpc_cli.c | 11 +- applications/rpc/rpc_gui.c | 2 +- applications/rpc/rpc_storage.c | 6 +- applications/snake_game/snake_game.c | 24 +- applications/storage/storage.c | 4 +- applications/storage/storage_external_api.c | 36 +- applications/storage/storage_glue.c | 6 +- applications/storage/storage_glue.h | 2 +- applications/storage/storage_i.h | 2 +- applications/storage/storage_internal_api.c | 2 +- applications/storage/storage_message.h | 2 +- applications/storage/storage_processing.c | 2 +- applications/storage/storage_test_app.c | 2 +- applications/storage/storages/storage_ext.c | 2 +- .../storage_move_to_sd_scene_progress.c | 1 - .../storage_move_to_sd/storage_move_to_sd.c | 5 +- .../scenes/storage_settings_scene_benchmark.c | 13 +- applications/subghz/helpers/subghz_chat.c | 24 +- .../subghz_frequency_analyzer_worker.c | 8 +- applications/subghz/subghz_cli.c | 14 +- applications/subghz/subghz_history.c | 6 +- applications/subghz/views/receiver.c | 14 +- .../subghz/views/subghz_test_carrier.c | 12 +- .../subghz/views/subghz_test_packet.c | 14 +- .../subghz/views/subghz_test_static.c | 2 +- applications/u2f/scenes/u2f_scene_main.c | 16 +- applications/u2f/u2f_app_i.h | 2 +- applications/u2f/u2f_hid.c | 17 +- .../unit_tests/furi/furi_valuemutex_test.c | 1 - applications/unit_tests/nfc/nfc_test.c | 2 +- applications/unit_tests/rpc/rpc_test.c | 27 +- .../unit_tests/storage/storage_test.c | 29 +- applications/unit_tests/subghz/subghz_test.c | 28 +- applications/unit_tests/test_index.c | 6 +- applications/updater/cli/updater_cli.c | 4 +- applications/updater/util/update_task.c | 2 +- .../updater/util/update_task_worker_flasher.c | 2 +- core/furi.c | 13 - core/furi.h | 37 - core/furi/base.h | 45 - core/furi/event_flags.c | 222 ---- core/furi/event_flags.h | 63 - core/furi/mutex.c | 217 ---- core/furi/mutex.h | 56 - core/furi/semaphore.c | 190 --- core/furi/semaphore.h | 57 - firmware.scons | 8 +- firmware/targets/f7/Inc/FreeRTOSConfig.h | 7 +- firmware/targets/f7/Inc/stm32_assert.h | 4 +- firmware/targets/f7/Src/main.c | 2 +- firmware/targets/f7/Src/update.c | 1 - firmware/targets/f7/ble_glue/app_common.h | 2 +- firmware/targets/f7/ble_glue/ble_app.c | 22 +- firmware/targets/f7/ble_glue/ble_glue.c | 26 +- firmware/targets/f7/ble_glue/gap.c | 66 +- firmware/targets/f7/ble_glue/serial_service.c | 16 +- firmware/targets/f7/fatfs/ffconf.h | 2 +- firmware/targets/f7/fatfs/spi_sd_hal.c | 6 +- firmware/targets/f7/fatfs/stm32_adafruit_sd.c | 6 +- firmware/targets/f7/fatfs/syscall.c | 8 +- firmware/targets/f7/furi_hal/furi_hal.c | 3 +- firmware/targets/f7/furi_hal/furi_hal_bt.c | 19 +- .../targets/f7/furi_hal/furi_hal_cortex.c | 20 + firmware/targets/f7/furi_hal/furi_hal_crc.c | 93 -- firmware/targets/f7/furi_hal/furi_hal_crc.h | 35 - .../targets/f7/furi_hal/furi_hal_crypto.c | 14 +- firmware/targets/f7/furi_hal/furi_hal_delay.c | 45 - firmware/targets/f7/furi_hal/furi_hal_i2c.c | 29 +- .../targets/f7/furi_hal/furi_hal_i2c_config.c | 22 +- .../targets/f7/furi_hal/furi_hal_infrared.c | 26 +- .../targets/f7/furi_hal/furi_hal_interrupt.c | 1 - firmware/targets/f7/furi_hal/furi_hal_light.c | 7 +- firmware/targets/f7/furi_hal/furi_hal_nfc.c | 30 +- firmware/targets/f7/furi_hal/furi_hal_os.c | 5 +- firmware/targets/f7/furi_hal/furi_hal_power.c | 3 +- .../targets/f7/furi_hal/furi_hal_resources.c | 3 +- .../targets/f7/furi_hal/furi_hal_spi_config.c | 20 +- firmware/targets/f7/furi_hal/furi_hal_uart.c | 1 - firmware/targets/f7/furi_hal/furi_hal_usb.c | 8 +- .../targets/f7/furi_hal/furi_hal_usb_hid.c | 10 +- .../targets/f7/furi_hal/furi_hal_usb_u2f.c | 10 +- firmware/targets/furi_hal_include/furi_hal.h | 2 +- .../furi_hal_include/furi_hal_cortex.h | 32 + .../targets/furi_hal_include/furi_hal_delay.h | 51 - {core => furi}/SConscript | 4 +- furi/core/base.h | 43 + {core/furi => furi/core}/check.c | 0 {core/furi => furi/core}/check.h | 0 {core/furi => furi/core}/common_defines.h | 47 +- {core/furi => furi/core}/dangerous_defines.h | 0 furi/core/event_flag.c | 135 ++ furi/core/event_flag.h | 70 ++ furi/core/kernel.c | 174 +++ furi/core/kernel.h | 93 ++ {core/furi => furi/core}/log.c | 12 +- {core/furi => furi/core}/log.h | 38 + {core/furi => furi/core}/memmgr.c | 0 {core/furi => furi/core}/memmgr.h | 0 {core/furi => furi/core}/memmgr_heap.c | 11 +- {core/furi => furi/core}/memmgr_heap.h | 2 +- furi/core/message_queue.c | 178 +++ furi/core/message_queue.h | 95 ++ furi/core/mutex.c | 122 ++ furi/core/mutex.h | 62 + {core/furi => furi/core}/pubsub.c | 18 +- {core/furi => furi/core}/pubsub.h | 4 + {core/furi => furi/core}/record.c | 24 +- {core/furi => furi/core}/record.h | 0 furi/core/semaphore.c | 115 ++ furi/core/semaphore.h | 58 + {core/furi => furi/core}/stdglue.c | 15 +- {core/furi => furi/core}/stdglue.h | 0 {core/furi => furi/core}/thread.c | 39 +- {core/furi => furi/core}/thread.h | 1 + furi/core/timer.c | 142 +++ furi/core/timer.h | 61 + {core/furi => furi/core}/valuemutex.c | 11 +- {core/furi => furi/core}/valuemutex.h | 13 +- {core => furi}/flipper.c | 0 {core => furi}/flipper.h | 0 furi/furi.c | 27 + furi/furi.h | 37 + lib/FreeRTOS-glue/cmsis_os2.c | 1120 ----------------- lib/FreeRTOS-glue/cmsis_os2.h | 302 ----- lib/FreeRTOS-glue/freertos_os2.h | 319 ----- lib/ST25RFAL002/platform.c | 2 +- lib/ST25RFAL002/platform.h | 6 +- lib/ST25RFAL002/timer.c | 10 +- lib/app-scened-template/record_controller.hpp | 2 +- lib/app-scened-template/view_controller.hpp | 14 +- lib/drivers/bq27220.c | 9 +- lib/drivers/cc1101.c | 2 - lib/drivers/lp5562.c | 6 +- lib/flipper_format/flipper_format.c | 2 +- lib/flipper_format/flipper_format_stream.c | 2 +- lib/freertos.scons | 1 - .../common/infrared_common_decoder.c | 4 +- .../common/infrared_common_encoder.c | 2 +- lib/infrared/encoder_decoder/infrared.c | 2 +- .../nec/infrared_encoder_nec.c | 2 +- .../rc5/infrared_encoder_rc5.c | 2 +- .../rc6/infrared_encoder_rc6.c | 2 +- .../samsung/infrared_encoder_samsung.c | 2 +- .../sirc/infrared_encoder_sirc.c | 2 +- lib/infrared/worker/infrared_transmit.c | 1 - lib/infrared/worker/infrared_worker.c | 8 +- lib/nfc_protocols/emv.c | 2 +- lib/one_wire/ibutton/encoder/encoder_cyfral.c | 2 +- .../ibutton/encoder/encoder_metakom.c | 2 +- lib/one_wire/ibutton/ibutton_worker.c | 31 +- lib/one_wire/ibutton/ibutton_worker_i.h | 2 +- lib/one_wire/ibutton/ibutton_worker_modes.c | 6 +- lib/one_wire/ibutton/ibutton_writer.c | 20 +- .../ibutton/pulse_protocols/protocol_cyfral.c | 6 +- .../pulse_protocols/protocol_metakom.c | 3 +- lib/one_wire/one_wire_host.c | 24 +- lib/one_wire/one_wire_slave.c | 13 +- lib/one_wire/pulse_protocols/pulse_decoder.c | 2 +- lib/subghz/blocks/encoder.c | 4 +- lib/subghz/protocols/princeton_for_testing.c | 5 +- lib/subghz/protocols/raw.c | 2 +- lib/subghz/subghz_file_encoder_worker.c | 6 +- lib/subghz/subghz_tx_rx_worker.c | 10 +- lib/toolbox/stream/stream.c | 4 +- lib/toolbox/stream/string_stream.c | 2 +- lib/toolbox/tar/tar_archive.c | 4 +- lib/u8g2/u8g2_glue.c | 4 +- 264 files changed, 2569 insertions(+), 3883 deletions(-) mode change 100755 => 100644 applications/bt/bt_service/bt_api.c delete mode 100644 core/furi.c delete mode 100644 core/furi.h delete mode 100644 core/furi/base.h delete mode 100644 core/furi/event_flags.c delete mode 100644 core/furi/event_flags.h delete mode 100644 core/furi/mutex.c delete mode 100644 core/furi/mutex.h delete mode 100644 core/furi/semaphore.c delete mode 100644 core/furi/semaphore.h create mode 100644 firmware/targets/f7/furi_hal/furi_hal_cortex.c delete mode 100644 firmware/targets/f7/furi_hal/furi_hal_crc.c delete mode 100644 firmware/targets/f7/furi_hal/furi_hal_crc.h delete mode 100644 firmware/targets/f7/furi_hal/furi_hal_delay.c create mode 100644 firmware/targets/furi_hal_include/furi_hal_cortex.h delete mode 100644 firmware/targets/furi_hal_include/furi_hal_delay.h rename {core => furi}/SConscript (71%) create mode 100644 furi/core/base.h rename {core/furi => furi/core}/check.c (100%) rename {core/furi => furi/core}/check.h (100%) rename {core/furi => furi/core}/common_defines.h (77%) rename {core/furi => furi/core}/dangerous_defines.h (100%) create mode 100644 furi/core/event_flag.c create mode 100644 furi/core/event_flag.h create mode 100644 furi/core/kernel.c create mode 100644 furi/core/kernel.h rename {core/furi => furi/core}/log.c (82%) rename {core/furi => furi/core}/log.h (77%) rename {core/furi => furi/core}/memmgr.c (100%) rename {core/furi => furi/core}/memmgr.h (100%) rename {core/furi => furi/core}/memmgr_heap.c (99%) rename {core/furi => furi/core}/memmgr_heap.h (97%) create mode 100644 furi/core/message_queue.c create mode 100644 furi/core/message_queue.h create mode 100644 furi/core/mutex.c create mode 100644 furi/core/mutex.h rename {core/furi => furi/core}/pubsub.c (80%) rename {core/furi => furi/core}/pubsub.h (97%) rename {core/furi => furi/core}/record.c (84%) rename {core/furi => furi/core}/record.h (100%) create mode 100644 furi/core/semaphore.c create mode 100644 furi/core/semaphore.h rename {core/furi => furi/core}/stdglue.c (83%) rename {core/furi => furi/core}/stdglue.h (100%) rename {core/furi => furi/core}/thread.c (91%) rename {core/furi => furi/core}/thread.h (99%) create mode 100644 furi/core/timer.c create mode 100644 furi/core/timer.h rename {core/furi => furi/core}/valuemutex.c (79%) rename {core/furi => furi/core}/valuemutex.h (93%) rename {core => furi}/flipper.c (100%) rename {core => furi}/flipper.h (100%) create mode 100644 furi/furi.c create mode 100644 furi/furi.h delete mode 100644 lib/FreeRTOS-glue/cmsis_os2.c delete mode 100644 lib/FreeRTOS-glue/cmsis_os2.h delete mode 100644 lib/FreeRTOS-glue/freertos_os2.h diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 40fb1e43..da0cfd2c 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -40,7 +40,7 @@ /assets/ @skotopes @DrZlo13 @hedger # Furi Core -/core/ @skotopes @DrZlo13 @hedger +/furi/ @skotopes @DrZlo13 @hedger # Debug tools and plugins /debug/ @skotopes @DrZlo13 @hedger diff --git a/ReadMe.md b/ReadMe.md index 0d4af039..f3a35056 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -155,7 +155,7 @@ Connect your device via ST-Link and run: - `applications` - Applications and services used in firmware - `assets` - Assets used by applications and services -- `core` - Furi Core: os level primitives and helpers +- `furi` - Furi Core: os level primitives and helpers - `debug` - Debug tool: GDB-plugins, SVD-file and etc - `docker` - Docker image sources (used for firmware build automation) - `documentation` - Documentation generation system configs and input files diff --git a/applications/accessor/accessor_view_manager.cpp b/applications/accessor/accessor_view_manager.cpp index f54ad62f..7c681cbb 100644 --- a/applications/accessor/accessor_view_manager.cpp +++ b/applications/accessor/accessor_view_manager.cpp @@ -3,7 +3,7 @@ #include AccessorAppViewManager::AccessorAppViewManager() { - event_queue = osMessageQueueNew(10, sizeof(AccessorEvent), NULL); + event_queue = furi_message_queue_alloc(10, sizeof(AccessorEvent)); view_dispatcher = view_dispatcher_alloc(); auto callback = cbc::obtain_connector(this, &AccessorAppViewManager::previous_view_callback); @@ -38,7 +38,7 @@ AccessorAppViewManager::~AccessorAppViewManager() { view_dispatcher_free(view_dispatcher); // free event queue - osMessageQueueDelete(event_queue); + furi_message_queue_free(event_queue); } void AccessorAppViewManager::switch_to(ViewType type) { @@ -54,14 +54,14 @@ Popup* AccessorAppViewManager::get_popup() { } void AccessorAppViewManager::receive_event(AccessorEvent* event) { - if(osMessageQueueGet(event_queue, event, NULL, 100) != osOK) { + if(furi_message_queue_get(event_queue, event, 100) != FuriStatusOk) { event->type = AccessorEvent::Type::Tick; } } void AccessorAppViewManager::send_event(AccessorEvent* event) { - osStatus_t result = osMessageQueuePut(event_queue, event, 0, 0); - furi_check(result == osOK); + FuriStatus result = furi_message_queue_put(event_queue, event, 0); + furi_check(result == FuriStatusOk); } uint32_t AccessorAppViewManager::previous_view_callback(void*) { diff --git a/applications/accessor/accessor_view_manager.h b/applications/accessor/accessor_view_manager.h index f2c6f2bb..8cd43779 100644 --- a/applications/accessor/accessor_view_manager.h +++ b/applications/accessor/accessor_view_manager.h @@ -13,7 +13,7 @@ public: Tune, }; - osMessageQueueId_t event_queue; + FuriMessageQueue* event_queue; AccessorAppViewManager(); ~AccessorAppViewManager(); diff --git a/applications/archive/helpers/archive_browser.c b/applications/archive/helpers/archive_browser.c index 3e4d6731..28284136 100644 --- a/applications/archive/helpers/archive_browser.c +++ b/applications/archive/helpers/archive_browser.c @@ -2,8 +2,8 @@ #include "archive_files.h" #include "archive_apps.h" #include "archive_browser.h" -#include "furi/common_defines.h" -#include "furi/log.h" +#include +#include #include "gui/modules/file_browser_worker.h" #include "m-string.h" #include diff --git a/applications/bad_usb/bad_usb_script.c b/applications/bad_usb/bad_usb_script.c index 322a7292..a06f6d59 100644 --- a/applications/bad_usb/bad_usb_script.c +++ b/applications/bad_usb/bad_usb_script.c @@ -485,8 +485,8 @@ static int32_t bad_usb_worker(void* context) { } else if(worker_state == BadUsbStateNotConnected) { // State: USB not connected uint32_t flags = furi_thread_flags_wait( - WorkerEvtEnd | WorkerEvtConnect, osFlagsWaitAny, osWaitForever); - furi_check((flags & osFlagsError) == 0); + WorkerEvtEnd | WorkerEvtConnect, FuriFlagWaitAny, FuriWaitForever); + furi_check((flags & FuriFlagError) == 0); if(flags & WorkerEvtEnd) { break; } else if(flags & WorkerEvtConnect) { @@ -497,9 +497,9 @@ static int32_t bad_usb_worker(void* context) { } else if(worker_state == BadUsbStateIdle) { // State: ready to start uint32_t flags = furi_thread_flags_wait( WorkerEvtEnd | WorkerEvtToggle | WorkerEvtDisconnect, - osFlagsWaitAny, - osWaitForever); - furi_check((flags & osFlagsError) == 0); + FuriFlagWaitAny, + FuriWaitForever); + furi_check((flags & FuriFlagError) == 0); if(flags & WorkerEvtEnd) { break; } else if(flags & WorkerEvtToggle) { // Start executing script @@ -520,9 +520,9 @@ static int32_t bad_usb_worker(void* context) { } else if(worker_state == BadUsbStateRunning) { // State: running uint16_t delay_cur = (delay_val > 1000) ? (1000) : (delay_val); uint32_t flags = furi_thread_flags_wait( - WorkerEvtEnd | WorkerEvtToggle | WorkerEvtDisconnect, osFlagsWaitAny, delay_cur); + WorkerEvtEnd | WorkerEvtToggle | WorkerEvtDisconnect, FuriFlagWaitAny, delay_cur); delay_val -= delay_cur; - if(!(flags & osFlagsError)) { + if(!(flags & FuriFlagError)) { if(flags & WorkerEvtEnd) { break; } else if(flags & WorkerEvtToggle) { @@ -534,7 +534,7 @@ static int32_t bad_usb_worker(void* context) { } bad_usb->st.state = worker_state; continue; - } else if((flags == osFlagsErrorTimeout) || (flags == osFlagsErrorResource)) { + } else if((flags == FuriFlagErrorTimeout) || (flags == FuriFlagErrorResource)) { if(delay_val > 0) { bad_usb->st.delay_remain--; continue; @@ -556,15 +556,15 @@ static int32_t bad_usb_worker(void* context) { bad_usb->st.delay_remain = delay_val / 1000; } } else { - furi_check((flags & osFlagsError) == 0); + furi_check((flags & FuriFlagError) == 0); } } else if( (worker_state == BadUsbStateFileError) || (worker_state == BadUsbStateScriptError)) { // State: error uint32_t flags = furi_thread_flags_wait( - WorkerEvtEnd, osFlagsWaitAny, osWaitForever); // Waiting for exit command - furi_check((flags & osFlagsError) == 0); + WorkerEvtEnd, FuriFlagWaitAny, FuriWaitForever); // Waiting for exit command + furi_check((flags & FuriFlagError) == 0); if(flags & WorkerEvtEnd) { break; } diff --git a/applications/bt/bt_cli.c b/applications/bt/bt_cli.c index 98f73d22..d12724d2 100644 --- a/applications/bt/bt_cli.c +++ b/applications/bt/bt_cli.c @@ -41,7 +41,7 @@ static void bt_cli_command_carrier_tx(Cli* cli, string_t args, void* context) { furi_hal_bt_start_tone_tx(channel, 0x19 + power); while(!cli_cmd_interrupt_received(cli)) { - osDelay(250); + furi_delay_ms(250); } furi_hal_bt_stop_tone_tx(); @@ -69,7 +69,7 @@ static void bt_cli_command_carrier_rx(Cli* cli, string_t args, void* context) { furi_hal_bt_start_packet_rx(channel, 1); while(!cli_cmd_interrupt_received(cli)) { - osDelay(250); + furi_delay_ms(250); printf("RSSI: %6.1f dB\r", (double)furi_hal_bt_get_rssi()); fflush(stdout); } @@ -119,7 +119,7 @@ static void bt_cli_command_packet_tx(Cli* cli, string_t args, void* context) { furi_hal_bt_start_packet_tx(channel, pattern, datarate); while(!cli_cmd_interrupt_received(cli)) { - osDelay(250); + furi_delay_ms(250); } furi_hal_bt_stop_packet_test(); printf("Transmitted %lu packets", furi_hal_bt_get_transmitted_packets()); @@ -152,7 +152,7 @@ static void bt_cli_command_packet_rx(Cli* cli, string_t args, void* context) { furi_hal_bt_start_packet_rx(channel, datarate); while(!cli_cmd_interrupt_received(cli)) { - osDelay(250); + furi_delay_ms(250); printf("RSSI: %03.1f dB\r", (double)furi_hal_bt_get_rssi()); fflush(stdout); } diff --git a/applications/bt/bt_debug_app/views/bt_carrier_test.c b/applications/bt/bt_debug_app/views/bt_carrier_test.c index 0e0b3792..c09aa3fd 100755 --- a/applications/bt/bt_debug_app/views/bt_carrier_test.c +++ b/applications/bt/bt_debug_app/views/bt_carrier_test.c @@ -9,7 +9,7 @@ struct BtCarrierTest { BtTestMode mode; BtTestChannel channel; BtTestPower power; - osTimerId_t timer; + FuriTimer* timer; }; static BtTestParamValue bt_param_mode[] = { @@ -35,10 +35,10 @@ static void bt_carrier_test_start(BtCarrierTest* bt_carrier_test) { furi_assert(bt_carrier_test); if(bt_carrier_test->mode == BtTestModeRx) { furi_hal_bt_start_packet_rx(bt_carrier_test->channel, 1); - osTimerStart(bt_carrier_test->timer, osKernelGetTickFreq() / 4); + furi_timer_start(bt_carrier_test->timer, furi_kernel_get_tick_frequency() / 4); } else if(bt_carrier_test->mode == BtTestModeTxHopping) { furi_hal_bt_start_tone_tx(bt_carrier_test->channel, bt_carrier_test->power); - osTimerStart(bt_carrier_test->timer, osKernelGetTickFreq() * 2); + furi_timer_start(bt_carrier_test->timer, furi_kernel_get_tick_frequency() * 2); } else if(bt_carrier_test->mode == BtTestModeTx) { furi_hal_bt_start_tone_tx(bt_carrier_test->channel, bt_carrier_test->power); } @@ -68,12 +68,12 @@ static void bt_carrier_test_stop(BtCarrierTest* bt_carrier_test) { furi_assert(bt_carrier_test); if(bt_carrier_test->mode == BtTestModeTxHopping) { furi_hal_bt_stop_tone_tx(); - osTimerStop(bt_carrier_test->timer); + furi_timer_stop(bt_carrier_test->timer); } else if(bt_carrier_test->mode == BtTestModeTx) { furi_hal_bt_stop_tone_tx(); } else if(bt_carrier_test->mode == BtTestModeRx) { furi_hal_bt_stop_packet_test(); - osTimerStop(bt_carrier_test->timer); + furi_timer_stop(bt_carrier_test->timer); } } @@ -170,7 +170,7 @@ BtCarrierTest* bt_carrier_test_alloc() { bt_carrier_test->power = BtPower0dB; bt_carrier_test->timer = - osTimerNew(bt_test_carrier_timer_callback, osTimerPeriodic, bt_carrier_test, NULL); + furi_timer_alloc(bt_test_carrier_timer_callback, FuriTimerTypePeriodic, bt_carrier_test); return bt_carrier_test; } @@ -178,7 +178,7 @@ BtCarrierTest* bt_carrier_test_alloc() { void bt_carrier_test_free(BtCarrierTest* bt_carrier_test) { furi_assert(bt_carrier_test); bt_test_free(bt_carrier_test->bt_test); - osTimerDelete(bt_carrier_test->timer); + furi_timer_free(bt_carrier_test->timer); free(bt_carrier_test); } diff --git a/applications/bt/bt_debug_app/views/bt_packet_test.c b/applications/bt/bt_debug_app/views/bt_packet_test.c index e9b3bd75..7cbc3c5c 100644 --- a/applications/bt/bt_debug_app/views/bt_packet_test.c +++ b/applications/bt/bt_debug_app/views/bt_packet_test.c @@ -8,7 +8,7 @@ struct BtPacketTest { BtTestMode mode; BtTestChannel channel; BtTestDataRate data_rate; - osTimerId_t timer; + FuriTimer* timer; }; static BtTestParamValue bt_param_mode[] = { @@ -31,7 +31,7 @@ static void bt_packet_test_start(BtPacketTest* bt_packet_test) { furi_assert(bt_packet_test); if(bt_packet_test->mode == BtTestModeRx) { furi_hal_bt_start_packet_rx(bt_packet_test->channel, bt_packet_test->data_rate); - osTimerStart(bt_packet_test->timer, osKernelGetTickFreq() / 4); + furi_timer_start(bt_packet_test->timer, furi_kernel_get_tick_frequency() / 4); } else if(bt_packet_test->mode == BtTestModeTx) { furi_hal_bt_start_packet_tx(bt_packet_test->channel, 1, bt_packet_test->data_rate); } @@ -44,7 +44,7 @@ static void bt_packet_test_stop(BtPacketTest* bt_packet_test) { bt_test_set_packets_tx(bt_packet_test->bt_test, furi_hal_bt_get_transmitted_packets()); } else if(bt_packet_test->mode == BtTestModeRx) { bt_test_set_packets_rx(bt_packet_test->bt_test, furi_hal_bt_stop_packet_test()); - osTimerStop(bt_packet_test->timer); + furi_timer_stop(bt_packet_test->timer); } } @@ -137,7 +137,7 @@ BtPacketTest* bt_packet_test_alloc() { bt_packet_test->data_rate = BtDataRate1M; bt_packet_test->timer = - osTimerNew(bt_test_packet_timer_callback, osTimerPeriodic, bt_packet_test, NULL); + furi_timer_alloc(bt_test_packet_timer_callback, FuriTimerTypePeriodic, bt_packet_test); return bt_packet_test; } @@ -145,7 +145,7 @@ BtPacketTest* bt_packet_test_alloc() { void bt_packet_test_free(BtPacketTest* bt_packet_test) { furi_assert(bt_packet_test); bt_test_free(bt_packet_test->bt_test); - osTimerDelete(bt_packet_test->timer); + furi_timer_free(bt_packet_test->timer); free(bt_packet_test); } diff --git a/applications/bt/bt_service/bt.c b/applications/bt/bt_service/bt.c index f387ec6d..d122aa17 100644 --- a/applications/bt/bt_service/bt.c +++ b/applications/bt/bt_service/bt.c @@ -96,12 +96,14 @@ static void bt_battery_level_changed_callback(const void* _event, void* context) if(event->type == PowerEventTypeBatteryLevelChanged) { message.type = BtMessageTypeUpdateBatteryLevel; message.data.battery_level = event->data.battery_level; - furi_check(osMessageQueuePut(bt->message_queue, &message, 0, osWaitForever) == osOK); + furi_check( + furi_message_queue_put(bt->message_queue, &message, FuriWaitForever) == FuriStatusOk); } else if( event->type == PowerEventTypeStartCharging || event->type == PowerEventTypeFullyCharged || event->type == PowerEventTypeStopCharging) { message.type = BtMessageTypeUpdatePowerState; - furi_check(osMessageQueuePut(bt->message_queue, &message, 0, osWaitForever) == osOK); + furi_check( + furi_message_queue_put(bt->message_queue, &message, FuriWaitForever) == FuriStatusOk); } } @@ -115,7 +117,7 @@ Bt* bt_alloc() { bt_settings_save(&bt->bt_settings); } // Alloc queue - bt->message_queue = osMessageQueueNew(8, sizeof(BtMessage), NULL); + bt->message_queue = furi_message_queue_alloc(8, sizeof(BtMessage)); // Setup statusbar view port bt->statusbar_view_port = bt_statusbar_view_port_alloc(bt); @@ -139,10 +141,10 @@ Bt* bt_alloc() { // RPC bt->rpc = furi_record_open("rpc"); - bt->rpc_event = osEventFlagsNew(NULL); + bt->rpc_event = furi_event_flag_alloc(); // API evnent - bt->api_event = osEventFlagsNew(NULL); + bt->api_event = furi_event_flag_alloc(); return bt; } @@ -162,7 +164,7 @@ static uint16_t bt_serial_event_callback(SerialServiceEvent event, void* context } ret = rpc_session_get_available_size(bt->rpc_session); } else if(event.event == SerialServiceEventTypeDataSent) { - osEventFlagsSet(bt->rpc_event, BT_RPC_EVENT_BUFF_SENT); + furi_event_flag_set(bt->rpc_event, BT_RPC_EVENT_BUFF_SENT); } return ret; } @@ -172,11 +174,11 @@ static void bt_rpc_send_bytes_callback(void* context, uint8_t* bytes, size_t byt furi_assert(context); Bt* bt = context; - if(osEventFlagsGet(bt->rpc_event) & BT_RPC_EVENT_DISCONNECTED) { + if(furi_event_flag_get(bt->rpc_event) & BT_RPC_EVENT_DISCONNECTED) { // Early stop from sending if we're already disconnected return; } - osEventFlagsClear(bt->rpc_event, BT_RPC_EVENT_ALL & (~BT_RPC_EVENT_DISCONNECTED)); + furi_event_flag_clear(bt->rpc_event, BT_RPC_EVENT_ALL & (~BT_RPC_EVENT_DISCONNECTED)); size_t bytes_sent = 0; while(bytes_sent < bytes_len) { size_t bytes_remain = bytes_len - bytes_sent; @@ -188,13 +190,13 @@ static void bt_rpc_send_bytes_callback(void* context, uint8_t* bytes, size_t byt bytes_sent += bytes_remain; } // We want BT_RPC_EVENT_DISCONNECTED to stick, so don't clear - uint32_t event_flag = osEventFlagsWait( - bt->rpc_event, BT_RPC_EVENT_ALL, osFlagsWaitAny | osFlagsNoClear, osWaitForever); + uint32_t event_flag = furi_event_flag_wait( + bt->rpc_event, BT_RPC_EVENT_ALL, FuriFlagWaitAny | FuriFlagNoClear, FuriWaitForever); if(event_flag & BT_RPC_EVENT_DISCONNECTED) { break; } else { // If we didn't get BT_RPC_EVENT_DISCONNECTED, then clear everything else - osEventFlagsClear(bt->rpc_event, BT_RPC_EVENT_ALL & (~BT_RPC_EVENT_DISCONNECTED)); + furi_event_flag_clear(bt->rpc_event, BT_RPC_EVENT_ALL & (~BT_RPC_EVENT_DISCONNECTED)); } } } @@ -209,9 +211,10 @@ static bool bt_on_gap_event_callback(GapEvent event, void* context) { // Update status bar bt->status = BtStatusConnected; BtMessage message = {.type = BtMessageTypeUpdateStatus}; - furi_check(osMessageQueuePut(bt->message_queue, &message, 0, osWaitForever) == osOK); + furi_check( + furi_message_queue_put(bt->message_queue, &message, FuriWaitForever) == FuriStatusOk); // Clear BT_RPC_EVENT_DISCONNECTED because it might be set from previous session - osEventFlagsClear(bt->rpc_event, BT_RPC_EVENT_DISCONNECTED); + furi_event_flag_clear(bt->rpc_event, BT_RPC_EVENT_DISCONNECTED); if(bt->profile == BtProfileSerial) { // Open RPC session bt->rpc_session = rpc_session_open(bt->rpc); @@ -232,12 +235,13 @@ static bool bt_on_gap_event_callback(GapEvent event, void* context) { power_get_info(bt->power, &info); message.type = BtMessageTypeUpdateBatteryLevel; message.data.battery_level = info.charge; - furi_check(osMessageQueuePut(bt->message_queue, &message, 0, osWaitForever) == osOK); + furi_check( + furi_message_queue_put(bt->message_queue, &message, FuriWaitForever) == FuriStatusOk); ret = true; } else if(event.type == GapEventTypeDisconnected) { if(bt->profile == BtProfileSerial && bt->rpc_session) { FURI_LOG_I(TAG, "Close RPC connection"); - osEventFlagsSet(bt->rpc_event, BT_RPC_EVENT_DISCONNECTED); + furi_event_flag_set(bt->rpc_event, BT_RPC_EVENT_DISCONNECTED); rpc_session_close(bt->rpc_session); furi_hal_bt_serial_set_event_callback(0, NULL, NULL); bt->rpc_session = NULL; @@ -246,17 +250,20 @@ static bool bt_on_gap_event_callback(GapEvent event, void* context) { } else if(event.type == GapEventTypeStartAdvertising) { bt->status = BtStatusAdvertising; BtMessage message = {.type = BtMessageTypeUpdateStatus}; - furi_check(osMessageQueuePut(bt->message_queue, &message, 0, osWaitForever) == osOK); + furi_check( + furi_message_queue_put(bt->message_queue, &message, FuriWaitForever) == FuriStatusOk); ret = true; } else if(event.type == GapEventTypeStopAdvertising) { bt->status = BtStatusOff; BtMessage message = {.type = BtMessageTypeUpdateStatus}; - furi_check(osMessageQueuePut(bt->message_queue, &message, 0, osWaitForever) == osOK); + furi_check( + furi_message_queue_put(bt->message_queue, &message, FuriWaitForever) == FuriStatusOk); ret = true; } else if(event.type == GapEventTypePinCodeShow) { BtMessage message = { .type = BtMessageTypePinCodeShow, .data.pin_code = event.data.pin_code}; - furi_check(osMessageQueuePut(bt->message_queue, &message, 0, osWaitForever) == osOK); + furi_check( + furi_message_queue_put(bt->message_queue, &message, FuriWaitForever) == FuriStatusOk); ret = true; } else if(event.type == GapEventTypePinCodeVerify) { ret = bt_pin_code_verify_event_handler(bt, event.data.pin_code); @@ -272,7 +279,8 @@ static void bt_on_key_storage_change_callback(uint8_t* addr, uint16_t size, void Bt* bt = context; FURI_LOG_I(TAG, "Changed addr start: %08lX, size changed: %d", addr, size); BtMessage message = {.type = BtMessageTypeKeysStorageUpdated}; - furi_check(osMessageQueuePut(bt->message_queue, &message, 0, osWaitForever) == osOK); + furi_check( + furi_message_queue_put(bt->message_queue, &message, FuriWaitForever) == FuriStatusOk); } static void bt_statusbar_update(Bt* bt) { @@ -296,7 +304,7 @@ static void bt_show_warning(Bt* bt, const char* text) { static void bt_close_rpc_connection(Bt* bt) { if(bt->profile == BtProfileSerial && bt->rpc_session) { FURI_LOG_I(TAG, "Close RPC connection"); - osEventFlagsSet(bt->rpc_event, BT_RPC_EVENT_DISCONNECTED); + furi_event_flag_set(bt->rpc_event, BT_RPC_EVENT_DISCONNECTED); rpc_session_close(bt->rpc_session); furi_hal_bt_serial_set_event_callback(0, NULL, NULL); bt->rpc_session = NULL; @@ -331,12 +339,12 @@ static void bt_change_profile(Bt* bt, BtMessage* message) { bt_show_warning(bt, "Radio stack doesn't support this app"); *message->result = false; } - osEventFlagsSet(bt->api_event, BT_API_UNLOCK_EVENT); + furi_event_flag_set(bt->api_event, BT_API_UNLOCK_EVENT); } static void bt_close_connection(Bt* bt) { bt_close_rpc_connection(bt); - osEventFlagsSet(bt->api_event, BT_API_UNLOCK_EVENT); + furi_event_flag_set(bt->api_event, BT_API_UNLOCK_EVENT); } int32_t bt_srv() { @@ -377,7 +385,8 @@ int32_t bt_srv() { BtMessage message; while(1) { - furi_check(osMessageQueueGet(bt->message_queue, &message, NULL, osWaitForever) == osOK); + furi_check( + furi_message_queue_get(bt->message_queue, &message, FuriWaitForever) == FuriStatusOk); if(message.type == BtMessageTypeUpdateStatus) { // Update view ports bt_statusbar_update(bt); diff --git a/applications/bt/bt_service/bt_api.c b/applications/bt/bt_service/bt_api.c old mode 100755 new mode 100644 index 884ec4a9..3de896d5 --- a/applications/bt/bt_service/bt_api.c +++ b/applications/bt/bt_service/bt_api.c @@ -7,9 +7,10 @@ bool bt_set_profile(Bt* bt, BtProfile profile) { bool result = false; BtMessage message = { .type = BtMessageTypeSetProfile, .data.profile = profile, .result = &result}; - furi_check(osMessageQueuePut(bt->message_queue, &message, 0, osWaitForever) == osOK); + furi_check( + furi_message_queue_put(bt->message_queue, &message, FuriWaitForever) == FuriStatusOk); // Wait for unlock - osEventFlagsWait(bt->api_event, BT_API_UNLOCK_EVENT, osFlagsWaitAny, osWaitForever); + furi_event_flag_wait(bt->api_event, BT_API_UNLOCK_EVENT, FuriFlagWaitAny, FuriWaitForever); return result; } @@ -19,9 +20,10 @@ void bt_disconnect(Bt* bt) { // Send message BtMessage message = {.type = BtMessageTypeDisconnect}; - furi_check(osMessageQueuePut(bt->message_queue, &message, 0, osWaitForever) == osOK); + furi_check( + furi_message_queue_put(bt->message_queue, &message, FuriWaitForever) == FuriStatusOk); // Wait for unlock - osEventFlagsWait(bt->api_event, BT_API_UNLOCK_EVENT, osFlagsWaitAny, osWaitForever); + furi_event_flag_wait(bt->api_event, BT_API_UNLOCK_EVENT, FuriFlagWaitAny, FuriWaitForever); } void bt_set_status_changed_callback(Bt* bt, BtStatusChangedCallback callback, void* context) { @@ -34,5 +36,6 @@ void bt_set_status_changed_callback(Bt* bt, BtStatusChangedCallback callback, vo void bt_forget_bonded_devices(Bt* bt) { furi_assert(bt); BtMessage message = {.type = BtMessageTypeForgetBondedDevices}; - furi_check(osMessageQueuePut(bt->message_queue, &message, 0, osWaitForever) == osOK); + furi_check( + furi_message_queue_put(bt->message_queue, &message, FuriWaitForever) == FuriStatusOk); } diff --git a/applications/bt/bt_service/bt_i.h b/applications/bt/bt_service/bt_i.h index 90ee0851..a45a36c9 100644 --- a/applications/bt/bt_service/bt_i.h +++ b/applications/bt/bt_service/bt_i.h @@ -48,7 +48,7 @@ struct Bt { BtSettings bt_settings; BtStatus status; BtProfile profile; - osMessageQueueId_t message_queue; + FuriMessageQueue* message_queue; NotificationApp* notification; Gui* gui; ViewPort* statusbar_view_port; @@ -59,8 +59,8 @@ struct Bt { Power* power; Rpc* rpc; RpcSession* rpc_session; - osEventFlagsId_t rpc_event; - osEventFlagsId_t api_event; + FuriEventFlag* rpc_event; + FuriEventFlag* api_event; BtStatusChangedCallback status_changed_cb; void* status_changed_ctx; }; diff --git a/applications/cli/cli.c b/applications/cli/cli.c index 35baad7e..a0b239d3 100644 --- a/applications/cli/cli.c +++ b/applications/cli/cli.c @@ -16,10 +16,10 @@ Cli* cli_alloc() { cli->session = NULL; - cli->mutex = osMutexNew(NULL); + cli->mutex = furi_mutex_alloc(FuriMutexTypeNormal); furi_check(cli->mutex); - cli->idle_sem = osSemaphoreNew(1, 0, NULL); + cli->idle_sem = furi_semaphore_alloc(1, 0); return cli; } @@ -35,7 +35,7 @@ char cli_getc(Cli* cli) { furi_assert(cli); char c = 0; if(cli->session != NULL) { - if(cli->session->rx((uint8_t*)&c, 1, osWaitForever) == 0) { + if(cli->session->rx((uint8_t*)&c, 1, FuriWaitForever) == 0) { cli_reset(cli); } } else { @@ -54,7 +54,7 @@ void cli_write(Cli* cli, const uint8_t* buffer, size_t size) { size_t cli_read(Cli* cli, uint8_t* buffer, size_t size) { furi_assert(cli); if(cli->session != NULL) { - return cli->session->rx(buffer, size, osWaitForever); + return cli->session->rx(buffer, size, FuriWaitForever); } else { return 0; } @@ -228,17 +228,17 @@ static void cli_handle_enter(Cli* cli) { } // Search for command - furi_check(osMutexAcquire(cli->mutex, osWaitForever) == osOK); + furi_check(furi_mutex_acquire(cli->mutex, FuriWaitForever) == FuriStatusOk); CliCommand* cli_command_ptr = CliCommandTree_get(cli->commands, command); if(cli_command_ptr) { CliCommand cli_command; memcpy(&cli_command, cli_command_ptr, sizeof(CliCommand)); - furi_check(osMutexRelease(cli->mutex) == osOK); + furi_check(furi_mutex_release(cli->mutex) == FuriStatusOk); cli_nl(cli); cli_execute_command(cli, &cli_command, args); } else { - furi_check(osMutexRelease(cli->mutex) == osOK); + furi_check(furi_mutex_release(cli->mutex) == FuriStatusOk); cli_nl(cli); printf( "`%s` command not found, use `help` or `?` to list all available commands", @@ -339,7 +339,7 @@ void cli_process_input(Cli* cli) { if(in_chr == CliSymbolAsciiTab) { cli_handle_autocomplete(cli); } else if(in_chr == CliSymbolAsciiSOH) { - osDelay(33); // We are too fast, Minicom is not ready yet + furi_delay_ms(33); // We are too fast, Minicom is not ready yet cli_motd(); cli_prompt(cli); } else if(in_chr == CliSymbolAsciiETX) { @@ -406,9 +406,9 @@ void cli_add_command( c.context = context; c.flags = flags; - furi_check(osMutexAcquire(cli->mutex, osWaitForever) == osOK); + furi_check(furi_mutex_acquire(cli->mutex, FuriWaitForever) == FuriStatusOk); CliCommandTree_set_at(cli->commands, name_str, c); - furi_check(osMutexRelease(cli->mutex) == osOK); + furi_check(furi_mutex_release(cli->mutex) == FuriStatusOk); string_clear(name_str); } @@ -423,9 +423,9 @@ void cli_delete_command(Cli* cli, const char* name) { name_replace = string_replace_str(name_str, " ", "_"); } while(name_replace != STRING_FAILURE); - furi_check(osMutexAcquire(cli->mutex, osWaitForever) == osOK); + furi_check(furi_mutex_acquire(cli->mutex, FuriWaitForever) == FuriStatusOk); CliCommandTree_erase(cli->commands, name_str); - furi_check(osMutexRelease(cli->mutex) == osOK); + furi_check(furi_mutex_release(cli->mutex) == FuriStatusOk); string_clear(name_str); } @@ -433,7 +433,7 @@ void cli_delete_command(Cli* cli, const char* name) { void cli_session_open(Cli* cli, void* session) { furi_assert(cli); - furi_check(osMutexAcquire(cli->mutex, osWaitForever) == osOK); + furi_check(furi_mutex_acquire(cli->mutex, FuriWaitForever) == FuriStatusOk); cli->session = session; if(cli->session != NULL) { cli->session->init(); @@ -441,20 +441,20 @@ void cli_session_open(Cli* cli, void* session) { } else { furi_stdglue_set_thread_stdout_callback(NULL); } - osSemaphoreRelease(cli->idle_sem); - furi_check(osMutexRelease(cli->mutex) == osOK); + furi_semaphore_release(cli->idle_sem); + furi_check(furi_mutex_release(cli->mutex) == FuriStatusOk); } void cli_session_close(Cli* cli) { furi_assert(cli); - furi_check(osMutexAcquire(cli->mutex, osWaitForever) == osOK); + furi_check(furi_mutex_acquire(cli->mutex, FuriWaitForever) == FuriStatusOk); if(cli->session != NULL) { cli->session->deinit(); } cli->session = NULL; furi_stdglue_set_thread_stdout_callback(NULL); - furi_check(osMutexRelease(cli->mutex) == osOK); + furi_check(furi_mutex_release(cli->mutex) == FuriStatusOk); } int32_t cli_srv(void* p) { @@ -482,7 +482,7 @@ int32_t cli_srv(void* p) { if(cli->session != NULL) { cli_process_input(cli); } else { - furi_check(osSemaphoreAcquire(cli->idle_sem, osWaitForever) == osOK); + furi_check(furi_semaphore_acquire(cli->idle_sem, FuriWaitForever) == FuriStatusOk); } } diff --git a/applications/cli/cli_i.h b/applications/cli/cli_i.h index feb3bcb7..076dd75e 100755 --- a/applications/cli/cli_i.h +++ b/applications/cli/cli_i.h @@ -41,8 +41,8 @@ BPTREE_DEF2( struct Cli { CliCommandTree_t commands; - osMutexId_t mutex; - osSemaphoreId_t idle_sem; + FuriMutex* mutex; + FuriSemaphore* idle_sem; string_t last_line; string_t line; CliSession* session; diff --git a/applications/cli/cli_vcp.c b/applications/cli/cli_vcp.c index 332dd7cb..5d66b8f8 100644 --- a/applications/cli/cli_vcp.c +++ b/applications/cli/cli_vcp.c @@ -103,8 +103,8 @@ static int32_t vcp_worker(void* context) { while(1) { uint32_t flags = - furi_thread_flags_wait(VCP_THREAD_FLAG_ALL, osFlagsWaitAny, osWaitForever); - furi_assert((flags & osFlagsError) == 0); + furi_thread_flags_wait(VCP_THREAD_FLAG_ALL, FuriFlagWaitAny, FuriWaitForever); + furi_assert((flags & FuriFlagError) == 0); // VCP session opened if(flags & VcpEvtConnect) { @@ -113,7 +113,7 @@ static int32_t vcp_worker(void* context) { #endif if(vcp->connected == false) { vcp->connected = true; - xStreamBufferSend(vcp->rx_stream, &ascii_soh, 1, osWaitForever); + xStreamBufferSend(vcp->rx_stream, &ascii_soh, 1, FuriWaitForever); } } @@ -125,7 +125,7 @@ static int32_t vcp_worker(void* context) { if(vcp->connected == true) { vcp->connected = false; xStreamBufferReceive(vcp->tx_stream, vcp->data_buffer, USB_CDC_PKT_LEN, 0); - xStreamBufferSend(vcp->rx_stream, &ascii_eot, 1, osWaitForever); + xStreamBufferSend(vcp->rx_stream, &ascii_eot, 1, FuriWaitForever); } } @@ -149,7 +149,7 @@ static int32_t vcp_worker(void* context) { #endif if(len > 0) { furi_check( - xStreamBufferSend(vcp->rx_stream, vcp->data_buffer, len, osWaitForever) == + xStreamBufferSend(vcp->rx_stream, vcp->data_buffer, len, FuriWaitForever) == (size_t)len); } } else { @@ -203,7 +203,7 @@ static int32_t vcp_worker(void* context) { furi_hal_usb_set_config(vcp->usb_if_prev, NULL); } xStreamBufferReceive(vcp->tx_stream, vcp->data_buffer, USB_CDC_PKT_LEN, 0); - xStreamBufferSend(vcp->rx_stream, &ascii_eot, 1, osWaitForever); + xStreamBufferSend(vcp->rx_stream, &ascii_eot, 1, FuriWaitForever); break; } } @@ -262,7 +262,7 @@ static void cli_vcp_tx(const uint8_t* buffer, size_t size) { size_t batch_size = size; if(batch_size > USB_CDC_PKT_LEN) batch_size = USB_CDC_PKT_LEN; - xStreamBufferSend(vcp->tx_stream, buffer, batch_size, osWaitForever); + xStreamBufferSend(vcp->tx_stream, buffer, batch_size, FuriWaitForever); furi_thread_flags_set(furi_thread_get_id(vcp->thread), VcpEvtStreamTx); #ifdef CLI_VCP_DEBUG FURI_LOG_D(TAG, "tx %u", batch_size); @@ -304,7 +304,7 @@ static void vcp_on_cdc_control_line(void* context, uint8_t state) { static void vcp_on_cdc_rx(void* context) { UNUSED(context); uint32_t ret = furi_thread_flags_set(furi_thread_get_id(vcp->thread), VcpEvtRx); - furi_check((ret & osFlagsError) == 0); + furi_check((ret & FuriFlagError) == 0); } static void vcp_on_cdc_tx_complete(void* context) { diff --git a/applications/debug_tools/blink_test.c b/applications/debug_tools/blink_test.c index 68139a43..3870c11e 100644 --- a/applications/debug_tools/blink_test.c +++ b/applications/debug_tools/blink_test.c @@ -1,4 +1,4 @@ -#include "furi/common_defines.h" +#include #include #include @@ -55,10 +55,10 @@ static const NotificationSequence* blink_test_colors[] = { static void blink_test_update(void* ctx) { furi_assert(ctx); - osMessageQueueId_t event_queue = ctx; + FuriMessageQueue* event_queue = ctx; BlinkEvent event = {.type = BlinkEventTypeTick}; // It's OK to loose this event if system overloaded - osMessageQueuePut(event_queue, &event, 0, 0); + furi_message_queue_put(event_queue, &event, 0); } static void blink_test_draw_callback(Canvas* canvas, void* ctx) { @@ -70,22 +70,22 @@ static void blink_test_draw_callback(Canvas* canvas, void* ctx) { static void blink_test_input_callback(InputEvent* input_event, void* ctx) { furi_assert(ctx); - osMessageQueueId_t event_queue = ctx; + FuriMessageQueue* event_queue = ctx; BlinkEvent event = {.type = BlinkEventTypeInput, .input = *input_event}; - osMessageQueuePut(event_queue, &event, 0, osWaitForever); + furi_message_queue_put(event_queue, &event, FuriWaitForever); } int32_t blink_test_app(void* p) { UNUSED(p); - osMessageQueueId_t event_queue = osMessageQueueNew(8, sizeof(BlinkEvent), NULL); + FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(BlinkEvent)); // Configure view port ViewPort* view_port = view_port_alloc(); view_port_draw_callback_set(view_port, blink_test_draw_callback, NULL); view_port_input_callback_set(view_port, blink_test_input_callback, event_queue); - osTimerId_t timer = osTimerNew(blink_test_update, osTimerPeriodic, event_queue, NULL); - osTimerStart(timer, osKernelGetTickFreq()); + FuriTimer* timer = furi_timer_alloc(blink_test_update, FuriTimerTypePeriodic, event_queue); + furi_timer_start(timer, furi_kernel_get_tick_frequency()); // Register view port in GUI Gui* gui = furi_record_open("gui"); @@ -97,7 +97,7 @@ int32_t blink_test_app(void* p) { BlinkEvent event; while(1) { - furi_check(osMessageQueueGet(event_queue, &event, NULL, osWaitForever) == osOK); + furi_check(furi_message_queue_get(event_queue, &event, FuriWaitForever) == FuriStatusOk); if(event.type == BlinkEventTypeInput) { if((event.input.type == InputTypeShort) && (event.input.key == InputKeyBack)) { break; @@ -113,11 +113,11 @@ int32_t blink_test_app(void* p) { notification_message(notifications, &blink_test_sequence_hw_blink_stop); - osTimerDelete(timer); + furi_timer_free(timer); gui_remove_view_port(gui, view_port); view_port_free(view_port); - osMessageQueueDelete(event_queue); + furi_message_queue_free(event_queue); furi_record_close("notification"); furi_record_close("gui"); diff --git a/applications/debug_tools/display_test/view_display_test.c b/applications/debug_tools/display_test/view_display_test.c index 133195d0..f00fe009 100644 --- a/applications/debug_tools/display_test/view_display_test.c +++ b/applications/debug_tools/display_test/view_display_test.c @@ -9,7 +9,7 @@ typedef struct { struct ViewDisplayTest { View* view; - osTimerId_t timer; + FuriTimer* timer; }; static void view_display_test_draw_callback_intro(Canvas* canvas, void* _model) { @@ -138,12 +138,12 @@ static bool view_display_test_input_callback(InputEvent* event, void* context) { static void view_display_test_enter(void* context) { ViewDisplayTest* instance = context; - osTimerStart(instance->timer, osKernelGetTickFreq() / 32); + furi_timer_start(instance->timer, furi_kernel_get_tick_frequency() / 32); } static void view_display_test_exit(void* context) { ViewDisplayTest* instance = context; - osTimerStop(instance->timer); + furi_timer_stop(instance->timer); } static void view_display_test_timer_callback(void* context) { @@ -167,7 +167,7 @@ ViewDisplayTest* view_display_test_alloc() { view_set_exit_callback(instance->view, view_display_test_exit); instance->timer = - osTimerNew(view_display_test_timer_callback, osTimerPeriodic, instance, NULL); + furi_timer_alloc(view_display_test_timer_callback, FuriTimerTypePeriodic, instance); return instance; } @@ -175,7 +175,7 @@ ViewDisplayTest* view_display_test_alloc() { void view_display_test_free(ViewDisplayTest* instance) { furi_assert(instance); - osTimerDelete(instance->timer); + furi_timer_free(instance->timer); view_free(instance->view); free(instance); } diff --git a/applications/debug_tools/file_browser_test/scenes/file_browser_scene_browser.c b/applications/debug_tools/file_browser_test/scenes/file_browser_scene_browser.c index ca16ad0d..d9bd1ac5 100644 --- a/applications/debug_tools/file_browser_test/scenes/file_browser_scene_browser.c +++ b/applications/debug_tools/file_browser_test/scenes/file_browser_scene_browser.c @@ -1,6 +1,6 @@ #include "../file_browser_app_i.h" -#include "furi/check.h" -#include "furi/log.h" +#include +#include #include "furi_hal.h" #include "m-string.h" diff --git a/applications/debug_tools/keypad_test.c b/applications/debug_tools/keypad_test.c index 705a1542..9a6e7f25 100644 --- a/applications/debug_tools/keypad_test.c +++ b/applications/debug_tools/keypad_test.c @@ -55,13 +55,13 @@ static void keypad_test_render_callback(Canvas* canvas, void* ctx) { } static void keypad_test_input_callback(InputEvent* input_event, void* ctx) { - osMessageQueueId_t event_queue = ctx; - osMessageQueuePut(event_queue, input_event, 0, osWaitForever); + FuriMessageQueue* event_queue = ctx; + furi_message_queue_put(event_queue, input_event, FuriWaitForever); } int32_t keypad_test_app(void* p) { UNUSED(p); - osMessageQueueId_t event_queue = osMessageQueueNew(32, sizeof(InputEvent), NULL); + FuriMessageQueue* event_queue = furi_message_queue_alloc(32, sizeof(InputEvent)); furi_check(event_queue); KeypadTestState _state = {{false, false, false, false, false}, 0, 0, 0, 0, 0}; @@ -82,7 +82,7 @@ int32_t keypad_test_app(void* p) { gui_add_view_port(gui, view_port, GuiLayerFullscreen); InputEvent event; - while(osMessageQueueGet(event_queue, &event, NULL, osWaitForever) == osOK) { + while(furi_message_queue_get(event_queue, &event, FuriWaitForever) == FuriStatusOk) { KeypadTestState* state = (KeypadTestState*)acquire_mutex_block(&state_mutex); FURI_LOG_I( TAG, @@ -146,7 +146,7 @@ int32_t keypad_test_app(void* p) { // remove & free all stuff created by app gui_remove_view_port(gui, view_port); view_port_free(view_port); - osMessageQueueDelete(event_queue); + furi_message_queue_free(event_queue); delete_mutex(&state_mutex); furi_record_close("gui"); diff --git a/applications/debug_tools/text_box_test.c b/applications/debug_tools/text_box_test.c index bc56e88b..837c34b6 100644 --- a/applications/debug_tools/text_box_test.c +++ b/applications/debug_tools/text_box_test.c @@ -65,13 +65,13 @@ static void text_box_test_render_callback(Canvas* canvas, void* ctx) { } static void text_box_test_input_callback(InputEvent* input_event, void* ctx) { - osMessageQueueId_t event_queue = ctx; - osMessageQueuePut(event_queue, input_event, 0, osWaitForever); + FuriMessageQueue* event_queue = ctx; + furi_message_queue_put(event_queue, input_event, FuriWaitForever); } int32_t text_box_test_app(void* p) { UNUSED(p); - osMessageQueueId_t event_queue = osMessageQueueNew(32, sizeof(InputEvent), NULL); + FuriMessageQueue* event_queue = furi_message_queue_alloc(32, sizeof(InputEvent)); furi_check(event_queue); TextBoxTestState _state = {.idx = 0}; @@ -93,7 +93,7 @@ int32_t text_box_test_app(void* p) { uint32_t test_renders_num = COUNT_OF(text_box_test_render); InputEvent event; - while(osMessageQueueGet(event_queue, &event, NULL, osWaitForever) == osOK) { + while(furi_message_queue_get(event_queue, &event, FuriWaitForever) == FuriStatusOk) { TextBoxTestState* state = acquire_mutex_block(&state_mutex); if(event.type == InputTypeShort) { @@ -118,7 +118,7 @@ int32_t text_box_test_app(void* p) { // remove & free all stuff created by app gui_remove_view_port(gui, view_port); view_port_free(view_port); - osMessageQueueDelete(event_queue); + furi_message_queue_free(event_queue); delete_mutex(&state_mutex); furi_record_close("gui"); diff --git a/applications/debug_tools/uart_echo.c b/applications/debug_tools/uart_echo.c index 213769a5..8f795c56 100644 --- a/applications/debug_tools/uart_echo.c +++ b/applications/debug_tools/uart_echo.c @@ -150,8 +150,8 @@ static int32_t uart_echo_worker(void* context) { while(1) { uint32_t events = - furi_thread_flags_wait(WORKER_EVENTS_MASK, osFlagsWaitAny, osWaitForever); - furi_check((events & osFlagsError) == 0); + furi_thread_flags_wait(WORKER_EVENTS_MASK, FuriFlagWaitAny, FuriWaitForever); + furi_check((events & FuriFlagError) == 0); if(events & WorkerEventStop) break; if(events & WorkerEventRx) { diff --git a/applications/debug_tools/usb_mouse.c b/applications/debug_tools/usb_mouse.c index a136375a..3174ccae 100644 --- a/applications/debug_tools/usb_mouse.c +++ b/applications/debug_tools/usb_mouse.c @@ -29,17 +29,17 @@ static void usb_mouse_render_callback(Canvas* canvas, void* ctx) { } static void usb_mouse_input_callback(InputEvent* input_event, void* ctx) { - osMessageQueueId_t event_queue = ctx; + FuriMessageQueue* event_queue = ctx; UsbMouseEvent event; event.type = EventTypeInput; event.input = *input_event; - osMessageQueuePut(event_queue, &event, 0, osWaitForever); + furi_message_queue_put(event_queue, &event, FuriWaitForever); } int32_t usb_mouse_app(void* p) { UNUSED(p); - osMessageQueueId_t event_queue = osMessageQueueNew(8, sizeof(UsbMouseEvent), NULL); + FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(UsbMouseEvent)); furi_check(event_queue); ViewPort* view_port = view_port_alloc(); @@ -56,9 +56,9 @@ int32_t usb_mouse_app(void* p) { UsbMouseEvent event; while(1) { - osStatus_t event_status = osMessageQueueGet(event_queue, &event, NULL, osWaitForever); + FuriStatus event_status = furi_message_queue_get(event_queue, &event, FuriWaitForever); - if(event_status == osOK) { + if(event_status == FuriStatusOk) { if(event.type == EventTypeInput) { if(event.input.type == InputTypeLong && event.input.key == InputKeyBack) { break; @@ -118,7 +118,7 @@ int32_t usb_mouse_app(void* p) { // remove & free all stuff created by app gui_remove_view_port(gui, view_port); view_port_free(view_port); - osMessageQueueDelete(event_queue); + furi_message_queue_free(event_queue); return 0; } diff --git a/applications/debug_tools/vibro_test.c b/applications/debug_tools/vibro_test.c index af6d336d..dbd35d60 100644 --- a/applications/debug_tools/vibro_test.c +++ b/applications/debug_tools/vibro_test.c @@ -18,13 +18,13 @@ void vibro_test_draw_callback(Canvas* canvas, void* ctx) { void vibro_test_input_callback(InputEvent* input_event, void* ctx) { furi_assert(ctx); - osMessageQueueId_t event_queue = ctx; - osMessageQueuePut(event_queue, input_event, 0, osWaitForever); + FuriMessageQueue* event_queue = ctx; + furi_message_queue_put(event_queue, input_event, FuriWaitForever); } int32_t vibro_test_app(void* p) { UNUSED(p); - osMessageQueueId_t event_queue = osMessageQueueNew(8, sizeof(InputEvent), NULL); + FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(InputEvent)); // Configure view port ViewPort* view_port = view_port_alloc(); @@ -39,7 +39,7 @@ int32_t vibro_test_app(void* p) { InputEvent event; - while(osMessageQueueGet(event_queue, &event, NULL, osWaitForever) == osOK) { + while(furi_message_queue_get(event_queue, &event, FuriWaitForever) == FuriStatusOk) { if(event.type == InputTypeShort && event.key == InputKeyBack) { notification_message(notification, &sequence_reset_vibro); notification_message(notification, &sequence_reset_green); @@ -58,7 +58,7 @@ int32_t vibro_test_app(void* p) { gui_remove_view_port(gui, view_port); view_port_free(view_port); - osMessageQueueDelete(event_queue); + furi_message_queue_free(event_queue); furi_record_close("notification"); furi_record_close("gui"); diff --git a/applications/desktop/animations/animation_manager.c b/applications/desktop/animations/animation_manager.c index 75d45ef7..9b702811 100644 --- a/applications/desktop/animations/animation_manager.c +++ b/applications/desktop/animations/animation_manager.c @@ -44,7 +44,7 @@ struct AnimationManager { FuriPubSubSubscription* pubsub_subscription_dolphin; BubbleAnimationView* animation_view; OneShotView* one_shot_view; - osTimerId_t idle_animation_timer; + FuriTimer* idle_animation_timer; StorageAnimation* current_animation; AnimationManagerInteractCallback interact_callback; AnimationManagerSetNewIdleAnimationCallback new_idle_callback; @@ -198,7 +198,7 @@ static void animation_manager_start_new_idle(AnimationManager* animation_manager const BubbleAnimation* bubble_animation = animation_storage_get_bubble_animation(animation_manager->current_animation); animation_manager->state = AnimationManagerStateIdle; - osTimerStart(animation_manager->idle_animation_timer, bubble_animation->duration * 1000); + furi_timer_start(animation_manager->idle_animation_timer, bubble_animation->duration * 1000); } static bool animation_manager_check_blocking(AnimationManager* animation_manager) { @@ -246,7 +246,7 @@ static bool animation_manager_check_blocking(AnimationManager* animation_manager } if(blocking_animation) { - osTimerStop(animation_manager->idle_animation_timer); + furi_timer_stop(animation_manager->idle_animation_timer); animation_manager_replace_current_animation(animation_manager, blocking_animation); /* no timer starting because this is blocking animation */ animation_manager->state = AnimationManagerStateBlocked; @@ -283,7 +283,7 @@ AnimationManager* animation_manager_alloc(void) { string_init(animation_manager->freezed_animation_name); animation_manager->idle_animation_timer = - osTimerNew(animation_manager_timer_callback, osTimerOnce, animation_manager, NULL); + furi_timer_alloc(animation_manager_timer_callback, FuriTimerTypeOnce, animation_manager); bubble_animation_view_set_interact_callback( animation_manager->animation_view, animation_manager_interact_callback, animation_manager); @@ -322,7 +322,7 @@ void animation_manager_free(AnimationManager* animation_manager) { View* animation_view = bubble_animation_get_view(animation_manager->animation_view); view_stack_remove_view(animation_manager->view_stack, animation_view); bubble_animation_view_free(animation_manager->animation_view); - osTimerDelete(animation_manager->idle_animation_timer); + furi_timer_free(animation_manager->idle_animation_timer); } View* animation_manager_get_animation_view(AnimationManager* animation_manager) { @@ -449,7 +449,7 @@ void animation_manager_unload_and_stall_animation(AnimationManager* animation_ma if(animation_manager->freezed_animation_time_left < 0) { animation_manager->freezed_animation_time_left = 0; } - osTimerStop(animation_manager->idle_animation_timer); + furi_timer_stop(animation_manager->idle_animation_timer); } else { furi_assert(0); } @@ -504,13 +504,13 @@ void animation_manager_load_and_continue_animation(AnimationManager* animation_m animation_manager->state = AnimationManagerStateIdle; if(animation_manager->freezed_animation_time_left) { - osTimerStart( + furi_timer_start( animation_manager->idle_animation_timer, animation_manager->freezed_animation_time_left); } else { const BubbleAnimation* animation = animation_storage_get_bubble_animation( animation_manager->current_animation); - osTimerStart( + furi_timer_start( animation_manager->idle_animation_timer, animation->duration * 1000); } } diff --git a/applications/desktop/animations/animation_storage.c b/applications/desktop/animations/animation_storage.c index 8f2740a7..36b20bc8 100644 --- a/applications/desktop/animations/animation_storage.c +++ b/applications/desktop/animations/animation_storage.c @@ -2,7 +2,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/applications/desktop/animations/views/bubble_animation_view.c b/applications/desktop/animations/views/bubble_animation_view.c index 380664c8..54a686fb 100644 --- a/applications/desktop/animations/views/bubble_animation_view.c +++ b/applications/desktop/animations/views/bubble_animation_view.c @@ -11,9 +11,7 @@ #include #include #include -#include -#include -#include +#include #define ACTIVE_SHIFT 2 @@ -31,7 +29,7 @@ typedef struct { struct BubbleAnimationView { View* view; - osTimerId_t timer; + FuriTimer* timer; BubbleAnimationInteractCallback interact_callback; void* interact_callback_context; }; @@ -192,7 +190,7 @@ static void bubble_animation_activate_right_now(BubbleAnimationView* view) { view_commit_model(view->view, true); if(frame_rate) { - osTimerStart(view->timer, 1000 / frame_rate); + furi_timer_start(view->timer, 1000 / frame_rate); } } @@ -294,21 +292,21 @@ static void bubble_animation_enter(void* context) { view_commit_model(view->view, false); if(frame_rate) { - osTimerStart(view->timer, 1000 / frame_rate); + furi_timer_start(view->timer, 1000 / frame_rate); } } static void bubble_animation_exit(void* context) { furi_assert(context); BubbleAnimationView* view = context; - osTimerStop(view->timer); + furi_timer_stop(view->timer); } BubbleAnimationView* bubble_animation_view_alloc(void) { BubbleAnimationView* view = malloc(sizeof(BubbleAnimationView)); view->view = view_alloc(); view->interact_callback = NULL; - view->timer = osTimerNew(bubble_animation_timer_callback, osTimerPeriodic, view, NULL); + view->timer = furi_timer_alloc(bubble_animation_timer_callback, FuriTimerTypePeriodic, view); view_allocate_model(view->view, ViewModelTypeLocking, sizeof(BubbleAnimationViewModel)); view_set_context(view->view, view); @@ -369,7 +367,7 @@ void bubble_animation_view_set_animation( model->active_cycle = 0; view_commit_model(view->view, true); - osTimerStart(view->timer, 1000 / new_animation->icon_animation.frame_rate); + furi_timer_start(view->timer, 1000 / new_animation->icon_animation.frame_rate); } void bubble_animation_freeze(BubbleAnimationView* view) { @@ -381,7 +379,7 @@ void bubble_animation_freeze(BubbleAnimationView* view) { model->freeze_frame = bubble_animation_clone_first_frame(&model->current->icon_animation); model->current = NULL; view_commit_model(view->view, false); - osTimerStop(view->timer); + furi_timer_stop(view->timer); } void bubble_animation_unfreeze(BubbleAnimationView* view) { @@ -395,7 +393,7 @@ void bubble_animation_unfreeze(BubbleAnimationView* view) { frame_rate = model->current->icon_animation.frame_rate; view_commit_model(view->view, true); - osTimerStart(view->timer, 1000 / frame_rate); + furi_timer_start(view->timer, 1000 / frame_rate); bubble_animation_activate(view, false); } diff --git a/applications/desktop/desktop.c b/applications/desktop/desktop.c index 52091753..83b4f0f3 100644 --- a/applications/desktop/desktop.c +++ b/applications/desktop/desktop.c @@ -93,12 +93,12 @@ static void desktop_auto_lock_timer_callback(void* context) { } static void desktop_start_auto_lock_timer(Desktop* desktop) { - osTimerStart( - desktop->auto_lock_timer, furi_hal_ms_to_ticks(desktop->settings.auto_lock_delay_ms)); + furi_timer_start( + desktop->auto_lock_timer, furi_ms_to_ticks(desktop->settings.auto_lock_delay_ms)); } static void desktop_stop_auto_lock_timer(Desktop* desktop) { - osTimerStop(desktop->auto_lock_timer); + furi_timer_stop(desktop->auto_lock_timer); } static void desktop_auto_lock_arm(Desktop* desktop) { @@ -232,7 +232,7 @@ Desktop* desktop_alloc() { desktop->input_events_subscription = NULL; desktop->auto_lock_timer = - osTimerNew(desktop_auto_lock_timer_callback, osTimerOnce, desktop, NULL); + furi_timer_alloc(desktop_auto_lock_timer_callback, FuriTimerTypeOnce, desktop); return desktop; } @@ -283,7 +283,7 @@ void desktop_free(Desktop* desktop) { furi_record_close("menu"); - osTimerDelete(desktop->auto_lock_timer); + furi_timer_free(desktop->auto_lock_timer); free(desktop); } diff --git a/applications/desktop/desktop_i.h b/applications/desktop/desktop_i.h index 8dc92e84..0b5d607d 100644 --- a/applications/desktop/desktop_i.h +++ b/applications/desktop/desktop_i.h @@ -67,7 +67,7 @@ struct Desktop { FuriPubSubSubscription* app_start_stop_subscription; FuriPubSub* input_events_pubsub; FuriPubSubSubscription* input_events_subscription; - osTimerId_t auto_lock_timer; + FuriTimer* auto_lock_timer; }; Desktop* desktop_alloc(); diff --git a/applications/desktop/desktop_settings/scenes/desktop_settings_scene_pin_auth.c b/applications/desktop/desktop_settings/scenes/desktop_settings_scene_pin_auth.c index 54330c74..c43fff6a 100644 --- a/applications/desktop/desktop_settings/scenes/desktop_settings_scene_pin_auth.c +++ b/applications/desktop/desktop_settings/scenes/desktop_settings_scene_pin_auth.c @@ -1,5 +1,5 @@ #include -#include +#include #include #include "../../helpers/pin_lock.h" #include "../desktop_settings_app.h" diff --git a/applications/desktop/desktop_settings/scenes/desktop_settings_scene_pin_disable.c b/applications/desktop/desktop_settings/scenes/desktop_settings_scene_pin_disable.c index c0b3190e..f6f6b256 100644 --- a/applications/desktop/desktop_settings/scenes/desktop_settings_scene_pin_disable.c +++ b/applications/desktop/desktop_settings/scenes/desktop_settings_scene_pin_disable.c @@ -1,5 +1,5 @@ #include -#include +#include #include #include diff --git a/applications/desktop/desktop_settings/scenes/desktop_settings_scene_pin_error.c b/applications/desktop/desktop_settings/scenes/desktop_settings_scene_pin_error.c index a023d6b7..38852dd8 100644 --- a/applications/desktop/desktop_settings/scenes/desktop_settings_scene_pin_error.c +++ b/applications/desktop/desktop_settings/scenes/desktop_settings_scene_pin_error.c @@ -1,5 +1,5 @@ #include -#include +#include #include #include "desktop/desktop_settings/desktop_settings.h" diff --git a/applications/desktop/desktop_settings/scenes/desktop_settings_scene_pin_setup.c b/applications/desktop/desktop_settings/scenes/desktop_settings_scene_pin_setup.c index 282bf853..b536a343 100644 --- a/applications/desktop/desktop_settings/scenes/desktop_settings_scene_pin_setup.c +++ b/applications/desktop/desktop_settings/scenes/desktop_settings_scene_pin_setup.c @@ -1,5 +1,5 @@ #include -#include +#include #include #include "../desktop_settings_app.h" diff --git a/applications/desktop/helpers/slideshow.c b/applications/desktop/helpers/slideshow.c index 593b2854..4ec55a5a 100644 --- a/applications/desktop/helpers/slideshow.c +++ b/applications/desktop/helpers/slideshow.c @@ -4,7 +4,7 @@ #include #include #include -#include +#include #define SLIDESHOW_MAGIC 0x72676468 #define SLIDESHOW_MAX_SUPPORTED_VERSION 1 @@ -118,4 +118,4 @@ void slideshow_draw(Slideshow* slideshow, Canvas* canvas, uint8_t x, uint8_t y) slideshow->icon.width, slideshow->icon.height, slideshow->icon.frames[slideshow->current_frame]); -} \ No newline at end of file +} diff --git a/applications/desktop/scenes/desktop_scene_pin_input.c b/applications/desktop/scenes/desktop_scene_pin_input.c index dd5c8ce3..7d980a85 100644 --- a/applications/desktop/scenes/desktop_scene_pin_input.c +++ b/applications/desktop/scenes/desktop_scene_pin_input.c @@ -150,7 +150,7 @@ void desktop_scene_pin_input_on_exit(void* context) { desktop->scene_manager, DesktopScenePinInput); xTimerStop(state->timer, portMAX_DELAY); while(xTimerIsTimerActive(state->timer)) { - furi_hal_delay_ms(1); + furi_delay_tick(1); } xTimerDelete(state->timer, portMAX_DELAY); free(state); diff --git a/applications/desktop/views/desktop_view_locked.c b/applications/desktop/views/desktop_view_locked.c index 1245c152..58ed4fac 100644 --- a/applications/desktop/views/desktop_view_locked.c +++ b/applications/desktop/views/desktop_view_locked.c @@ -206,7 +206,7 @@ DesktopViewLocked* desktop_view_locked_alloc() { void desktop_view_locked_free(DesktopViewLocked* locked_view) { furi_assert(locked_view); - osTimerDelete(locked_view->timer); + furi_timer_free(locked_view->timer); view_free(locked_view->view); free(locked_view); } diff --git a/applications/desktop/views/desktop_view_main.c b/applications/desktop/views/desktop_view_main.c index ba944a9e..2b1d61f4 100644 --- a/applications/desktop/views/desktop_view_main.c +++ b/applications/desktop/views/desktop_view_main.c @@ -99,6 +99,6 @@ DesktopMainView* desktop_main_alloc() { void desktop_main_free(DesktopMainView* main_view) { furi_assert(main_view); view_free(main_view->view); - osTimerDelete(main_view->poweroff_timer); + furi_timer_free(main_view->poweroff_timer); free(main_view); } diff --git a/applications/desktop/views/desktop_view_pin_input.c b/applications/desktop/views/desktop_view_pin_input.c index 2b3b53aa..d6ce1a02 100644 --- a/applications/desktop/views/desktop_view_pin_input.c +++ b/applications/desktop/views/desktop_view_pin_input.c @@ -214,7 +214,7 @@ void desktop_view_pin_input_free(DesktopViewPinInput* pin_input) { xTimerStop(pin_input->timer, portMAX_DELAY); while(xTimerIsTimerActive(pin_input->timer)) { - furi_hal_delay_ms(1); + furi_delay_tick(1); } xTimerDelete(pin_input->timer, portMAX_DELAY); diff --git a/applications/dialogs/dialogs.c b/applications/dialogs/dialogs.c index 8929dc11..da047d8a 100644 --- a/applications/dialogs/dialogs.c +++ b/applications/dialogs/dialogs.c @@ -6,7 +6,7 @@ static DialogsApp* dialogs_app_alloc() { DialogsApp* app = malloc(sizeof(DialogsApp)); - app->message_queue = osMessageQueueNew(8, sizeof(DialogsAppMessage), NULL); + app->message_queue = furi_message_queue_alloc(8, sizeof(DialogsAppMessage)); return app; } @@ -33,7 +33,7 @@ int32_t dialogs_srv(void* p) { DialogsAppMessage message; while(1) { - if(osMessageQueueGet(app->message_queue, &message, NULL, osWaitForever) == osOK) { + if(furi_message_queue_get(app->message_queue, &message, FuriWaitForever) == FuriStatusOk) { dialogs_app_process_message(app, &message); } } diff --git a/applications/dialogs/dialogs_api.c b/applications/dialogs/dialogs_api.c index fab3a5ea..72aa2a1b 100644 --- a/applications/dialogs/dialogs_api.c +++ b/applications/dialogs/dialogs_api.c @@ -35,7 +35,8 @@ bool dialog_file_browser_show( .return_data = &return_data, }; - furi_check(osMessageQueuePut(context->message_queue, &message, 0, osWaitForever) == osOK); + furi_check( + furi_message_queue_put(context->message_queue, &message, FuriWaitForever) == FuriStatusOk); API_LOCK_WAIT_UNTIL_UNLOCK_AND_FREE(lock); return return_data.bool_value; @@ -60,7 +61,8 @@ DialogMessageButton dialog_message_show(DialogsApp* context, const DialogMessage .return_data = &return_data, }; - furi_check(osMessageQueuePut(context->message_queue, &message, 0, osWaitForever) == osOK); + furi_check( + furi_message_queue_put(context->message_queue, &message, FuriWaitForever) == FuriStatusOk); API_LOCK_WAIT_UNTIL_UNLOCK_AND_FREE(lock); return return_data.dialog_value; diff --git a/applications/dialogs/dialogs_api_lock.h b/applications/dialogs/dialogs_api_lock.h index ad3c78e5..a165803f 100644 --- a/applications/dialogs/dialogs_api_lock.h +++ b/applications/dialogs/dialogs_api_lock.h @@ -1,17 +1,17 @@ #pragma once -typedef osEventFlagsId_t FuriApiLock; +typedef FuriEventFlag* FuriApiLock; #define API_LOCK_EVENT (1U << 0) -#define API_LOCK_INIT_LOCKED() osEventFlagsNew(NULL); +#define API_LOCK_INIT_LOCKED() furi_event_flag_alloc(); #define API_LOCK_WAIT_UNTIL_UNLOCK(_lock) \ - osEventFlagsWait(_lock, API_LOCK_EVENT, osFlagsWaitAny, osWaitForever); + furi_event_flag_wait(_lock, API_LOCK_EVENT, FuriFlagWaitAny, FuriWaitForever); -#define API_LOCK_FREE(_lock) osEventFlagsDelete(_lock); +#define API_LOCK_FREE(_lock) furi_event_flag_free(_lock); -#define API_LOCK_UNLOCK(_lock) osEventFlagsSet(_lock, API_LOCK_EVENT); +#define API_LOCK_UNLOCK(_lock) furi_event_flag_set(_lock, API_LOCK_EVENT); #define API_LOCK_WAIT_UNTIL_UNLOCK_AND_FREE(_lock) \ API_LOCK_WAIT_UNTIL_UNLOCK(_lock); \ diff --git a/applications/dialogs/dialogs_i.h b/applications/dialogs/dialogs_i.h index b61e10ab..36bee024 100644 --- a/applications/dialogs/dialogs_i.h +++ b/applications/dialogs/dialogs_i.h @@ -7,7 +7,7 @@ extern "C" { #endif struct DialogsApp { - osMessageQueueId_t message_queue; + FuriMessageQueue* message_queue; }; #ifdef __cplusplus diff --git a/applications/dialogs/view_holder.c b/applications/dialogs/view_holder.c index eb8a1502..d2ae7750 100644 --- a/applications/dialogs/view_holder.c +++ b/applications/dialogs/view_holder.c @@ -96,7 +96,7 @@ void view_holder_start(ViewHolder* view_holder) { } void view_holder_stop(ViewHolder* view_holder) { - while(view_holder->ongoing_input) osDelay(1); + while(view_holder->ongoing_input) furi_delay_tick(1); view_port_enabled_set(view_holder->view_port, false); } diff --git a/applications/dolphin/dolphin.c b/applications/dolphin/dolphin.c index 47960286..f495068b 100644 --- a/applications/dolphin/dolphin.c +++ b/applications/dolphin/dolphin.c @@ -77,7 +77,7 @@ Dolphin* dolphin_alloc() { Dolphin* dolphin = malloc(sizeof(Dolphin)); dolphin->state = dolphin_state_alloc(); - dolphin->event_queue = osMessageQueueNew(8, sizeof(DolphinEvent), NULL); + dolphin->event_queue = furi_message_queue_alloc(8, sizeof(DolphinEvent)); dolphin->pubsub = furi_pubsub_alloc(); dolphin->butthurt_timer = xTimerCreate( NULL, HOURS_IN_TICKS(2 * 24), pdTRUE, dolphin, dolphin_butthurt_timer_callback); @@ -93,7 +93,7 @@ void dolphin_free(Dolphin* dolphin) { furi_assert(dolphin); dolphin_state_free(dolphin->state); - osMessageQueueDelete(dolphin->event_queue); + furi_message_queue_free(dolphin->event_queue); free(dolphin); } @@ -102,25 +102,28 @@ void dolphin_event_send_async(Dolphin* dolphin, DolphinEvent* event) { furi_assert(dolphin); furi_assert(event); event->flag = NULL; - furi_check(osMessageQueuePut(dolphin->event_queue, event, 0, osWaitForever) == osOK); + furi_check( + furi_message_queue_put(dolphin->event_queue, event, FuriWaitForever) == FuriStatusOk); } void dolphin_event_send_wait(Dolphin* dolphin, DolphinEvent* event) { furi_assert(dolphin); furi_assert(event); - event->flag = osEventFlagsNew(NULL); + event->flag = furi_event_flag_alloc(); furi_check(event->flag); - furi_check(osMessageQueuePut(dolphin->event_queue, event, 0, osWaitForever) == osOK); furi_check( - osEventFlagsWait(event->flag, DOLPHIN_LOCK_EVENT_FLAG, osFlagsWaitAny, osWaitForever) == + furi_message_queue_put(dolphin->event_queue, event, FuriWaitForever) == FuriStatusOk); + furi_check( + furi_event_flag_wait( + event->flag, DOLPHIN_LOCK_EVENT_FLAG, FuriFlagWaitAny, FuriWaitForever) == DOLPHIN_LOCK_EVENT_FLAG); - furi_check(osEventFlagsDelete(event->flag) == osOK); + furi_event_flag_free(event->flag); } void dolphin_event_release(Dolphin* dolphin, DolphinEvent* event) { UNUSED(dolphin); if(event->flag) { - osEventFlagsSet(event->flag, DOLPHIN_LOCK_EVENT_FLAG); + furi_event_flag_set(event->flag, DOLPHIN_LOCK_EVENT_FLAG); } } @@ -161,7 +164,8 @@ int32_t dolphin_srv(void* p) { DolphinEvent event; while(1) { - if(osMessageQueueGet(dolphin->event_queue, &event, NULL, HOURS_IN_TICKS(1)) == osOK) { + if(furi_message_queue_get(dolphin->event_queue, &event, HOURS_IN_TICKS(1)) == + FuriStatusOk) { if(event.type == DolphinEventTypeDeed) { dolphin_state_on_deed(dolphin->state, event.deed); DolphinPubsubEvent event = DolphinPubsubEventUpdate; diff --git a/applications/dolphin/dolphin.h b/applications/dolphin/dolphin.h index ca3bb4b3..2abb166b 100644 --- a/applications/dolphin/dolphin.h +++ b/applications/dolphin/dolphin.h @@ -1,6 +1,6 @@ #pragma once -#include "furi/pubsub.h" +#include #include "gui/view.h" #include "helpers/dolphin_deed.h" #include diff --git a/applications/dolphin/dolphin_i.h b/applications/dolphin/dolphin_i.h index 46f14915..4bb0df08 100644 --- a/applications/dolphin/dolphin_i.h +++ b/applications/dolphin/dolphin_i.h @@ -1,6 +1,6 @@ #pragma once -#include "furi/pubsub.h" +#include #include #include @@ -17,7 +17,7 @@ typedef enum { typedef struct { DolphinEventType type; - osEventFlagsId_t flag; + FuriEventFlag* flag; union { DolphinDeed deed; DolphinStats* stats; @@ -28,7 +28,7 @@ struct Dolphin { // State DolphinState* state; // Queue - osMessageQueueId_t event_queue; + FuriMessageQueue* event_queue; FuriPubSub* pubsub; TimerHandle_t butthurt_timer; TimerHandle_t flush_timer; diff --git a/applications/dolphin/passport/passport.c b/applications/dolphin/passport/passport.c index 13bf086b..b9be2d22 100644 --- a/applications/dolphin/passport/passport.c +++ b/applications/dolphin/passport/passport.c @@ -1,8 +1,7 @@ #include "assets_icons.h" -#include "cmsis_os2.h" #include "dolphin/helpers/dolphin_state.h" -#include "furi/check.h" -#include "furi/record.h" +#include +#include #include #include #include @@ -28,10 +27,10 @@ static const Icon* const portrait_bad[BUTTHURT_MAX] = { static const Icon* const* portraits[MOODS_TOTAL] = {portrait_happy, portrait_ok, portrait_bad}; static void input_callback(InputEvent* input, void* ctx) { - osSemaphoreId_t semaphore = ctx; + FuriSemaphore* semaphore = ctx; if((input->type == InputTypeShort) && (input->key == InputKeyBack)) { - osSemaphoreRelease(semaphore); + furi_semaphore_release(semaphore); } } @@ -91,7 +90,7 @@ static void render_callback(Canvas* canvas, void* ctx) { int32_t passport_app(void* p) { UNUSED(p); - osSemaphoreId_t semaphore = osSemaphoreNew(1, 0, NULL); + FuriSemaphore* semaphore = furi_semaphore_alloc(1, 0); furi_assert(semaphore); ViewPort* view_port = view_port_alloc(); @@ -105,12 +104,12 @@ int32_t passport_app(void* p) { gui_add_view_port(gui, view_port, GuiLayerFullscreen); view_port_update(view_port); - furi_check(osSemaphoreAcquire(semaphore, osWaitForever) == osOK); + furi_check(furi_semaphore_acquire(semaphore, FuriWaitForever) == FuriStatusOk); gui_remove_view_port(gui, view_port); view_port_free(view_port); furi_record_close("gui"); - osSemaphoreDelete(semaphore); + furi_semaphore_free(semaphore); return 0; } diff --git a/applications/gpio/usb_uart_bridge.c b/applications/gpio/usb_uart_bridge.c index 9c6ba0a6..c51be513 100644 --- a/applications/gpio/usb_uart_bridge.c +++ b/applications/gpio/usb_uart_bridge.c @@ -45,9 +45,9 @@ struct UsbUartBridge { StreamBufferHandle_t rx_stream; - osMutexId_t usb_mutex; + FuriMutex* usb_mutex; - osSemaphoreId_t tx_sem; + FuriSemaphore* tx_sem; UsbUartState st; @@ -158,8 +158,8 @@ static int32_t usb_uart_worker(void* context) { usb_uart->rx_stream = xStreamBufferCreate(USB_UART_RX_BUF_SIZE, 1); - usb_uart->tx_sem = osSemaphoreNew(1, 1, NULL); - usb_uart->usb_mutex = osMutexNew(NULL); + usb_uart->tx_sem = furi_semaphore_alloc(1, 1); + usb_uart->usb_mutex = furi_mutex_alloc(FuriMutexTypeNormal); usb_uart->tx_thread = furi_thread_alloc(); furi_thread_set_name(usb_uart->tx_thread, "UsbUartTxWorker"); @@ -185,18 +185,19 @@ static int32_t usb_uart_worker(void* context) { while(1) { uint32_t events = - furi_thread_flags_wait(WORKER_ALL_RX_EVENTS, osFlagsWaitAny, osWaitForever); - furi_check((events & osFlagsError) == 0); + furi_thread_flags_wait(WORKER_ALL_RX_EVENTS, FuriFlagWaitAny, FuriWaitForever); + furi_check((events & FuriFlagError) == 0); if(events & WorkerEvtStop) break; if(events & WorkerEvtRxDone) { size_t len = xStreamBufferReceive(usb_uart->rx_stream, usb_uart->rx_buf, USB_CDC_PKT_LEN, 0); if(len > 0) { - if(osSemaphoreAcquire(usb_uart->tx_sem, 100) == osOK) { + if(furi_semaphore_acquire(usb_uart->tx_sem, 100) == FuriStatusOk) { usb_uart->st.rx_cnt += len; - furi_check(osMutexAcquire(usb_uart->usb_mutex, osWaitForever) == osOK); + furi_check( + furi_mutex_acquire(usb_uart->usb_mutex, FuriWaitForever) == FuriStatusOk); furi_hal_cdc_send(usb_uart->cfg.vcp_ch, usb_uart->rx_buf, len); - furi_check(osMutexRelease(usb_uart->usb_mutex) == osOK); + furi_check(furi_mutex_release(usb_uart->usb_mutex) == FuriStatusOk); } else { xStreamBufferReset(usb_uart->rx_stream); } @@ -270,8 +271,8 @@ static int32_t usb_uart_worker(void* context) { furi_thread_free(usb_uart->tx_thread); vStreamBufferDelete(usb_uart->rx_stream); - osMutexDelete(usb_uart->usb_mutex); - osSemaphoreDelete(usb_uart->tx_sem); + furi_mutex_free(usb_uart->usb_mutex); + furi_semaphore_free(usb_uart->tx_sem); furi_hal_usb_unlock(); furi_check(furi_hal_usb_set_config(&usb_cdc_single, NULL) == true); @@ -288,13 +289,13 @@ static int32_t usb_uart_tx_thread(void* context) { uint8_t data[USB_CDC_PKT_LEN]; while(1) { uint32_t events = - furi_thread_flags_wait(WORKER_ALL_TX_EVENTS, osFlagsWaitAny, osWaitForever); - furi_check((events & osFlagsError) == 0); + furi_thread_flags_wait(WORKER_ALL_TX_EVENTS, FuriFlagWaitAny, FuriWaitForever); + furi_check((events & FuriFlagError) == 0); if(events & WorkerEvtTxStop) break; if(events & WorkerEvtCdcRx) { - furi_check(osMutexAcquire(usb_uart->usb_mutex, osWaitForever) == osOK); + furi_check(furi_mutex_acquire(usb_uart->usb_mutex, FuriWaitForever) == FuriStatusOk); size_t len = furi_hal_cdc_receive(usb_uart->cfg.vcp_ch, data, USB_CDC_PKT_LEN); - furi_check(osMutexRelease(usb_uart->usb_mutex) == osOK); + furi_check(furi_mutex_release(usb_uart->usb_mutex) == FuriStatusOk); if(len > 0) { usb_uart->st.tx_cnt += len; @@ -309,7 +310,7 @@ static int32_t usb_uart_tx_thread(void* context) { static void vcp_on_cdc_tx_complete(void* context) { UsbUartBridge* usb_uart = (UsbUartBridge*)context; - osSemaphoreRelease(usb_uart->tx_sem); + furi_semaphore_release(usb_uart->tx_sem); } static void vcp_on_cdc_rx(void* context) { diff --git a/applications/gui/gui.c b/applications/gui/gui.c index d9e32cdd..50df399a 100644 --- a/applications/gui/gui.c +++ b/applications/gui/gui.c @@ -28,7 +28,7 @@ void gui_input_events_callback(const void* value, void* ctx) { Gui* gui = ctx; - osMessageQueuePut(gui->input_queue, value, 0, osWaitForever); + furi_message_queue_put(gui->input_queue, value, FuriWaitForever); furi_thread_flags_set(gui->thread_id, GUI_THREAD_FLAG_INPUT); } @@ -308,12 +308,12 @@ void gui_input(Gui* gui, InputEvent* input_event) { void gui_lock(Gui* gui) { furi_assert(gui); - furi_check(osMutexAcquire(gui->mutex, osWaitForever) == osOK); + furi_check(furi_mutex_acquire(gui->mutex, FuriWaitForever) == FuriStatusOk); } void gui_unlock(Gui* gui) { furi_assert(gui); - furi_check(osMutexRelease(gui->mutex) == osOK); + furi_check(furi_mutex_release(gui->mutex) == FuriStatusOk); } void gui_add_view_port(Gui* gui, ViewPort* view_port, GuiLayer layer) { @@ -473,7 +473,7 @@ Gui* gui_alloc() { // Thread ID gui->thread_id = furi_thread_get_current_id(); // Allocate mutex - gui->mutex = osMutexNew(NULL); + gui->mutex = furi_mutex_alloc(FuriMutexTypeNormal); furi_check(gui->mutex); // Layers for(size_t i = 0; i < GuiLayerMAX; i++) { @@ -484,7 +484,7 @@ Gui* gui_alloc() { CanvasCallbackPairArray_init(gui->canvas_callback_pair); // Input - gui->input_queue = osMessageQueueNew(8, sizeof(InputEvent), NULL); + gui->input_queue = furi_message_queue_alloc(8, sizeof(InputEvent)); gui->input_events = furi_record_open("input_events"); furi_check(gui->input_events); @@ -501,12 +501,12 @@ int32_t gui_srv(void* p) { while(1) { uint32_t flags = - furi_thread_flags_wait(GUI_THREAD_FLAG_ALL, osFlagsWaitAny, osWaitForever); + furi_thread_flags_wait(GUI_THREAD_FLAG_ALL, FuriFlagWaitAny, FuriWaitForever); // Process and dispatch input if(flags & GUI_THREAD_FLAG_INPUT) { // Process till queue become empty InputEvent input_event; - while(osMessageQueueGet(gui->input_queue, &input_event, NULL, 0) == osOK) { + while(furi_message_queue_get(gui->input_queue, &input_event, 0) == FuriStatusOk) { gui_input(gui, &input_event); } } diff --git a/applications/gui/gui_i.h b/applications/gui/gui_i.h index abe85615..b3fd0aa7 100644 --- a/applications/gui/gui_i.h +++ b/applications/gui/gui_i.h @@ -58,7 +58,7 @@ ALGO_DEF(CanvasCallbackPairArray, CanvasCallbackPairArray_t); struct Gui { // Thread and lock FuriThreadId thread_id; - osMutexId_t mutex; + FuriMutex* mutex; // Layers and Canvas bool lockdown; @@ -67,7 +67,7 @@ struct Gui { CanvasCallbackPairArray_t canvas_callback_pair; // Input - osMessageQueueId_t input_queue; + FuriMessageQueue* input_queue; FuriPubSub* input_events; uint8_t ongoing_input; ViewPort* ongoing_input_view_port; diff --git a/applications/gui/icon_animation.c b/applications/gui/icon_animation.c index 5170eea4..48c86220 100644 --- a/applications/gui/icon_animation.c +++ b/applications/gui/icon_animation.c @@ -7,15 +7,16 @@ IconAnimation* icon_animation_alloc(const Icon* icon) { furi_assert(icon); IconAnimation* instance = malloc(sizeof(IconAnimation)); instance->icon = icon; - instance->timer = osTimerNew(icon_animation_timer_callback, osTimerPeriodic, instance, NULL); + instance->timer = + furi_timer_alloc(icon_animation_timer_callback, FuriTimerTypePeriodic, instance); return instance; } void icon_animation_free(IconAnimation* instance) { furi_assert(instance); icon_animation_stop(instance); - while(xTimerIsTimerActive(instance->timer) == pdTRUE) osDelay(1); - furi_check(osTimerDelete(instance->timer) == osOK); + while(xTimerIsTimerActive(instance->timer) == pdTRUE) furi_delay_tick(1); + furi_timer_free(instance->timer); free(instance); } @@ -68,7 +69,7 @@ void icon_animation_start(IconAnimation* instance) { furi_check( xTimerChangePeriod( instance->timer, - (osKernelGetTickFreq() / instance->icon->frame_rate), + (furi_kernel_get_tick_frequency() / instance->icon->frame_rate), portMAX_DELAY) == pdPASS); } } diff --git a/applications/gui/icon_animation_i.h b/applications/gui/icon_animation_i.h index 241bcaa3..4053a120 100644 --- a/applications/gui/icon_animation_i.h +++ b/applications/gui/icon_animation_i.h @@ -13,7 +13,7 @@ struct IconAnimation { const Icon* icon; uint8_t frame; bool animating; - osTimerId_t timer; + FuriTimer* timer; IconAnimationCallback callback; void* callback_context; }; diff --git a/applications/gui/modules/file_browser.c b/applications/gui/modules/file_browser.c index 4dc0ee54..a987eb1e 100644 --- a/applications/gui/modules/file_browser.c +++ b/applications/gui/modules/file_browser.c @@ -1,10 +1,9 @@ #include "file_browser.h" #include "assets_icons.h" -#include "cmsis_os2.h" #include "file_browser_worker.h" -#include "furi/check.h" -#include "furi/common_defines.h" -#include "furi/log.h" +#include +#include +#include #include "furi_hal_resources.h" #include "m-string.h" #include diff --git a/applications/gui/modules/file_browser_worker.c b/applications/gui/modules/file_browser_worker.c index cd7b6cb7..ce3def41 100644 --- a/applications/gui/modules/file_browser_worker.c +++ b/applications/gui/modules/file_browser_worker.c @@ -1,6 +1,6 @@ #include "file_browser_worker.h" -#include "furi/check.h" -#include "furi/common_defines.h" +#include +#include #include "m-string.h" #include "storage/filesystem_api_defines.h" #include @@ -262,8 +262,9 @@ static int32_t browser_worker(void* context) { furi_thread_flags_set(furi_thread_get_id(browser->thread), WorkerEvtConfigChange); while(1) { - uint32_t flags = furi_thread_flags_wait(WORKER_FLAGS_ALL, osFlagsWaitAny, osWaitForever); - furi_assert((flags & osFlagsError) == 0); + uint32_t flags = + furi_thread_flags_wait(WORKER_FLAGS_ALL, FuriFlagWaitAny, FuriWaitForever); + furi_assert((flags & FuriFlagError) == 0); if(flags & WorkerEvtConfigChange) { // If start path is a path to the file - try finding index of this file in a folder diff --git a/applications/gui/modules/popup.c b/applications/gui/modules/popup.c index 3b53d962..b3cb5e53 100644 --- a/applications/gui/modules/popup.c +++ b/applications/gui/modules/popup.c @@ -7,7 +7,7 @@ struct Popup { void* context; PopupCallback callback; - osTimerId_t timer; + FuriTimer* timer; uint32_t timer_period_in_ms; bool timer_enabled; }; @@ -93,10 +93,11 @@ static bool popup_view_input_callback(InputEvent* event, void* context) { void popup_start_timer(void* context) { Popup* popup = context; if(popup->timer_enabled) { - uint32_t timer_period = popup->timer_period_in_ms / (1000.0f / osKernelGetTickFreq()); + uint32_t timer_period = + popup->timer_period_in_ms / (1000.0f / furi_kernel_get_tick_frequency()); if(timer_period == 0) timer_period = 1; - if(osTimerStart(popup->timer, timer_period) != osOK) { + if(furi_timer_start(popup->timer, timer_period) != FuriStatusOk) { furi_assert(0); }; } @@ -104,13 +105,13 @@ void popup_start_timer(void* context) { void popup_stop_timer(void* context) { Popup* popup = context; - osTimerStop(popup->timer); + furi_timer_stop(popup->timer); } Popup* popup_alloc() { Popup* popup = malloc(sizeof(Popup)); popup->view = view_alloc(); - popup->timer = osTimerNew(popup_timer_callback, osTimerOnce, popup, NULL); + popup->timer = furi_timer_alloc(popup_timer_callback, FuriTimerTypeOnce, popup); furi_assert(popup->timer); popup->timer_period_in_ms = 1000; popup->timer_enabled = false; @@ -146,7 +147,7 @@ Popup* popup_alloc() { void popup_free(Popup* popup) { furi_assert(popup); - osTimerDelete(popup->timer); + furi_timer_free(popup->timer); view_free(popup->view); free(popup); } diff --git a/applications/gui/modules/text_input.c b/applications/gui/modules/text_input.c index 04cd2d7f..5aa101bb 100644 --- a/applications/gui/modules/text_input.c +++ b/applications/gui/modules/text_input.c @@ -4,7 +4,7 @@ struct TextInput { View* view; - osTimerId_t timer; + FuriTimer* timer; }; typedef struct { @@ -310,7 +310,7 @@ static void text_input_handle_ok(TextInput* text_input, TextInputModel* model, b (!model->validator_callback( model->text_buffer, model->validator_text, model->validator_callback_context))) { model->valadator_message_visible = true; - osTimerStart(text_input->timer, osKernelGetTickFreq() * 4); + furi_timer_start(text_input->timer, furi_kernel_get_tick_frequency() * 4); } else if(model->callback != 0 && text_length > 0) { model->callback(model->callback_context); } @@ -438,7 +438,7 @@ TextInput* text_input_alloc() { view_set_draw_callback(text_input->view, text_input_view_draw_callback); view_set_input_callback(text_input->view, text_input_view_input_callback); - text_input->timer = osTimerNew(text_input_timer_callback, osTimerOnce, text_input, NULL); + text_input->timer = furi_timer_alloc(text_input_timer_callback, FuriTimerTypeOnce, text_input); with_view_model( text_input->view, (TextInputModel * model) { @@ -460,11 +460,11 @@ void text_input_free(TextInput* text_input) { }); // Send stop command - osTimerStop(text_input->timer); + furi_timer_stop(text_input->timer); // Wait till timer stop - while(osTimerIsRunning(text_input->timer)) osDelay(1); + while(furi_timer_is_running(text_input->timer)) furi_delay_tick(1); // Release allocated memory - osTimerDelete(text_input->timer); + furi_timer_free(text_input->timer); view_free(text_input->view); diff --git a/applications/gui/view.c b/applications/gui/view.c index ec73882d..7ab6d15b 100644 --- a/applications/gui/view.c +++ b/applications/gui/view.c @@ -81,7 +81,7 @@ void view_allocate_model(View* view, ViewModelType type, size_t size) { view->model = malloc(size); } else if(view->model_type == ViewModelTypeLocking) { ViewModelLocking* model = malloc(sizeof(ViewModelLocking)); - model->mutex = osMutexNew(NULL); + model->mutex = furi_mutex_alloc(FuriMutexTypeNormal); furi_check(model->mutex); model->data = malloc(size); view->model = model; @@ -98,7 +98,7 @@ void view_free_model(View* view) { free(view->model); } else if(view->model_type == ViewModelTypeLocking) { ViewModelLocking* model = view->model; - furi_check(osMutexDelete(model->mutex) == osOK); + furi_mutex_free(model->mutex); free(model->data); free(model); view->model = NULL; @@ -111,7 +111,7 @@ void* view_get_model(View* view) { furi_assert(view); if(view->model_type == ViewModelTypeLocking) { ViewModelLocking* model = (ViewModelLocking*)(view->model); - furi_check(osMutexAcquire(model->mutex, osWaitForever) == osOK); + furi_check(furi_mutex_acquire(model->mutex, FuriWaitForever) == FuriStatusOk); return model->data; } return view->model; @@ -138,7 +138,7 @@ void view_unlock_model(View* view) { furi_assert(view); if(view->model_type == ViewModelTypeLocking) { ViewModelLocking* model = (ViewModelLocking*)(view->model); - furi_check(osMutexRelease(model->mutex) == osOK); + furi_check(furi_mutex_release(model->mutex) == FuriStatusOk); } } diff --git a/applications/gui/view_dispatcher.c b/applications/gui/view_dispatcher.c index 8bfb9e4e..307206c1 100644 --- a/applications/gui/view_dispatcher.c +++ b/applications/gui/view_dispatcher.c @@ -30,7 +30,7 @@ void view_dispatcher_free(ViewDispatcher* view_dispatcher) { view_port_free(view_dispatcher->view_port); // Free internal queue if(view_dispatcher->queue) { - osMessageQueueDelete(view_dispatcher->queue); + furi_message_queue_free(view_dispatcher->queue); } // Free dispatcher free(view_dispatcher); @@ -39,7 +39,7 @@ void view_dispatcher_free(ViewDispatcher* view_dispatcher) { void view_dispatcher_enable_queue(ViewDispatcher* view_dispatcher) { furi_assert(view_dispatcher); furi_assert(view_dispatcher->queue == NULL); - view_dispatcher->queue = osMessageQueueNew(16, sizeof(ViewDispatcherMessage), NULL); + view_dispatcher->queue = furi_message_queue_alloc(16, sizeof(ViewDispatcherMessage)); } void view_dispatcher_set_event_callback_context(ViewDispatcher* view_dispatcher, void* context) { @@ -77,11 +77,11 @@ void view_dispatcher_run(ViewDispatcher* view_dispatcher) { furi_assert(view_dispatcher); furi_assert(view_dispatcher->queue); - uint32_t tick_period = view_dispatcher->tick_period == 0 ? osWaitForever : + uint32_t tick_period = view_dispatcher->tick_period == 0 ? FuriWaitForever : view_dispatcher->tick_period; ViewDispatcherMessage message; while(1) { - if(osMessageQueueGet(view_dispatcher->queue, &message, NULL, tick_period) != osOK) { + if(furi_message_queue_get(view_dispatcher->queue, &message, tick_period) != FuriStatusOk) { view_dispatcher_handle_tick_event(view_dispatcher); continue; } @@ -96,7 +96,7 @@ void view_dispatcher_run(ViewDispatcher* view_dispatcher) { // Wait till all input events delivered while(view_dispatcher->ongoing_input) { - osMessageQueueGet(view_dispatcher->queue, &message, NULL, osWaitForever); + furi_message_queue_get(view_dispatcher->queue, &message, FuriWaitForever); if(message.type == ViewDispatcherMessageTypeInput) { uint8_t key_bit = (1 << message.input.key); if(message.input.type == InputTypePress) { @@ -113,7 +113,8 @@ void view_dispatcher_stop(ViewDispatcher* view_dispatcher) { furi_assert(view_dispatcher->queue); ViewDispatcherMessage message; message.type = ViewDispatcherMessageTypeStop; - furi_check(osMessageQueuePut(view_dispatcher->queue, &message, 0, osWaitForever) == osOK); + furi_check( + furi_message_queue_put(view_dispatcher->queue, &message, FuriWaitForever) == FuriStatusOk); } void view_dispatcher_add_view(ViewDispatcher* view_dispatcher, uint32_t view_id, View* view) { @@ -224,7 +225,9 @@ void view_dispatcher_input_callback(InputEvent* event, void* context) { ViewDispatcherMessage message; message.type = ViewDispatcherMessageTypeInput; message.input = *event; - furi_check(osMessageQueuePut(view_dispatcher->queue, &message, 0, osWaitForever) == osOK); + furi_check( + furi_message_queue_put(view_dispatcher->queue, &message, FuriWaitForever) == + FuriStatusOk); } else { view_dispatcher_handle_input(view_dispatcher, event); } @@ -314,7 +317,8 @@ void view_dispatcher_send_custom_event(ViewDispatcher* view_dispatcher, uint32_t message.type = ViewDispatcherMessageTypeCustomEvent; message.custom_event = event; - furi_check(osMessageQueuePut(view_dispatcher->queue, &message, 0, osWaitForever) == osOK); + furi_check( + furi_message_queue_put(view_dispatcher->queue, &message, FuriWaitForever) == FuriStatusOk); } void view_dispatcher_set_current_view(ViewDispatcher* view_dispatcher, View* view) { diff --git a/applications/gui/view_dispatcher_i.h b/applications/gui/view_dispatcher_i.h index ad0f0888..f30a84e6 100644 --- a/applications/gui/view_dispatcher_i.h +++ b/applications/gui/view_dispatcher_i.h @@ -15,7 +15,7 @@ DICT_DEF2(ViewDict, uint32_t, M_DEFAULT_OPLIST, View*, M_PTR_OPLIST) struct ViewDispatcher { - osMessageQueueId_t queue; + FuriMessageQueue* queue; Gui* gui; ViewPort* view_port; ViewDict_t views; diff --git a/applications/gui/view_i.h b/applications/gui/view_i.h index 21b374d5..3e895bd9 100644 --- a/applications/gui/view_i.h +++ b/applications/gui/view_i.h @@ -10,7 +10,7 @@ typedef struct { void* data; - osMutexId_t mutex; + FuriMutex* mutex; } ViewModelLocking; struct View { diff --git a/applications/gui/view_stack.c b/applications/gui/view_stack.c index a1c96faa..3bb00fbf 100644 --- a/applications/gui/view_stack.c +++ b/applications/gui/view_stack.c @@ -1,5 +1,5 @@ #include "gui/view.h" -#include "furi/memmgr.h" +#include #include "view_stack.h" #include "view_i.h" diff --git a/applications/ibutton/ibutton_cli.c b/applications/ibutton/ibutton_cli.c index 4592cdad..324c636d 100644 --- a/applications/ibutton/ibutton_cli.c +++ b/applications/ibutton/ibutton_cli.c @@ -67,14 +67,14 @@ void ibutton_cli_print_key_data(iButtonKey* key) { static void ibutton_cli_worker_read_cb(void* context) { furi_assert(context); - osEventFlagsId_t event = context; - osEventFlagsSet(event, EVENT_FLAG_IBUTTON_COMPLETE); + FuriEventFlag* event = context; + furi_event_flag_set(event, EVENT_FLAG_IBUTTON_COMPLETE); } void ibutton_cli_read(Cli* cli) { iButtonKey* key = ibutton_key_alloc(); iButtonWorker* worker = ibutton_worker_alloc(); - osEventFlagsId_t event = osEventFlagsNew(NULL); + FuriEventFlag* event = furi_event_flag_alloc(); ibutton_worker_start_thread(worker); ibutton_worker_read_set_callback(worker, ibutton_cli_worker_read_cb, event); @@ -82,7 +82,8 @@ void ibutton_cli_read(Cli* cli) { printf("Reading iButton...\r\nPress Ctrl+C to abort\r\n"); ibutton_worker_read_start(worker, key); while(true) { - uint32_t flags = osEventFlagsWait(event, EVENT_FLAG_IBUTTON_COMPLETE, osFlagsWaitAny, 100); + uint32_t flags = + furi_event_flag_wait(event, EVENT_FLAG_IBUTTON_COMPLETE, FuriFlagWaitAny, 100); if(flags & EVENT_FLAG_IBUTTON_COMPLETE) { ibutton_cli_print_key_data(key); @@ -107,11 +108,11 @@ void ibutton_cli_read(Cli* cli) { ibutton_worker_free(worker); ibutton_key_free(key); - osEventFlagsDelete(event); + furi_event_flag_free(event); }; typedef struct { - osEventFlagsId_t event; + FuriEventFlag* event; iButtonWorkerWriteResult result; } iButtonWriteContext; @@ -119,7 +120,7 @@ static void ibutton_cli_worker_write_cb(void* context, iButtonWorkerWriteResult furi_assert(context); iButtonWriteContext* write_context = (iButtonWriteContext*)context; write_context->result = result; - osEventFlagsSet(write_context->event, EVENT_FLAG_IBUTTON_COMPLETE); + furi_event_flag_set(write_context->event, EVENT_FLAG_IBUTTON_COMPLETE); } void ibutton_cli_write(Cli* cli, string_t args) { @@ -130,7 +131,7 @@ void ibutton_cli_write(Cli* cli, string_t args) { uint8_t key_data[IBUTTON_KEY_DATA_SIZE]; string_t data; - write_context.event = osEventFlagsNew(NULL); + write_context.event = furi_event_flag_alloc(); string_init(data); ibutton_worker_start_thread(worker); @@ -166,8 +167,8 @@ void ibutton_cli_write(Cli* cli, string_t args) { ibutton_worker_write_start(worker, key); while(true) { - uint32_t flags = osEventFlagsWait( - write_context.event, EVENT_FLAG_IBUTTON_COMPLETE, osFlagsWaitAny, 100); + uint32_t flags = furi_event_flag_wait( + write_context.event, EVENT_FLAG_IBUTTON_COMPLETE, FuriFlagWaitAny, 100); if(flags & EVENT_FLAG_IBUTTON_COMPLETE) { if(write_context.result == iButtonWorkerWriteSameKey || @@ -190,7 +191,7 @@ void ibutton_cli_write(Cli* cli, string_t args) { ibutton_worker_free(worker); ibutton_key_free(key); - osEventFlagsDelete(write_context.event); + furi_event_flag_free(write_context.event); }; void ibutton_cli_emulate(Cli* cli, string_t args) { @@ -228,7 +229,7 @@ void ibutton_cli_emulate(Cli* cli, string_t args) { ibutton_worker_emulate_start(worker, key); while(!cli_cmd_interrupt_received(cli)) { - furi_hal_delay_ms(100); + furi_delay_ms(100); }; ibutton_worker_stop(worker); } while(false); @@ -291,7 +292,7 @@ static void onewire_cli_search(Cli* cli) { } printf("\r\n"); } - furi_hal_delay_ms(100); + furi_delay_ms(100); } furi_hal_power_disable_otg(); diff --git a/applications/ibutton/scenes/ibutton_scene_emulate.c b/applications/ibutton/scenes/ibutton_scene_emulate.c index 0483b77a..3420f847 100644 --- a/applications/ibutton/scenes/ibutton_scene_emulate.c +++ b/applications/ibutton/scenes/ibutton_scene_emulate.c @@ -1,5 +1,5 @@ #include "../ibutton_i.h" -#include "furi/log.h" +#include #include #include diff --git a/applications/infrared/infrared_cli.c b/applications/infrared/infrared_cli.c index d88e7fff..a2dfc2a3 100644 --- a/applications/infrared/infrared_cli.c +++ b/applications/infrared/infrared_cli.c @@ -63,7 +63,7 @@ static void infrared_cli_start_ir_rx(Cli* cli, string_t args) { printf("Receiving INFRARED...\r\nPress Ctrl+C to abort\r\n"); while(!cli_cmd_interrupt_received(cli)) { - furi_hal_delay_ms(50); + furi_delay_ms(50); } infrared_worker_rx_stop(worker); diff --git a/applications/infrared/infrared_remote.c b/applications/infrared/infrared_remote.c index 94658035..d693be17 100644 --- a/applications/infrared/infrared_remote.c +++ b/applications/infrared/infrared_remote.c @@ -7,7 +7,7 @@ #include #include #include -#include +#include #define TAG "InfraredRemote" diff --git a/applications/infrared/infrared_signal.c b/applications/infrared/infrared_signal.c index 79eafb30..b76717dd 100644 --- a/applications/infrared/infrared_signal.c +++ b/applications/infrared/infrared_signal.c @@ -2,7 +2,7 @@ #include #include -#include +#include #include #include diff --git a/applications/infrared/views/infrared_progress_view.c b/applications/infrared/views/infrared_progress_view.c index cd2a0754..5c84ce0d 100644 --- a/applications/infrared/views/infrared_progress_view.c +++ b/applications/infrared/views/infrared_progress_view.c @@ -1,4 +1,4 @@ -#include "furi/check.h" +#include #include "furi_hal_resources.h" #include "assets_icons.h" #include "gui/canvas.h" diff --git a/applications/input/input.c b/applications/input/input.c index 2be67a71..7270a020 100644 --- a/applications/input/input.c +++ b/applications/input/input.c @@ -4,18 +4,18 @@ static Input* input = NULL; -inline static void input_timer_start(osTimerId_t timer_id, uint32_t ticks) { +inline static void input_timer_start(FuriTimer* timer_id, uint32_t ticks) { TimerHandle_t hTimer = (TimerHandle_t)timer_id; furi_check(xTimerChangePeriod(hTimer, ticks, portMAX_DELAY) == pdPASS); } -inline static void input_timer_stop(osTimerId_t timer_id) { +inline static void input_timer_stop(FuriTimer* timer_id) { TimerHandle_t hTimer = (TimerHandle_t)timer_id; furi_check(xTimerStop(hTimer, portMAX_DELAY) == pdPASS); // xTimerStop is not actually stopping timer, // Instead it places stop event into timer queue // This code ensures that timer is stopped - while(xTimerIsTimerActive(hTimer) == pdTRUE) osDelay(1); + while(xTimerIsTimerActive(hTimer) == pdTRUE) furi_delay_tick(1); } void input_press_timer_callback(void* arg) { @@ -84,8 +84,8 @@ int32_t input_srv() { input->pin_states[i].pin = &input_pins[i]; input->pin_states[i].state = GPIO_Read(input->pin_states[i]); input->pin_states[i].debounce = INPUT_DEBOUNCE_TICKS_HALF; - input->pin_states[i].press_timer = - osTimerNew(input_press_timer_callback, osTimerPeriodic, &input->pin_states[i], NULL); + input->pin_states[i].press_timer = furi_timer_alloc( + input_press_timer_callback, FuriTimerTypePeriodic, &input->pin_states[i]); input->pin_states[i].press_counter = 0; } @@ -127,9 +127,9 @@ int32_t input_srv() { } if(is_changing) { - osDelay(1); + furi_delay_tick(1); } else { - furi_thread_flags_wait(INPUT_THREAD_FLAG_ISR, osFlagsWaitAny, osWaitForever); + furi_thread_flags_wait(INPUT_THREAD_FLAG_ISR, FuriFlagWaitAny, FuriWaitForever); } } diff --git a/applications/input/input_cli.c b/applications/input/input_cli.c index afb05afd..037ac53e 100644 --- a/applications/input/input_cli.c +++ b/applications/input/input_cli.c @@ -15,20 +15,20 @@ static void input_cli_usage() { static void input_cli_dump_events_callback(const void* value, void* ctx) { furi_assert(value); furi_assert(ctx); - osMessageQueueId_t input_queue = ctx; - osMessageQueuePut(input_queue, value, 0, osWaitForever); + FuriMessageQueue* input_queue = ctx; + furi_message_queue_put(input_queue, value, FuriWaitForever); } static void input_cli_dump(Cli* cli, string_t args, Input* input) { UNUSED(args); - osMessageQueueId_t input_queue = osMessageQueueNew(8, sizeof(InputEvent), NULL); + FuriMessageQueue* input_queue = furi_message_queue_alloc(8, sizeof(InputEvent)); FuriPubSubSubscription* input_subscription = furi_pubsub_subscribe(input->event_pubsub, input_cli_dump_events_callback, input_queue); InputEvent input_event; printf("Press CTRL+C to stop\r\n"); while(!cli_cmd_interrupt_received(cli)) { - if(osMessageQueueGet(input_queue, &input_event, NULL, 100) == osOK) { + if(furi_message_queue_get(input_queue, &input_event, 100) == FuriStatusOk) { printf( "key: %s type: %s\r\n", input_get_key_name(input_event.key), @@ -37,7 +37,7 @@ static void input_cli_dump(Cli* cli, string_t args, Input* input) { } furi_pubsub_unsubscribe(input->event_pubsub, input_subscription); - osMessageQueueDelete(input_queue); + furi_message_queue_free(input_queue); } static void input_cli_send_print_usage() { diff --git a/applications/input/input_i.h b/applications/input/input_i.h index 63a9c85a..f709e048 100644 --- a/applications/input/input_i.h +++ b/applications/input/input_i.h @@ -25,7 +25,7 @@ typedef struct { // State volatile bool state; volatile uint8_t debounce; - volatile osTimerId_t press_timer; + FuriTimer* press_timer; volatile uint8_t press_counter; volatile uint32_t counter; } InputPinState; diff --git a/applications/lfrfid/helpers/rfid_key.cpp b/applications/lfrfid/helpers/rfid_key.cpp index 02e45e68..2d99d40f 100644 --- a/applications/lfrfid/helpers/rfid_key.cpp +++ b/applications/lfrfid/helpers/rfid_key.cpp @@ -1,5 +1,5 @@ #include "rfid_key.h" -#include +#include #include RfidKey::RfidKey() { diff --git a/applications/lfrfid/helpers/rfid_reader.cpp b/applications/lfrfid/helpers/rfid_reader.cpp index fb837cb7..029b1cb4 100644 --- a/applications/lfrfid/helpers/rfid_reader.cpp +++ b/applications/lfrfid/helpers/rfid_reader.cpp @@ -39,12 +39,12 @@ void RfidReader::decode(bool polarity) { } bool RfidReader::switch_timer_elapsed() { - const uint32_t seconds_to_switch = osKernelGetTickFreq() * 2.0f; - return (osKernelGetTickCount() - switch_os_tick_last) > seconds_to_switch; + const uint32_t seconds_to_switch = furi_kernel_get_tick_frequency() * 2.0f; + return (furi_get_tick() - switch_os_tick_last) > seconds_to_switch; } void RfidReader::switch_timer_reset() { - switch_os_tick_last = osKernelGetTickCount(); + switch_os_tick_last = furi_get_tick(); } void RfidReader::switch_mode() { diff --git a/applications/lfrfid/helpers/rfid_writer.cpp b/applications/lfrfid/helpers/rfid_writer.cpp index e85ab936..31838fde 100644 --- a/applications/lfrfid/helpers/rfid_writer.cpp +++ b/applications/lfrfid/helpers/rfid_writer.cpp @@ -49,15 +49,15 @@ void RfidWriter::stop() { void RfidWriter::write_gap(uint32_t gap_time) { furi_hal_rfid_tim_read_stop(); - furi_hal_delay_us(gap_time * 8); + furi_delay_us(gap_time * 8); furi_hal_rfid_tim_read_start(); } void RfidWriter::write_bit(bool value) { if(value) { - furi_hal_delay_us(T55xxTiming::data_1 * 8); + furi_delay_us(T55xxTiming::data_1 * 8); } else { - furi_hal_delay_us(T55xxTiming::data_0 * 8); + furi_delay_us(T55xxTiming::data_0 * 8); } write_gap(T55xxTiming::write_gap); } @@ -69,7 +69,7 @@ void RfidWriter::write_byte(uint8_t value) { } void RfidWriter::write_block(uint8_t page, uint8_t block, bool lock_bit, uint32_t data) { - furi_hal_delay_us(T55xxTiming::wait_time * 8); + furi_delay_us(T55xxTiming::wait_time * 8); // start gap write_gap(T55xxTiming::start_gap); @@ -102,9 +102,9 @@ void RfidWriter::write_block(uint8_t page, uint8_t block, bool lock_bit, uint32_ write_bit((block >> 1) & 1); write_bit((block >> 0) & 1); - furi_hal_delay_us(T55xxTiming::program * 8); + furi_delay_us(T55xxTiming::program * 8); - furi_hal_delay_us(T55xxTiming::wait_time * 8); + furi_delay_us(T55xxTiming::wait_time * 8); write_reset(); } diff --git a/applications/lfrfid/lfrfid_app.cpp b/applications/lfrfid/lfrfid_app.cpp index d2c92d24..c491cf40 100644 --- a/applications/lfrfid/lfrfid_app.cpp +++ b/applications/lfrfid/lfrfid_app.cpp @@ -1,6 +1,6 @@ #include "lfrfid_app.h" #include "assets_icons.h" -#include "furi/common_defines.h" +#include #include "m-string.h" #include "scene/lfrfid_app_scene_start.h" #include "scene/lfrfid_app_scene_read.h" diff --git a/applications/lfrfid/lfrfid_cli.cpp b/applications/lfrfid/lfrfid_cli.cpp index 451f10ce..7d1bb6d4 100644 --- a/applications/lfrfid/lfrfid_cli.cpp +++ b/applications/lfrfid/lfrfid_cli.cpp @@ -94,7 +94,7 @@ static void lfrfid_cli_read(Cli* cli, string_t args) { printf("\r\n"); break; } - furi_hal_delay_ms(100); + furi_delay_ms(100); } printf("Reading stopped\r\n"); @@ -144,7 +144,7 @@ static void lfrfid_cli_emulate(Cli* cli, string_t args) { printf("Emulating RFID...\r\nPress Ctrl+C to abort\r\n"); while(!cli_cmd_interrupt_received(cli)) { - furi_hal_delay_ms(100); + furi_delay_ms(100); } printf("Emulation stopped\r\n"); emulator.stop(); diff --git a/applications/lfrfid/scene/lfrfid_app_scene_emulate.cpp b/applications/lfrfid/scene/lfrfid_app_scene_emulate.cpp index 3df526d0..183361a0 100644 --- a/applications/lfrfid/scene/lfrfid_app_scene_emulate.cpp +++ b/applications/lfrfid/scene/lfrfid_app_scene_emulate.cpp @@ -1,5 +1,5 @@ #include "lfrfid_app_scene_emulate.h" -#include "furi/common_defines.h" +#include #include static const NotificationSequence sequence_blink_start_magenta = { diff --git a/applications/lfrfid/scene/lfrfid_app_scene_rpc.cpp b/applications/lfrfid/scene/lfrfid_app_scene_rpc.cpp index 012c96ac..80d47934 100644 --- a/applications/lfrfid/scene/lfrfid_app_scene_rpc.cpp +++ b/applications/lfrfid/scene/lfrfid_app_scene_rpc.cpp @@ -1,5 +1,5 @@ #include "lfrfid_app_scene_rpc.h" -#include "furi/common_defines.h" +#include #include void LfRfidAppSceneRpc::on_enter(LfRfidApp* app, bool /* need_restore */) { diff --git a/applications/loader/loader.c b/applications/loader/loader.c index 1acff8b7..f5db5586 100644 --- a/applications/loader/loader.c +++ b/applications/loader/loader.c @@ -471,7 +471,7 @@ int32_t loader_srv(void* p) { while(1) { uint32_t flags = - furi_thread_flags_wait(LOADER_THREAD_FLAG_ALL, osFlagsWaitAny, osWaitForever); + furi_thread_flags_wait(LOADER_THREAD_FLAG_ALL, FuriFlagWaitAny, FuriWaitForever); if(flags & LOADER_THREAD_FLAG_SHOW_MENU) { menu_set_selected_item(loader_instance->primary_menu, 0); view_dispatcher_switch_to_view( diff --git a/applications/loader/loader.h b/applications/loader/loader.h index b65539fe..4bf835b4 100644 --- a/applications/loader/loader.h +++ b/applications/loader/loader.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include typedef struct Loader Loader; diff --git a/applications/loader/loader_i.h b/applications/loader/loader_i.h index a311c6e8..db91f806 100644 --- a/applications/loader/loader_i.h +++ b/applications/loader/loader_i.h @@ -2,7 +2,7 @@ #include #include -#include +#include #include #include diff --git a/applications/music_player/music_player.c b/applications/music_player/music_player.c index 9b5dda0f..26dfb812 100644 --- a/applications/music_player/music_player.c +++ b/applications/music_player/music_player.c @@ -27,9 +27,9 @@ typedef struct { typedef struct { MusicPlayerModel* model; - osMutexId_t* model_mutex; + FuriMutex** model_mutex; - osMessageQueueId_t input_queue; + FuriMessageQueue* input_queue; ViewPort* view_port; Gui* gui; @@ -126,7 +126,7 @@ static bool is_black_note(uint8_t semitone, uint8_t id) { static void render_callback(Canvas* canvas, void* ctx) { MusicPlayer* music_player = ctx; - furi_check(osMutexAcquire(music_player->model_mutex, osWaitForever) == osOK); + furi_check(furi_mutex_acquire(music_player->model_mutex, FuriWaitForever) == FuriStatusOk); canvas_clear(canvas); canvas_set_color(canvas, ColorBlack); @@ -208,13 +208,13 @@ static void render_callback(Canvas* canvas, void* ctx) { canvas_draw_line(canvas, x_pos, 64 - 16 * i, x_pos + 48, 64 - 16 * i); } - osMutexRelease(music_player->model_mutex); + furi_mutex_release(music_player->model_mutex); } static void input_callback(InputEvent* input_event, void* ctx) { MusicPlayer* music_player = ctx; if(input_event->type == InputTypeShort) { - osMessageQueuePut(music_player->input_queue, input_event, 0, 0); + furi_message_queue_put(music_player->input_queue, input_event, 0); } } @@ -225,7 +225,7 @@ static void music_player_worker_callback( float position, void* context) { MusicPlayer* music_player = context; - furi_check(osMutexAcquire(music_player->model_mutex, osWaitForever) == osOK); + furi_check(furi_mutex_acquire(music_player->model_mutex, FuriWaitForever) == FuriStatusOk); for(size_t i = 0; i < MUSIC_PLAYER_SEMITONE_HISTORY_SIZE - 1; i++) { size_t r = MUSIC_PLAYER_SEMITONE_HISTORY_SIZE - 1 - i; @@ -243,7 +243,7 @@ static void music_player_worker_callback( music_player->model->semitone_history[0] = semitone; music_player->model->duration_history[0] = duration; - osMutexRelease(music_player->model_mutex); + furi_mutex_release(music_player->model_mutex); view_port_update(music_player->view_port); } @@ -255,9 +255,9 @@ MusicPlayer* music_player_alloc() { memset(instance->model->semitone_history, 0xff, MUSIC_PLAYER_SEMITONE_HISTORY_SIZE); instance->model->volume = 3; - instance->model_mutex = osMutexNew(NULL); + instance->model_mutex = furi_mutex_alloc(FuriMutexTypeNormal); - instance->input_queue = osMessageQueueNew(8, sizeof(InputEvent), NULL); + instance->input_queue = furi_message_queue_alloc(8, sizeof(InputEvent)); instance->worker = music_player_worker_alloc(); music_player_worker_set_volume( @@ -282,9 +282,9 @@ void music_player_free(MusicPlayer* instance) { music_player_worker_free(instance->worker); - osMessageQueueDelete(instance->input_queue); + furi_message_queue_free(instance->input_queue); - osMutexDelete(instance->model_mutex); + furi_mutex_free(instance->model_mutex); free(instance->model); free(instance); @@ -327,11 +327,13 @@ int32_t music_player_app(void* p) { music_player_worker_start(music_player->worker); InputEvent input; - while(osMessageQueueGet(music_player->input_queue, &input, NULL, osWaitForever) == osOK) { - furi_check(osMutexAcquire(music_player->model_mutex, osWaitForever) == osOK); + while(furi_message_queue_get(music_player->input_queue, &input, FuriWaitForever) == + FuriStatusOk) { + furi_check( + furi_mutex_acquire(music_player->model_mutex, FuriWaitForever) == FuriStatusOk); if(input.key == InputKeyBack) { - osMutexRelease(music_player->model_mutex); + furi_mutex_release(music_player->model_mutex); break; } else if(input.key == InputKeyUp) { if(music_player->model->volume < COUNT_OF(MUSIC_PLAYER_VOLUMES) - 1) @@ -344,7 +346,7 @@ int32_t music_player_app(void* p) { music_player->worker, MUSIC_PLAYER_VOLUMES[music_player->model->volume]); } - osMutexRelease(music_player->model_mutex); + furi_mutex_release(music_player->model_mutex); view_port_update(music_player->view_port); } diff --git a/applications/music_player/music_player_cli.c b/applications/music_player/music_player_cli.c index febb8b10..986c8781 100644 --- a/applications/music_player/music_player_cli.c +++ b/applications/music_player/music_player_cli.c @@ -26,7 +26,7 @@ static void music_player_cli(Cli* cli, string_t args, void* context) { music_player_worker_set_volume(music_player_worker, 1.0f); music_player_worker_start(music_player_worker); while(!cli_cmd_interrupt_received(cli)) { - osDelay(50); + furi_delay_ms(50); } music_player_worker_stop(music_player_worker); } while(0); diff --git a/applications/music_player/music_player_worker.c b/applications/music_player/music_player_worker.c index f43aa7be..835745b7 100644 --- a/applications/music_player/music_player_worker.c +++ b/applications/music_player/music_player_worker.c @@ -51,20 +51,20 @@ static int32_t music_player_worker_thread_callback(void* context) { while(instance->should_work) { if(NoteBlockArray_end_p(it)) { NoteBlockArray_it(it, instance->notes); - osDelay(10); + furi_delay_ms(10); } else { NoteBlock* note_block = NoteBlockArray_ref(it); float note_from_a4 = (float)note_block->semitone - NOTE_C4_SEMITONE; float frequency = NOTE_C4 * powf(TWO_POW_TWELTH_ROOT, note_from_a4); float duration = - 60.0 * osKernelGetTickFreq() * 4 / instance->bpm / note_block->duration; + 60.0 * furi_kernel_get_tick_frequency() * 4 / instance->bpm / note_block->duration; uint32_t dots = note_block->dots; while(dots > 0) { duration += duration / 2; dots--; } - uint32_t next_tick = furi_hal_get_tick() + duration; + uint32_t next_tick = furi_get_tick() + duration; float volume = instance->volume; if(instance->callback) { @@ -78,10 +78,10 @@ static int32_t music_player_worker_thread_callback(void* context) { furi_hal_speaker_stop(); furi_hal_speaker_start(frequency, volume); - while(instance->should_work && furi_hal_get_tick() < next_tick) { + while(instance->should_work && furi_get_tick() < next_tick) { volume *= 0.9945679; furi_hal_speaker_set_volume(volume); - furi_hal_delay_ms(2); + furi_delay_ms(2); } NoteBlockArray_next(it); } diff --git a/applications/nfc/helpers/nfc_debug_pcap.c b/applications/nfc/helpers/nfc_debug_pcap.c index 85e020b6..d340791b 100644 --- a/applications/nfc/helpers/nfc_debug_pcap.c +++ b/applications/nfc/helpers/nfc_debug_pcap.c @@ -77,8 +77,8 @@ static void .event = event, .len = len << 8 | len >> 8, }; - xStreamBufferSend(instance->stream, &pkt_hdr, sizeof(pkt_hdr), osWaitForever); - xStreamBufferSend(instance->stream, data, len, osWaitForever); + xStreamBufferSend(instance->stream, &pkt_hdr, sizeof(pkt_hdr), FuriWaitForever); + xStreamBufferSend(instance->stream, data, len, FuriWaitForever); } static void diff --git a/applications/nfc/nfc_cli.c b/applications/nfc/nfc_cli.c index 9b77a29f..bed00776 100755 --- a/applications/nfc/nfc_cli.c +++ b/applications/nfc/nfc_cli.c @@ -40,7 +40,7 @@ static void nfc_cli_detect(Cli* cli, string_t args) { break; } furi_hal_nfc_sleep(); - osDelay(50); + furi_delay_ms(50); } furi_hal_nfc_sleep(); } @@ -70,7 +70,7 @@ static void nfc_cli_emulate(Cli* cli, string_t args) { printf("Reader detected\r\n"); furi_hal_nfc_sleep(); } - osDelay(50); + furi_delay_ms(50); } furi_hal_nfc_sleep(); } @@ -90,7 +90,7 @@ static void nfc_cli_field(Cli* cli, string_t args) { printf("Press Ctrl+C to abort\r\n"); while(!cli_cmd_interrupt_received(cli)) { - osDelay(50); + furi_delay_ms(50); } furi_hal_nfc_field_off(); diff --git a/applications/nfc/nfc_worker.c b/applications/nfc/nfc_worker.c index 7d78fa74..0ca26736 100644 --- a/applications/nfc/nfc_worker.c +++ b/applications/nfc/nfc_worker.c @@ -23,7 +23,7 @@ NfcWorker* nfc_worker_alloc() { // Initialize rfal while(furi_hal_nfc_is_busy()) { - osDelay(10); + furi_delay_ms(10); } nfc_worker_change_state(nfc_worker, NfcWorkerStateReady); @@ -59,7 +59,7 @@ void nfc_worker_start( furi_assert(nfc_worker); furi_assert(dev_data); while(furi_hal_nfc_is_busy()) { - osDelay(10); + furi_delay_ms(10); } nfc_worker->callback = callback; @@ -148,7 +148,7 @@ void nfc_worker_detect(NfcWorker* nfc_worker) { break; } furi_hal_nfc_sleep(); - osDelay(100); + furi_delay_ms(100); } } @@ -203,7 +203,7 @@ void nfc_worker_read_emv_app(NfcWorker* nfc_worker) { FURI_LOG_D(TAG, "Can't find any cards"); } furi_hal_nfc_sleep(); - osDelay(20); + furi_delay_ms(20); } } @@ -252,7 +252,7 @@ void nfc_worker_read_emv(NfcWorker* nfc_worker) { FURI_LOG_D(TAG, "Can't find any cards"); } furi_hal_nfc_sleep(); - osDelay(20); + furi_delay_ms(20); } } @@ -277,7 +277,7 @@ void nfc_worker_emulate_apdu(NfcWorker* nfc_worker) { FURI_LOG_D(TAG, "Can't find reader"); } furi_hal_nfc_sleep(); - osDelay(20); + furi_delay_ms(20); } } @@ -312,7 +312,7 @@ void nfc_worker_read_mifare_ultralight(NfcWorker* nfc_worker) { FURI_LOG_D(TAG, "Can't find any tags"); } furi_hal_nfc_sleep(); - osDelay(100); + furi_delay_ms(100); } } @@ -434,7 +434,7 @@ void nfc_worker_mifare_classic_dict_attack(NfcWorker* nfc_worker) { } } if(nfc_worker->state != NfcWorkerStateReadMifareClassic) break; - osDelay(1); + furi_delay_tick(1); } if(nfc_worker->state != NfcWorkerStateReadMifareClassic) break; if(sector_key_found) { @@ -529,14 +529,14 @@ void nfc_worker_read_mifare_desfire(NfcWorker* nfc_worker) { while(nfc_worker->state == NfcWorkerStateReadMifareDesfire) { furi_hal_nfc_sleep(); if(!furi_hal_nfc_detect(nfc_data, 300)) { - osDelay(100); + furi_delay_ms(100); continue; } memset(data, 0, sizeof(MifareDesfireData)); if(nfc_data->type != FuriHalNfcTypeA || !mf_df_check_card_type(nfc_data->atqa[0], nfc_data->atqa[1], nfc_data->sak)) { FURI_LOG_D(TAG, "Tag is not DESFire"); - osDelay(100); + furi_delay_ms(100); continue; } diff --git a/applications/nfc/scenes/nfc_scene_emulate_apdu_sequence.c b/applications/nfc/scenes/nfc_scene_emulate_apdu_sequence.c index 2a6bb944..e6062ba4 100644 --- a/applications/nfc/scenes/nfc_scene_emulate_apdu_sequence.c +++ b/applications/nfc/scenes/nfc_scene_emulate_apdu_sequence.c @@ -1,5 +1,5 @@ #include "../nfc_i.h" -#include "furi/common_defines.h" +#include void nfc_scene_emulate_apdu_sequence_on_enter(void* context) { Nfc* nfc = context; diff --git a/applications/notification/notification_app.c b/applications/notification/notification_app.c index 9f362358..437d20ab 100644 --- a/applications/notification/notification_app.c +++ b/applications/notification/notification_app.c @@ -30,10 +30,12 @@ uint8_t notification_settings_get_rgb_led_brightness(NotificationApp* app, uint8 uint32_t notification_settings_display_off_delay_ticks(NotificationApp* app); void notification_message_save_settings(NotificationApp* app) { - NotificationAppMessage m = {.type = SaveSettingsMessage, .back_event = osEventFlagsNew(NULL)}; - furi_check(osMessageQueuePut(app->queue, &m, 0, osWaitForever) == osOK); - osEventFlagsWait(m.back_event, NOTIFICATION_EVENT_COMPLETE, osFlagsWaitAny, osWaitForever); - osEventFlagsDelete(m.back_event); + NotificationAppMessage m = { + .type = SaveSettingsMessage, .back_event = furi_event_flag_alloc()}; + furi_check(furi_message_queue_put(app->queue, &m, FuriWaitForever) == FuriStatusOk); + furi_event_flag_wait( + m.back_event, NOTIFICATION_EVENT_COMPLETE, FuriFlagWaitAny, FuriWaitForever); + furi_event_flag_free(m.back_event); }; // internal layer @@ -112,7 +114,7 @@ void notification_reset_notification_layer(NotificationApp* app, uint8_t reset_m notification_sound_off(); } if(reset_mask & reset_display_mask) { - osTimerStart(app->display_timer, notification_settings_display_off_delay_ticks(app)); + furi_timer_start(app->display_timer, notification_settings_display_off_delay_ticks(app)); } } @@ -133,7 +135,9 @@ uint8_t notification_settings_get_rgb_led_brightness(NotificationApp* app, uint8 } uint32_t notification_settings_display_off_delay_ticks(NotificationApp* app) { - return ((float)(app->settings.display_off_delay_ms) / (1000.0f / osKernelGetTickFreq())); + return ( + (float)(app->settings.display_off_delay_ms) / + (1000.0f / furi_kernel_get_tick_frequency())); } // generics @@ -189,8 +193,8 @@ void notification_process_notification_message( notification_message->data.led.value * display_brightness_setting); } else { notification_reset_notification_led_layer(&app->display); - if(osTimerIsRunning(app->display_timer)) { - osTimerStop(app->display_timer); + if(furi_timer_is_running(app->display_timer)) { + furi_timer_stop(app->display_timer); } } reset_mask |= reset_display_mask; @@ -280,7 +284,7 @@ void notification_process_notification_message( if(led_active) { if(notification_is_any_led_layer_internal_and_not_empty(app)) { notification_apply_notification_leds(app, led_off_values); - furi_hal_delay_ms(minimal_delay); + furi_delay_ms(minimal_delay); } led_active = false; @@ -291,7 +295,7 @@ void notification_process_notification_message( reset_mask |= reset_blue_mask; } - furi_hal_delay_ms(notification_message->data.delay.length); + furi_delay_ms(notification_message->data.delay.length); break; case NotificationMessageTypeDoNotReset: reset_notifications = false; @@ -334,7 +338,7 @@ void notification_process_notification_message( if((need_minimal_delay) && (reset_notifications)) { notification_apply_notification_leds(app, led_off_values); - furi_hal_delay_ms(minimal_delay); + furi_delay_ms(minimal_delay); } } @@ -416,9 +420,9 @@ static bool notification_load_settings(NotificationApp* app) { FURI_LOG_E( TAG, "version(%d != %d) mismatch", settings.version, NOTIFICATION_SETTINGS_VERSION); } else { - osKernelLock(); + furi_kernel_lock(); memcpy(&app->settings, &settings, settings_size); - osKernelUnlock(); + furi_kernel_unlock(); } } else { FURI_LOG_E(TAG, "load failed, %s", storage_file_get_error_desc(file)); @@ -438,9 +442,9 @@ static bool notification_save_settings(NotificationApp* app) { FURI_LOG_I(TAG, "saving settings to \"%s\"", NOTIFICATION_SETTINGS_PATH); - osKernelLock(); + furi_kernel_lock(); memcpy(&settings, &app->settings, settings_size); - osKernelUnlock(); + furi_kernel_unlock(); bool fs_result = storage_file_open(file, NOTIFICATION_SETTINGS_PATH, FSAM_WRITE, FSOM_CREATE_ALWAYS); @@ -476,8 +480,8 @@ static void input_event_callback(const void* value, void* context) { // App alloc static NotificationApp* notification_app_alloc() { NotificationApp* app = malloc(sizeof(NotificationApp)); - app->queue = osMessageQueueNew(8, sizeof(NotificationAppMessage), NULL); - app->display_timer = osTimerNew(notification_display_timer, osTimerOnce, app, NULL); + app->queue = furi_message_queue_alloc(8, sizeof(NotificationAppMessage)); + app->display_timer = furi_timer_alloc(notification_display_timer, FuriTimerTypeOnce, app); app->settings.speaker_volume = 1.0f; app->settings.display_brightness = 1.0f; @@ -535,7 +539,7 @@ int32_t notification_srv(void* p) { NotificationAppMessage message; while(1) { - furi_check(osMessageQueueGet(app->queue, &message, NULL, osWaitForever) == osOK); + furi_check(furi_message_queue_get(app->queue, &message, FuriWaitForever) == FuriStatusOk); switch(message.type) { case NotificationLayerMessage: @@ -550,7 +554,7 @@ int32_t notification_srv(void* p) { } if(message.back_event != NULL) { - osEventFlagsSet(message.back_event, NOTIFICATION_EVENT_COMPLETE); + furi_event_flag_set(message.back_event, NOTIFICATION_EVENT_COMPLETE); } } diff --git a/applications/notification/notification_app.h b/applications/notification/notification_app.h index b56b7e3b..f5c7cc46 100644 --- a/applications/notification/notification_app.h +++ b/applications/notification/notification_app.h @@ -15,7 +15,7 @@ typedef enum { typedef struct { const NotificationSequence* sequence; NotificationAppMessageType type; - osEventFlagsId_t back_event; + FuriEventFlag* back_event; } NotificationAppMessage; typedef enum { @@ -44,9 +44,9 @@ typedef struct { } NotificationSettings; struct NotificationApp { - osMessageQueueId_t queue; + FuriMessageQueue* queue; FuriPubSub* event_record; - osTimerId_t display_timer; + FuriTimer* display_timer; NotificationLedLayer display; NotificationLedLayer led[NOTIFICATION_LED_COUNT]; diff --git a/applications/notification/notification_app_api.c b/applications/notification/notification_app_api.c index d11a289b..9bc06b01 100644 --- a/applications/notification/notification_app_api.c +++ b/applications/notification/notification_app_api.c @@ -7,31 +7,33 @@ void notification_message(NotificationApp* app, const NotificationSequence* sequence) { NotificationAppMessage m = { .type = NotificationLayerMessage, .sequence = sequence, .back_event = NULL}; - furi_check(osMessageQueuePut(app->queue, &m, 0, osWaitForever) == osOK); + furi_check(furi_message_queue_put(app->queue, &m, FuriWaitForever) == FuriStatusOk); }; void notification_internal_message(NotificationApp* app, const NotificationSequence* sequence) { NotificationAppMessage m = { .type = InternalLayerMessage, .sequence = sequence, .back_event = NULL}; - furi_check(osMessageQueuePut(app->queue, &m, 0, osWaitForever) == osOK); + furi_check(furi_message_queue_put(app->queue, &m, FuriWaitForever) == FuriStatusOk); }; void notification_message_block(NotificationApp* app, const NotificationSequence* sequence) { NotificationAppMessage m = { .type = NotificationLayerMessage, .sequence = sequence, - .back_event = osEventFlagsNew(NULL)}; - furi_check(osMessageQueuePut(app->queue, &m, 0, osWaitForever) == osOK); - osEventFlagsWait(m.back_event, NOTIFICATION_EVENT_COMPLETE, osFlagsWaitAny, osWaitForever); - osEventFlagsDelete(m.back_event); + .back_event = furi_event_flag_alloc()}; + furi_check(furi_message_queue_put(app->queue, &m, FuriWaitForever) == FuriStatusOk); + furi_event_flag_wait( + m.back_event, NOTIFICATION_EVENT_COMPLETE, FuriFlagWaitAny, FuriWaitForever); + furi_event_flag_free(m.back_event); }; void notification_internal_message_block( NotificationApp* app, const NotificationSequence* sequence) { NotificationAppMessage m = { - .type = InternalLayerMessage, .sequence = sequence, .back_event = osEventFlagsNew(NULL)}; - furi_check(osMessageQueuePut(app->queue, &m, 0, osWaitForever) == osOK); - osEventFlagsWait(m.back_event, NOTIFICATION_EVENT_COMPLETE, osFlagsWaitAny, osWaitForever); - osEventFlagsDelete(m.back_event); + .type = InternalLayerMessage, .sequence = sequence, .back_event = furi_event_flag_alloc()}; + furi_check(furi_message_queue_put(app->queue, &m, FuriWaitForever) == FuriStatusOk); + furi_event_flag_wait( + m.back_event, NOTIFICATION_EVENT_COMPLETE, FuriFlagWaitAny, FuriWaitForever); + furi_event_flag_free(m.back_event); }; diff --git a/applications/picopass/picopass_worker.c b/applications/picopass/picopass_worker.c index 40fe4448..645a1bce 100644 --- a/applications/picopass/picopass_worker.c +++ b/applications/picopass/picopass_worker.c @@ -305,6 +305,6 @@ void picopass_worker_detect(PicopassWorker* picopass_worker) { } break; } - osDelay(100); + furi_delay_ms(100); } } diff --git a/applications/power/power_cli.c b/applications/power/power_cli.c index d474a729..8c6a986d 100644 --- a/applications/power/power_cli.c +++ b/applications/power/power_cli.c @@ -10,7 +10,7 @@ void power_cli_off(Cli* cli, string_t args) { UNUSED(args); Power* power = furi_record_open("power"); printf("It's now safe to disconnect USB from your flipper\r\n"); - osDelay(666); + furi_delay_ms(666); power_off(power); } diff --git a/applications/power/power_service/power.c b/applications/power/power_service/power.c index 1315809e..991c2a81 100644 --- a/applications/power/power_service/power.c +++ b/applications/power/power_service/power.c @@ -51,7 +51,7 @@ Power* power_alloc() { power->state = PowerStateNotCharging; power->battery_low = false; power->power_off_timeout = POWER_OFF_TIMEOUT; - power->api_mtx = osMutexNew(NULL); + power->api_mtx = furi_mutex_alloc(FuriMutexTypeNormal); // Gui power->view_dispatcher = view_dispatcher_alloc(); @@ -83,7 +83,7 @@ void power_free(Power* power) { view_port_free(power->battery_view_port); // State - osMutexDelete(power->api_mtx); + furi_mutex_free(power->api_mtx); // FuriPubSub furi_pubsub_free(power->event_pubsub); @@ -138,10 +138,10 @@ static bool power_update_info(Power* power) { info.temperature_charger = furi_hal_power_get_battery_temperature(FuriHalPowerICCharger); info.temperature_gauge = furi_hal_power_get_battery_temperature(FuriHalPowerICFuelGauge); - osMutexAcquire(power->api_mtx, osWaitForever); + furi_mutex_acquire(power->api_mtx, FuriWaitForever); bool need_refresh = power->info.charge != info.charge; power->info = info; - osMutexRelease(power->api_mtx); + furi_mutex_release(power->api_mtx); return need_refresh; } @@ -226,7 +226,7 @@ int32_t power_srv(void* p) { furi_hal_power_check_otg_status(); } - osDelay(1000); + furi_delay_ms(1000); } power_free(power); diff --git a/applications/power/power_service/power.h b/applications/power/power_service/power.h index c32c31b3..cea1663f 100644 --- a/applications/power/power_service/power.h +++ b/applications/power/power_service/power.h @@ -1,7 +1,7 @@ #pragma once #include -#include +#include #include typedef struct Power Power; diff --git a/applications/power/power_service/power_api.c b/applications/power/power_service/power_api.c index 865c21c8..d26fb3b4 100644 --- a/applications/power/power_service/power_api.c +++ b/applications/power/power_service/power_api.c @@ -9,7 +9,7 @@ void power_off(Power* power) { // Notify user if USB is plugged view_dispatcher_send_to_front(power->view_dispatcher); view_dispatcher_switch_to_view(power->view_dispatcher, PowerViewPopup); - osDelay(10); + furi_delay_ms(10); furi_halt("Disconnect USB for safe shutdown"); } @@ -28,9 +28,9 @@ void power_get_info(Power* power, PowerInfo* info) { furi_assert(power); furi_assert(info); - osMutexAcquire(power->api_mtx, osWaitForever); + furi_mutex_acquire(power->api_mtx, FuriWaitForever); memcpy(info, &power->info, sizeof(power->info)); - osMutexRelease(power->api_mtx); + furi_mutex_release(power->api_mtx); } FuriPubSub* power_get_pubsub(Power* power) { @@ -41,15 +41,15 @@ FuriPubSub* power_get_pubsub(Power* power) { bool power_is_battery_healthy(Power* power) { furi_assert(power); bool is_healthy = false; - osMutexAcquire(power->api_mtx, osWaitForever); + furi_mutex_acquire(power->api_mtx, FuriWaitForever); is_healthy = power->info.health > POWER_BATTERY_HEALTHY_LEVEL; - osMutexRelease(power->api_mtx); + furi_mutex_release(power->api_mtx); return is_healthy; } void power_enable_low_battery_level_notification(Power* power, bool enable) { furi_assert(power); - osMutexAcquire(power->api_mtx, osWaitForever); + furi_mutex_acquire(power->api_mtx, FuriWaitForever); power->show_low_bat_level_message = enable; - osMutexRelease(power->api_mtx); + furi_mutex_release(power->api_mtx); } diff --git a/applications/power/power_service/power_i.h b/applications/power/power_service/power_i.h index f88b8f24..c7181d0a 100755 --- a/applications/power/power_service/power_i.h +++ b/applications/power/power_service/power_i.h @@ -38,7 +38,7 @@ struct Power { uint8_t battery_level; uint8_t power_off_timeout; - osMutexId_t api_mtx; + FuriMutex* api_mtx; }; typedef enum { diff --git a/applications/rpc/rpc.c b/applications/rpc/rpc.c index ce063b8e..a85d0a42 100644 --- a/applications/rpc/rpc.c +++ b/applications/rpc/rpc.c @@ -68,7 +68,7 @@ struct RpcSession { void** system_contexts; bool decode_error; - osMutexId_t callbacks_mutex; + FuriMutex* callbacks_mutex; RpcSendBytesCallback send_bytes_callback; RpcBufferIsEmptyCallback buffer_is_empty_callback; RpcSessionClosedCallback closed_callback; @@ -77,7 +77,7 @@ struct RpcSession { }; struct Rpc { - osMutexId_t busy_mutex; + FuriMutex* busy_mutex; }; static bool content_callback(pb_istream_t* stream, const pb_field_t* field, void** arg); @@ -89,13 +89,13 @@ static void rpc_close_session_process(const PB_Main* request, void* context) { furi_assert(session); rpc_send_and_release_empty(session, request->command_id, PB_CommandStatus_OK); - osMutexAcquire(session->callbacks_mutex, osWaitForever); + furi_mutex_acquire(session->callbacks_mutex, FuriWaitForever); if(session->closed_callback) { session->closed_callback(session->context); } else { FURI_LOG_W(TAG, "Session stop isn't processed by transport layer"); } - osMutexRelease(session->callbacks_mutex); + furi_mutex_release(session->callbacks_mutex); } static size_t rpc_sprintf_msg_file( @@ -359,25 +359,25 @@ void rpc_print_message(const PB_Main* message) { void rpc_session_set_context(RpcSession* session, void* context) { furi_assert(session); - osMutexAcquire(session->callbacks_mutex, osWaitForever); + furi_mutex_acquire(session->callbacks_mutex, FuriWaitForever); session->context = context; - osMutexRelease(session->callbacks_mutex); + furi_mutex_release(session->callbacks_mutex); } void rpc_session_set_close_callback(RpcSession* session, RpcSessionClosedCallback callback) { furi_assert(session); - osMutexAcquire(session->callbacks_mutex, osWaitForever); + furi_mutex_acquire(session->callbacks_mutex, FuriWaitForever); session->closed_callback = callback; - osMutexRelease(session->callbacks_mutex); + furi_mutex_release(session->callbacks_mutex); } void rpc_session_set_send_bytes_callback(RpcSession* session, RpcSendBytesCallback callback) { furi_assert(session); - osMutexAcquire(session->callbacks_mutex, osWaitForever); + furi_mutex_acquire(session->callbacks_mutex, FuriWaitForever); session->send_bytes_callback = callback; - osMutexRelease(session->callbacks_mutex); + furi_mutex_release(session->callbacks_mutex); } void rpc_session_set_buffer_is_empty_callback( @@ -385,9 +385,9 @@ void rpc_session_set_buffer_is_empty_callback( RpcBufferIsEmptyCallback callback) { furi_assert(session); - osMutexAcquire(session->callbacks_mutex, osWaitForever); + furi_mutex_acquire(session->callbacks_mutex, FuriWaitForever); session->buffer_is_empty_callback = callback; - osMutexRelease(session->callbacks_mutex); + furi_mutex_release(session->callbacks_mutex); } void rpc_session_set_terminated_callback( @@ -395,9 +395,9 @@ void rpc_session_set_terminated_callback( RpcSessionTerminatedCallback callback) { furi_assert(session); - osMutexAcquire(session->callbacks_mutex, osWaitForever); + furi_mutex_acquire(session->callbacks_mutex, FuriWaitForever); session->terminated_callback = callback; - osMutexRelease(session->callbacks_mutex); + furi_mutex_release(session->callbacks_mutex); } /* Doesn't forbid using rpc_feed_bytes() after session close - it's safe. @@ -444,7 +444,7 @@ bool rpc_pb_stream_read(pb_istream_t* istream, pb_byte_t* buf, size_t count) { if(count == bytes_received) { break; } else { - flags = furi_thread_flags_wait(RPC_ALL_EVENTS, osFlagsWaitAny, osWaitForever); + flags = furi_thread_flags_wait(RPC_ALL_EVENTS, FuriFlagWaitAny, FuriWaitForever); if(flags & RpcEvtDisconnect) { if(xStreamBufferIsEmpty(session->stream)) { session->terminate = true; @@ -508,9 +508,9 @@ static int32_t rpc_session_worker(void* context) { RpcHandlerDict_get(session->handlers, session->decoded_message->which_content); if(handler && handler->message_handler) { - furi_check(osMutexAcquire(rpc->busy_mutex, osWaitForever) == osOK); + furi_check(furi_mutex_acquire(rpc->busy_mutex, FuriWaitForever) == FuriStatusOk); handler->message_handler(session->decoded_message, handler->context); - furi_check(osMutexRelease(rpc->busy_mutex) == osOK); + furi_check(furi_mutex_release(rpc->busy_mutex) == FuriStatusOk); } else if(session->decoded_message->which_content == 0) { /* Receiving zeroes means message is 0-length, which * is valid for proto3: all fields are filled with default values. @@ -551,11 +551,11 @@ static int32_t rpc_session_worker(void* context) { FURI_LOG_E(TAG, "Decode failed, error: \'%.128s\'", PB_GET_ERROR(&istream)); session->decode_error = true; rpc_send_and_release_empty(session, 0, PB_CommandStatus_ERROR_DECODE); - osMutexAcquire(session->callbacks_mutex, osWaitForever); + furi_mutex_acquire(session->callbacks_mutex, FuriWaitForever); if(session->closed_callback) { session->closed_callback(session->context); } - osMutexRelease(session->callbacks_mutex); + furi_mutex_release(session->callbacks_mutex); } } @@ -586,13 +586,13 @@ static void rpc_session_free_callback(FuriThreadState thread_state, void* contex RpcHandlerDict_clear(session->handlers); vStreamBufferDelete(session->stream); - osMutexAcquire(session->callbacks_mutex, osWaitForever); + furi_mutex_acquire(session->callbacks_mutex, FuriWaitForever); if(session->terminated_callback) { session->terminated_callback(session->context); } - osMutexRelease(session->callbacks_mutex); + furi_mutex_release(session->callbacks_mutex); - osMutexDelete(session->callbacks_mutex); + furi_mutex_free(session->callbacks_mutex); furi_thread_free(session->thread); free(session); } @@ -602,7 +602,7 @@ RpcSession* rpc_session_open(Rpc* rpc) { furi_assert(rpc); RpcSession* session = malloc(sizeof(RpcSession)); - session->callbacks_mutex = osMutexNew(NULL); + session->callbacks_mutex = furi_mutex_alloc(FuriMutexTypeNormal); session->stream = xStreamBufferCreate(RPC_BUFFER_SIZE, 1); session->rpc = rpc; session->terminate = false; @@ -653,7 +653,7 @@ int32_t rpc_srv(void* p) { UNUSED(p); Rpc* rpc = malloc(sizeof(Rpc)); - rpc->busy_mutex = osMutexNew(NULL); + rpc->busy_mutex = furi_mutex_alloc(FuriMutexTypeNormal); Cli* cli = furi_record_open("cli"); cli_add_command( @@ -693,11 +693,11 @@ void rpc_send(RpcSession* session, PB_Main* message) { rpc_print_data("OUTPUT", buffer, ostream.bytes_written); #endif - osMutexAcquire(session->callbacks_mutex, osWaitForever); + furi_mutex_acquire(session->callbacks_mutex, FuriWaitForever); if(session->send_bytes_callback) { session->send_bytes_callback(session->context, buffer, ostream.bytes_written); } - osMutexRelease(session->callbacks_mutex); + furi_mutex_release(session->callbacks_mutex); free(buffer); } diff --git a/applications/rpc/rpc_app.c b/applications/rpc/rpc_app.c index f6678c3b..84cb5410 100644 --- a/applications/rpc/rpc_app.c +++ b/applications/rpc/rpc_app.c @@ -1,6 +1,5 @@ -#include "cmsis_os2.h" #include "flipper.pb.h" -#include "furi/record.h" +#include #include "rpc_i.h" #include #include @@ -13,7 +12,7 @@ struct RpcAppSystem { RpcSession* session; RpcAppSystemCallback app_callback; void* app_context; - osTimerId_t timer; + FuriTimer* timer; }; static void rpc_system_app_timer_callback(void* context) { @@ -111,7 +110,7 @@ static void rpc_system_app_exit(const PB_Main* request, void* context) { if(rpc_app->app_callback) { if(rpc_app->app_callback(RpcAppEventAppExit, NULL, rpc_app->app_context)) { status = PB_CommandStatus_OK; - osTimerStop(rpc_app->timer); + furi_timer_stop(rpc_app->timer); } else { status = PB_CommandStatus_ERROR_APP_CMD_ERROR; } @@ -160,7 +159,7 @@ static void rpc_system_app_button_press(const PB_Main* request, void* context) { const char* args = request->content.app_button_press_request.args; if(rpc_app->app_callback(RpcAppEventButtonPress, args, rpc_app->app_context)) { status = PB_CommandStatus_OK; - osTimerStart(rpc_app->timer, APP_BUTTON_TIMEOUT); + furi_timer_start(rpc_app->timer, APP_BUTTON_TIMEOUT); } else { status = PB_CommandStatus_ERROR_APP_CMD_ERROR; } @@ -184,7 +183,7 @@ static void rpc_system_app_button_release(const PB_Main* request, void* context) if(rpc_app->app_callback) { if(rpc_app->app_callback(RpcAppEventButtonRelease, NULL, rpc_app->app_context)) { status = PB_CommandStatus_OK; - osTimerStop(rpc_app->timer); + furi_timer_stop(rpc_app->timer); } else { status = PB_CommandStatus_ERROR_APP_CMD_ERROR; } @@ -208,7 +207,7 @@ void* rpc_system_app_alloc(RpcSession* session) { RpcAppSystem* rpc_app = malloc(sizeof(RpcAppSystem)); rpc_app->session = session; - rpc_app->timer = osTimerNew(rpc_system_app_timer_callback, osTimerOnce, rpc_app, NULL); + rpc_app->timer = furi_timer_alloc(rpc_system_app_timer_callback, FuriTimerTypeOnce, rpc_app); RpcHandler rpc_handler = { .message_handler = NULL, @@ -242,7 +241,7 @@ void rpc_system_app_free(void* context) { RpcSession* session = rpc_app->session; furi_assert(session); - osTimerDelete(rpc_app->timer); + furi_timer_free(rpc_app->timer); if(rpc_app->app_callback) { rpc_app->app_callback(RpcAppEventSessionClose, NULL, rpc_app->app_context); diff --git a/applications/rpc/rpc_cli.c b/applications/rpc/rpc_cli.c index 1c8991bc..efc67219 100644 --- a/applications/rpc/rpc_cli.c +++ b/applications/rpc/rpc_cli.c @@ -9,7 +9,7 @@ typedef struct { Cli* cli; bool session_close_request; - osSemaphoreId_t terminate_semaphore; + FuriSemaphore* terminate_semaphore; } CliRpc; #define CLI_READ_BUFFER_SIZE 64 @@ -34,7 +34,7 @@ static void rpc_session_terminated_callback(void* context) { furi_check(context); CliRpc* cli_rpc = context; - osSemaphoreRelease(cli_rpc->terminate_semaphore); + furi_semaphore_release(cli_rpc->terminate_semaphore); } void rpc_cli_command_start_session(Cli* cli, string_t args, void* context) { @@ -53,7 +53,7 @@ void rpc_cli_command_start_session(Cli* cli, string_t args, void* context) { } CliRpc cli_rpc = {.cli = cli, .session_close_request = false}; - cli_rpc.terminate_semaphore = osSemaphoreNew(1, 0, NULL); + cli_rpc.terminate_semaphore = furi_semaphore_alloc(1, 0); rpc_session_set_context(rpc_session, &cli_rpc); rpc_session_set_send_bytes_callback(rpc_session, rpc_send_bytes_callback); rpc_session_set_close_callback(rpc_session, rpc_session_close_callback); @@ -77,9 +77,10 @@ void rpc_cli_command_start_session(Cli* cli, string_t args, void* context) { rpc_session_close(rpc_session); - furi_check(osSemaphoreAcquire(cli_rpc.terminate_semaphore, osWaitForever) == osOK); + furi_check( + furi_semaphore_acquire(cli_rpc.terminate_semaphore, FuriWaitForever) == FuriStatusOk); - osSemaphoreDelete(cli_rpc.terminate_semaphore); + furi_semaphore_free(cli_rpc.terminate_semaphore); free(buffer); furi_hal_usb_unlock(); diff --git a/applications/rpc/rpc_gui.c b/applications/rpc/rpc_gui.c index da91ae06..62a232d8 100644 --- a/applications/rpc/rpc_gui.c +++ b/applications/rpc/rpc_gui.c @@ -50,7 +50,7 @@ static int32_t rpc_system_gui_screen_stream_frame_transmit_thread(void* context) while(true) { uint32_t flags = - furi_thread_flags_wait(RpcGuiWorkerFlagAny, osFlagsWaitAny, osWaitForever); + furi_thread_flags_wait(RpcGuiWorkerFlagAny, FuriFlagWaitAny, FuriWaitForever); if(flags & RpcGuiWorkerFlagTransmit) { rpc_send(rpc_gui->session, rpc_gui->transmit_frame); } diff --git a/applications/rpc/rpc_storage.c b/applications/rpc/rpc_storage.c index 336346b5..4ab681ae 100644 --- a/applications/rpc/rpc_storage.c +++ b/applications/rpc/rpc_storage.c @@ -1,7 +1,7 @@ #include "flipper.pb.h" -#include "furi/common_defines.h" -#include "furi/memmgr.h" -#include "furi/record.h" +#include +#include +#include #include "pb_decode.h" #include "rpc/rpc.h" #include "rpc_i.h" diff --git a/applications/snake_game/snake_game.c b/applications/snake_game/snake_game.c index 1a4bf812..bfd31ced 100644 --- a/applications/snake_game/snake_game.c +++ b/applications/snake_game/snake_game.c @@ -105,18 +105,18 @@ static void snake_game_render_callback(Canvas* const canvas, void* ctx) { release_mutex((ValueMutex*)ctx, snake_state); } -static void snake_game_input_callback(InputEvent* input_event, osMessageQueueId_t event_queue) { +static void snake_game_input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { furi_assert(event_queue); SnakeEvent event = {.type = EventTypeKey, .input = *input_event}; - osMessageQueuePut(event_queue, &event, 0, osWaitForever); + furi_message_queue_put(event_queue, &event, FuriWaitForever); } -static void snake_game_update_timer_callback(osMessageQueueId_t event_queue) { +static void snake_game_update_timer_callback(FuriMessageQueue* event_queue) { furi_assert(event_queue); SnakeEvent event = {.type = EventTypeTick}; - osMessageQueuePut(event_queue, &event, 0, 0); + furi_message_queue_put(event_queue, &event, 0); } static void snake_game_init_game(SnakeState* const snake_state) { @@ -283,7 +283,7 @@ int32_t snake_game_app(void* p) { UNUSED(p); srand(DWT->CYCCNT); - osMessageQueueId_t event_queue = osMessageQueueNew(8, sizeof(SnakeEvent), NULL); + FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(SnakeEvent)); SnakeState* snake_state = malloc(sizeof(SnakeState)); snake_game_init_game(snake_state); @@ -299,9 +299,9 @@ int32_t snake_game_app(void* p) { view_port_draw_callback_set(view_port, snake_game_render_callback, &state_mutex); view_port_input_callback_set(view_port, snake_game_input_callback, event_queue); - osTimerId_t timer = - osTimerNew(snake_game_update_timer_callback, osTimerPeriodic, event_queue, NULL); - osTimerStart(timer, osKernelGetTickFreq() / 4); + FuriTimer* timer = + furi_timer_alloc(snake_game_update_timer_callback, FuriTimerTypePeriodic, event_queue); + furi_timer_start(timer, furi_kernel_get_tick_frequency() / 4); // Open GUI and register view_port Gui* gui = furi_record_open("gui"); @@ -309,11 +309,11 @@ int32_t snake_game_app(void* p) { SnakeEvent event; for(bool processing = true; processing;) { - osStatus_t event_status = osMessageQueueGet(event_queue, &event, NULL, 100); + FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100); SnakeState* snake_state = (SnakeState*)acquire_mutex_block(&state_mutex); - if(event_status == osOK) { + if(event_status == FuriStatusOk) { // press events if(event.type == EventTypeKey) { if(event.input.type == InputTypePress) { @@ -351,12 +351,12 @@ int32_t snake_game_app(void* p) { release_mutex(&state_mutex, snake_state); } - osTimerDelete(timer); + furi_timer_free(timer); view_port_enabled_set(view_port, false); gui_remove_view_port(gui, view_port); furi_record_close("gui"); view_port_free(view_port); - osMessageQueueDelete(event_queue); + furi_message_queue_free(event_queue); delete_mutex(&state_mutex); free(snake_state); diff --git a/applications/storage/storage.c b/applications/storage/storage.c index b280547b..90a191a2 100644 --- a/applications/storage/storage.c +++ b/applications/storage/storage.c @@ -33,7 +33,7 @@ static void storage_app_sd_icon_draw_callback(Canvas* canvas, void* context) { Storage* storage_app_alloc() { Storage* app = malloc(sizeof(Storage)); - app->message_queue = osMessageQueueNew(8, sizeof(StorageMessage), NULL); + app->message_queue = furi_message_queue_alloc(8, sizeof(StorageMessage)); app->pubsub = furi_pubsub_alloc(); for(uint8_t i = 0; i < STORAGE_COUNT; i++) { @@ -106,7 +106,7 @@ int32_t storage_srv(void* p) { StorageMessage message; while(1) { - if(osMessageQueueGet(app->message_queue, &message, NULL, STORAGE_TICK) == osOK) { + if(furi_message_queue_get(app->message_queue, &message, STORAGE_TICK) == FuriStatusOk) { storage_process_message(app, &message); } else { storage_tick(app); diff --git a/applications/storage/storage_external_api.c b/applications/storage/storage_external_api.c index dc29faa6..426fac9a 100644 --- a/applications/storage/storage_external_api.c +++ b/applications/storage/storage_external_api.c @@ -1,5 +1,5 @@ -#include "furi/log.h" -#include +#include +#include #include #include "storage.h" #include "storage_i.h" @@ -13,18 +13,20 @@ #define TAG "StorageAPI" -#define S_API_PROLOGUE \ - osSemaphoreId_t semaphore = osSemaphoreNew(1, 0, NULL); \ +#define S_API_PROLOGUE \ + FuriSemaphore* semaphore = furi_semaphore_alloc(1, 0); \ furi_check(semaphore != NULL); #define S_FILE_API_PROLOGUE \ Storage* storage = file->storage; \ furi_assert(storage); -#define S_API_EPILOGUE \ - furi_check(osMessageQueuePut(storage->message_queue, &message, 0, osWaitForever) == osOK); \ - osSemaphoreAcquire(semaphore, osWaitForever); \ - osSemaphoreDelete(semaphore); +#define S_API_EPILOGUE \ + furi_check( \ + furi_message_queue_put(storage->message_queue, &message, FuriWaitForever) == \ + FuriStatusOk); \ + furi_semaphore_acquire(semaphore, FuriWaitForever); \ + furi_semaphore_free(semaphore); #define S_API_MESSAGE(_command) \ SAReturn return_data; \ @@ -88,8 +90,8 @@ static void storage_file_close_callback(const void* message, void* context) { if(storage_event->type == StorageEventTypeFileClose || storage_event->type == StorageEventTypeDirClose) { furi_assert(context); - osEventFlagsId_t event = context; - osEventFlagsSet(event, StorageEventFlagFileClose); + FuriEventFlag* event = context; + furi_event_flag_set(event, StorageEventFlagFileClose); } } @@ -99,7 +101,7 @@ bool storage_file_open( FS_AccessMode access_mode, FS_OpenMode open_mode) { bool result; - osEventFlagsId_t event = osEventFlagsNew(NULL); + FuriEventFlag* event = furi_event_flag_alloc(); FuriPubSubSubscription* subscription = furi_pubsub_subscribe( storage_get_pubsub(file->storage), storage_file_close_callback, event); @@ -107,14 +109,15 @@ bool storage_file_open( result = storage_file_open_internal(file, path, access_mode, open_mode); if(!result && file->error_id == FSE_ALREADY_OPEN) { - osEventFlagsWait(event, StorageEventFlagFileClose, osFlagsWaitAny, osWaitForever); + furi_event_flag_wait( + event, StorageEventFlagFileClose, FuriFlagWaitAny, FuriWaitForever); } else { break; } } while(true); furi_pubsub_unsubscribe(storage_get_pubsub(file->storage), subscription); - osEventFlagsDelete(event); + furi_event_flag_free(event); FURI_LOG_T( TAG, "File %p - %p open (%s)", (uint32_t)file - SRAM_BASE, file->file_id - SRAM_BASE, path); @@ -258,7 +261,7 @@ static bool storage_dir_open_internal(File* file, const char* path) { bool storage_dir_open(File* file, const char* path) { bool result; - osEventFlagsId_t event = osEventFlagsNew(NULL); + FuriEventFlag* event = furi_event_flag_alloc(); FuriPubSubSubscription* subscription = furi_pubsub_subscribe( storage_get_pubsub(file->storage), storage_file_close_callback, event); @@ -266,14 +269,15 @@ bool storage_dir_open(File* file, const char* path) { result = storage_dir_open_internal(file, path); if(!result && file->error_id == FSE_ALREADY_OPEN) { - osEventFlagsWait(event, StorageEventFlagFileClose, osFlagsWaitAny, osWaitForever); + furi_event_flag_wait( + event, StorageEventFlagFileClose, FuriFlagWaitAny, FuriWaitForever); } else { break; } } while(true); furi_pubsub_unsubscribe(storage_get_pubsub(file->storage), subscription); - osEventFlagsDelete(event); + furi_event_flag_free(event); FURI_LOG_T( TAG, "Dir %p - %p open (%s)", (uint32_t)file - SRAM_BASE, file->file_id - SRAM_BASE, path); diff --git a/applications/storage/storage_glue.c b/applications/storage/storage_glue.c index 09656ae3..d9d599c5 100644 --- a/applications/storage/storage_glue.c +++ b/applications/storage/storage_glue.c @@ -31,7 +31,7 @@ void storage_file_clear(StorageFile* obj) { /****************** storage data ******************/ void storage_data_init(StorageData* storage) { - storage->mutex = osMutexNew(NULL); + storage->mutex = furi_mutex_alloc(FuriMutexTypeNormal); furi_check(storage->mutex != NULL); storage->data = NULL; storage->status = StorageStatusNotReady; @@ -39,11 +39,11 @@ void storage_data_init(StorageData* storage) { } bool storage_data_lock(StorageData* storage) { - return (osMutexAcquire(storage->mutex, osWaitForever) == osOK); + return (furi_mutex_acquire(storage->mutex, FuriWaitForever) == FuriStatusOk); } bool storage_data_unlock(StorageData* storage) { - return (osMutexRelease(storage->mutex) == osOK); + return (furi_mutex_release(storage->mutex) == FuriStatusOk); } StorageStatus storage_data_status(StorageData* storage) { diff --git a/applications/storage/storage_glue.h b/applications/storage/storage_glue.h index 0d50e39b..7cf2e072 100644 --- a/applications/storage/storage_glue.h +++ b/applications/storage/storage_glue.h @@ -56,7 +56,7 @@ struct StorageData { const FS_Api* fs_api; StorageApi api; void* data; - osMutexId_t mutex; + FuriMutex* mutex; StorageStatus status; StorageFileList_t files; }; diff --git a/applications/storage/storage_i.h b/applications/storage/storage_i.h index 0db5218d..5c836ccd 100644 --- a/applications/storage/storage_i.h +++ b/applications/storage/storage_i.h @@ -17,7 +17,7 @@ typedef struct { } StorageSDGui; struct Storage { - osMessageQueueId_t message_queue; + FuriMessageQueue* message_queue; StorageData storage[STORAGE_COUNT]; StorageSDGui sd_gui; FuriPubSub* pubsub; diff --git a/applications/storage/storage_internal_api.c b/applications/storage/storage_internal_api.c index ee49d672..09314043 100644 --- a/applications/storage/storage_internal_api.c +++ b/applications/storage/storage_internal_api.c @@ -1,4 +1,4 @@ -#include +#include #include #include "storage.h" #include diff --git a/applications/storage/storage_message.h b/applications/storage/storage_message.h index f3aeaf32..78cd1e03 100644 --- a/applications/storage/storage_message.h +++ b/applications/storage/storage_message.h @@ -123,7 +123,7 @@ typedef enum { } StorageCommand; typedef struct { - osSemaphoreId_t semaphore; + FuriSemaphore* semaphore; StorageCommand command; SAData* data; SAReturn* return_data; diff --git a/applications/storage/storage_processing.c b/applications/storage/storage_processing.c index 30e6b5e7..0eb8a32c 100644 --- a/applications/storage/storage_processing.c +++ b/applications/storage/storage_processing.c @@ -573,7 +573,7 @@ void storage_process_message_internal(Storage* app, StorageMessage* message) { break; } - osSemaphoreRelease(message->semaphore); + furi_semaphore_release(message->semaphore); } void storage_process_message(Storage* app, StorageMessage* message) { diff --git a/applications/storage/storage_test_app.c b/applications/storage/storage_test_app.c index f11d2d72..226024b3 100644 --- a/applications/storage/storage_test_app.c +++ b/applications/storage/storage_test_app.c @@ -335,7 +335,7 @@ int32_t storage_test_app(void* p) { do_test_end(api, "/ext"); while(true) { - furi_hal_delay_ms(1000); + furi_delay_ms(1000); } return 0; diff --git a/applications/storage/storages/storage_ext.c b/applications/storage/storages/storage_ext.c index 49c52f77..abfcb0e7 100644 --- a/applications/storage/storages/storage_ext.c +++ b/applications/storage/storages/storage_ext.c @@ -84,7 +84,7 @@ static bool sd_mount_card(StorageData* storage, bool notify) { } if(!result) { - furi_hal_delay_ms(1000); + furi_delay_ms(1000); FURI_LOG_E( TAG, "init cycle %d, error: %s", counter, storage_data_status_text(storage)); counter--; diff --git a/applications/storage_move_to_sd/scenes/storage_move_to_sd_scene_progress.c b/applications/storage_move_to_sd/scenes/storage_move_to_sd_scene_progress.c index d44b25c3..7aa951bd 100644 --- a/applications/storage_move_to_sd/scenes/storage_move_to_sd_scene_progress.c +++ b/applications/storage_move_to_sd/scenes/storage_move_to_sd_scene_progress.c @@ -1,5 +1,4 @@ #include "../storage_move_to_sd.h" -#include "cmsis_os2.h" void storage_move_to_sd_scene_progress_on_enter(void* context) { StorageMoveToSd* app = context; diff --git a/applications/storage_move_to_sd/storage_move_to_sd.c b/applications/storage_move_to_sd/storage_move_to_sd.c index f703321d..fe5807d1 100644 --- a/applications/storage_move_to_sd/storage_move_to_sd.c +++ b/applications/storage_move_to_sd/storage_move_to_sd.c @@ -1,7 +1,6 @@ #include "storage_move_to_sd.h" -#include "cmsis_os2.h" -#include "furi/common_defines.h" -#include "furi/log.h" +#include +#include #include "loader/loader.h" #include "m-string.h" #include diff --git a/applications/storage_settings/scenes/storage_settings_scene_benchmark.c b/applications/storage_settings/scenes/storage_settings_scene_benchmark.c index 707891df..e7c55ad1 100644 --- a/applications/storage_settings/scenes/storage_settings_scene_benchmark.c +++ b/applications/storage_settings/scenes/storage_settings_scene_benchmark.c @@ -1,4 +1,5 @@ #include "../storage_settings.h" +#include #define BENCH_DATA_SIZE 4096 #define BENCH_COUNT 6 @@ -21,7 +22,7 @@ static bool storage_settings_scene_bench_write( bool result = true; if(storage_file_open(file, BENCH_FILE, FSAM_WRITE, FSOM_CREATE_ALWAYS)) { uint32_t ticks; - ticks = osKernelGetTickCount(); + ticks = furi_get_tick(); for(size_t repeat = 0; repeat < BENCH_REPEATS; repeat++) { for(size_t i = 0; i < BENCH_DATA_SIZE / size; i++) { @@ -32,8 +33,8 @@ static bool storage_settings_scene_bench_write( } } - ticks = osKernelGetTickCount() - ticks; - *speed = BENCH_DATA_SIZE * osKernelGetTickFreq() * BENCH_REPEATS; + ticks = furi_get_tick() - ticks; + *speed = BENCH_DATA_SIZE * furi_kernel_get_tick_frequency() * BENCH_REPEATS; *speed /= ticks; *speed /= 1024; } @@ -50,7 +51,7 @@ static bool if(storage_file_open(file, BENCH_FILE, FSAM_READ, FSOM_OPEN_EXISTING)) { uint32_t ticks; - ticks = osKernelGetTickCount(); + ticks = furi_get_tick(); for(size_t repeat = 0; repeat < BENCH_REPEATS; repeat++) { for(size_t i = 0; i < BENCH_DATA_SIZE / size; i++) { @@ -61,8 +62,8 @@ static bool } } - ticks = osKernelGetTickCount() - ticks; - *speed = BENCH_DATA_SIZE * osKernelGetTickFreq() * BENCH_REPEATS; + ticks = furi_get_tick() - ticks; + *speed = BENCH_DATA_SIZE * furi_kernel_get_tick_frequency() * BENCH_REPEATS; *speed /= ticks; *speed /= 1024; } diff --git a/applications/subghz/helpers/subghz_chat.c b/applications/subghz/helpers/subghz_chat.c index 7a359165..f821feaa 100644 --- a/applications/subghz/helpers/subghz_chat.c +++ b/applications/subghz/helpers/subghz_chat.c @@ -10,7 +10,7 @@ struct SubGhzChatWorker { volatile bool worker_running; volatile bool worker_stoping; - osMessageQueueId_t event_queue; + FuriMessageQueue* event_queue; uint32_t last_time_rx_data; Cli* cli; @@ -27,12 +27,12 @@ static int32_t subghz_chat_worker_thread(void* context) { char c; SubGhzChatEvent event; event.event = SubGhzChatEventUserEntrance; - osMessageQueuePut(instance->event_queue, &event, 0, 0); + furi_message_queue_put(instance->event_queue, &event, 0); while(instance->worker_running) { if(cli_read_timeout(instance->cli, (uint8_t*)&c, 1, 1000) == 1) { event.event = SubGhzChatEventInputData; event.c = c; - osMessageQueuePut(instance->event_queue, &event, 0, osWaitForever); + furi_message_queue_put(instance->event_queue, &event, FuriWaitForever); } } @@ -44,14 +44,14 @@ static void subghz_chat_worker_update_rx_event_chat(void* context) { furi_assert(context); SubGhzChatWorker* instance = context; SubGhzChatEvent event; - if((furi_hal_get_tick() - instance->last_time_rx_data) > + if((furi_get_tick() - instance->last_time_rx_data) > SUBGHZ_CHAT_WORKER_TIMEOUT_BETWEEN_MESSAGES) { event.event = SubGhzChatEventNewMessage; - osMessageQueuePut(instance->event_queue, &event, 0, osWaitForever); + furi_message_queue_put(instance->event_queue, &event, FuriWaitForever); } - instance->last_time_rx_data = furi_hal_get_tick(); + instance->last_time_rx_data = furi_get_tick(); event.event = SubGhzChatEventRXData; - osMessageQueuePut(instance->event_queue, &event, 0, osWaitForever); + furi_message_queue_put(instance->event_queue, &event, FuriWaitForever); } SubGhzChatWorker* subghz_chat_worker_alloc(Cli* cli) { @@ -65,14 +65,14 @@ SubGhzChatWorker* subghz_chat_worker_alloc(Cli* cli) { furi_thread_set_context(instance->thread, instance); furi_thread_set_callback(instance->thread, subghz_chat_worker_thread); instance->subghz_txrx = subghz_tx_rx_worker_alloc(); - instance->event_queue = osMessageQueueNew(80, sizeof(SubGhzChatEvent), NULL); + instance->event_queue = furi_message_queue_alloc(80, sizeof(SubGhzChatEvent)); return instance; } void subghz_chat_worker_free(SubGhzChatWorker* instance) { furi_assert(instance); furi_assert(!instance->worker_running); - osMessageQueueDelete(instance->event_queue); + furi_message_queue_free(instance->event_queue); subghz_tx_rx_worker_free(instance->subghz_txrx); furi_thread_free(instance->thread); @@ -85,7 +85,7 @@ bool subghz_chat_worker_start(SubGhzChatWorker* instance, uint32_t frequency) { bool res = false; if(subghz_tx_rx_worker_start(instance->subghz_txrx, frequency)) { - osMessageQueueReset(instance->event_queue); + furi_message_queue_reset(instance->event_queue); subghz_tx_rx_worker_set_callback_have_read( instance->subghz_txrx, subghz_chat_worker_update_rx_event_chat, instance); @@ -119,7 +119,7 @@ bool subghz_chat_worker_is_running(SubGhzChatWorker* instance) { SubGhzChatEvent subghz_chat_worker_get_event_chat(SubGhzChatWorker* instance) { furi_assert(instance); SubGhzChatEvent event; - if(osMessageQueueGet(instance->event_queue, &event, NULL, osWaitForever) == osOK) { + if(furi_message_queue_get(instance->event_queue, &event, FuriWaitForever) == FuriStatusOk) { return event; } else { event.event = SubGhzChatEventNoEvent; @@ -129,7 +129,7 @@ SubGhzChatEvent subghz_chat_worker_get_event_chat(SubGhzChatWorker* instance) { void subghz_chat_worker_put_event_chat(SubGhzChatWorker* instance, SubGhzChatEvent* event) { furi_assert(instance); - osMessageQueuePut(instance->event_queue, event, 0, osWaitForever); + furi_message_queue_put(instance->event_queue, event, FuriWaitForever); } size_t subghz_chat_worker_available(SubGhzChatWorker* instance) { diff --git a/applications/subghz/helpers/subghz_frequency_analyzer_worker.c b/applications/subghz/helpers/subghz_frequency_analyzer_worker.c index 43acf034..10c5a9ea 100644 --- a/applications/subghz/helpers/subghz_frequency_analyzer_worker.c +++ b/applications/subghz/helpers/subghz_frequency_analyzer_worker.c @@ -100,7 +100,7 @@ static int32_t subghz_frequency_analyzer_worker_thread(void* context) { furi_hal_subghz_set_path(FuriHalSubGhzPathIsolate); while(instance->worker_running) { - osDelay(10); + furi_delay_ms(10); float rssi_min = 26.0f; float rssi_avg = 0; @@ -129,8 +129,7 @@ static int32_t subghz_frequency_analyzer_worker_thread(void* context) { cc1101_switch_to_rx(&furi_hal_spi_bus_handle_subghz); furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); - // delay will be in range between 1 and 2ms - osDelay(3); + furi_delay_ms(2); rssi = furi_hal_subghz_get_rssi(); @@ -175,8 +174,7 @@ static int32_t subghz_frequency_analyzer_worker_thread(void* context) { cc1101_switch_to_rx(&furi_hal_spi_bus_handle_subghz); furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); - // delay will be in range between 1 and 2ms - osDelay(3); + furi_delay_ms(2); rssi = furi_hal_subghz_get_rssi(); diff --git a/applications/subghz/subghz_cli.c b/applications/subghz/subghz_cli.c index 20930df2..541b5c50 100644 --- a/applications/subghz/subghz_cli.c +++ b/applications/subghz/subghz_cli.c @@ -51,7 +51,7 @@ void subghz_cli_command_tx_carrier(Cli* cli, string_t args, void* context) { printf("Transmitting at frequency %lu Hz\r\n", frequency); printf("Press CTRL+C to stop\r\n"); while(!cli_cmd_interrupt_received(cli)) { - osDelay(250); + furi_delay_ms(250); } } else { printf("This frequency can only be used for RX in your region\r\n"); @@ -93,7 +93,7 @@ void subghz_cli_command_rx_carrier(Cli* cli, string_t args, void* context) { furi_hal_subghz_rx(); while(!cli_cmd_interrupt_received(cli)) { - osDelay(250); + furi_delay_ms(250); printf("RSSI: %03.1fdbm\r", (double)furi_hal_subghz_get_rssi()); fflush(stdout); } @@ -172,7 +172,7 @@ void subghz_cli_command_tx(Cli* cli, string_t args, void* context) { while(!(furi_hal_subghz_is_async_tx_complete() || cli_cmd_interrupt_received(cli))) { printf("."); fflush(stdout); - osDelay(333); + furi_delay_ms(333); } furi_hal_subghz_stop_async_tx(); furi_hal_subghz_sleep(); @@ -377,7 +377,7 @@ void subghz_cli_command_decode_raw(Cli* cli, string_t args, void* context) { SubGhzFileEncoderWorker* file_worker_encoder = subghz_file_encoder_worker_alloc(); if(subghz_file_encoder_worker_start(file_worker_encoder, string_get_cstr(file_name))) { //the worker needs a file in order to open and read part of the file - osDelay(100); + furi_delay_ms(100); } printf( @@ -386,7 +386,7 @@ void subghz_cli_command_decode_raw(Cli* cli, string_t args, void* context) { LevelDuration level_duration; while(!cli_cmd_interrupt_received(cli)) { - furi_hal_delay_us(500); //you need to have time to read from the file from the SD card + furi_delay_us(500); //you need to have time to read from the file from the SD card level_duration = subghz_file_encoder_worker_get_level_duration(file_worker_encoder); if(!level_duration_is_reset(level_duration)) { bool level = level_duration_get_level(level_duration); @@ -616,7 +616,7 @@ static void subghz_cli_command_chat(Cli* cli, string_t args) { subghz_chat, (uint8_t*)string_get_cstr(input), strlen(string_get_cstr(input)))) { - furi_hal_delay_ms(10); + furi_delay_ms(10); } string_printf(input, "%s", string_get_cstr(name)); @@ -668,7 +668,7 @@ static void subghz_cli_command_chat(Cli* cli, string_t args) { subghz_chat, (uint8_t*)string_get_cstr(sysmsg), strlen(string_get_cstr(sysmsg))); - furi_hal_delay_ms(10); + furi_delay_ms(10); exit = true; break; default: diff --git a/applications/subghz/subghz_history.c b/applications/subghz/subghz_history.c index a8f86eec..85578b99 100644 --- a/applications/subghz/subghz_history.c +++ b/applications/subghz/subghz_history.c @@ -140,13 +140,13 @@ bool subghz_history_add_to_history( SubGhzProtocolDecoderBase* decoder_base = context; if((instance->code_last_hash_data == subghz_protocol_decoder_base_get_hash_data(decoder_base)) && - ((furi_hal_get_tick() - instance->last_update_timestamp) < 500)) { - instance->last_update_timestamp = furi_hal_get_tick(); + ((furi_get_tick() - instance->last_update_timestamp) < 500)) { + instance->last_update_timestamp = furi_get_tick(); return false; } instance->code_last_hash_data = subghz_protocol_decoder_base_get_hash_data(decoder_base); - instance->last_update_timestamp = furi_hal_get_tick(); + instance->last_update_timestamp = furi_get_tick(); string_t text; string_init(text); diff --git a/applications/subghz/views/receiver.c b/applications/subghz/views/receiver.c index bb4a8f16..c28c3363 100644 --- a/applications/subghz/views/receiver.c +++ b/applications/subghz/views/receiver.c @@ -45,7 +45,7 @@ typedef enum { struct SubGhzViewReceiver { SubGhzLock lock; uint8_t lock_count; - osTimerId_t timer; + FuriTimer* timer; View* view; SubGhzViewReceiverCallback callback; void* context; @@ -72,7 +72,7 @@ void subghz_view_receiver_set_lock(SubGhzViewReceiver* subghz_receiver, SubGhzLo model->bar_show = SubGhzViewReceiverBarShowLock; return true; }); - osTimerStart(subghz_receiver->timer, pdMS_TO_TICKS(1000)); + furi_timer_start(subghz_receiver->timer, pdMS_TO_TICKS(1000)); } else { with_view_model( subghz_receiver->view, (SubGhzViewReceiverModel * model) { @@ -266,7 +266,7 @@ bool subghz_view_receiver_input(InputEvent* event, void* context) { return true; }); if(subghz_receiver->lock_count == 0) { - osTimerStart(subghz_receiver->timer, pdMS_TO_TICKS(1000)); + furi_timer_start(subghz_receiver->timer, pdMS_TO_TICKS(1000)); } if(event->key == InputKeyBack && event->type == InputTypeShort) { subghz_receiver->lock_count++; @@ -280,7 +280,7 @@ bool subghz_view_receiver_input(InputEvent* event, void* context) { return true; }); //subghz_receiver->lock = SubGhzLockOff; - osTimerStart(subghz_receiver->timer, pdMS_TO_TICKS(650)); + furi_timer_start(subghz_receiver->timer, pdMS_TO_TICKS(650)); } return true; @@ -345,7 +345,7 @@ void subghz_view_receiver_exit(void* context) { model->history_item = 0; return false; }); - osTimerStop(subghz_receiver->timer); + furi_timer_stop(subghz_receiver->timer); } SubGhzViewReceiver* subghz_view_receiver_alloc() { @@ -375,7 +375,7 @@ SubGhzViewReceiver* subghz_view_receiver_alloc() { return true; }); subghz_receiver->timer = - osTimerNew(subghz_view_receiver_timer_callback, osTimerOnce, subghz_receiver, NULL); + furi_timer_alloc(subghz_view_receiver_timer_callback, FuriTimerTypeOnce, subghz_receiver); return subghz_receiver; } @@ -396,7 +396,7 @@ void subghz_view_receiver_free(SubGhzViewReceiver* subghz_receiver) { free(model->history); return false; }); - osTimerDelete(subghz_receiver->timer); + furi_timer_free(subghz_receiver->timer); view_free(subghz_receiver->view); free(subghz_receiver); } diff --git a/applications/subghz/views/subghz_test_carrier.c b/applications/subghz/views/subghz_test_carrier.c index cd2f70ec..6729eaad 100644 --- a/applications/subghz/views/subghz_test_carrier.c +++ b/applications/subghz/views/subghz_test_carrier.c @@ -9,7 +9,7 @@ struct SubGhzTestCarrier { View* view; - osTimerId_t timer; + FuriTimer* timer; SubGhzTestCarrierCallback callback; void* context; }; @@ -154,14 +154,14 @@ void subghz_test_carrier_enter(void* context) { furi_hal_subghz_rx(); - osTimerStart(subghz_test_carrier->timer, osKernelGetTickFreq() / 4); + furi_timer_start(subghz_test_carrier->timer, furi_kernel_get_tick_frequency() / 4); } void subghz_test_carrier_exit(void* context) { furi_assert(context); SubGhzTestCarrier* subghz_test_carrier = context; - osTimerStop(subghz_test_carrier->timer); + furi_timer_stop(subghz_test_carrier->timer); // Reinitialize IC to default state furi_hal_subghz_sleep(); @@ -194,15 +194,15 @@ SubGhzTestCarrier* subghz_test_carrier_alloc() { view_set_enter_callback(subghz_test_carrier->view, subghz_test_carrier_enter); view_set_exit_callback(subghz_test_carrier->view, subghz_test_carrier_exit); - subghz_test_carrier->timer = osTimerNew( - subghz_test_carrier_rssi_timer_callback, osTimerPeriodic, subghz_test_carrier, NULL); + subghz_test_carrier->timer = furi_timer_alloc( + subghz_test_carrier_rssi_timer_callback, FuriTimerTypePeriodic, subghz_test_carrier); return subghz_test_carrier; } void subghz_test_carrier_free(SubGhzTestCarrier* subghz_test_carrier) { furi_assert(subghz_test_carrier); - osTimerDelete(subghz_test_carrier->timer); + furi_timer_free(subghz_test_carrier->timer); view_free(subghz_test_carrier->view); free(subghz_test_carrier); } diff --git a/applications/subghz/views/subghz_test_packet.c b/applications/subghz/views/subghz_test_packet.c index 57f85085..c83aebec 100644 --- a/applications/subghz/views/subghz_test_packet.c +++ b/applications/subghz/views/subghz_test_packet.c @@ -13,7 +13,7 @@ struct SubGhzTestPacket { View* view; - osTimerId_t timer; + FuriTimer* timer; SubGhzDecoderPrinceton* decoder; SubGhzEncoderPrinceton* encoder; @@ -141,7 +141,7 @@ static bool subghz_test_packet_input(InputEvent* event, void* context) { if(model->status == SubGhzTestPacketModelStatusRx) { furi_hal_subghz_stop_async_rx(); } else if(model->status == SubGhzTestPacketModelStatusTx) { - subghz_encoder_princeton_for_testing_stop(instance->encoder, furi_hal_get_tick()); + subghz_encoder_princeton_for_testing_stop(instance->encoder, furi_get_tick()); furi_hal_subghz_stop_async_tx(); } @@ -206,14 +206,14 @@ void subghz_test_packet_enter(void* context) { furi_hal_subghz_start_async_rx(subghz_test_packet_rx_callback, instance); - osTimerStart(instance->timer, osKernelGetTickFreq() / 4); + furi_timer_start(instance->timer, furi_kernel_get_tick_frequency() / 4); } void subghz_test_packet_exit(void* context) { furi_assert(context); SubGhzTestPacket* instance = context; - osTimerStop(instance->timer); + furi_timer_stop(instance->timer); // Reinitialize IC to default state with_view_model( @@ -221,7 +221,7 @@ void subghz_test_packet_exit(void* context) { if(model->status == SubGhzTestPacketModelStatusRx) { furi_hal_subghz_stop_async_rx(); } else if(model->status == SubGhzTestPacketModelStatusTx) { - subghz_encoder_princeton_for_testing_stop(instance->encoder, furi_hal_get_tick()); + subghz_encoder_princeton_for_testing_stop(instance->encoder, furi_get_tick()); furi_hal_subghz_stop_async_tx(); } return true; @@ -242,7 +242,7 @@ SubGhzTestPacket* subghz_test_packet_alloc() { view_set_exit_callback(instance->view, subghz_test_packet_exit); instance->timer = - osTimerNew(subghz_test_packet_rssi_timer_callback, osTimerPeriodic, instance, NULL); + furi_timer_alloc(subghz_test_packet_rssi_timer_callback, FuriTimerTypePeriodic, instance); instance->decoder = subghz_decoder_princeton_for_testing_alloc(); subghz_decoder_princeton_for_testing_set_callback( @@ -258,7 +258,7 @@ void subghz_test_packet_free(SubGhzTestPacket* instance) { subghz_decoder_princeton_for_testing_free(instance->decoder); subghz_encoder_princeton_for_testing_free(instance->encoder); - osTimerDelete(instance->timer); + furi_timer_free(instance->timer); view_free(instance->view); free(instance); } diff --git a/applications/subghz/views/subghz_test_static.c b/applications/subghz/views/subghz_test_static.c index d1a7bfd4..26cf9b48 100644 --- a/applications/subghz/views/subghz_test_static.c +++ b/applications/subghz/views/subghz_test_static.c @@ -119,7 +119,7 @@ bool subghz_test_static_input(InputEvent* event, void* context) { if(instance->satus_tx == SubGhzTestStaticStatusTX) { FURI_LOG_I(TAG, "TX Stop"); subghz_encoder_princeton_for_testing_stop( - instance->encoder, furi_hal_get_tick()); + instance->encoder, furi_get_tick()); subghz_encoder_princeton_for_testing_print_log(instance->encoder); furi_hal_subghz_stop_async_tx(); notification_message(notification, &sequence_reset_red); diff --git a/applications/u2f/scenes/u2f_scene_main.c b/applications/u2f/scenes/u2f_scene_main.c index f6264338..60ed71c7 100644 --- a/applications/u2f/scenes/u2f_scene_main.c +++ b/applications/u2f/scenes/u2f_scene_main.c @@ -46,14 +46,14 @@ bool u2f_scene_main_on_event(void* context, SceneManagerEvent event) { if(event.type == SceneManagerEventTypeCustom) { if(event.event == U2fCustomEventConnect) { - osTimerStop(app->timer); + furi_timer_stop(app->timer); u2f_view_set_state(app->u2f_view, U2fMsgIdle); } else if(event.event == U2fCustomEventDisconnect) { - osTimerStop(app->timer); + furi_timer_stop(app->timer); app->event_cur = U2fCustomEventNone; u2f_view_set_state(app->u2f_view, U2fMsgNotConnected); } else if((event.event == U2fCustomEventRegister) || (event.event == U2fCustomEventAuth)) { - osTimerStart(app->timer, U2F_REQUEST_TIMEOUT); + furi_timer_start(app->timer, U2F_REQUEST_TIMEOUT); if(app->event_cur == U2fCustomEventNone) { app->event_cur = event.event; if(event.event == U2fCustomEventRegister) @@ -69,7 +69,7 @@ bool u2f_scene_main_on_event(void* context, SceneManagerEvent event) { } else if(event.event == U2fCustomEventAuthSuccess) { notification_message_block(app->notifications, &sequence_set_green_255); DOLPHIN_DEED(DolphinDeedU2fAuthorized); - osTimerStart(app->timer, U2F_SUCCESS_TIMEOUT); + furi_timer_start(app->timer, U2F_SUCCESS_TIMEOUT); app->event_cur = U2fCustomEventNone; u2f_view_set_state(app->u2f_view, U2fMsgSuccess); } else if(event.event == U2fCustomEventTimeout) { @@ -82,7 +82,7 @@ bool u2f_scene_main_on_event(void* context, SceneManagerEvent event) { } } else if(event.event == U2fCustomEventDataError) { notification_message(app->notifications, &sequence_set_red_255); - osTimerStop(app->timer); + furi_timer_stop(app->timer); u2f_view_set_state(app->u2f_view, U2fMsgError); } consumed = true; @@ -94,7 +94,7 @@ bool u2f_scene_main_on_event(void* context, SceneManagerEvent event) { void u2f_scene_main_on_enter(void* context) { U2fApp* app = context; - app->timer = osTimerNew(u2f_scene_main_timer_callback, osTimerOnce, app, NULL); + app->timer = furi_timer_alloc(u2f_scene_main_timer_callback, FuriTimerTypeOnce, app); app->u2f_instance = u2f_alloc(); app->u2f_ready = u2f_init(app->u2f_instance); @@ -113,8 +113,8 @@ void u2f_scene_main_on_enter(void* context) { void u2f_scene_main_on_exit(void* context) { U2fApp* app = context; notification_message_block(app->notifications, &sequence_reset_rgb); - osTimerStop(app->timer); - osTimerDelete(app->timer); + furi_timer_stop(app->timer); + furi_timer_free(app->timer); if(app->u2f_ready == true) { u2f_hid_stop(app->u2f_hid); u2f_free(app->u2f_instance); diff --git a/applications/u2f/u2f_app_i.h b/applications/u2f/u2f_app_i.h index fa9f6f09..53647859 100644 --- a/applications/u2f/u2f_app_i.h +++ b/applications/u2f/u2f_app_i.h @@ -51,7 +51,7 @@ struct U2fApp { SceneManager* scene_manager; NotificationApp* notifications; Widget* widget; - osTimerId_t timer; + FuriTimer* timer; U2fHid* u2f_hid; U2fView* u2f_view; U2fData* u2f_instance; diff --git a/applications/u2f/u2f_hid.c b/applications/u2f/u2f_hid.c index 581feadb..4922d6a5 100644 --- a/applications/u2f/u2f_hid.c +++ b/applications/u2f/u2f_hid.c @@ -57,7 +57,7 @@ struct U2fHid_packet { struct U2fHid { FuriThread* thread; - osTimerId_t lock_timer; + FuriTimer* lock_timer; struct U2fHid_packet packet; uint8_t seq_id_last; uint16_t req_buf_ptr; @@ -157,7 +157,7 @@ static bool u2f_hid_parse_request(U2fHid* u2f_hid) { } else { // Lock on u2f_hid->lock = true; u2f_hid->lock_cid = u2f_hid->packet.cid; - osTimerStart(u2f_hid->lock_timer, lock_timeout * 1000); + furi_timer_start(u2f_hid->lock_timer, lock_timeout * 1000); } } else if(u2f_hid->packet.cmd == U2F_HID_INIT) { // INIT - channel initialization request @@ -193,16 +193,17 @@ static int32_t u2f_hid_worker(void* context) { FuriHalUsbInterface* usb_mode_prev = furi_hal_usb_get_config(); furi_check(furi_hal_usb_set_config(&usb_hid_u2f, NULL) == true); - u2f_hid->lock_timer = osTimerNew(u2f_hid_lock_timeout_callback, osTimerOnce, u2f_hid, NULL); + u2f_hid->lock_timer = + furi_timer_alloc(u2f_hid_lock_timeout_callback, FuriTimerTypeOnce, u2f_hid); furi_hal_hid_u2f_set_callback(u2f_hid_event_callback, u2f_hid); while(1) { uint32_t flags = furi_thread_flags_wait( WorkerEvtStop | WorkerEvtConnect | WorkerEvtDisconnect | WorkerEvtRequest, - osFlagsWaitAny, - osWaitForever); - furi_check((flags & osFlagsError) == 0); + FuriFlagWaitAny, + FuriWaitForever); + furi_check((flags & FuriFlagError) == 0); if(flags & WorkerEvtStop) break; if(flags & WorkerEvtConnect) { u2f_set_state(u2f_hid->u2f_instance, 1); @@ -266,8 +267,8 @@ static int32_t u2f_hid_worker(void* context) { u2f_hid->lock_cid = 0; } } - osTimerStop(u2f_hid->lock_timer); - osTimerDelete(u2f_hid->lock_timer); + furi_timer_stop(u2f_hid->lock_timer); + furi_timer_free(u2f_hid->lock_timer); furi_hal_hid_u2f_set_callback(NULL, NULL); furi_hal_usb_set_config(usb_mode_prev, NULL); diff --git a/applications/unit_tests/furi/furi_valuemutex_test.c b/applications/unit_tests/furi/furi_valuemutex_test.c index ed98be32..02fd47ee 100644 --- a/applications/unit_tests/furi/furi_valuemutex_test.c +++ b/applications/unit_tests/furi/furi_valuemutex_test.c @@ -1,7 +1,6 @@ #include #include #include -#include "furi_hal_delay.h" #include "../minunit.h" diff --git a/applications/unit_tests/nfc/nfc_test.c b/applications/unit_tests/nfc/nfc_test.c index a2262735..4e1b9a64 100644 --- a/applications/unit_tests/nfc/nfc_test.c +++ b/applications/unit_tests/nfc/nfc_test.c @@ -104,7 +104,7 @@ static bool nfc_test_digital_signal_test_encode( nfca_signal_encode( nfc_test->signal, nfc_test->test_data, nfc_test->test_data_len * 8, parity); digital_signal_prepare_arr(nfc_test->signal->tx_signal); - time = (DWT->CYCCNT - time) / furi_hal_delay_instructions_per_microsecond(); + time = (DWT->CYCCNT - time) / furi_hal_cortex_instructions_per_microsecond(); FURI_CRITICAL_EXIT(); // Check timings diff --git a/applications/unit_tests/rpc/rpc_test.c b/applications/unit_tests/rpc/rpc_test.c index ca894cb4..c5336385 100644 --- a/applications/unit_tests/rpc/rpc_test.c +++ b/applications/unit_tests/rpc/rpc_test.c @@ -1,7 +1,6 @@ #include "flipper.pb.h" -#include "furi_hal_delay.h" -#include "furi/check.h" -#include "furi/record.h" +#include +#include #include "pb_decode.h" #include #include "rpc/rpc_i.h" @@ -87,7 +86,7 @@ static void test_rpc_setup(void) { rpc = furi_record_open("rpc"); for(int i = 0; !(rpc_session[0].session) && (i < 10000); ++i) { rpc_session[0].session = rpc_session_open(rpc); - furi_hal_delay_ms(1); + furi_delay_tick(1); } furi_check(rpc_session[0].session); @@ -107,7 +106,7 @@ static void test_rpc_setup_second_session(void) { for(int i = 0; !(rpc_session[1].session) && (i < 10000); ++i) { rpc_session[1].session = rpc_session_open(rpc); - furi_hal_delay_ms(1); + furi_delay_tick(1); } furi_check(rpc_session[1].session); @@ -269,7 +268,7 @@ static void output_bytes_callback(void* ctx, uint8_t* got_bytes, size_t got_size RpcSessionContext* callbacks_context = ctx; size_t bytes_sent = - xStreamBufferSend(callbacks_context->output_stream, got_bytes, got_size, osWaitForever); + xStreamBufferSend(callbacks_context->output_stream, got_bytes, got_size, FuriWaitForever); (void)bytes_sent; furi_check(bytes_sent == got_size); } @@ -1525,28 +1524,28 @@ MU_TEST(test_app_start_and_lock_status) { test_app_get_status_lock_run(false, ++command_id); test_app_start_run("Delay Test", "0", PB_CommandStatus_OK, ++command_id); - furi_hal_delay_ms(100); + furi_delay_ms(100); test_app_get_status_lock_run(false, ++command_id); test_app_start_run("Delay Test", "200", PB_CommandStatus_OK, ++command_id); test_app_get_status_lock_run(true, ++command_id); - furi_hal_delay_ms(100); + furi_delay_ms(100); test_app_get_status_lock_run(true, ++command_id); test_app_start_run("Delay Test", "0", PB_CommandStatus_ERROR_APP_SYSTEM_LOCKED, ++command_id); - furi_hal_delay_ms(200); + furi_delay_ms(200); test_app_get_status_lock_run(false, ++command_id); test_app_start_run("Delay Test", "500", PB_CommandStatus_OK, ++command_id); - furi_hal_delay_ms(100); + furi_delay_ms(100); test_app_get_status_lock_run(true, ++command_id); test_app_start_run("Infrared", "0", PB_CommandStatus_ERROR_APP_SYSTEM_LOCKED, ++command_id); - furi_hal_delay_ms(100); + furi_delay_ms(100); test_app_get_status_lock_run(true, ++command_id); test_app_start_run( "2_girls_1_app", "0", PB_CommandStatus_ERROR_INVALID_PARAMETERS, ++command_id); - furi_hal_delay_ms(100); + furi_delay_ms(100); test_app_get_status_lock_run(true, ++command_id); - furi_hal_delay_ms(500); + furi_delay_ms(500); test_app_get_status_lock_run(false, ++command_id); } @@ -1794,7 +1793,7 @@ int32_t delay_test_app(void* p) { int timeout = atoi((const char*)p); if(timeout > 0) { - furi_hal_delay_ms(timeout); + furi_delay_ms(timeout); } return 0; diff --git a/applications/unit_tests/storage/storage_test.c b/applications/unit_tests/storage/storage_test.c index db78583d..c21abecc 100644 --- a/applications/unit_tests/storage/storage_test.c +++ b/applications/unit_tests/storage/storage_test.c @@ -1,6 +1,5 @@ #include "../minunit.h" #include -#include #include #define STORAGE_LOCKED_FILE "/ext/locked_file.test" @@ -25,11 +24,11 @@ static void storage_file_open_lock_teardown() { static int32_t storage_file_locker(void* ctx) { Storage* storage = furi_record_open("storage"); - osSemaphoreId_t semaphore = ctx; + FuriSemaphore* semaphore = ctx; File* file = storage_file_alloc(storage); furi_check(storage_file_open(file, STORAGE_LOCKED_FILE, FSAM_READ_WRITE, FSOM_OPEN_EXISTING)); - osSemaphoreRelease(semaphore); - furi_hal_delay_ms(1000); + furi_semaphore_release(semaphore); + furi_delay_ms(1000); furi_check(storage_file_close(file)); furi_record_close("storage"); @@ -40,7 +39,7 @@ static int32_t storage_file_locker(void* ctx) { MU_TEST(storage_file_open_lock) { Storage* storage = furi_record_open("storage"); bool result = false; - osSemaphoreId_t semaphore = osSemaphoreNew(1, 0, NULL); + FuriSemaphore* semaphore = furi_semaphore_alloc(1, 0); File* file = storage_file_alloc(storage); // file_locker thread start @@ -52,14 +51,14 @@ MU_TEST(storage_file_open_lock) { furi_thread_start(locker_thread); // wait for file lock - osSemaphoreAcquire(semaphore, osWaitForever); - osSemaphoreDelete(semaphore); + furi_semaphore_acquire(semaphore, FuriWaitForever); + furi_semaphore_free(semaphore); result = storage_file_open(file, STORAGE_LOCKED_FILE, FSAM_READ_WRITE, FSOM_OPEN_EXISTING); storage_file_close(file); // file_locker thread stop - mu_check(furi_thread_join(locker_thread) == osOK); + mu_check(furi_thread_join(locker_thread) == FuriStatusOk); furi_thread_free(locker_thread); // clean data @@ -115,11 +114,11 @@ MU_TEST(storage_dir_open_close) { static int32_t storage_dir_locker(void* ctx) { Storage* storage = furi_record_open("storage"); - osSemaphoreId_t semaphore = ctx; + FuriSemaphore* semaphore = ctx; File* file = storage_file_alloc(storage); furi_check(storage_dir_open(file, STORAGE_LOCKED_DIR)); - osSemaphoreRelease(semaphore); - furi_hal_delay_ms(1000); + furi_semaphore_release(semaphore); + furi_delay_ms(1000); furi_check(storage_dir_close(file)); furi_record_close("storage"); @@ -130,7 +129,7 @@ static int32_t storage_dir_locker(void* ctx) { MU_TEST(storage_dir_open_lock) { Storage* storage = furi_record_open("storage"); bool result = false; - osSemaphoreId_t semaphore = osSemaphoreNew(1, 0, NULL); + FuriSemaphore* semaphore = furi_semaphore_alloc(1, 0); File* file = storage_file_alloc(storage); // file_locker thread start @@ -142,14 +141,14 @@ MU_TEST(storage_dir_open_lock) { furi_thread_start(locker_thread); // wait for dir lock - osSemaphoreAcquire(semaphore, osWaitForever); - osSemaphoreDelete(semaphore); + furi_semaphore_acquire(semaphore, FuriWaitForever); + furi_semaphore_free(semaphore); result = storage_dir_open(file, STORAGE_LOCKED_DIR); storage_dir_close(file); // file_locker thread stop - mu_check(furi_thread_join(locker_thread) == osOK); + mu_check(furi_thread_join(locker_thread) == FuriStatusOk); furi_thread_free(locker_thread); // clean data diff --git a/applications/unit_tests/subghz/subghz_test.c b/applications/unit_tests/subghz/subghz_test.c index fea407ed..23c6117b 100644 --- a/applications/unit_tests/subghz/subghz_test.c +++ b/applications/unit_tests/subghz/subghz_test.c @@ -56,7 +56,7 @@ static void subghz_test_deinit(void) { static bool subghz_decoder_test(const char* path, const char* name_decoder) { subghz_test_decoder_count = 0; - uint32_t test_start = furi_hal_get_tick(); + uint32_t test_start = furi_get_tick(); SubGhzProtocolDecoderBase* decoder = subghz_receiver_search_decoder_base_by_name(receiver_handler, name_decoder); @@ -65,10 +65,10 @@ static bool subghz_decoder_test(const char* path, const char* name_decoder) { file_worker_encoder_handler = subghz_file_encoder_worker_alloc(); if(subghz_file_encoder_worker_start(file_worker_encoder_handler, path)) { // the worker needs a file in order to open and read part of the file - osDelay(100); + furi_delay_ms(100); LevelDuration level_duration; - while(furi_hal_get_tick() - test_start < TEST_TIMEOUT) { + while(furi_get_tick() - test_start < TEST_TIMEOUT) { level_duration = subghz_file_encoder_worker_get_level_duration(file_worker_encoder_handler); if(!level_duration_is_reset(level_duration)) { @@ -81,7 +81,7 @@ static bool subghz_decoder_test(const char* path, const char* name_decoder) { break; } } - furi_hal_delay_ms(10); + furi_delay_ms(10); } if(subghz_file_encoder_worker_is_running(file_worker_encoder_handler)) { subghz_file_encoder_worker_stop(file_worker_encoder_handler); @@ -89,7 +89,7 @@ static bool subghz_decoder_test(const char* path, const char* name_decoder) { subghz_file_encoder_worker_free(file_worker_encoder_handler); } FURI_LOG_T(TAG, "\r\n Decoder count parse \033[0;33m%d\033[0m ", subghz_test_decoder_count); - if(furi_hal_get_tick() - test_start > TEST_TIMEOUT) { + if(furi_get_tick() - test_start > TEST_TIMEOUT) { printf("\033[0;31mTest decoder %s ERROR TimeOut\033[0m\r\n", name_decoder); return false; } else { @@ -100,15 +100,15 @@ static bool subghz_decoder_test(const char* path, const char* name_decoder) { static bool subghz_decode_random_test(const char* path) { subghz_test_decoder_count = 0; subghz_receiver_reset(receiver_handler); - uint32_t test_start = furi_hal_get_tick(); + uint32_t test_start = furi_get_tick(); file_worker_encoder_handler = subghz_file_encoder_worker_alloc(); if(subghz_file_encoder_worker_start(file_worker_encoder_handler, path)) { // the worker needs a file in order to open and read part of the file - osDelay(100); + furi_delay_ms(100); LevelDuration level_duration; - while(furi_hal_get_tick() - test_start < TEST_TIMEOUT * 10) { + while(furi_get_tick() - test_start < TEST_TIMEOUT * 10) { level_duration = subghz_file_encoder_worker_get_level_duration(file_worker_encoder_handler); if(!level_duration_is_reset(level_duration)) { @@ -121,14 +121,14 @@ static bool subghz_decode_random_test(const char* path) { break; } } - furi_hal_delay_ms(10); + furi_delay_ms(10); if(subghz_file_encoder_worker_is_running(file_worker_encoder_handler)) { subghz_file_encoder_worker_stop(file_worker_encoder_handler); } subghz_file_encoder_worker_free(file_worker_encoder_handler); } FURI_LOG_T(TAG, "\r\n Decoder count parse \033[0;33m%d\033[0m ", subghz_test_decoder_count); - if(furi_hal_get_tick() - test_start > TEST_TIMEOUT * 10) { + if(furi_get_tick() - test_start > TEST_TIMEOUT * 10) { printf("\033[0;31mRandom test ERROR TimeOut\033[0m\r\n"); return false; } else if(subghz_test_decoder_count == TEST_RANDOM_COUNT_PARSE) { @@ -140,7 +140,7 @@ static bool subghz_decode_random_test(const char* path) { static bool subghz_encoder_test(const char* path) { subghz_test_decoder_count = 0; - uint32_t test_start = furi_hal_get_tick(); + uint32_t test_start = furi_get_tick(); string_t temp_str; string_init(temp_str); bool file_load = false; @@ -175,7 +175,7 @@ static bool subghz_encoder_test(const char* path) { if(decoder) { LevelDuration level_duration; - while(furi_hal_get_tick() - test_start < TEST_TIMEOUT) { + while(furi_get_tick() - test_start < TEST_TIMEOUT) { level_duration = subghz_transmitter_yield(transmitter); if(!level_duration_is_reset(level_duration)) { bool level = level_duration_get_level(level_duration); @@ -185,13 +185,13 @@ static bool subghz_encoder_test(const char* path) { break; } } - furi_hal_delay_ms(10); + furi_delay_ms(10); } subghz_transmitter_free(transmitter); } flipper_format_free(fff_data_file); FURI_LOG_T(TAG, "\r\n Decoder count parse \033[0;33m%d\033[0m ", subghz_test_decoder_count); - if(furi_hal_get_tick() - test_start > TEST_TIMEOUT) { + if(furi_get_tick() - test_start > TEST_TIMEOUT) { printf("\033[0;31mTest encoder %s ERROR TimeOut\033[0m\r\n", string_get_cstr(temp_str)); subghz_test_decoder_count = 0; } diff --git a/applications/unit_tests/test_index.c b/applications/unit_tests/test_index.c index 9f12adae..ca7641b1 100644 --- a/applications/unit_tests/test_index.c +++ b/applications/unit_tests/test_index.c @@ -78,7 +78,7 @@ void unit_tests_cli(Cli* cli, string_t args, void* context) { notification_message_block(notification, &sequence_set_only_blue_255); uint32_t heap_before = memmgr_get_free_heap(); - uint32_t cycle_counter = furi_hal_get_tick(); + uint32_t cycle_counter = furi_get_tick(); for(size_t i = 0; i < COUNT_OF(unit_tests); i++) { if(cli_cmd_interrupt_received(cli)) { @@ -98,11 +98,11 @@ void unit_tests_cli(Cli* cli, string_t args, void* context) { printf("\r\nFailed tests: %lu\r\n", failed_tests); // Time report - cycle_counter = (furi_hal_get_tick() - cycle_counter); + cycle_counter = (furi_get_tick() - cycle_counter); printf("Consumed: %lu ms\r\n", cycle_counter); // Wait for tested services and apps to deallocate memory - furi_hal_delay_ms(200); + furi_delay_ms(200); uint32_t heap_after = memmgr_get_free_heap(); printf("Leaked: %ld\r\n", heap_before - heap_after); diff --git a/applications/updater/cli/updater_cli.c b/applications/updater/cli/updater_cli.c index fb2edeb9..3dfd145c 100644 --- a/applications/updater/cli/updater_cli.c +++ b/applications/updater/cli/updater_cli.c @@ -29,7 +29,7 @@ static void updater_cli_install(string_t manifest_path) { return; } printf("OK.\r\nRestarting to apply update. BRB\r\n"); - osDelay(100); + furi_delay_ms(100); furi_hal_power_reset(); } @@ -134,4 +134,4 @@ void updater_on_system_start() { #else UNUSED(updater_start_app); #endif -} \ No newline at end of file +} diff --git a/applications/updater/util/update_task.c b/applications/updater/util/update_task.c index 47bb7ae5..f7b9f812 100644 --- a/applications/updater/util/update_task.c +++ b/applications/updater/util/update_task.c @@ -197,7 +197,7 @@ static void update_task_worker_thread_cb(FuriThreadState state, void* context) { } if(furi_thread_get_return_code(update_task->thread) == UPDATE_TASK_NOERR) { - osDelay(UPDATE_DELAY_OPERATION_OK); + furi_delay_ms(UPDATE_DELAY_OPERATION_OK); furi_hal_power_reset(); } } diff --git a/applications/updater/util/update_task_worker_flasher.c b/applications/updater/util/update_task_worker_flasher.c index d02858bc..d56b4ae0 100644 --- a/applications/updater/util/update_task_worker_flasher.c +++ b/applications/updater/util/update_task_worker_flasher.c @@ -130,7 +130,7 @@ static bool update_task_write_stack_data(UpdateTask* update_task) { static void update_task_wait_for_restart(UpdateTask* update_task) { update_task_set_progress(update_task, UpdateTaskStageRadioBusy, 10); - osDelay(C2_MODE_SWITCH_TIMEOUT); + furi_delay_ms(C2_MODE_SWITCH_TIMEOUT); furi_crash("C2 timeout"); } diff --git a/core/furi.c b/core/furi.c deleted file mode 100644 index edee1592..00000000 --- a/core/furi.c +++ /dev/null @@ -1,13 +0,0 @@ -#include "furi.h" - -void furi_init() { - osKernelInitialize(); - - furi_log_init(); - furi_record_init(); - furi_stdglue_init(); -} - -void furi_run() { - osKernelStart(); -} diff --git a/core/furi.h b/core/furi.h deleted file mode 100644 index 7a36c1ba..00000000 --- a/core/furi.h +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once - -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -void furi_init(); - -void furi_run(); - -#ifdef __cplusplus -} -#endif diff --git a/core/furi/base.h b/core/furi/base.h deleted file mode 100644 index 41873fbd..00000000 --- a/core/furi/base.h +++ /dev/null @@ -1,45 +0,0 @@ -#pragma once - -#include -#include - -// FreeRTOS part -#include - -#ifdef __cplusplus -extern "C" { -#endif - -// Timeout value. -#define osWaitForever 0xFFFFFFFFU ///< Wait forever timeout value. - -// Flags options (\ref furi_thread_flags_wait and \ref osEventFlagsWait). -#define osFlagsWaitAny 0x00000000U ///< Wait for any flag (default). -#define osFlagsWaitAll 0x00000001U ///< Wait for all flags. -#define osFlagsNoClear 0x00000002U ///< Do not clear flags which have been specified to wait for. - -// Flags errors (returned by osThreadFlagsXxxx and osEventFlagsXxxx). -#define osFlagsError 0x80000000U ///< Error indicator. -#define osFlagsErrorUnknown 0xFFFFFFFFU ///< osError (-1). -#define osFlagsErrorTimeout 0xFFFFFFFEU ///< osErrorTimeout (-2). -#define osFlagsErrorResource 0xFFFFFFFDU ///< osErrorResource (-3). -#define osFlagsErrorParameter 0xFFFFFFFCU ///< osErrorParameter (-4). -#define osFlagsErrorISR 0xFFFFFFFAU ///< osErrorISR (-6). - -/// Status code values returned by CMSIS-RTOS functions. -typedef enum { - osOK = 0, ///< Operation completed successfully. - osError = -1, ///< Unspecified RTOS error: run-time error but no other error message fits. - osErrorTimeout = -2, ///< Operation not completed within the timeout period. - osErrorResource = -3, ///< Resource not available. - osErrorParameter = -4, ///< Parameter error. - osErrorNoMemory = - -5, ///< System is out of memory: it was impossible to allocate or reserve memory for the operation. - osErrorISR = - -6, ///< Not allowed in ISR context: the function cannot be called from interrupt service routines. - osStatusReserved = 0x7FFFFFFF ///< Prevents enum down-size compiler optimization. -} osStatus_t; - -#ifdef __cplusplus -} -#endif diff --git a/core/furi/event_flags.c b/core/furi/event_flags.c deleted file mode 100644 index ba8cba48..00000000 --- a/core/furi/event_flags.c +++ /dev/null @@ -1,222 +0,0 @@ -#include "event_flags.h" -#include "common_defines.h" - -#include - -#define MAX_BITS_EVENT_GROUPS 24U -#define EVENT_FLAGS_INVALID_BITS (~((1UL << MAX_BITS_EVENT_GROUPS) - 1U)) - -osEventFlagsId_t osEventFlagsNew(const osEventFlagsAttr_t* attr) { - EventGroupHandle_t hEventGroup; - int32_t mem; - - hEventGroup = NULL; - - if(FURI_IS_IRQ_MODE() == 0U) { - mem = -1; - - if(attr != NULL) { - if((attr->cb_mem != NULL) && (attr->cb_size >= sizeof(StaticEventGroup_t))) { - /* The memory for control block is provided, use static object */ - mem = 1; - } else { - if((attr->cb_mem == NULL) && (attr->cb_size == 0U)) { - /* Control block will be allocated from the dynamic pool */ - mem = 0; - } - } - } else { - mem = 0; - } - - if(mem == 1) { -#if(configSUPPORT_STATIC_ALLOCATION == 1) - hEventGroup = xEventGroupCreateStatic(attr->cb_mem); -#endif - } else { - if(mem == 0) { -#if(configSUPPORT_DYNAMIC_ALLOCATION == 1) - hEventGroup = xEventGroupCreate(); -#endif - } - } - } - - /* Return event flags ID */ - return ((osEventFlagsId_t)hEventGroup); -} - -/* - Set the specified Event Flags. - - Limitations: - - Event flags are limited to 24 bits. -*/ -uint32_t osEventFlagsSet(osEventFlagsId_t ef_id, uint32_t flags) { - EventGroupHandle_t hEventGroup = (EventGroupHandle_t)ef_id; - uint32_t rflags; - BaseType_t yield; - - if((hEventGroup == NULL) || ((flags & EVENT_FLAGS_INVALID_BITS) != 0U)) { - rflags = (uint32_t)osErrorParameter; - } else if(FURI_IS_IRQ_MODE() != 0U) { -#if(configUSE_OS2_EVENTFLAGS_FROM_ISR == 0) - (void)yield; - /* Enable timers and xTimerPendFunctionCall function to support osEventFlagsSet from ISR */ - rflags = (uint32_t)osErrorResource; -#else - yield = pdFALSE; - - if(xEventGroupSetBitsFromISR(hEventGroup, (EventBits_t)flags, &yield) == pdFAIL) { - rflags = (uint32_t)osErrorResource; - } else { - rflags = flags; - portYIELD_FROM_ISR(yield); - } -#endif - } else { - rflags = xEventGroupSetBits(hEventGroup, (EventBits_t)flags); - } - - /* Return event flags after setting */ - return (rflags); -} - -/* - Clear the specified Event Flags. - - Limitations: - - Event flags are limited to 24 bits. -*/ -uint32_t osEventFlagsClear(osEventFlagsId_t ef_id, uint32_t flags) { - EventGroupHandle_t hEventGroup = (EventGroupHandle_t)ef_id; - uint32_t rflags; - - if((hEventGroup == NULL) || ((flags & EVENT_FLAGS_INVALID_BITS) != 0U)) { - rflags = (uint32_t)osErrorParameter; - } else if(FURI_IS_IRQ_MODE() != 0U) { -#if(configUSE_OS2_EVENTFLAGS_FROM_ISR == 0) - /* Enable timers and xTimerPendFunctionCall function to support osEventFlagsSet from ISR */ - rflags = (uint32_t)osErrorResource; -#else - rflags = xEventGroupGetBitsFromISR(hEventGroup); - - if(xEventGroupClearBitsFromISR(hEventGroup, (EventBits_t)flags) == pdFAIL) { - rflags = (uint32_t)osErrorResource; - } else { - /* xEventGroupClearBitsFromISR only registers clear operation in the timer command queue. */ - /* Yield is required here otherwise clear operation might not execute in the right order. */ - /* See https://github.com/FreeRTOS/FreeRTOS-Kernel/issues/93 for more info. */ - portYIELD_FROM_ISR(pdTRUE); - } -#endif - } else { - rflags = xEventGroupClearBits(hEventGroup, (EventBits_t)flags); - } - - /* Return event flags before clearing */ - return (rflags); -} - -/* - Get the current Event Flags. - - Limitations: - - Event flags are limited to 24 bits. -*/ -uint32_t osEventFlagsGet(osEventFlagsId_t ef_id) { - EventGroupHandle_t hEventGroup = (EventGroupHandle_t)ef_id; - uint32_t rflags; - - if(ef_id == NULL) { - rflags = 0U; - } else if(FURI_IS_IRQ_MODE() != 0U) { - rflags = xEventGroupGetBitsFromISR(hEventGroup); - } else { - rflags = xEventGroupGetBits(hEventGroup); - } - - /* Return current event flags */ - return (rflags); -} - -/* - Wait for one or more Event Flags to become signaled. - - Limitations: - - Event flags are limited to 24 bits. - - osEventFlagsWait cannot be called from an ISR. -*/ -uint32_t - osEventFlagsWait(osEventFlagsId_t ef_id, uint32_t flags, uint32_t options, uint32_t timeout) { - EventGroupHandle_t hEventGroup = (EventGroupHandle_t)ef_id; - BaseType_t wait_all; - BaseType_t exit_clr; - uint32_t rflags; - - if((hEventGroup == NULL) || ((flags & EVENT_FLAGS_INVALID_BITS) != 0U)) { - rflags = (uint32_t)osErrorParameter; - } else if(FURI_IS_IRQ_MODE() != 0U) { - rflags = (uint32_t)osErrorISR; - } else { - if(options & osFlagsWaitAll) { - wait_all = pdTRUE; - } else { - wait_all = pdFAIL; - } - - if(options & osFlagsNoClear) { - exit_clr = pdFAIL; - } else { - exit_clr = pdTRUE; - } - - rflags = xEventGroupWaitBits( - hEventGroup, (EventBits_t)flags, exit_clr, wait_all, (TickType_t)timeout); - - if(options & osFlagsWaitAll) { - if((flags & rflags) != flags) { - if(timeout > 0U) { - rflags = (uint32_t)osErrorTimeout; - } else { - rflags = (uint32_t)osErrorResource; - } - } - } else { - if((flags & rflags) == 0U) { - if(timeout > 0U) { - rflags = (uint32_t)osErrorTimeout; - } else { - rflags = (uint32_t)osErrorResource; - } - } - } - } - - /* Return event flags before clearing */ - return (rflags); -} - -/* - Delete an Event Flags object. -*/ -osStatus_t osEventFlagsDelete(osEventFlagsId_t ef_id) { - EventGroupHandle_t hEventGroup = (EventGroupHandle_t)ef_id; - osStatus_t stat; - -#ifndef USE_FreeRTOS_HEAP_1 - if(FURI_IS_IRQ_MODE() != 0U) { - stat = osErrorISR; - } else if(hEventGroup == NULL) { - stat = osErrorParameter; - } else { - stat = osOK; - vEventGroupDelete(hEventGroup); - } -#else - stat = osError; -#endif - - /* Return execution status */ - return (stat); -} diff --git a/core/furi/event_flags.h b/core/furi/event_flags.h deleted file mode 100644 index 66aa2d7a..00000000 --- a/core/furi/event_flags.h +++ /dev/null @@ -1,63 +0,0 @@ -#pragma once - -#include "base.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/// Attributes structure for event flags. -typedef struct { - const char* name; ///< name of the event flags - uint32_t attr_bits; ///< attribute bits - void* cb_mem; ///< memory for control block - uint32_t cb_size; ///< size of provided memory for control block -} osEventFlagsAttr_t; - -/// \details Event Flags ID identifies the event flags. -typedef void* osEventFlagsId_t; - -/// Create and Initialize an Event Flags object. -/// \param[in] attr event flags attributes; NULL: default values. -/// \return event flags ID for reference by other functions or NULL in case of error. -osEventFlagsId_t osEventFlagsNew(const osEventFlagsAttr_t* attr); - -/// Get name of an Event Flags object. -/// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. -/// \return name as null-terminated string. -const char* osEventFlagsGetName(osEventFlagsId_t ef_id); - -/// Set the specified Event Flags. -/// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. -/// \param[in] flags specifies the flags that shall be set. -/// \return event flags after setting or error code if highest bit set. -uint32_t osEventFlagsSet(osEventFlagsId_t ef_id, uint32_t flags); - -/// Clear the specified Event Flags. -/// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. -/// \param[in] flags specifies the flags that shall be cleared. -/// \return event flags before clearing or error code if highest bit set. -uint32_t osEventFlagsClear(osEventFlagsId_t ef_id, uint32_t flags); - -/// Get the current Event Flags. -/// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. -/// \return current event flags. -uint32_t osEventFlagsGet(osEventFlagsId_t ef_id); - -/// Wait for one or more Event Flags to become signaled. -/// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. -/// \param[in] flags specifies the flags to wait for. -/// \param[in] options specifies flags options (osFlagsXxxx). -/// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. -/// \return event flags before clearing or error code if highest bit set. -uint32_t - osEventFlagsWait(osEventFlagsId_t ef_id, uint32_t flags, uint32_t options, uint32_t timeout); - -/// Delete an Event Flags object. -/// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. -/// \return status code that indicates the execution status of the function. -osStatus_t osEventFlagsDelete(osEventFlagsId_t ef_id); - -#ifdef __cplusplus -} -#endif diff --git a/core/furi/mutex.c b/core/furi/mutex.c deleted file mode 100644 index 42f1d528..00000000 --- a/core/furi/mutex.c +++ /dev/null @@ -1,217 +0,0 @@ -#include "mutex.h" -#include "check.h" -#include "common_defines.h" - -#include - -osMutexId_t osMutexNew(const osMutexAttr_t* attr) { - SemaphoreHandle_t hMutex; - uint32_t type; - uint32_t rmtx; - int32_t mem; - - hMutex = NULL; - - if(FURI_IS_IRQ_MODE() == 0U) { - if(attr != NULL) { - type = attr->attr_bits; - } else { - type = 0U; - } - - if((type & osMutexRecursive) == osMutexRecursive) { - rmtx = 1U; - } else { - rmtx = 0U; - } - - if((type & osMutexRobust) != osMutexRobust) { - mem = -1; - - if(attr != NULL) { - if((attr->cb_mem != NULL) && (attr->cb_size >= sizeof(StaticSemaphore_t))) { - /* The memory for control block is provided, use static object */ - mem = 1; - } else { - if((attr->cb_mem == NULL) && (attr->cb_size == 0U)) { - /* Control block will be allocated from the dynamic pool */ - mem = 0; - } - } - } else { - mem = 0; - } - - if(mem == 1) { -#if(configSUPPORT_STATIC_ALLOCATION == 1) - if(rmtx != 0U) { -#if(configUSE_RECURSIVE_MUTEXES == 1) - hMutex = xSemaphoreCreateRecursiveMutexStatic(attr->cb_mem); -#endif - } else { - hMutex = xSemaphoreCreateMutexStatic(attr->cb_mem); - } -#endif - } else { - if(mem == 0) { -#if(configSUPPORT_DYNAMIC_ALLOCATION == 1) - if(rmtx != 0U) { -#if(configUSE_RECURSIVE_MUTEXES == 1) - hMutex = xSemaphoreCreateRecursiveMutex(); -#endif - } else { - hMutex = xSemaphoreCreateMutex(); - } -#endif - } - } - -#if(configQUEUE_REGISTRY_SIZE > 0) - if(hMutex != NULL) { - if((attr != NULL) && (attr->name != NULL)) { - /* Only non-NULL name objects are added to the Queue Registry */ - vQueueAddToRegistry(hMutex, attr->name); - } - } -#endif - - if((hMutex != NULL) && (rmtx != 0U)) { - /* Set LSB as 'recursive mutex flag' */ - hMutex = (SemaphoreHandle_t)((uint32_t)hMutex | 1U); - } - } - } - - /* Return mutex ID */ - return ((osMutexId_t)hMutex); -} - -/* - Acquire a Mutex or timeout if it is locked. -*/ -osStatus_t osMutexAcquire(osMutexId_t mutex_id, uint32_t timeout) { - SemaphoreHandle_t hMutex; - osStatus_t stat; - uint32_t rmtx; - - hMutex = (SemaphoreHandle_t)((uint32_t)mutex_id & ~1U); - - /* Extract recursive mutex flag */ - rmtx = (uint32_t)mutex_id & 1U; - - stat = osOK; - - if(FURI_IS_IRQ_MODE() != 0U) { - stat = osErrorISR; - } else if(hMutex == NULL) { - stat = osErrorParameter; - } else { - if(rmtx != 0U) { -#if(configUSE_RECURSIVE_MUTEXES == 1) - if(xSemaphoreTakeRecursive(hMutex, timeout) != pdPASS) { - if(timeout != 0U) { - stat = osErrorTimeout; - } else { - stat = osErrorResource; - } - } -#endif - } else { - if(xSemaphoreTake(hMutex, timeout) != pdPASS) { - if(timeout != 0U) { - stat = osErrorTimeout; - } else { - stat = osErrorResource; - } - } - } - } - - /* Return execution status */ - return (stat); -} - -/* - Release a Mutex that was acquired by osMutexAcquire. -*/ -osStatus_t osMutexRelease(osMutexId_t mutex_id) { - SemaphoreHandle_t hMutex; - osStatus_t stat; - uint32_t rmtx; - - hMutex = (SemaphoreHandle_t)((uint32_t)mutex_id & ~1U); - - /* Extract recursive mutex flag */ - rmtx = (uint32_t)mutex_id & 1U; - - stat = osOK; - - if(FURI_IS_IRQ_MODE() != 0U) { - stat = osErrorISR; - } else if(hMutex == NULL) { - stat = osErrorParameter; - } else { - if(rmtx != 0U) { -#if(configUSE_RECURSIVE_MUTEXES == 1) - if(xSemaphoreGiveRecursive(hMutex) != pdPASS) { - stat = osErrorResource; - } -#endif - } else { - if(xSemaphoreGive(hMutex) != pdPASS) { - stat = osErrorResource; - } - } - } - - /* Return execution status */ - return (stat); -} - -/* - Get Thread which owns a Mutex object. -*/ -FuriThreadId osMutexGetOwner(osMutexId_t mutex_id) { - SemaphoreHandle_t hMutex; - FuriThreadId owner; - - hMutex = (SemaphoreHandle_t)((uint32_t)mutex_id & ~1U); - - if((FURI_IS_IRQ_MODE() != 0U) || (hMutex == NULL)) { - owner = 0; - } else { - owner = (FuriThreadId)xSemaphoreGetMutexHolder(hMutex); - } - - /* Return owner thread ID */ - return (owner); -} - -/* - Delete a Mutex object. -*/ -osStatus_t osMutexDelete(osMutexId_t mutex_id) { - osStatus_t stat; -#ifndef USE_FreeRTOS_HEAP_1 - SemaphoreHandle_t hMutex; - - hMutex = (SemaphoreHandle_t)((uint32_t)mutex_id & ~1U); - - if(FURI_IS_IRQ_MODE() != 0U) { - stat = osErrorISR; - } else if(hMutex == NULL) { - stat = osErrorParameter; - } else { -#if(configQUEUE_REGISTRY_SIZE > 0) - vQueueUnregisterQueue(hMutex); -#endif - stat = osOK; - vSemaphoreDelete(hMutex); - } -#else - stat = osError; -#endif - - /* Return execution status */ - return (stat); -} diff --git a/core/furi/mutex.h b/core/furi/mutex.h deleted file mode 100644 index 44f351b7..00000000 --- a/core/furi/mutex.h +++ /dev/null @@ -1,56 +0,0 @@ -#pragma once - -#include "base.h" -#include "thread.h" - -#ifdef __cplusplus -extern "C" { -#endif - -// Mutex attributes (attr_bits in \ref osMutexAttr_t). -#define osMutexRecursive 0x00000001U ///< Recursive mutex. -#define osMutexPrioInherit 0x00000002U ///< Priority inherit protocol. -#define osMutexRobust 0x00000008U ///< Robust mutex. - -/// Attributes structure for mutex. -typedef struct { - const char* name; ///< name of the mutex - uint32_t attr_bits; ///< attribute bits - void* cb_mem; ///< memory for control block - uint32_t cb_size; ///< size of provided memory for control block -} osMutexAttr_t; - -/// \details Mutex ID identifies the mutex. -typedef void* osMutexId_t; - -/// Create and Initialize a Mutex object. -/// \param[in] attr mutex attributes; NULL: default values. -/// \return mutex ID for reference by other functions or NULL in case of error. -osMutexId_t osMutexNew(const osMutexAttr_t* attr); - -/// Get name of a Mutex object. -/// \param[in] mutex_id mutex ID obtained by \ref osMutexNew. -/// \return name as null-terminated string. -const char* osMutexGetName(osMutexId_t mutex_id); - -/// Acquire a Mutex or timeout if it is locked. -/// \param[in] mutex_id mutex ID obtained by \ref osMutexNew. -/// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. -/// \return status code that indicates the execution status of the function. -osStatus_t osMutexAcquire(osMutexId_t mutex_id, uint32_t timeout); - -/// Release a Mutex that was acquired by \ref osMutexAcquire. -/// \param[in] mutex_id mutex ID obtained by \ref osMutexNew. -/// \return status code that indicates the execution status of the function. -osStatus_t osMutexRelease(osMutexId_t mutex_id); - -/// Delete a Mutex object. -/// \param[in] mutex_id mutex ID obtained by \ref osMutexNew. -/// \return status code that indicates the execution status of the function. -osStatus_t osMutexDelete(osMutexId_t mutex_id); - -FuriThreadId osMutexGetOwner(osMutexId_t mutex_id); - -#ifdef __cplusplus -} -#endif diff --git a/core/furi/semaphore.c b/core/furi/semaphore.c deleted file mode 100644 index cbacdef0..00000000 --- a/core/furi/semaphore.c +++ /dev/null @@ -1,190 +0,0 @@ -#include "semaphore.h" -#include "check.h" -#include "common_defines.h" - -#include - -osSemaphoreId_t - osSemaphoreNew(uint32_t max_count, uint32_t initial_count, const osSemaphoreAttr_t* attr) { - SemaphoreHandle_t hSemaphore; - int32_t mem; - - hSemaphore = NULL; - - if((FURI_IS_IRQ_MODE() == 0U) && (max_count > 0U) && (initial_count <= max_count)) { - mem = -1; - - if(attr != NULL) { - if((attr->cb_mem != NULL) && (attr->cb_size >= sizeof(StaticSemaphore_t))) { - /* The memory for control block is provided, use static object */ - mem = 1; - } else { - if((attr->cb_mem == NULL) && (attr->cb_size == 0U)) { - /* Control block will be allocated from the dynamic pool */ - mem = 0; - } - } - } else { - mem = 0; - } - - if(mem != -1) { - if(max_count == 1U) { - if(mem == 1) { -#if(configSUPPORT_STATIC_ALLOCATION == 1) - hSemaphore = xSemaphoreCreateBinaryStatic((StaticSemaphore_t*)attr->cb_mem); -#endif - } else { -#if(configSUPPORT_DYNAMIC_ALLOCATION == 1) - hSemaphore = xSemaphoreCreateBinary(); -#endif - } - - if((hSemaphore != NULL) && (initial_count != 0U)) { - if(xSemaphoreGive(hSemaphore) != pdPASS) { - vSemaphoreDelete(hSemaphore); - hSemaphore = NULL; - } - } - } else { - if(mem == 1) { -#if(configSUPPORT_STATIC_ALLOCATION == 1) - hSemaphore = xSemaphoreCreateCountingStatic( - max_count, initial_count, (StaticSemaphore_t*)attr->cb_mem); -#endif - } else { -#if(configSUPPORT_DYNAMIC_ALLOCATION == 1) - hSemaphore = xSemaphoreCreateCounting(max_count, initial_count); -#endif - } - } - -#if(configQUEUE_REGISTRY_SIZE > 0) - if(hSemaphore != NULL) { - if((attr != NULL) && (attr->name != NULL)) { - /* Only non-NULL name objects are added to the Queue Registry */ - vQueueAddToRegistry(hSemaphore, attr->name); - } - } -#endif - } - } - - /* Return semaphore ID */ - return ((osSemaphoreId_t)hSemaphore); -} - -/* - Acquire a Semaphore token or timeout if no tokens are available. -*/ -osStatus_t osSemaphoreAcquire(osSemaphoreId_t semaphore_id, uint32_t timeout) { - SemaphoreHandle_t hSemaphore = (SemaphoreHandle_t)semaphore_id; - osStatus_t stat; - BaseType_t yield; - - stat = osOK; - - if(hSemaphore == NULL) { - stat = osErrorParameter; - } else if(FURI_IS_IRQ_MODE() != 0U) { - if(timeout != 0U) { - stat = osErrorParameter; - } else { - yield = pdFALSE; - - if(xSemaphoreTakeFromISR(hSemaphore, &yield) != pdPASS) { - stat = osErrorResource; - } else { - portYIELD_FROM_ISR(yield); - } - } - } else { - if(xSemaphoreTake(hSemaphore, (TickType_t)timeout) != pdPASS) { - if(timeout != 0U) { - stat = osErrorTimeout; - } else { - stat = osErrorResource; - } - } - } - - /* Return execution status */ - return (stat); -} - -/* - Release a Semaphore token up to the initial maximum count. -*/ -osStatus_t osSemaphoreRelease(osSemaphoreId_t semaphore_id) { - SemaphoreHandle_t hSemaphore = (SemaphoreHandle_t)semaphore_id; - osStatus_t stat; - BaseType_t yield; - - stat = osOK; - - if(hSemaphore == NULL) { - stat = osErrorParameter; - } else if(FURI_IS_IRQ_MODE() != 0U) { - yield = pdFALSE; - - if(xSemaphoreGiveFromISR(hSemaphore, &yield) != pdTRUE) { - stat = osErrorResource; - } else { - portYIELD_FROM_ISR(yield); - } - } else { - if(xSemaphoreGive(hSemaphore) != pdPASS) { - stat = osErrorResource; - } - } - - /* Return execution status */ - return (stat); -} - -/* - Get current Semaphore token count. -*/ -uint32_t osSemaphoreGetCount(osSemaphoreId_t semaphore_id) { - SemaphoreHandle_t hSemaphore = (SemaphoreHandle_t)semaphore_id; - uint32_t count; - - if(hSemaphore == NULL) { - count = 0U; - } else if(FURI_IS_IRQ_MODE() != 0U) { - count = (uint32_t)uxSemaphoreGetCountFromISR(hSemaphore); - } else { - count = (uint32_t)uxSemaphoreGetCount(hSemaphore); - } - - /* Return number of tokens */ - return (count); -} - -/* - Delete a Semaphore object. -*/ -osStatus_t osSemaphoreDelete(osSemaphoreId_t semaphore_id) { - SemaphoreHandle_t hSemaphore = (SemaphoreHandle_t)semaphore_id; - osStatus_t stat; - -#ifndef USE_FreeRTOS_HEAP_1 - if(FURI_IS_IRQ_MODE() != 0U) { - stat = osErrorISR; - } else if(hSemaphore == NULL) { - stat = osErrorParameter; - } else { -#if(configQUEUE_REGISTRY_SIZE > 0) - vQueueUnregisterQueue(hSemaphore); -#endif - - stat = osOK; - vSemaphoreDelete(hSemaphore); - } -#else - stat = osError; -#endif - - /* Return execution status */ - return (stat); -} diff --git a/core/furi/semaphore.h b/core/furi/semaphore.h deleted file mode 100644 index b4de78fd..00000000 --- a/core/furi/semaphore.h +++ /dev/null @@ -1,57 +0,0 @@ -#pragma once - -#include "base.h" -#include "thread.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/// Attributes structure for semaphore. -typedef struct { - const char* name; ///< name of the semaphore - uint32_t attr_bits; ///< attribute bits - void* cb_mem; ///< memory for control block - uint32_t cb_size; ///< size of provided memory for control block -} osSemaphoreAttr_t; - -/// \details Semaphore ID identifies the semaphore. -typedef void* osSemaphoreId_t; - -/// Create and Initialize a Semaphore object. -/// \param[in] max_count maximum number of available tokens. -/// \param[in] initial_count initial number of available tokens. -/// \param[in] attr semaphore attributes; NULL: default values. -/// \return semaphore ID for reference by other functions or NULL in case of error. -osSemaphoreId_t - osSemaphoreNew(uint32_t max_count, uint32_t initial_count, const osSemaphoreAttr_t* attr); - -/// Get name of a Semaphore object. -/// \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew. -/// \return name as null-terminated string. -const char* osSemaphoreGetName(osSemaphoreId_t semaphore_id); - -/// Acquire a Semaphore token or timeout if no tokens are available. -/// \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew. -/// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. -/// \return status code that indicates the execution status of the function. -osStatus_t osSemaphoreAcquire(osSemaphoreId_t semaphore_id, uint32_t timeout); - -/// Release a Semaphore token up to the initial maximum count. -/// \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew. -/// \return status code that indicates the execution status of the function. -osStatus_t osSemaphoreRelease(osSemaphoreId_t semaphore_id); - -/// Get current Semaphore token count. -/// \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew. -/// \return number of tokens available. -uint32_t osSemaphoreGetCount(osSemaphoreId_t semaphore_id); - -/// Delete a Semaphore object. -/// \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew. -/// \return status code that indicates the execution status of the function. -osStatus_t osSemaphoreDelete(osSemaphoreId_t semaphore_id); - -#ifdef __cplusplus -} -#endif diff --git a/firmware.scons b/firmware.scons index 2ad29c21..0d120592 100644 --- a/firmware.scons +++ b/firmware.scons @@ -23,7 +23,7 @@ env = ENV.Clone( "${LIB_DIST_DIR}", ], CPPPATH=[ - "#/core", + "#/furi", "#/applications", "#/firmware/targets/f${TARGET_HW}/ble_glue", "#/firmware/targets/f${TARGET_HW}/fatfs", @@ -45,7 +45,7 @@ env = ENV.Clone( # If they are present, they have precedence over Default }, # for furi_check to respect build type - "core": { + "furi": { "CCFLAGS": [ "-Os", ], @@ -100,7 +100,7 @@ lib_targets = env.BuildModules( "lib", "assets", "firmware", - "core", + "furi", ], ) @@ -177,7 +177,7 @@ fwelf = fwenv["FW_ELF"] = fwenv.Program( sources, LIBS=[ "flipper${TARGET_HW}", - "core", + "furi", "freertos", "stm32cubewb", "hwdrivers", diff --git a/firmware/targets/f7/Inc/FreeRTOSConfig.h b/firmware/targets/f7/Inc/FreeRTOSConfig.h index 9f1b83c0..4f9d1fcf 100644 --- a/firmware/targets/f7/Inc/FreeRTOSConfig.h +++ b/firmware/targets/f7/Inc/FreeRTOSConfig.h @@ -19,7 +19,8 @@ extern uint32_t SystemCoreClock; #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configCPU_CLOCK_HZ (SystemCoreClock) -#define configTICK_RATE_HZ ((TickType_t)1000) +#define configTICK_RATE_HZ_RAW 1000 +#define configTICK_RATE_HZ ((TickType_t)configTICK_RATE_HZ_RAW) #define configMAX_PRIORITIES (32) #define configMINIMAL_STACK_SIZE ((uint16_t)128) @@ -30,7 +31,7 @@ extern uint32_t SystemCoreClock; #define configUSE_TRACE_FACILITY 1 #define configUSE_16_BIT_TICKS 0 #define configUSE_MUTEXES 1 -#define configQUEUE_REGISTRY_SIZE 8 +#define configQUEUE_REGISTRY_SIZE 0 #define configCHECK_FOR_STACK_OVERFLOW 2 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 @@ -129,7 +130,7 @@ See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ /* Normal assert() semantics without relying on the provision of an assert.h header file. */ #ifdef DEBUG -#include +#include #define configASSERT(x) \ if((x) == 0) { \ furi_crash("FreeRTOS Assert"); \ diff --git a/firmware/targets/f7/Inc/stm32_assert.h b/firmware/targets/f7/Inc/stm32_assert.h index 3b0a543d..3a54d23a 100644 --- a/firmware/targets/f7/Inc/stm32_assert.h +++ b/firmware/targets/f7/Inc/stm32_assert.h @@ -22,7 +22,7 @@ #ifndef STM32_ASSERT_H #define STM32_ASSERT_H -#include +#include #ifdef __cplusplus extern "C" { @@ -49,4 +49,4 @@ extern "C" { } #endif -#endif /* STM32_ASSERT_H */ \ No newline at end of file +#endif /* STM32_ASSERT_H */ diff --git a/firmware/targets/f7/Src/main.c b/firmware/targets/f7/Src/main.c index 82a2819b..5f33569a 100644 --- a/firmware/targets/f7/Src/main.c +++ b/firmware/targets/f7/Src/main.c @@ -37,7 +37,7 @@ int main() { furi_hal_light_sequence("RGB"); // Delay is for button sampling - furi_hal_delay_ms(100); + furi_delay_ms(100); FuriHalRtcBootMode boot_mode = furi_hal_rtc_get_boot_mode(); if(boot_mode == FuriHalRtcBootModeDfu || !furi_hal_gpio_read(&gpio_button_left)) { diff --git a/firmware/targets/f7/Src/update.c b/firmware/targets/f7/Src/update.c index a91972e9..bab3b9aa 100644 --- a/firmware/targets/f7/Src/update.c +++ b/firmware/targets/f7/Src/update.c @@ -27,7 +27,6 @@ static bool flipper_update_init() { furi_hal_clock_init(); furi_hal_rtc_init(); furi_hal_interrupt_init(); - furi_hal_delay_init(); furi_hal_spi_init(); diff --git a/firmware/targets/f7/ble_glue/app_common.h b/firmware/targets/f7/ble_glue/app_common.h index a94a96c7..214c85ac 100644 --- a/firmware/targets/f7/ble_glue/app_common.h +++ b/firmware/targets/f7/ble_glue/app_common.h @@ -32,7 +32,7 @@ extern "C" { #include #include -#include +#include #include "app_conf.h" diff --git a/firmware/targets/f7/ble_glue/ble_app.c b/firmware/targets/f7/ble_glue/ble_app.c index f0406a88..4d3c96e1 100644 --- a/firmware/targets/f7/ble_glue/ble_app.c +++ b/firmware/targets/f7/ble_glue/ble_app.c @@ -22,8 +22,8 @@ _Static_assert( "Ble stack config structure size mismatch"); typedef struct { - osMutexId_t hci_mtx; - osSemaphoreId_t hci_sem; + FuriMutex* hci_mtx; + FuriSemaphore* hci_sem; FuriThread* thread; } BleApp; @@ -37,8 +37,8 @@ bool ble_app_init() { SHCI_CmdStatus_t status; ble_app = malloc(sizeof(BleApp)); // Allocate semafore and mutex for ble command buffer access - ble_app->hci_mtx = osMutexNew(NULL); - ble_app->hci_sem = osSemaphoreNew(1, 0, NULL); + ble_app->hci_mtx = furi_mutex_alloc(FuriMutexTypeNormal); + ble_app->hci_sem = furi_semaphore_alloc(1, 0); // HCI transport layer thread to handle user asynch events ble_app->thread = furi_thread_alloc(); furi_thread_set_name(ble_app->thread, "BleHciDriver"); @@ -113,8 +113,8 @@ void ble_app_thread_stop() { furi_thread_join(ble_app->thread); furi_thread_free(ble_app->thread); // Free resources - osMutexDelete(ble_app->hci_mtx); - osSemaphoreDelete(ble_app->hci_sem); + furi_mutex_free(ble_app->hci_mtx); + furi_semaphore_free(ble_app->hci_sem); free(ble_app); ble_app = NULL; memset(&ble_app_cmd_buffer, 0, sizeof(ble_app_cmd_buffer)); @@ -126,7 +126,7 @@ static int32_t ble_app_hci_thread(void* arg) { uint32_t flags = 0; while(1) { - flags = furi_thread_flags_wait(BLE_APP_FLAG_ALL, osFlagsWaitAny, osWaitForever); + flags = furi_thread_flags_wait(BLE_APP_FLAG_ALL, FuriFlagWaitAny, FuriWaitForever); if(flags & BLE_APP_FLAG_KILL_THREAD) { break; } @@ -151,14 +151,14 @@ void hci_notify_asynch_evt(void* pdata) { void hci_cmd_resp_release(uint32_t flag) { UNUSED(flag); if(ble_app) { - osSemaphoreRelease(ble_app->hci_sem); + furi_semaphore_release(ble_app->hci_sem); } } void hci_cmd_resp_wait(uint32_t timeout) { UNUSED(timeout); if(ble_app) { - osSemaphoreAcquire(ble_app->hci_sem, osWaitForever); + furi_semaphore_acquire(ble_app->hci_sem, FuriWaitForever); } } @@ -178,9 +178,9 @@ static void ble_app_hci_event_handler(void* pPayload) { static void ble_app_hci_status_not_handler(HCI_TL_CmdStatus_t status) { if(status == HCI_TL_CmdBusy) { - osMutexAcquire(ble_app->hci_mtx, osWaitForever); + furi_mutex_acquire(ble_app->hci_mtx, FuriWaitForever); } else if(status == HCI_TL_CmdAvailable) { - osMutexRelease(ble_app->hci_mtx); + furi_mutex_release(ble_app->hci_mtx); } } diff --git a/firmware/targets/f7/ble_glue/ble_glue.c b/firmware/targets/f7/ble_glue/ble_glue.c index 6fa3dbd0..be2ae0ee 100644 --- a/firmware/targets/f7/ble_glue/ble_glue.c +++ b/firmware/targets/f7/ble_glue/ble_glue.c @@ -30,8 +30,8 @@ ALIGN(4) static uint8_t ble_glue_ble_spare_event_buff[sizeof(TL_PacketHeader_t) + TL_EVT_HDR_SIZE + 255]; typedef struct { - osMutexId_t shci_mtx; - osSemaphoreId_t shci_sem; + FuriMutex* shci_mtx; + FuriSemaphore* shci_sem; FuriThread* thread; BleGlueStatus status; BleGlueKeyStorageChangedCallback callback; @@ -74,8 +74,8 @@ void ble_glue_init() { // Reference table initialization TL_Init(); - ble_glue->shci_mtx = osMutexNew(NULL); - ble_glue->shci_sem = osSemaphoreNew(1, 0, NULL); + ble_glue->shci_mtx = furi_mutex_alloc(FuriMutexTypeNormal); + ble_glue->shci_sem = furi_semaphore_alloc(1, 0); // FreeRTOS system task creation ble_glue->thread = furi_thread_alloc(); @@ -201,7 +201,7 @@ bool ble_glue_wait_for_c2_start(int32_t timeout) { started = ble_glue->status == BleGlueStatusC2Started; if(!started) { timeout--; - osDelay(1); + furi_delay_tick(1); } } while(!started && (timeout > 0)); @@ -300,10 +300,10 @@ BleGlueCommandResult ble_glue_force_c2_mode(BleGlueC2Mode desired_mode) { static void ble_glue_sys_status_not_callback(SHCI_TL_CmdStatus_t status) { switch(status) { case SHCI_TL_CmdBusy: - osMutexAcquire(ble_glue->shci_mtx, osWaitForever); + furi_mutex_acquire(ble_glue->shci_mtx, FuriWaitForever); break; case SHCI_TL_CmdAvailable: - osMutexRelease(ble_glue->shci_mtx); + furi_mutex_release(ble_glue->shci_mtx); break; default: break; @@ -368,8 +368,8 @@ void ble_glue_thread_stop() { furi_thread_join(ble_glue->thread); furi_thread_free(ble_glue->thread); // Free resources - osMutexDelete(ble_glue->shci_mtx); - osSemaphoreDelete(ble_glue->shci_sem); + furi_mutex_free(ble_glue->shci_mtx); + furi_semaphore_free(ble_glue->shci_sem); ble_glue_clear_shared_memory(); free(ble_glue); ble_glue = NULL; @@ -382,7 +382,7 @@ static int32_t ble_glue_shci_thread(void* context) { uint32_t flags = 0; while(true) { - flags = furi_thread_flags_wait(BLE_GLUE_FLAG_ALL, osFlagsWaitAny, osWaitForever); + flags = furi_thread_flags_wait(BLE_GLUE_FLAG_ALL, FuriFlagWaitAny, FuriWaitForever); if(flags & BLE_GLUE_FLAG_SHCI_EVENT) { shci_user_evt_proc(); } @@ -406,14 +406,14 @@ void shci_notify_asynch_evt(void* pdata) { void shci_cmd_resp_release(uint32_t flag) { UNUSED(flag); if(ble_glue) { - osSemaphoreRelease(ble_glue->shci_sem); + furi_semaphore_release(ble_glue->shci_sem); } } void shci_cmd_resp_wait(uint32_t timeout) { UNUSED(timeout); if(ble_glue) { - osSemaphoreAcquire(ble_glue->shci_sem, osWaitForever); + furi_semaphore_acquire(ble_glue->shci_sem, FuriWaitForever); } } @@ -468,7 +468,7 @@ BleGlueCommandResult ble_glue_fus_wait_operation() { } wip = fus_status == BleGlueCommandResultOperationOngoing; if(wip) { - osDelay(20); + furi_delay_ms(20); } } while(wip); diff --git a/firmware/targets/f7/ble_glue/gap.c b/firmware/targets/f7/ble_glue/gap.c index 7965d3f5..7154b9b1 100644 --- a/firmware/targets/f7/ble_glue/gap.c +++ b/firmware/targets/f7/ble_glue/gap.c @@ -27,12 +27,12 @@ typedef struct { GapConfig* config; GapConnectionParams connection_params; GapState state; - osMutexId_t state_mutex; + FuriMutex* state_mutex; GapEventCallback on_event_cb; void* context; - osTimerId_t advertise_timer; + FuriTimer* advertise_timer; FuriThread* thread; - osMessageQueueId_t command_queue; + FuriMessageQueue* command_queue; bool enable_adv; } Gap; @@ -94,7 +94,7 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void* pckt) { event_pckt = (hci_event_pckt*)((hci_uart_pckt*)pckt)->data; if(gap) { - osMutexAcquire(gap->state_mutex, osWaitForever); + furi_mutex_acquire(gap->state_mutex, FuriWaitForever); } switch(event_pckt->evt) { case EVT_DISCONN_COMPLETE: { @@ -152,7 +152,7 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void* pckt) { gap->connection_params.supervisor_timeout = event->Supervision_Timeout; // Stop advertising as connection completed - osTimerStop(gap->advertise_timer); + furi_timer_stop(gap->advertise_timer); // Update connection status and handle gap->state = GapStateConnected; @@ -268,7 +268,7 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void* pckt) { break; } if(gap) { - osMutexRelease(gap->state_mutex); + furi_mutex_release(gap->state_mutex); } return SVCCTL_UserEvtFlowEnable; } @@ -382,7 +382,7 @@ static void gap_advertise_start(GapState new_state) { max_interval = 0x0fa0; // 2.5 s } // Stop advertising timer - osTimerStop(gap->advertise_timer); + furi_timer_stop(gap->advertise_timer); if((new_state == GapStateAdvLowPower) && ((gap->state == GapStateAdvFast) || (gap->state == GapStateAdvLowPower))) { @@ -413,7 +413,7 @@ static void gap_advertise_start(GapState new_state) { gap->state = new_state; GapEvent event = {.type = GapEventTypeStartAdvertising}; gap->on_event_cb(event, gap->context); - osTimerStart(gap->advertise_timer, INITIAL_ADV_TIMEOUT); + furi_timer_start(gap->advertise_timer, INITIAL_ADV_TIMEOUT); } static void gap_advertise_stop() { @@ -429,7 +429,7 @@ static void gap_advertise_stop() { } } // Stop advertising - osTimerStop(gap->advertise_timer); + furi_timer_stop(gap->advertise_timer); ret = aci_gap_set_non_discoverable(); if(ret != BLE_STATUS_SUCCESS) { FURI_LOG_E(TAG, "set_non_discoverable failed %d", ret); @@ -443,32 +443,32 @@ static void gap_advertise_stop() { } void gap_start_advertising() { - osMutexAcquire(gap->state_mutex, osWaitForever); + furi_mutex_acquire(gap->state_mutex, FuriWaitForever); if(gap->state == GapStateIdle) { gap->state = GapStateStartingAdv; FURI_LOG_I(TAG, "Start advertising"); gap->enable_adv = true; GapCommand command = GapCommandAdvFast; - furi_check(osMessageQueuePut(gap->command_queue, &command, 0, 0) == osOK); + furi_check(furi_message_queue_put(gap->command_queue, &command, 0) == FuriStatusOk); } - osMutexRelease(gap->state_mutex); + furi_mutex_release(gap->state_mutex); } void gap_stop_advertising() { - osMutexAcquire(gap->state_mutex, osWaitForever); + furi_mutex_acquire(gap->state_mutex, FuriWaitForever); if(gap->state > GapStateIdle) { FURI_LOG_I(TAG, "Stop advertising"); gap->enable_adv = false; GapCommand command = GapCommandAdvStop; - furi_check(osMessageQueuePut(gap->command_queue, &command, 0, 0) == osOK); + furi_check(furi_message_queue_put(gap->command_queue, &command, 0) == FuriStatusOk); } - osMutexRelease(gap->state_mutex); + furi_mutex_release(gap->state_mutex); } static void gap_advetise_timer_callback(void* context) { UNUSED(context); GapCommand command = GapCommandAdvLowPower; - furi_check(osMessageQueuePut(gap->command_queue, &command, 0, 0) == osOK); + furi_check(furi_message_queue_put(gap->command_queue, &command, 0) == FuriStatusOk); } bool gap_init(GapConfig* config, GapEventCallback on_event_cb, void* context) { @@ -480,14 +480,14 @@ bool gap_init(GapConfig* config, GapEventCallback on_event_cb, void* context) { gap->config = config; srand(DWT->CYCCNT); // Create advertising timer - gap->advertise_timer = osTimerNew(gap_advetise_timer_callback, osTimerOnce, NULL, NULL); + gap->advertise_timer = furi_timer_alloc(gap_advetise_timer_callback, FuriTimerTypeOnce, NULL); // Initialization of GATT & GAP layer gap->service.adv_name = config->adv_name; gap_init_svc(gap); // Initialization of the BLE Services SVCCTL_Init(); // Initialization of the GAP state - gap->state_mutex = osMutexNew(NULL); + gap->state_mutex = furi_mutex_alloc(FuriMutexTypeNormal); gap->state = GapStateIdle; gap->service.connection_handle = 0xFFFF; gap->enable_adv = true; @@ -501,7 +501,7 @@ bool gap_init(GapConfig* config, GapEventCallback on_event_cb, void* context) { furi_thread_start(gap->thread); // Command queue allocation - gap->command_queue = osMessageQueueNew(8, sizeof(GapCommand), NULL); + gap->command_queue = furi_message_queue_alloc(8, sizeof(GapCommand)); uint8_t adv_service_uid[2]; gap->service.adv_svc_uuid_len = 1; @@ -518,9 +518,9 @@ bool gap_init(GapConfig* config, GapEventCallback on_event_cb, void* context) { GapState gap_get_state() { GapState state; if(gap) { - osMutexAcquire(gap->state_mutex, osWaitForever); + furi_mutex_acquire(gap->state_mutex, FuriWaitForever); state = gap->state; - osMutexRelease(gap->state_mutex); + furi_mutex_release(gap->state_mutex); } else { state = GapStateUninitialized; } @@ -529,19 +529,19 @@ GapState gap_get_state() { void gap_thread_stop() { if(gap) { - osMutexAcquire(gap->state_mutex, osWaitForever); + furi_mutex_acquire(gap->state_mutex, FuriWaitForever); gap->enable_adv = false; GapCommand command = GapCommandKillThread; - osMessageQueuePut(gap->command_queue, &command, 0, osWaitForever); - osMutexRelease(gap->state_mutex); + furi_message_queue_put(gap->command_queue, &command, FuriWaitForever); + furi_mutex_release(gap->state_mutex); furi_thread_join(gap->thread); furi_thread_free(gap->thread); // Free resources - osMutexDelete(gap->state_mutex); - osMessageQueueDelete(gap->command_queue); - osTimerStop(gap->advertise_timer); - while(xTimerIsTimerActive(gap->advertise_timer) == pdTRUE) osDelay(1); - furi_check(osTimerDelete(gap->advertise_timer) == osOK); + furi_mutex_free(gap->state_mutex); + furi_message_queue_free(gap->command_queue); + furi_timer_stop(gap->advertise_timer); + while(xTimerIsTimerActive(gap->advertise_timer) == pdTRUE) furi_delay_tick(1); + furi_timer_free(gap->advertise_timer); free(gap); gap = NULL; } @@ -551,12 +551,12 @@ static int32_t gap_app(void* context) { UNUSED(context); GapCommand command; while(1) { - osStatus_t status = osMessageQueueGet(gap->command_queue, &command, NULL, osWaitForever); - if(status != osOK) { + FuriStatus status = furi_message_queue_get(gap->command_queue, &command, FuriWaitForever); + if(status != FuriStatusOk) { FURI_LOG_E(TAG, "Message queue get error: %d", status); continue; } - osMutexAcquire(gap->state_mutex, osWaitForever); + furi_mutex_acquire(gap->state_mutex, FuriWaitForever); if(command == GapCommandKillThread) { break; } @@ -567,7 +567,7 @@ static int32_t gap_app(void* context) { } else if(command == GapCommandAdvStop) { gap_advertise_stop(); } - osMutexRelease(gap->state_mutex); + furi_mutex_release(gap->state_mutex); } return 0; diff --git a/firmware/targets/f7/ble_glue/serial_service.c b/firmware/targets/f7/ble_glue/serial_service.c index a5d3b97a..91e12dd6 100644 --- a/firmware/targets/f7/ble_glue/serial_service.c +++ b/firmware/targets/f7/ble_glue/serial_service.c @@ -11,7 +11,7 @@ typedef struct { uint16_t rx_char_handle; uint16_t tx_char_handle; uint16_t flow_ctrl_char_handle; - osMutexId_t buff_size_mtx; + FuriMutex* buff_size_mtx; uint32_t buff_size; uint16_t bytes_ready_to_receive; SerialServiceEventCallback callback; @@ -44,7 +44,9 @@ static SVCCTL_EvtAckStatus_t serial_svc_event_handler(void* event) { } else if(attribute_modified->Attr_Handle == serial_svc->rx_char_handle + 1) { FURI_LOG_D(TAG, "Received %d bytes", attribute_modified->Attr_Data_Length); if(serial_svc->callback) { - furi_check(osMutexAcquire(serial_svc->buff_size_mtx, osWaitForever) == osOK); + furi_check( + furi_mutex_acquire(serial_svc->buff_size_mtx, FuriWaitForever) == + FuriStatusOk); if(attribute_modified->Attr_Data_Length > serial_svc->bytes_ready_to_receive) { FURI_LOG_W( TAG, @@ -62,7 +64,7 @@ static SVCCTL_EvtAckStatus_t serial_svc_event_handler(void* event) { }}; uint32_t buff_free_size = serial_svc->callback(event, serial_svc->context); FURI_LOG_D(TAG, "Available buff size: %d", buff_free_size); - furi_check(osMutexRelease(serial_svc->buff_size_mtx) == osOK); + furi_check(furi_mutex_release(serial_svc->buff_size_mtx) == FuriStatusOk); } ret = SVCCTL_EvtAckFlowEnable; } @@ -140,7 +142,7 @@ void serial_svc_start() { FURI_LOG_E(TAG, "Failed to add Flow Control characteristic: %d", status); } // Allocate buffer size mutex - serial_svc->buff_size_mtx = osMutexNew(NULL); + serial_svc->buff_size_mtx = furi_mutex_alloc(FuriMutexTypeNormal); } void serial_svc_set_callbacks( @@ -165,7 +167,7 @@ void serial_svc_notify_buffer_is_empty() { furi_assert(serial_svc); furi_assert(serial_svc->buff_size_mtx); - furi_check(osMutexAcquire(serial_svc->buff_size_mtx, osWaitForever) == osOK); + furi_check(furi_mutex_acquire(serial_svc->buff_size_mtx, FuriWaitForever) == FuriStatusOk); if(serial_svc->bytes_ready_to_receive == 0) { FURI_LOG_D(TAG, "Buffer is empty. Notifying client"); serial_svc->bytes_ready_to_receive = serial_svc->buff_size; @@ -177,7 +179,7 @@ void serial_svc_notify_buffer_is_empty() { sizeof(uint32_t), (uint8_t*)&buff_size_reversed); } - furi_check(osMutexRelease(serial_svc->buff_size_mtx) == osOK); + furi_check(furi_mutex_release(serial_svc->buff_size_mtx) == FuriStatusOk); } void serial_svc_stop() { @@ -202,7 +204,7 @@ void serial_svc_stop() { FURI_LOG_E(TAG, "Failed to delete Serial service: %d", status); } // Delete buffer size mutex - osMutexDelete(serial_svc->buff_size_mtx); + furi_mutex_free(serial_svc->buff_size_mtx); free(serial_svc); serial_svc = NULL; } diff --git a/firmware/targets/f7/fatfs/ffconf.h b/firmware/targets/f7/fatfs/ffconf.h index 83bcfc78..9410cedc 100644 --- a/firmware/targets/f7/fatfs/ffconf.h +++ b/firmware/targets/f7/fatfs/ffconf.h @@ -245,7 +245,7 @@ #define _FS_REENTRANT 0 /* 0:Disable or 1:Enable */ #define _FS_TIMEOUT 1000 /* Timeout period in unit of time ticks */ -#define _SYNC_t osMutexId_t +#define _SYNC_t FuriMutex* /* The option _FS_REENTRANT switches the re-entrancy (thread safe) of the FatFs / module itself. Note that regardless of this option, file access to different / volume is always re-entrant and volume control functions, f_mount(), f_mkfs() diff --git a/firmware/targets/f7/fatfs/spi_sd_hal.c b/firmware/targets/f7/fatfs/spi_sd_hal.c index 1b96568c..bfe046b5 100644 --- a/firmware/targets/f7/fatfs/spi_sd_hal.c +++ b/firmware/targets/f7/fatfs/spi_sd_hal.c @@ -46,7 +46,7 @@ void SD_IO_Init(void) { /* SD chip select high */ furi_hal_gpio_write(furi_hal_sd_spi_handle->cs, true); - furi_hal_delay_us(10); + furi_delay_us(10); /* Send dummy byte 0xFF, 10 times with CS high */ /* Rise CS and MOSI for 80 clocks cycles */ @@ -64,11 +64,11 @@ void SD_IO_Init(void) { void SD_IO_CSState(uint8_t val) { /* Some SD Cards are prone to fail if CLK-ed too soon after CS transition. Worst case found: 8us */ if(val == 1) { - furi_hal_delay_us(10); // Exit guard time for some SD cards + furi_delay_us(10); // Exit guard time for some SD cards furi_hal_gpio_write(furi_hal_sd_spi_handle->cs, true); } else { furi_hal_gpio_write(furi_hal_sd_spi_handle->cs, false); - furi_hal_delay_us(10); // Entry guard time for some SD cards + furi_delay_us(10); // Entry guard time for some SD cards } } diff --git a/firmware/targets/f7/fatfs/stm32_adafruit_sd.c b/firmware/targets/f7/fatfs/stm32_adafruit_sd.c index fc2924d4..1ca38abe 100644 --- a/firmware/targets/f7/fatfs/stm32_adafruit_sd.c +++ b/firmware/targets/f7/fatfs/stm32_adafruit_sd.c @@ -349,13 +349,13 @@ uint8_t BSP_SD_Init(bool reset_card) { furi_hal_power_disable_external_3_3v(); SD_SPI_Bus_To_Down_State(); hal_sd_detect_set_low(); - furi_hal_delay_ms(250); + furi_delay_ms(250); /* reinit bus and enable power */ SD_SPI_Bus_To_Normal_State(); hal_sd_detect_init(); furi_hal_power_enable_external_3_3v(); - furi_hal_delay_ms(100); + furi_delay_ms(100); } /* Configure IO functionalities for SD pin */ @@ -869,7 +869,7 @@ SD_CmdAnswer_typedef SD_SendCmd(uint8_t Cmd, uint32_t Arg, uint8_t Crc, uint8_t retr.r2 = SD_IO_WriteByte(SD_DUMMY_BYTE); /* Set CS High */ SD_IO_CSState(1); - furi_hal_delay_us(1000); + furi_delay_us(1000); /* Set CS Low */ SD_IO_CSState(0); diff --git a/firmware/targets/f7/fatfs/syscall.c b/firmware/targets/f7/fatfs/syscall.c index 7bed9315..00eb8aed 100644 --- a/firmware/targets/f7/fatfs/syscall.c +++ b/firmware/targets/f7/fatfs/syscall.c @@ -38,7 +38,7 @@ int ff_cre_syncobj(/* 1:Function succeeded, 0:Could not create the sync object * //osSemaphoreDef(SEM); //*sobj = osSemaphoreCreate(osSemaphore(SEM), 1); - *sobj = osMutexNew(NULL); + *sobj = furi_mutex_alloc(FuriMutexTypeNormal); ret = (*sobj != NULL); return ret; @@ -55,7 +55,7 @@ int ff_cre_syncobj(/* 1:Function succeeded, 0:Could not create the sync object * int ff_del_syncobj(/* 1:Function succeeded, 0:Could not delete due to any error */ _SYNC_t sobj /* Sync object tied to the logical drive to be deleted */ ) { - osMutexDelete(sobj); + furi_mutex_free(sobj); return 1; } @@ -71,7 +71,7 @@ int ff_req_grant(/* 1:Got a grant to access the volume, 0:Could not get a grant ) { int ret = 0; - if(osMutexAcquire(sobj, _FS_TIMEOUT) == osOK) { + if(furi_mutex_acquire(sobj, _FS_TIMEOUT) == FuriStatusOk) { ret = 1; } @@ -86,7 +86,7 @@ int ff_req_grant(/* 1:Got a grant to access the volume, 0:Could not get a grant void ff_rel_grant(_SYNC_t sobj /* Sync object to be signaled */ ) { - osMutexRelease(sobj); + furi_mutex_release(sobj); } #endif diff --git a/firmware/targets/f7/furi_hal/furi_hal.c b/firmware/targets/f7/furi_hal/furi_hal.c index e97c0e8c..0cef33dd 100644 --- a/firmware/targets/f7/furi_hal/furi_hal.c +++ b/firmware/targets/f7/furi_hal/furi_hal.c @@ -7,8 +7,9 @@ #define TAG "FuriHal" void furi_hal_init_early() { + furi_hal_cortex_init_early(); + furi_hal_clock_init_early(); - furi_hal_delay_init(); furi_hal_resources_init_early(); diff --git a/firmware/targets/f7/furi_hal/furi_hal_bt.c b/firmware/targets/f7/furi_hal/furi_hal_bt.c index dde3842d..47ed5992 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_bt.c +++ b/firmware/targets/f7/furi_hal/furi_hal_bt.c @@ -2,7 +2,6 @@ #include #include #include -#include #include #include @@ -19,7 +18,7 @@ /* Time, in ms, to wait for mode transition before crashing */ #define C2_MODE_SWITCH_TIMEOUT 10000 -osMutexId_t furi_hal_bt_core2_mtx = NULL; +FuriMutex* furi_hal_bt_core2_mtx = NULL; static FuriHalBtStack furi_hal_bt_stack = FuriHalBtStackUnknown; typedef void (*FuriHalBtProfileStart)(void); @@ -79,7 +78,7 @@ FuriHalBtProfileConfig* current_profile = NULL; void furi_hal_bt_init() { if(!furi_hal_bt_core2_mtx) { - furi_hal_bt_core2_mtx = osMutexNew(NULL); + furi_hal_bt_core2_mtx = furi_mutex_alloc(FuriMutexTypeNormal); furi_assert(furi_hal_bt_core2_mtx); } @@ -94,12 +93,12 @@ void furi_hal_bt_init() { void furi_hal_bt_lock_core2() { furi_assert(furi_hal_bt_core2_mtx); - furi_check(osMutexAcquire(furi_hal_bt_core2_mtx, osWaitForever) == osOK); + furi_check(furi_mutex_acquire(furi_hal_bt_core2_mtx, FuriWaitForever) == FuriStatusOk); } void furi_hal_bt_unlock_core2() { furi_assert(furi_hal_bt_core2_mtx); - furi_check(osMutexRelease(furi_hal_bt_core2_mtx) == osOK); + furi_check(furi_mutex_release(furi_hal_bt_core2_mtx) == FuriStatusOk); } static bool furi_hal_bt_radio_stack_is_supported(const BleGlueC2Info* info) { @@ -126,7 +125,7 @@ bool furi_hal_bt_start_radio_stack() { bool res = false; furi_assert(furi_hal_bt_core2_mtx); - osMutexAcquire(furi_hal_bt_core2_mtx, osWaitForever); + furi_mutex_acquire(furi_hal_bt_core2_mtx, FuriWaitForever); // Explicitly tell that we are in charge of CLK48 domain if(!LL_HSEM_IsSemaphoreLocked(HSEM, CFG_HW_CLK48_CONFIG_SEMID)) { @@ -162,7 +161,7 @@ bool furi_hal_bt_start_radio_stack() { } res = true; } while(false); - osMutexRelease(furi_hal_bt_core2_mtx); + furi_mutex_release(furi_hal_bt_core2_mtx); return res; } @@ -255,7 +254,7 @@ void furi_hal_bt_reinit() { FURI_LOG_I(TAG, "Reset SHCI"); furi_check(ble_glue_reinit_c2()); - osDelay(100); + furi_delay_ms(100); ble_glue_thread_stop(); FURI_LOG_I(TAG, "Start BT initialization"); @@ -292,7 +291,7 @@ void furi_hal_bt_stop_advertising() { if(furi_hal_bt_is_active()) { gap_stop_advertising(); while(furi_hal_bt_is_active()) { - osDelay(1); + furi_delay_tick(1); } } } @@ -436,7 +435,7 @@ bool furi_hal_bt_ensure_c2_mode(BleGlueC2Mode mode) { return true; } else if(fw_start_res == BleGlueCommandResultRestartPending) { // Do nothing and wait for system reset - osDelay(C2_MODE_SWITCH_TIMEOUT); + furi_delay_ms(C2_MODE_SWITCH_TIMEOUT); furi_crash("Waiting for FUS->radio stack transition"); return true; } diff --git a/firmware/targets/f7/furi_hal/furi_hal_cortex.c b/firmware/targets/f7/furi_hal/furi_hal_cortex.c new file mode 100644 index 00000000..2b4ea6e9 --- /dev/null +++ b/firmware/targets/f7/furi_hal/furi_hal_cortex.c @@ -0,0 +1,20 @@ +#include "furi_hal_cortex.h" + +#include + +void furi_hal_cortex_init_early() { + CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; + DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; + DWT->CYCCNT = 0U; +} + +void furi_hal_cortex_delay_us(uint32_t microseconds) { + uint32_t start = DWT->CYCCNT; + uint32_t time_ticks = SystemCoreClock / 1000000 * microseconds; + while((DWT->CYCCNT - start) < time_ticks) { + }; +} + +uint32_t furi_hal_cortex_instructions_per_microsecond() { + return SystemCoreClock / 1000000; +} diff --git a/firmware/targets/f7/furi_hal/furi_hal_crc.c b/firmware/targets/f7/furi_hal/furi_hal_crc.c deleted file mode 100644 index 9ac13e97..00000000 --- a/firmware/targets/f7/furi_hal/furi_hal_crc.c +++ /dev/null @@ -1,93 +0,0 @@ -#include -#include - -typedef enum { - CRC_State_Reset, - CRC_State_Ready, - CRC_State_Busy, -} CRC_State; - -typedef struct { - CRC_State state; - osMutexId_t mtx; -} HAL_CRC_Control; - -static volatile HAL_CRC_Control hal_crc_control = { - .state = CRC_State_Reset, - .mtx = NULL, -}; - -void furi_hal_crc_init(bool synchronize) { - /* initialize peripheral with default generating polynomial */ - LL_CRC_SetInputDataReverseMode(CRC, LL_CRC_INDATA_REVERSE_BYTE); - LL_CRC_SetOutputDataReverseMode(CRC, LL_CRC_OUTDATA_REVERSE_BIT); - LL_CRC_SetPolynomialCoef(CRC, LL_CRC_DEFAULT_CRC32_POLY); - LL_CRC_SetPolynomialSize(CRC, LL_CRC_POLYLENGTH_32B); - LL_CRC_SetInitialData(CRC, LL_CRC_DEFAULT_CRC_INITVALUE); - - if(synchronize) { - hal_crc_control.mtx = osMutexNew(NULL); - } - hal_crc_control.state = CRC_State_Ready; -} - -void furi_hal_crc_reset() { - furi_check(hal_crc_control.state == CRC_State_Ready); - if(hal_crc_control.mtx) { - furi_check(osMutexGetOwner(hal_crc_control.mtx) == furi_thread_get_current_id()); - osMutexRelease(hal_crc_control.mtx); - } - LL_CRC_ResetCRCCalculationUnit(CRC); -} - -static uint32_t furi_hal_crc_handle_8(uint8_t pBuffer[], uint32_t BufferLength) { - uint32_t i; /* input data buffer index */ - hal_crc_control.state = CRC_State_Busy; - /* Processing time optimization: 4 bytes are entered in a row with a single word write, - * last bytes must be carefully fed to the CRC calculator to ensure a correct type - * handling by the peripheral */ - for(i = 0U; i < (BufferLength / 4U); i++) { - LL_CRC_FeedData32( - CRC, - ((uint32_t)pBuffer[4U * i] << 24U) | ((uint32_t)pBuffer[(4U * i) + 1U] << 16U) | - ((uint32_t)pBuffer[(4U * i) + 2U] << 8U) | (uint32_t)pBuffer[(4U * i) + 3U]); - } - /* last bytes specific handling */ - if((BufferLength % 4U) != 0U) { - if((BufferLength % 4U) == 1U) { - LL_CRC_FeedData8(CRC, pBuffer[4U * i]); - } else if((BufferLength % 4U) == 2U) { - LL_CRC_FeedData16( - CRC, ((uint16_t)(pBuffer[4U * i]) << 8U) | (uint16_t)pBuffer[(4U * i) + 1U]); - } else if((BufferLength % 4U) == 3U) { - LL_CRC_FeedData16( - CRC, ((uint16_t)(pBuffer[4U * i]) << 8U) | (uint16_t)pBuffer[(4U * i) + 1U]); - LL_CRC_FeedData8(CRC, pBuffer[(4U * i) + 2U]); - } - } - - hal_crc_control.state = CRC_State_Ready; - /* Return the CRC computed value */ - return LL_CRC_ReadData32(CRC); -} - -static uint32_t furi_hal_crc_accumulate(uint32_t pBuffer[], uint32_t BufferLength) { - furi_check(hal_crc_control.state == CRC_State_Ready); - if(hal_crc_control.mtx) { - furi_check(osMutexGetOwner(hal_crc_control.mtx) != NULL); - } - return furi_hal_crc_handle_8((uint8_t*)pBuffer, BufferLength); -} - -uint32_t furi_hal_crc_feed(void* data, uint16_t length) { - return ~furi_hal_crc_accumulate(data, length); -} - -bool furi_hal_crc_acquire(uint32_t timeout) { - furi_assert(hal_crc_control.mtx); - if(osMutexAcquire(hal_crc_control.mtx, timeout) == osOK) { - LL_CRC_ResetCRCCalculationUnit(CRC); - return true; - } - return false; -} diff --git a/firmware/targets/f7/furi_hal/furi_hal_crc.h b/firmware/targets/f7/furi_hal/furi_hal_crc.h deleted file mode 100644 index 8abaaad1..00000000 --- a/firmware/targets/f7/furi_hal/furi_hal_crc.h +++ /dev/null @@ -1,35 +0,0 @@ -#pragma once - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** Configure for CRC32 calculation - * @param synchronize enforce acquisition & release in multithreaded environment - */ -void furi_hal_crc_init(bool synchronize); - -/** Blocking call to get control of CRC block. Mandatory while RTOS is running - * @param timeout time to wait for CRC to be available. Can be osWaitForever - * @return bool acquisition success - */ -bool furi_hal_crc_acquire(uint32_t timeout); - -/** Reset current calculation state and release CRC block - */ -void furi_hal_crc_reset(); - -/** Process data block. Does not reset current state, - * allowing to process arbitrary data lengths - * @param data pointer to data - * @param length data length - * @return uint32_t CRC32 value - */ -uint32_t furi_hal_crc_feed(void* data, uint16_t length); - -#ifdef __cplusplus -} -#endif diff --git a/firmware/targets/f7/furi_hal/furi_hal_crypto.c b/firmware/targets/f7/furi_hal/furi_hal_crypto.c index 2164ebc3..b3c68e2d 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_crypto.c +++ b/firmware/targets/f7/furi_hal/furi_hal_crypto.c @@ -23,7 +23,7 @@ #define CRYPTO_KEYSIZE_256B (AES_CR_KEYSIZE) #define CRYPTO_AES_CBC (AES_CR_CHMOD_0) -static osMutexId_t furi_hal_crypto_mutex = NULL; +static FuriMutex* furi_hal_crypto_mutex = NULL; static bool furi_hal_crypto_mode_init_done = false; static const uint8_t enclave_signature_iv[ENCLAVE_FACTORY_KEY_SLOTS][16] = { @@ -66,7 +66,7 @@ static const uint8_t enclave_signature_expected[ENCLAVE_FACTORY_KEY_SLOTS][ENCLA }; void furi_hal_crypto_init() { - furi_hal_crypto_mutex = osMutexNew(NULL); + furi_hal_crypto_mutex = furi_mutex_alloc(FuriMutexTypeNormal); FURI_LOG_I(TAG, "Init OK"); } @@ -143,7 +143,7 @@ bool furi_hal_crypto_store_add_key(FuriHalCryptoKey* key, uint8_t* slot) { furi_assert(key); furi_assert(slot); - furi_check(osMutexAcquire(furi_hal_crypto_mutex, osWaitForever) == osOK); + furi_check(furi_mutex_acquire(furi_hal_crypto_mutex, FuriWaitForever) == FuriStatusOk); if(!furi_hal_bt_is_alive()) { return false; @@ -176,7 +176,7 @@ bool furi_hal_crypto_store_add_key(FuriHalCryptoKey* key, uint8_t* slot) { memcpy(pParam.KeyData, key->data, key_data_size); SHCI_CmdStatus_t shci_state = SHCI_C2_FUS_StoreUsrKey(&pParam, slot); - furi_check(osMutexRelease(furi_hal_crypto_mutex) == osOK); + furi_check(furi_mutex_release(furi_hal_crypto_mutex) == FuriStatusOk); return (shci_state == SHCI_Success); } @@ -239,7 +239,7 @@ static bool crypto_process_block(uint32_t* in, uint32_t* out, uint8_t blk_len) { bool furi_hal_crypto_store_load_key(uint8_t slot, const uint8_t* iv) { furi_assert(slot > 0 && slot <= 100); furi_assert(furi_hal_crypto_mutex); - furi_check(osMutexAcquire(furi_hal_crypto_mutex, osWaitForever) == osOK); + furi_check(furi_mutex_acquire(furi_hal_crypto_mutex, FuriWaitForever) == FuriStatusOk); if(!furi_hal_bt_is_alive()) { return false; @@ -252,7 +252,7 @@ bool furi_hal_crypto_store_load_key(uint8_t slot, const uint8_t* iv) { return true; } else { CLEAR_BIT(AES1->CR, AES_CR_EN); - furi_check(osMutexRelease(furi_hal_crypto_mutex) == osOK); + furi_check(furi_mutex_release(furi_hal_crypto_mutex) == FuriStatusOk); return false; } } @@ -272,7 +272,7 @@ bool furi_hal_crypto_store_unload_key(uint8_t slot) { LL_AHB2_GRP1_ReleaseReset(LL_AHB2_GRP1_PERIPH_AES1); FURI_CRITICAL_EXIT(); - furi_check(osMutexRelease(furi_hal_crypto_mutex) == osOK); + furi_check(furi_mutex_release(furi_hal_crypto_mutex) == FuriStatusOk); return (shci_state == SHCI_Success); } diff --git a/firmware/targets/f7/furi_hal/furi_hal_delay.c b/firmware/targets/f7/furi_hal/furi_hal_delay.c deleted file mode 100644 index 99636230..00000000 --- a/firmware/targets/f7/furi_hal/furi_hal_delay.c +++ /dev/null @@ -1,45 +0,0 @@ -#include "furi_hal_delay.h" - -#include -#include -#include - -#define TAG "FuriHalDelay" - -void furi_hal_delay_init() { - CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; - DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; - DWT->CYCCNT = 0U; -} - -uint32_t furi_hal_delay_instructions_per_microsecond() { - return SystemCoreClock / 1000000; -} - -uint32_t furi_hal_get_tick(void) { - return osKernelGetTickCount(); -} - -uint32_t furi_hal_ms_to_ticks(float milliseconds) { - return milliseconds / (1000.0f / osKernelGetTickFreq()); -} - -void furi_hal_delay_us(float microseconds) { - uint32_t start = DWT->CYCCNT; - uint32_t time_ticks = microseconds * furi_hal_delay_instructions_per_microsecond(); - while((DWT->CYCCNT - start) < time_ticks) { - }; -} - -// cannot be used in ISR -// TODO add delay_ISR variant -void furi_hal_delay_ms(float milliseconds) { - if(!FURI_IS_ISR() && osKernelGetState() == osKernelRunning) { - uint32_t ticks = milliseconds / (1000.0f / osKernelGetTickFreq()); - osStatus_t result = osDelay(ticks); - (void)result; - furi_assert(result == osOK); - } else { - furi_hal_delay_us(milliseconds * 1000); - } -} diff --git a/firmware/targets/f7/furi_hal/furi_hal_i2c.c b/firmware/targets/f7/furi_hal/furi_hal_i2c.c index fdef1127..36f5230c 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_i2c.c +++ b/firmware/targets/f7/furi_hal/furi_hal_i2c.c @@ -1,5 +1,4 @@ #include -#include #include #include @@ -61,11 +60,11 @@ bool furi_hal_i2c_tx( furi_assert(timeout > 0); bool ret = true; - uint32_t timeout_tick = furi_hal_get_tick() + timeout; + uint32_t timeout_tick = furi_get_tick() + timeout; do { while(LL_I2C_IsActiveFlag_BUSY(handle->bus->i2c)) { - if(furi_hal_get_tick() >= timeout_tick) { + if(furi_get_tick() >= timeout_tick) { ret = false; break; } @@ -90,7 +89,7 @@ bool furi_hal_i2c_tx( size--; } - if(furi_hal_get_tick() >= timeout_tick) { + if(furi_get_tick() >= timeout_tick) { ret = false; break; } @@ -112,11 +111,11 @@ bool furi_hal_i2c_rx( furi_assert(timeout > 0); bool ret = true; - uint32_t timeout_tick = furi_hal_get_tick() + timeout; + uint32_t timeout_tick = furi_get_tick() + timeout; do { while(LL_I2C_IsActiveFlag_BUSY(handle->bus->i2c)) { - if(furi_hal_get_tick() >= timeout_tick) { + if(furi_get_tick() >= timeout_tick) { ret = false; break; } @@ -141,7 +140,7 @@ bool furi_hal_i2c_rx( size--; } - if(furi_hal_get_tick() >= timeout_tick) { + if(furi_get_tick() >= timeout_tick) { ret = false; break; } @@ -176,11 +175,11 @@ bool furi_hal_i2c_is_device_ready(FuriHalI2cBusHandle* handle, uint8_t i2c_addr, furi_assert(timeout > 0); bool ret = true; - uint32_t timeout_tick = furi_hal_get_tick() + timeout; + uint32_t timeout_tick = furi_get_tick() + timeout; do { while(LL_I2C_IsActiveFlag_BUSY(handle->bus->i2c)) { - if(furi_hal_get_tick() >= timeout_tick) { + if(furi_get_tick() >= timeout_tick) { return false; } } @@ -191,14 +190,14 @@ bool furi_hal_i2c_is_device_ready(FuriHalI2cBusHandle* handle, uint8_t i2c_addr, while((!LL_I2C_IsActiveFlag_NACK(handle->bus->i2c)) && (!LL_I2C_IsActiveFlag_STOP(handle->bus->i2c))) { - if(furi_hal_get_tick() >= timeout_tick) { + if(furi_get_tick() >= timeout_tick) { return false; } } if(LL_I2C_IsActiveFlag_NACK(handle->bus->i2c)) { while(!LL_I2C_IsActiveFlag_STOP(handle->bus->i2c)) { - if(furi_hal_get_tick() >= timeout_tick) { + if(furi_get_tick() >= timeout_tick) { return false; } } @@ -215,7 +214,7 @@ bool furi_hal_i2c_is_device_ready(FuriHalI2cBusHandle* handle, uint8_t i2c_addr, } while(!LL_I2C_IsActiveFlag_STOP(handle->bus->i2c)) { - if(furi_hal_get_tick() >= timeout_tick) { + if(furi_get_tick() >= timeout_tick) { return false; } } @@ -309,11 +308,11 @@ bool furi_hal_i2c_write_mem( bool ret = true; uint8_t size = len + 1; - uint32_t timeout_tick = furi_hal_get_tick() + timeout; + uint32_t timeout_tick = furi_get_tick() + timeout; do { while(LL_I2C_IsActiveFlag_BUSY(handle->bus->i2c)) { - if(furi_hal_get_tick() >= timeout_tick) { + if(furi_get_tick() >= timeout_tick) { ret = false; break; } @@ -342,7 +341,7 @@ bool furi_hal_i2c_write_mem( size--; } - if(furi_hal_get_tick() >= timeout_tick) { + if(furi_get_tick() >= timeout_tick) { ret = false; break; } diff --git a/firmware/targets/f7/furi_hal/furi_hal_i2c_config.c b/firmware/targets/f7/furi_hal/furi_hal_i2c_config.c index 2cdef23a..d832c4f6 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_i2c_config.c +++ b/firmware/targets/f7/furi_hal/furi_hal_i2c_config.c @@ -16,26 +16,27 @@ */ #define FURI_HAL_I2C_CONFIG_POWER_I2C_TIMINGS_400 0x00602173 -osMutexId_t furi_hal_i2c_bus_power_mutex = NULL; +FuriMutex* furi_hal_i2c_bus_power_mutex = NULL; static void furi_hal_i2c_bus_power_event(FuriHalI2cBus* bus, FuriHalI2cBusEvent event) { if(event == FuriHalI2cBusEventInit) { - furi_hal_i2c_bus_power_mutex = osMutexNew(NULL); + furi_hal_i2c_bus_power_mutex = furi_mutex_alloc(FuriMutexTypeNormal); FURI_CRITICAL_ENTER(); LL_RCC_SetI2CClockSource(LL_RCC_I2C1_CLKSOURCE_PCLK1); LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I2C1); FURI_CRITICAL_EXIT(); bus->current_handle = NULL; } else if(event == FuriHalI2cBusEventDeinit) { - furi_check(osMutexDelete(furi_hal_i2c_bus_power_mutex) == osOK); + furi_mutex_free(furi_hal_i2c_bus_power_mutex); FURI_CRITICAL_ENTER(); LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I2C1); LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_I2C1); FURI_CRITICAL_EXIT(); } else if(event == FuriHalI2cBusEventLock) { - furi_check(osMutexAcquire(furi_hal_i2c_bus_power_mutex, osWaitForever) == osOK); + furi_check( + furi_mutex_acquire(furi_hal_i2c_bus_power_mutex, FuriWaitForever) == FuriStatusOk); } else if(event == FuriHalI2cBusEventUnlock) { - furi_check(osMutexRelease(furi_hal_i2c_bus_power_mutex) == osOK); + furi_check(furi_mutex_release(furi_hal_i2c_bus_power_mutex) == FuriStatusOk); } else if(event == FuriHalI2cBusEventActivate) { FURI_CRITICAL_ENTER(); LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_I2C1); @@ -52,26 +53,27 @@ FuriHalI2cBus furi_hal_i2c_bus_power = { .callback = furi_hal_i2c_bus_power_event, }; -osMutexId_t furi_hal_i2c_bus_external_mutex = NULL; +FuriMutex* furi_hal_i2c_bus_external_mutex = NULL; static void furi_hal_i2c_bus_external_event(FuriHalI2cBus* bus, FuriHalI2cBusEvent event) { if(event == FuriHalI2cBusEventInit) { - furi_hal_i2c_bus_external_mutex = osMutexNew(NULL); + furi_hal_i2c_bus_external_mutex = furi_mutex_alloc(FuriMutexTypeNormal); FURI_CRITICAL_ENTER(); LL_RCC_SetI2CClockSource(LL_RCC_I2C3_CLKSOURCE_PCLK1); LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I2C3); FURI_CRITICAL_EXIT(); bus->current_handle = NULL; } else if(event == FuriHalI2cBusEventDeinit) { - furi_check(osMutexDelete(furi_hal_i2c_bus_external_mutex) == osOK); + furi_mutex_free(furi_hal_i2c_bus_external_mutex); FURI_CRITICAL_ENTER(); LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I2C3); LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_I2C3); FURI_CRITICAL_EXIT(); } else if(event == FuriHalI2cBusEventLock) { - furi_check(osMutexAcquire(furi_hal_i2c_bus_external_mutex, osWaitForever) == osOK); + furi_check( + furi_mutex_acquire(furi_hal_i2c_bus_external_mutex, FuriWaitForever) == FuriStatusOk); } else if(event == FuriHalI2cBusEventUnlock) { - furi_check(osMutexRelease(furi_hal_i2c_bus_external_mutex) == osOK); + furi_check(furi_mutex_release(furi_hal_i2c_bus_external_mutex) == FuriStatusOk); } else if(event == FuriHalI2cBusEventActivate) { FURI_CRITICAL_ENTER(); LL_RCC_SetI2CClockSource(LL_RCC_I2C3_CLKSOURCE_PCLK1); diff --git a/firmware/targets/f7/furi_hal/furi_hal_infrared.c b/firmware/targets/f7/furi_hal/furi_hal_infrared.c index f6f01887..442ae715 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_infrared.c +++ b/firmware/targets/f7/furi_hal/furi_hal_infrared.c @@ -1,9 +1,7 @@ #include "furi_hal_infrared.h" -#include "furi_hal_delay.h" -#include "furi/check.h" +#include #include "stm32wbxx_ll_dma.h" #include "sys/_stdint.h" -#include #include #include @@ -52,7 +50,7 @@ typedef struct { void* data_context; void* signal_sent_context; InfraredTxBuf buffer[2]; - osSemaphoreId_t stop_semaphore; + FuriSemaphore* stop_semaphore; uint32_t tx_timing_rest_duration; /** if timing is too long (> 0xFFFF), send it in few iterations */ bool tx_timing_rest_level; @@ -225,8 +223,8 @@ static void furi_hal_infrared_tx_dma_terminate(void) { LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_2); LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_1); LL_TIM_DisableCounter(TIM1); - osStatus_t status = osSemaphoreRelease(infrared_tim_tx.stop_semaphore); - furi_check(status == osOK); + FuriStatus status = furi_semaphore_release(infrared_tim_tx.stop_semaphore); + furi_check(status == FuriStatusOk); furi_hal_infrared_state = InfraredStateAsyncTxStopped; } @@ -545,15 +543,13 @@ static void furi_hal_infrared_async_tx_free_resources(void) { furi_assert( (furi_hal_infrared_state == InfraredStateIdle) || (furi_hal_infrared_state == InfraredStateAsyncTxStopped)); - osStatus_t status; furi_hal_gpio_init(&gpio_infrared_tx, GpioModeOutputOpenDrain, GpioPullDown, GpioSpeedLow); furi_hal_interrupt_set_isr(FuriHalInterruptIdDma1Ch1, NULL, NULL); furi_hal_interrupt_set_isr(FuriHalInterruptIdDma1Ch2, NULL, NULL); LL_TIM_DeInit(TIM1); - status = osSemaphoreDelete(infrared_tim_tx.stop_semaphore); - furi_check(status == osOK); + furi_semaphore_free(infrared_tim_tx.stop_semaphore); free(infrared_tim_tx.buffer[0].data); free(infrared_tim_tx.buffer[1].data); free(infrared_tim_tx.buffer[0].polarity); @@ -586,7 +582,7 @@ void furi_hal_infrared_async_tx_start(uint32_t freq, float duty_cycle) { infrared_tim_tx.buffer[0].polarity = malloc(alloc_size_polarity); infrared_tim_tx.buffer[1].polarity = malloc(alloc_size_polarity); - infrared_tim_tx.stop_semaphore = osSemaphoreNew(1, 0, NULL); + infrared_tim_tx.stop_semaphore = furi_semaphore_alloc(1, 0); infrared_tim_tx.cycle_duration = 1000000.0 / freq; infrared_tim_tx.tx_timing_rest_duration = 0; @@ -603,9 +599,9 @@ void furi_hal_infrared_async_tx_start(uint32_t freq, float duty_cycle) { LL_TIM_ClearFlag_UPDATE(TIM1); LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_1); LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_2); - furi_hal_delay_us(5); + furi_delay_us(5); LL_TIM_GenerateEvent_UPDATE(TIM1); /* DMA -> TIMx_RCR */ - furi_hal_delay_us(5); + furi_delay_us(5); LL_GPIO_ResetOutputPin( gpio_infrared_tx.port, gpio_infrared_tx.pin); /* when disable it prevents false pulse */ furi_hal_gpio_init_ex( @@ -621,9 +617,9 @@ void furi_hal_infrared_async_tx_wait_termination(void) { furi_assert(furi_hal_infrared_state >= InfraredStateAsyncTx); furi_assert(furi_hal_infrared_state < InfraredStateMAX); - osStatus_t status; - status = osSemaphoreAcquire(infrared_tim_tx.stop_semaphore, osWaitForever); - furi_check(status == osOK); + FuriStatus status; + status = furi_semaphore_acquire(infrared_tim_tx.stop_semaphore, FuriWaitForever); + furi_check(status == FuriStatusOk); furi_hal_infrared_async_tx_free_resources(); furi_hal_infrared_state = InfraredStateIdle; } diff --git a/firmware/targets/f7/furi_hal/furi_hal_interrupt.c b/firmware/targets/f7/furi_hal/furi_hal_interrupt.c index 526c9f3d..fa595921 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_interrupt.c +++ b/firmware/targets/f7/furi_hal/furi_hal_interrupt.c @@ -1,5 +1,4 @@ #include "furi_hal_interrupt.h" -#include "furi_hal_delay.h" #include "furi_hal_os.h" #include diff --git a/firmware/targets/f7/furi_hal/furi_hal_light.c b/firmware/targets/f7/furi_hal/furi_hal_light.c index 5ff02f4a..e6b3ab7d 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_light.c +++ b/firmware/targets/f7/furi_hal/furi_hal_light.c @@ -1,7 +1,6 @@ -#include "furi/common_defines.h" +#include #include "furi_hal_resources.h" #include -#include #include #include @@ -108,9 +107,9 @@ void furi_hal_light_sequence(const char* sequence) { } else if(*sequence == 'w') { furi_hal_light_set(LightBacklight, 0x00); } else if(*sequence == '.') { - furi_hal_delay_ms(250); + furi_delay_ms(250); } else if(*sequence == '-') { - furi_hal_delay_ms(500); + furi_delay_ms(500); } sequence++; } while(*sequence != 0); diff --git a/firmware/targets/f7/furi_hal/furi_hal_nfc.c b/firmware/targets/f7/furi_hal/furi_hal_nfc.c index 73f83c5c..7b7d5f27 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_nfc.c +++ b/firmware/targets/f7/furi_hal/furi_hal_nfc.c @@ -7,16 +7,16 @@ #include #include -#include #include #include +#include #include #define TAG "FuriHalNfc" static const uint32_t clocks_in_ms = 64 * 1000; -osEventFlagsId_t event = NULL; +FuriEventFlag* event = NULL; #define EVENT_FLAG_INTERRUPT (1UL << 0) #define EVENT_FLAG_STATE_CHANGED (1UL << 1) #define EVENT_FLAG_STOP (1UL << 2) @@ -28,7 +28,7 @@ void furi_hal_nfc_init() { ReturnCode ret = rfalNfcInitialize(); if(ret == ERR_NONE) { furi_hal_nfc_start_sleep(); - event = osEventFlagsNew(NULL); + event = furi_event_flag_alloc(); FURI_LOG_I(TAG, "Init OK"); } else { FURI_LOG_W(TAG, "Initialization failed, RFAL returned: %d", ret); @@ -109,7 +109,7 @@ bool furi_hal_nfc_detect(FuriHalNfcDevData* nfc_data, uint32_t timeout) { FURI_LOG_T(TAG, "Timeout"); break; } - osDelay(1); + furi_delay_tick(1); } rfalNfcGetDevicesFound(&dev_list, &dev_cnt); if(detected) { @@ -243,7 +243,7 @@ bool furi_hal_nfc_listen( rfalNfcDeactivate(true); return false; } - osDelay(1); + furi_delay_tick(1); } return true; } @@ -273,7 +273,7 @@ bool furi_hal_nfc_listen_rx(FuriHalNfcTxRxContext* tx_rx, uint32_t timeout_ms) { furi_assert(tx_rx); // Wait for interrupts - uint32_t start = osKernelGetTickCount(); + uint32_t start = furi_get_tick(); bool data_received = false; while(true) { if(furi_hal_gpio_read(&gpio_nfc_irq_rfid_pull) == true) { @@ -285,9 +285,9 @@ bool furi_hal_nfc_listen_rx(FuriHalNfcTxRxContext* tx_rx, uint32_t timeout_ms) { } continue; } - if(osKernelGetTickCount() - start > timeout_ms) { + if(furi_get_tick() - start > timeout_ms) { FURI_LOG_T(TAG, "Interrupt waiting timeout"); - osDelay(1); + furi_delay_tick(1); break; } } @@ -352,17 +352,17 @@ void furi_hal_nfc_listen_start(FuriHalNfcDevData* nfc_data) { } void rfal_interrupt_callback_handler() { - osEventFlagsSet(event, EVENT_FLAG_INTERRUPT); + furi_event_flag_set(event, EVENT_FLAG_INTERRUPT); } void rfal_state_changed_callback(void* context) { UNUSED(context); - osEventFlagsSet(event, EVENT_FLAG_STATE_CHANGED); + furi_event_flag_set(event, EVENT_FLAG_STATE_CHANGED); } void furi_hal_nfc_stop() { if(event) { - osEventFlagsSet(event, EVENT_FLAG_STOP); + furi_event_flag_set(event, EVENT_FLAG_STOP); } } @@ -405,8 +405,8 @@ bool furi_hal_nfc_emulate_nfca( while(true) { buff_rx_len = 0; buff_tx_len = 0; - uint32_t flag = osEventFlagsWait(event, EVENT_FLAG_ALL, osFlagsWaitAny, timeout); - if(flag == osFlagsErrorTimeout || flag == EVENT_FLAG_STOP) { + uint32_t flag = furi_event_flag_wait(event, EVENT_FLAG_ALL, FuriFlagWaitAny, timeout); + if(flag == FuriFlagErrorTimeout || flag == EVENT_FLAG_STOP) { break; } bool data_received = false; @@ -515,7 +515,7 @@ static bool furi_hal_nfc_transparent_tx_rx(FuriHalNfcTxRxContext* tx_rx, uint16_ } } uint32_t timeout = DWT->CYCCNT - start; - if(timeout / furi_hal_delay_instructions_per_microsecond() > timeout_ms * 1000) { + if(timeout / furi_hal_cortex_instructions_per_microsecond() > timeout_ms * 1000) { FURI_LOG_D(TAG, "Interrupt waiting timeout"); break; } @@ -668,7 +668,7 @@ bool furi_hal_nfc_tx_rx(FuriHalNfcTxRxContext* tx_rx, uint16_t timeout_ms) { } else { start = DWT->CYCCNT; } - osDelay(1); + furi_delay_tick(1); } if(tx_rx->tx_rx_type == FuriHalNfcTxRxTypeRaw || diff --git a/firmware/targets/f7/furi_hal/furi_hal_os.c b/firmware/targets/f7/furi_hal/furi_hal_os.c index 9dd7191f..97d022c9 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_os.c +++ b/firmware/targets/f7/furi_hal/furi_hal_os.c @@ -47,8 +47,9 @@ void furi_hal_os_init() { furi_hal_gpio_init_simple(&gpio_ext_pa7, GpioModeOutputPushPull); furi_hal_gpio_init_simple(&gpio_ext_pa6, GpioModeOutputPushPull); furi_hal_gpio_init_simple(&gpio_ext_pa4, GpioModeOutputPushPull); - osTimerId_t second_timer = osTimerNew(furi_hal_os_timer_callback, osTimerPeriodic, NULL, NULL); - osTimerStart(second_timer, FURI_HAL_OS_TICK_HZ); + FuriTimer* second_timer = + furi_timer_alloc(furi_hal_os_timer_callback, FuriTimerTypePeriodic, NULL); + furi_timer_start(second_timer, FURI_HAL_OS_TICK_HZ); #endif FURI_LOG_I(TAG, "Init OK"); diff --git a/firmware/targets/f7/furi_hal/furi_hal_power.c b/firmware/targets/f7/furi_hal/furi_hal_power.c index 28e6cb05..24638392 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_power.c +++ b/firmware/targets/f7/furi_hal/furi_hal_power.c @@ -1,6 +1,5 @@ #include #include -#include #include #include #include @@ -302,7 +301,7 @@ void furi_hal_power_shutdown() { void furi_hal_power_off() { // Crutch: shutting down with ext 3V3 off is causing LSE to stop furi_hal_power_enable_external_3_3v(); - furi_hal_delay_us(1000); + furi_delay_us(1000); // Send poweroff to charger furi_hal_i2c_acquire(&furi_hal_i2c_handle_power); bq25896_poweroff(&furi_hal_i2c_handle_power); diff --git a/firmware/targets/f7/furi_hal/furi_hal_resources.c b/firmware/targets/f7/furi_hal/furi_hal_resources.c index c1238212..98ebedf5 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_resources.c +++ b/firmware/targets/f7/furi_hal/furi_hal_resources.c @@ -1,5 +1,4 @@ #include -#include #include #include @@ -98,7 +97,7 @@ void furi_hal_resources_init_early() { furi_hal_gpio_init_simple(&gpio_usb_dp, GpioModeOutputOpenDrain); furi_hal_gpio_write(&gpio_usb_dm, 0); furi_hal_gpio_write(&gpio_usb_dp, 0); - furi_hal_delay_us(5); // Device Driven disconnect: 2.5us + extra to compensate cables + furi_delay_us(5); // Device Driven disconnect: 2.5us + extra to compensate cables furi_hal_gpio_write(&gpio_usb_dm, 1); furi_hal_gpio_write(&gpio_usb_dp, 1); furi_hal_gpio_init_simple(&gpio_usb_dm, GpioModeAnalog); diff --git a/firmware/targets/f7/furi_hal/furi_hal_spi_config.c b/firmware/targets/f7/furi_hal/furi_hal_spi_config.c index e01f132e..56f67bbf 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_spi_config.c +++ b/firmware/targets/f7/furi_hal/furi_hal_spi_config.c @@ -70,25 +70,25 @@ const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_2m = { /* SPI Buses */ -osMutexId_t furi_hal_spi_bus_r_mutex = NULL; +FuriMutex* furi_hal_spi_bus_r_mutex = NULL; static void furi_hal_spi_bus_r_event_callback(FuriHalSpiBus* bus, FuriHalSpiBusEvent event) { if(event == FuriHalSpiBusEventInit) { - furi_hal_spi_bus_r_mutex = osMutexNew(NULL); + furi_hal_spi_bus_r_mutex = furi_mutex_alloc(FuriMutexTypeNormal); FURI_CRITICAL_ENTER(); LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_SPI1); FURI_CRITICAL_EXIT(); bus->current_handle = NULL; } else if(event == FuriHalSpiBusEventDeinit) { - furi_check(osMutexDelete(furi_hal_spi_bus_r_mutex) == osOK); + furi_mutex_free(furi_hal_spi_bus_r_mutex); FURI_CRITICAL_ENTER(); LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_SPI1); LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_SPI1); FURI_CRITICAL_EXIT(); } else if(event == FuriHalSpiBusEventLock) { - furi_check(osMutexAcquire(furi_hal_spi_bus_r_mutex, osWaitForever) == osOK); + furi_check(furi_mutex_acquire(furi_hal_spi_bus_r_mutex, FuriWaitForever) == FuriStatusOk); } else if(event == FuriHalSpiBusEventUnlock) { - furi_check(osMutexRelease(furi_hal_spi_bus_r_mutex) == osOK); + furi_check(furi_mutex_release(furi_hal_spi_bus_r_mutex) == FuriStatusOk); } else if(event == FuriHalSpiBusEventActivate) { FURI_CRITICAL_ENTER(); LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_SPI1); @@ -105,25 +105,25 @@ FuriHalSpiBus furi_hal_spi_bus_r = { .callback = furi_hal_spi_bus_r_event_callback, }; -osMutexId_t furi_hal_spi_bus_d_mutex = NULL; +FuriMutex* furi_hal_spi_bus_d_mutex = NULL; static void furi_hal_spi_bus_d_event_callback(FuriHalSpiBus* bus, FuriHalSpiBusEvent event) { if(event == FuriHalSpiBusEventInit) { - furi_hal_spi_bus_d_mutex = osMutexNew(NULL); + furi_hal_spi_bus_d_mutex = furi_mutex_alloc(FuriMutexTypeNormal); FURI_CRITICAL_ENTER(); LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_SPI2); FURI_CRITICAL_EXIT(); bus->current_handle = NULL; } else if(event == FuriHalSpiBusEventDeinit) { - furi_check(osMutexDelete(furi_hal_spi_bus_d_mutex) == osOK); + furi_mutex_free(furi_hal_spi_bus_d_mutex); FURI_CRITICAL_ENTER(); LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_SPI2); LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_SPI2); FURI_CRITICAL_EXIT(); } else if(event == FuriHalSpiBusEventLock) { - furi_check(osMutexAcquire(furi_hal_spi_bus_d_mutex, osWaitForever) == osOK); + furi_check(furi_mutex_acquire(furi_hal_spi_bus_d_mutex, FuriWaitForever) == FuriStatusOk); } else if(event == FuriHalSpiBusEventUnlock) { - furi_check(osMutexRelease(furi_hal_spi_bus_d_mutex) == osOK); + furi_check(furi_mutex_release(furi_hal_spi_bus_d_mutex) == FuriStatusOk); } else if(event == FuriHalSpiBusEventActivate) { FURI_CRITICAL_ENTER(); LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_SPI2); diff --git a/firmware/targets/f7/furi_hal/furi_hal_uart.c b/firmware/targets/f7/furi_hal/furi_hal_uart.c index 74b14f4f..cb44b6d1 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_uart.c +++ b/firmware/targets/f7/furi_hal/furi_hal_uart.c @@ -6,7 +6,6 @@ #include #include -#include static bool furi_hal_usart_prev_enabled[2]; diff --git a/firmware/targets/f7/furi_hal/furi_hal_usb.c b/firmware/targets/f7/furi_hal/furi_hal_usb.c index cedcc82a..86b10c79 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_usb.c +++ b/firmware/targets/f7/furi_hal/furi_hal_usb.c @@ -240,8 +240,8 @@ static int32_t furi_hal_usb_thread(void* context) { } while(true) { - uint32_t flags = furi_thread_flags_wait(USB_SRV_ALL_EVENTS, osFlagsWaitAny, 500); - if((flags & osFlagsError) == 0) { + uint32_t flags = furi_thread_flags_wait(USB_SRV_ALL_EVENTS, FuriFlagWaitAny, 500); + if((flags & FuriFlagError) == 0) { if(flags & EventModeChange) { if(usb.if_next != usb.if_cur) { if_new = usb.if_next; @@ -250,7 +250,7 @@ static int32_t furi_hal_usb_thread(void* context) { susp_evt(&udev, 0, 0); usbd_connect(&udev, false); usb.enabled = false; - osDelay(USB_RECONNECT_DELAY); + furi_delay_ms(USB_RECONNECT_DELAY); } flags |= EventModeChangeStart; } @@ -267,7 +267,7 @@ static int32_t furi_hal_usb_thread(void* context) { usbd_enable(&udev, true); if_new = usb.if_cur; - osDelay(USB_RECONNECT_DELAY); + furi_delay_ms(USB_RECONNECT_DELAY); flags |= EventModeChangeStart; } if(flags & EventModeChangeStart) { // Second stage of mode change process diff --git a/firmware/targets/f7/furi_hal/furi_hal_usb_hid.c b/firmware/targets/f7/furi_hal/furi_hal_usb_hid.c index 06f3f231..a7253223 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_usb_hid.c +++ b/firmware/targets/f7/furi_hal/furi_hal_usb_hid.c @@ -254,7 +254,7 @@ static bool hid_send_report(uint8_t report_id); static usbd_respond hid_ep_config(usbd_device* dev, uint8_t cfg); static usbd_respond hid_control(usbd_device* dev, usbd_ctlreq* req, usbd_rqc_callback* callback); static usbd_device* usb_dev; -static osSemaphoreId_t hid_semaphore = NULL; +static FuriSemaphore* hid_semaphore = NULL; static bool hid_connected = false; static HidStateCallback callback; static void* cb_ctx; @@ -372,7 +372,7 @@ static void* hid_set_string_descr(char* str) { static void hid_init(usbd_device* dev, FuriHalUsbInterface* intf, void* ctx) { UNUSED(intf); FuriHalUsbHidConfig* cfg = (FuriHalUsbHidConfig*)ctx; - if(hid_semaphore == NULL) hid_semaphore = osSemaphoreNew(1, 1, NULL); + if(hid_semaphore == NULL) hid_semaphore = furi_semaphore_alloc(1, 1); usb_dev = dev; hid_report.keyboard.report_id = ReportIdKeyboard; hid_report.mouse.report_id = ReportIdMouse; @@ -428,7 +428,7 @@ static void hid_on_suspend(usbd_device* dev) { UNUSED(dev); if(hid_connected) { hid_connected = false; - osSemaphoreRelease(hid_semaphore); + furi_semaphore_release(hid_semaphore); if(callback != NULL) { callback(false, cb_ctx); } @@ -438,7 +438,7 @@ static void hid_on_suspend(usbd_device* dev) { static bool hid_send_report(uint8_t report_id) { if((hid_semaphore == NULL) || (hid_connected == false)) return false; - furi_check(osSemaphoreAcquire(hid_semaphore, osWaitForever) == osOK); + furi_check(furi_semaphore_acquire(hid_semaphore, FuriWaitForever) == FuriStatusOk); if(hid_connected == true) { if(report_id == ReportIdKeyboard) usbd_ep_write(usb_dev, HID_EP_IN, &hid_report.keyboard, sizeof(hid_report.keyboard)); @@ -454,7 +454,7 @@ static bool hid_send_report(uint8_t report_id) { static void hid_txrx_ep_callback(usbd_device* dev, uint8_t event, uint8_t ep) { UNUSED(dev); if(event == usbd_evt_eptx) { - osSemaphoreRelease(hid_semaphore); + furi_semaphore_release(hid_semaphore); } else { struct HidReportLED leds; usbd_ep_read(usb_dev, ep, &leds, 2); diff --git a/firmware/targets/f7/furi_hal/furi_hal_usb_u2f.c b/firmware/targets/f7/furi_hal/furi_hal_usb_u2f.c index a8041086..60068f3b 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_usb_u2f.c +++ b/firmware/targets/f7/furi_hal/furi_hal_usb_u2f.c @@ -147,7 +147,7 @@ static usbd_respond hid_u2f_ep_config(usbd_device* dev, uint8_t cfg); static usbd_respond hid_u2f_control(usbd_device* dev, usbd_ctlreq* req, usbd_rqc_callback* callback); static usbd_device* usb_dev; -static osSemaphoreId_t hid_u2f_semaphore = NULL; +static FuriSemaphore* hid_u2f_semaphore = NULL; static bool hid_u2f_connected = false; static HidU2fCallback callback; @@ -193,7 +193,7 @@ static void hid_u2f_init(usbd_device* dev, FuriHalUsbInterface* intf, void* ctx) UNUSED(intf); UNUSED(ctx); if(hid_u2f_semaphore == NULL) { - hid_u2f_semaphore = osSemaphoreNew(1, 1, NULL); + hid_u2f_semaphore = furi_semaphore_alloc(1, 1); } usb_dev = dev; @@ -220,7 +220,7 @@ static void hid_u2f_on_suspend(usbd_device* dev) { UNUSED(dev); if(hid_u2f_connected) { hid_u2f_connected = false; - osSemaphoreRelease(hid_u2f_semaphore); + furi_semaphore_release(hid_u2f_semaphore); if(callback != NULL) { callback(HidU2fDisconnected, cb_ctx); } @@ -229,7 +229,7 @@ static void hid_u2f_on_suspend(usbd_device* dev) { void furi_hal_hid_u2f_send_response(uint8_t* data, uint8_t len) { if((hid_u2f_semaphore == NULL) || (hid_u2f_connected == false)) return; - furi_check(osSemaphoreAcquire(hid_u2f_semaphore, osWaitForever) == osOK); + furi_check(furi_semaphore_acquire(hid_u2f_semaphore, FuriWaitForever) == FuriStatusOk); if(hid_u2f_connected == true) { usbd_ep_write(usb_dev, HID_EP_OUT, data, len); } @@ -253,7 +253,7 @@ static void hid_u2f_tx_ep_callback(usbd_device* dev, uint8_t event, uint8_t ep) UNUSED(dev); UNUSED(event); UNUSED(ep); - osSemaphoreRelease(hid_u2f_semaphore); + furi_semaphore_release(hid_u2f_semaphore); } static void hid_u2f_txrx_ep_callback(usbd_device* dev, uint8_t event, uint8_t ep) { diff --git a/firmware/targets/furi_hal_include/furi_hal.h b/firmware/targets/furi_hal_include/furi_hal.h index 17814b13..4d1fc970 100644 --- a/firmware/targets/furi_hal_include/furi_hal.h +++ b/firmware/targets/furi_hal_include/furi_hal.h @@ -9,6 +9,7 @@ template struct STOP_EXTERNING_ME {}; #endif +#include "furi_hal_cortex.h" #include "furi_hal_clock.h" #include "furi_hal_crypto.h" #include "furi_hal_console.h" @@ -21,7 +22,6 @@ template struct STOP_EXTERNING_ME {}; #include "furi_hal_speaker.h" #include "furi_hal_gpio.h" #include "furi_hal_light.h" -#include "furi_hal_delay.h" #include "furi_hal_power.h" #include "furi_hal_interrupt.h" #include "furi_hal_version.h" diff --git a/firmware/targets/furi_hal_include/furi_hal_cortex.h b/firmware/targets/furi_hal_include/furi_hal_cortex.h new file mode 100644 index 00000000..13035161 --- /dev/null +++ b/firmware/targets/furi_hal_include/furi_hal_cortex.h @@ -0,0 +1,32 @@ +/** + * @file furi_hal_cortex.h + * ARM Cortex HAL + */ + +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** Early init stage for cortex + */ +void furi_hal_cortex_init_early(); + +/** Microseconds delay + * + * @param[in] microseconds The microseconds to wait + */ +void furi_hal_cortex_delay_us(uint32_t microseconds); + +/** Get instructions per microsecond count + * + * @return instructions per microsecond count + */ +uint32_t furi_hal_cortex_instructions_per_microsecond(); + +#ifdef __cplusplus +} +#endif diff --git a/firmware/targets/furi_hal_include/furi_hal_delay.h b/firmware/targets/furi_hal_include/furi_hal_delay.h deleted file mode 100644 index 8d88a4c1..00000000 --- a/firmware/targets/furi_hal_include/furi_hal_delay.h +++ /dev/null @@ -1,51 +0,0 @@ -/** - * @file furi_hal_delay.h - * Delay HAL API - */ - -#pragma once - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** Init Delay subsystem */ -void furi_hal_delay_init(); - -/** Get instructions per microsecond count */ -uint32_t furi_hal_delay_instructions_per_microsecond(); - -/** Get current tick counter - * - * System uptime, may overflow. - * - * @return Current ticks in milliseconds - */ -uint32_t furi_hal_get_tick(void); - -/** Convert milliseconds to ticks - * - * @param[in] milliseconds time in milliseconds - * @return time in ticks - */ -uint32_t furi_hal_ms_to_ticks(float milliseconds); - -/** Delay in milliseconds - * @warning Cannot be used from ISR - * - * @param[in] milliseconds milliseconds to wait - */ -void furi_hal_delay_ms(float milliseconds); - -/** Delay in microseconds - * - * @param[in] microseconds microseconds to wait - */ -void furi_hal_delay_us(float microseconds); - -#ifdef __cplusplus -} -#endif diff --git a/core/SConscript b/furi/SConscript similarity index 71% rename from core/SConscript rename to furi/SConscript index 83548355..a751eb6e 100644 --- a/core/SConscript +++ b/furi/SConscript @@ -1,9 +1,9 @@ Import("env") -env.Append(LINT_SOURCES=["core"]) +env.Append(LINT_SOURCES=["furi"]) -libenv = env.Clone(FW_LIB_NAME="core") +libenv = env.Clone(FW_LIB_NAME="furi") libenv.ApplyLibFlags() sources = libenv.GlobRecursive("*.c") diff --git a/furi/core/base.h b/furi/core/base.h new file mode 100644 index 00000000..29e87419 --- /dev/null +++ b/furi/core/base.h @@ -0,0 +1,43 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + FuriWaitForever = 0xFFFFFFFFU, +} FuriWait; + +typedef enum { + FuriFlagWaitAny = 0x00000000U, ///< Wait for any flag (default). + FuriFlagWaitAll = 0x00000001U, ///< Wait for all flags. + FuriFlagNoClear = 0x00000002U, ///< Do not clear flags which have been specified to wait for. + + FuriFlagError = 0x80000000U, ///< Error indicator. + FuriFlagErrorUnknown = 0xFFFFFFFFU, ///< FuriStatusError (-1). + FuriFlagErrorTimeout = 0xFFFFFFFEU, ///< FuriStatusErrorTimeout (-2). + FuriFlagErrorResource = 0xFFFFFFFDU, ///< FuriStatusErrorResource (-3). + FuriFlagErrorParameter = 0xFFFFFFFCU, ///< FuriStatusErrorParameter (-4). + FuriFlagErrorISR = 0xFFFFFFFAU, ///< FuriStatusErrorISR (-6). +} FuriFlag; + +typedef enum { + FuriStatusOk = 0, ///< Operation completed successfully. + FuriStatusError = + -1, ///< Unspecified RTOS error: run-time error but no other error message fits. + FuriStatusErrorTimeout = -2, ///< Operation not completed within the timeout period. + FuriStatusErrorResource = -3, ///< Resource not available. + FuriStatusErrorParameter = -4, ///< Parameter error. + FuriStatusErrorNoMemory = + -5, ///< System is out of memory: it was impossible to allocate or reserve memory for the operation. + FuriStatusErrorISR = + -6, ///< Not allowed in ISR context: the function cannot be called from interrupt service routines. + FuriStatusReserved = 0x7FFFFFFF ///< Prevents enum down-size compiler optimization. +} FuriStatus; + +#ifdef __cplusplus +} +#endif diff --git a/core/furi/check.c b/furi/core/check.c similarity index 100% rename from core/furi/check.c rename to furi/core/check.c diff --git a/core/furi/check.h b/furi/core/check.h similarity index 100% rename from core/furi/check.h rename to furi/core/check.h diff --git a/core/furi/common_defines.h b/furi/core/common_defines.h similarity index 77% rename from core/furi/common_defines.h rename to furi/core/common_defines.h index 5e9a7904..d75f7592 100644 --- a/core/furi/common_defines.h +++ b/furi/core/common_defines.h @@ -1,7 +1,8 @@ #pragma once #include -#include +#include +#include #ifdef __cplusplus extern "C" { @@ -100,16 +101,16 @@ extern "C" { #endif #ifndef FURI_CRITICAL_ENTER -#define FURI_CRITICAL_ENTER() \ - uint32_t __isrm = 0; \ - bool __from_isr = FURI_IS_ISR(); \ - bool __kernel_running = (osKernelGetState() == osKernelRunning); \ - if(__from_isr) { \ - __isrm = taskENTER_CRITICAL_FROM_ISR(); \ - } else if(__kernel_running) { \ - taskENTER_CRITICAL(); \ - } else { \ - __disable_irq(); \ +#define FURI_CRITICAL_ENTER() \ + uint32_t __isrm = 0; \ + bool __from_isr = FURI_IS_ISR(); \ + bool __kernel_running = (xTaskGetSchedulerState() == taskSCHEDULER_RUNNING); \ + if(__from_isr) { \ + __isrm = taskENTER_CRITICAL_FROM_ISR(); \ + } else if(__kernel_running) { \ + taskENTER_CRITICAL(); \ + } else { \ + __disable_irq(); \ } #endif @@ -124,6 +125,30 @@ extern "C" { } #endif +static inline bool furi_is_irq_context() { + bool irq = false; + BaseType_t state; + + if(FURI_IS_IRQ_MODE()) { + /* Called from interrupt context */ + irq = true; + } else { + /* Get FreeRTOS scheduler state */ + state = xTaskGetSchedulerState(); + + if(state != taskSCHEDULER_NOT_STARTED) { + /* Scheduler was started */ + if(FURI_IS_IRQ_MASKED()) { + /* Interrupts are masked */ + irq = true; + } + } + } + + /* Return context, 0: thread context, 1: IRQ context */ + return (irq); +} + #ifdef __cplusplus } #endif diff --git a/core/furi/dangerous_defines.h b/furi/core/dangerous_defines.h similarity index 100% rename from core/furi/dangerous_defines.h rename to furi/core/dangerous_defines.h diff --git a/furi/core/event_flag.c b/furi/core/event_flag.c new file mode 100644 index 00000000..5d2a4991 --- /dev/null +++ b/furi/core/event_flag.c @@ -0,0 +1,135 @@ +#include "event_flag.h" +#include "common_defines.h" +#include "check.h" + +#include + +#define FURI_EVENT_FLAG_MAX_BITS_EVENT_GROUPS 24U +#define FURI_EVENT_FLAG_INVALID_BITS (~((1UL << FURI_EVENT_FLAG_MAX_BITS_EVENT_GROUPS) - 1U)) + +FuriEventFlag* furi_event_flag_alloc() { + furi_assert(!FURI_IS_IRQ_MODE()); + return ((FuriEventFlag*)xEventGroupCreate()); +} + +void furi_event_flag_free(FuriEventFlag* instance) { + furi_assert(!FURI_IS_IRQ_MODE()); + vEventGroupDelete((EventGroupHandle_t)instance); +} + +uint32_t furi_event_flag_set(FuriEventFlag* instance, uint32_t flags) { + furi_assert(instance); + furi_assert((flags & FURI_EVENT_FLAG_INVALID_BITS) == 0U); + + EventGroupHandle_t hEventGroup = (EventGroupHandle_t)instance; + uint32_t rflags; + BaseType_t yield; + + if(FURI_IS_IRQ_MODE() != 0U) { + yield = pdFALSE; + if(xEventGroupSetBitsFromISR(hEventGroup, (EventBits_t)flags, &yield) == pdFAIL) { + rflags = (uint32_t)FuriStatusErrorResource; + } else { + rflags = flags; + portYIELD_FROM_ISR(yield); + } + } else { + rflags = xEventGroupSetBits(hEventGroup, (EventBits_t)flags); + } + + /* Return event flags after setting */ + return (rflags); +} + +uint32_t furi_event_flag_clear(FuriEventFlag* instance, uint32_t flags) { + furi_assert(instance); + furi_assert((flags & FURI_EVENT_FLAG_INVALID_BITS) == 0U); + + EventGroupHandle_t hEventGroup = (EventGroupHandle_t)instance; + uint32_t rflags; + + if(FURI_IS_IRQ_MODE() != 0U) { + rflags = xEventGroupGetBitsFromISR(hEventGroup); + + if(xEventGroupClearBitsFromISR(hEventGroup, (EventBits_t)flags) == pdFAIL) { + rflags = (uint32_t)FuriStatusErrorResource; + } else { + /* xEventGroupClearBitsFromISR only registers clear operation in the timer command queue. */ + /* Yield is required here otherwise clear operation might not execute in the right order. */ + /* See https://github.com/FreeRTOS/FreeRTOS-Kernel/issues/93 for more info. */ + portYIELD_FROM_ISR(pdTRUE); + } + } else { + rflags = xEventGroupClearBits(hEventGroup, (EventBits_t)flags); + } + + /* Return event flags before clearing */ + return (rflags); +} + +uint32_t furi_event_flag_get(FuriEventFlag* instance) { + furi_assert(instance); + + EventGroupHandle_t hEventGroup = (EventGroupHandle_t)instance; + uint32_t rflags; + + if(FURI_IS_IRQ_MODE() != 0U) { + rflags = xEventGroupGetBitsFromISR(hEventGroup); + } else { + rflags = xEventGroupGetBits(hEventGroup); + } + + /* Return current event flags */ + return (rflags); +} + +uint32_t furi_event_flag_wait( + FuriEventFlag* instance, + uint32_t flags, + uint32_t options, + uint32_t timeout) { + furi_assert(!FURI_IS_IRQ_MODE()); + furi_assert(instance); + furi_assert((flags & FURI_EVENT_FLAG_INVALID_BITS) == 0U); + + EventGroupHandle_t hEventGroup = (EventGroupHandle_t)instance; + BaseType_t wait_all; + BaseType_t exit_clr; + uint32_t rflags; + + if(options & FuriFlagWaitAll) { + wait_all = pdTRUE; + } else { + wait_all = pdFAIL; + } + + if(options & FuriFlagNoClear) { + exit_clr = pdFAIL; + } else { + exit_clr = pdTRUE; + } + + rflags = xEventGroupWaitBits( + hEventGroup, (EventBits_t)flags, exit_clr, wait_all, (TickType_t)timeout); + + if(options & FuriFlagWaitAll) { + if((flags & rflags) != flags) { + if(timeout > 0U) { + rflags = (uint32_t)FuriStatusErrorTimeout; + } else { + rflags = (uint32_t)FuriStatusErrorResource; + } + } + } else { + if((flags & rflags) == 0U) { + if(timeout > 0U) { + rflags = (uint32_t)FuriStatusErrorTimeout; + } else { + rflags = (uint32_t)FuriStatusErrorResource; + } + } + } + + /* Return event flags before clearing */ + return (rflags); +} diff --git a/furi/core/event_flag.h b/furi/core/event_flag.h new file mode 100644 index 00000000..133c95e7 --- /dev/null +++ b/furi/core/event_flag.h @@ -0,0 +1,70 @@ +/** + * @file event_flag.h + * Furi Event Flag + */ +#pragma once + +#include "base.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void FuriEventFlag; + +/** Allocate FuriEventFlag + * + * @return pointer to FuriEventFlag + */ +FuriEventFlag* furi_event_flag_alloc(); + +/** Deallocate FuriEventFlag + * + * @param instance pointer to FuriEventFlag + */ +void furi_event_flag_free(FuriEventFlag* instance); + +/** Set flags + * + * @param instance pointer to FuriEventFlag + * @param[in] flags The flags + * + * @return Resulting flags or error (FuriStatus) + */ +uint32_t furi_event_flag_set(FuriEventFlag* instance, uint32_t flags); + +/** Clear flags + * + * @param instance pointer to FuriEventFlag + * @param[in] flags The flags + * + * @return Resulting flags or error (FuriStatus) + */ +uint32_t furi_event_flag_clear(FuriEventFlag* instance, uint32_t flags); + +/** Get flags + * + * @param instance pointer to FuriEventFlag + * + * @return Resulting flags + */ +uint32_t furi_event_flag_get(FuriEventFlag* instance); + +/** Wait flags + * + * @param instance pointer to FuriEventFlag + * @param[in] flags The flags + * @param[in] options The option flags + * @param[in] timeout The timeout + * + * @return Resulting flags or error (FuriStatus) + */ +uint32_t furi_event_flag_wait( + FuriEventFlag* instance, + uint32_t flags, + uint32_t options, + uint32_t timeout); + +#ifdef __cplusplus +} +#endif diff --git a/furi/core/kernel.c b/furi/core/kernel.c new file mode 100644 index 00000000..73d2012b --- /dev/null +++ b/furi/core/kernel.c @@ -0,0 +1,174 @@ +#include "kernel.h" +#include "base.h" +#include "check.h" +#include "common_defines.h" + +#include + +#include CMSIS_device_header + +int32_t furi_kernel_lock() { + furi_assert(!furi_is_irq_context()); + + int32_t lock; + + switch(xTaskGetSchedulerState()) { + case taskSCHEDULER_SUSPENDED: + lock = 1; + break; + + case taskSCHEDULER_RUNNING: + vTaskSuspendAll(); + lock = 0; + break; + + case taskSCHEDULER_NOT_STARTED: + default: + lock = (int32_t)FuriStatusError; + break; + } + + /* Return previous lock state */ + return (lock); +} + +int32_t furi_kernel_unlock() { + furi_assert(!furi_is_irq_context()); + + int32_t lock; + + switch(xTaskGetSchedulerState()) { + case taskSCHEDULER_SUSPENDED: + lock = 1; + + if(xTaskResumeAll() != pdTRUE) { + if(xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED) { + lock = (int32_t)FuriStatusError; + } + } + break; + + case taskSCHEDULER_RUNNING: + lock = 0; + break; + + case taskSCHEDULER_NOT_STARTED: + default: + lock = (int32_t)FuriStatusError; + break; + } + + /* Return previous lock state */ + return (lock); +} + +int32_t furi_kernel_restore_lock(int32_t lock) { + furi_assert(!furi_is_irq_context()); + + switch(xTaskGetSchedulerState()) { + case taskSCHEDULER_SUSPENDED: + case taskSCHEDULER_RUNNING: + if(lock == 1) { + vTaskSuspendAll(); + } else { + if(lock != 0) { + lock = (int32_t)FuriStatusError; + } else { + if(xTaskResumeAll() != pdTRUE) { + if(xTaskGetSchedulerState() != taskSCHEDULER_RUNNING) { + lock = (int32_t)FuriStatusError; + } + } + } + } + break; + + case taskSCHEDULER_NOT_STARTED: + default: + lock = (int32_t)FuriStatusError; + break; + } + + /* Return new lock state */ + return (lock); +} + +uint32_t furi_kernel_get_tick_frequency() { + /* Return frequency in hertz */ + return (configTICK_RATE_HZ_RAW); +} + +void furi_delay_tick(uint32_t ticks) { + furi_assert(!furi_is_irq_context()); + if(ticks == 0U) { + taskYIELD(); + } else { + vTaskDelay(ticks); + } +} + +FuriStatus furi_delay_until_tick(uint32_t tick) { + furi_assert(!furi_is_irq_context()); + + TickType_t tcnt, delay; + FuriStatus stat; + + stat = FuriStatusOk; + tcnt = xTaskGetTickCount(); + + /* Determine remaining number of tick to delay */ + delay = (TickType_t)tick - tcnt; + + /* Check if target tick has not expired */ + if((delay != 0U) && (0 == (delay >> (8 * sizeof(TickType_t) - 1)))) { + if(xTaskDelayUntil(&tcnt, delay) == pdFALSE) { + /* Did not delay */ + stat = FuriStatusError; + } + } else { + /* No delay or already expired */ + stat = FuriStatusErrorParameter; + } + + /* Return execution status */ + return (stat); +} + +uint32_t furi_get_tick() { + TickType_t ticks; + + if(furi_is_irq_context() != 0U) { + ticks = xTaskGetTickCountFromISR(); + } else { + ticks = xTaskGetTickCount(); + } + + return ticks; +} + +uint32_t furi_ms_to_ticks(uint32_t milliseconds) { +#if configTICK_RATE_HZ_RAW == 1000 + return milliseconds; +#else + return (uint32_t)((float)configTICK_RATE_HZ_RAW) / 1000.0f * (float)milliseconds; +#endif +} + +void furi_delay_ms(uint32_t milliseconds) { + if(!FURI_IS_ISR() && xTaskGetSchedulerState() == taskSCHEDULER_RUNNING) { + if(milliseconds > 0 && milliseconds < portMAX_DELAY - 1) { + milliseconds += 1; + } +#if configTICK_RATE_HZ_RAW == 1000 + furi_delay_tick(milliseconds); +#else + furi_delay_tick(furi_ms_to_ticks(milliseconds)); +#endif + } else if(milliseconds > 0) { + furi_delay_us(milliseconds * 1000); + } +} + +void furi_delay_us(uint32_t microseconds) { + furi_hal_cortex_delay_us(microseconds); +} diff --git a/furi/core/kernel.h b/furi/core/kernel.h new file mode 100644 index 00000000..28afffd4 --- /dev/null +++ b/furi/core/kernel.h @@ -0,0 +1,93 @@ +/** + * @file kenrel.h + * Furi Kernel primitives + */ +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** Lock kernel, pause process scheduling + * + * @return previous lock state(0 - unlocked, 1 - locked) + */ +int32_t furi_kernel_lock(); + +/** Unlock kernel, resume process scheduling + * + * @return previous lock state(0 - unlocked, 1 - locked) + */ +int32_t furi_kernel_unlock(); + +/** Restore kernel lock state + * + * @param[in] lock The lock state + * + * @return new lock state or error + */ +int32_t furi_kernel_restore_lock(int32_t lock); + +/** Get kernel systick frequency + * + * @return systick counts per second + */ +uint32_t furi_kernel_get_tick_frequency(); + +/** Delay execution + * + * Also keep in mind delay is aliased to scheduler timer intervals. + * + * @param[in] ticks The ticks count to pause + */ +void furi_delay_tick(uint32_t ticks); + +/** Delay until tick + * + * @param[in] ticks The tick until which kerel should delay task execution + * + * @return The furi status. + */ +FuriStatus furi_delay_until_tick(uint32_t tick); + +/** Get current tick counter + * + * System uptime, may overflow. + * + * @return Current ticks in milliseconds + */ +uint32_t furi_get_tick(void); + +/** Convert milliseconds to ticks + * + * @param[in] milliseconds time in milliseconds + * @return time in ticks + */ +uint32_t furi_ms_to_ticks(uint32_t milliseconds); + +/** Delay in milliseconds + * + * This method uses kernel ticks on the inside, which causes delay to be aliased to scheduler timer intervals. + * Real wait time will be between X+ milliseconds. + * Special value: 0, will cause task yield. + * Also if used when kernel is not running will fall back to `furi_delay_us`. + * + * @warning Cannot be used from ISR + * + * @param[in] milliseconds milliseconds to wait + */ +void furi_delay_ms(uint32_t milliseconds); + +/** Delay in microseconds + * + * Implemented using Cortex DWT counter. Blocking and non aliased. + * + * @param[in] microseconds microseconds to wait + */ +void furi_delay_us(uint32_t microseconds); + +#ifdef __cplusplus +} +#endif diff --git a/core/furi/log.c b/furi/core/log.c similarity index 82% rename from core/furi/log.c rename to furi/core/log.c index 4653603c..8cf90485 100644 --- a/core/furi/log.c +++ b/furi/core/log.c @@ -1,7 +1,6 @@ #include "log.h" #include "check.h" #include "mutex.h" -#include #include #define FURI_LOG_LEVEL_DEFAULT FuriLogLevelInfo @@ -10,7 +9,7 @@ typedef struct { FuriLogLevel log_level; FuriLogPuts puts; FuriLogTimestamp timetamp; - osMutexId_t mutex; + FuriMutex* mutex; } FuriLogParams; static FuriLogParams furi_log; @@ -19,12 +18,13 @@ void furi_log_init() { // Set default logging parameters furi_log.log_level = FURI_LOG_LEVEL_DEFAULT; furi_log.puts = furi_hal_console_puts; - furi_log.timetamp = furi_hal_get_tick; - furi_log.mutex = osMutexNew(NULL); + furi_log.timetamp = furi_get_tick; + furi_log.mutex = furi_mutex_alloc(FuriMutexTypeNormal); } void furi_log_print(FuriLogLevel level, const char* format, ...) { - if(level <= furi_log.log_level && osMutexAcquire(furi_log.mutex, osWaitForever) == osOK) { + if(level <= furi_log.log_level && + furi_mutex_acquire(furi_log.mutex, FuriWaitForever) == FuriStatusOk) { string_t string; // Timestamp @@ -40,7 +40,7 @@ void furi_log_print(FuriLogLevel level, const char* format, ...) { furi_log.puts(string_get_cstr(string)); string_clear(string); - osMutexRelease(furi_log.mutex); + furi_mutex_release(furi_log.mutex); } } diff --git a/core/furi/log.h b/furi/core/log.h similarity index 77% rename from core/furi/log.h rename to furi/core/log.h index 3c86698b..6d23a9c2 100644 --- a/core/furi/log.h +++ b/furi/core/log.h @@ -1,3 +1,7 @@ +/** + * @file log.h + * Furi Logging system + */ #pragma once #include @@ -37,11 +41,39 @@ typedef enum { typedef void (*FuriLogPuts)(const char* data); typedef uint32_t (*FuriLogTimestamp)(void); +/** Initialize logging */ void furi_log_init(); + +/** Log record + * + * @param[in] level The level + * @param[in] format The format + * @param[in] VA args + */ void furi_log_print(FuriLogLevel level, const char* format, ...); + +/** Set log level + * + * @param[in] level The level + */ void furi_log_set_level(FuriLogLevel level); + +/** Get log level + * + * @return The furi log level. + */ FuriLogLevel furi_log_get_level(); + +/** Set log output callback + * + * @param[in] puts The puts callback + */ void furi_log_set_puts(FuriLogPuts puts); + +/** Set timestamp callback + * + * @param[in] timestamp The timestamp callback + */ void furi_log_set_timestamp(FuriLogTimestamp timestamp); #define FURI_LOG_FORMAT(log_letter, tag, format) \ @@ -49,6 +81,12 @@ void furi_log_set_timestamp(FuriLogTimestamp timestamp); #define FURI_LOG_SHOW(tag, format, log_level, log_letter, ...) \ furi_log_print(log_level, FURI_LOG_FORMAT(log_letter, tag, format), ##__VA_ARGS__) +/** Log methods + * + * @param tag The application tag + * @param format The format + * @param ... VA Args + */ #define FURI_LOG_E(tag, format, ...) \ FURI_LOG_SHOW(tag, format, FuriLogLevelError, E, ##__VA_ARGS__) #define FURI_LOG_W(tag, format, ...) FURI_LOG_SHOW(tag, format, FuriLogLevelWarn, W, ##__VA_ARGS__) diff --git a/core/furi/memmgr.c b/furi/core/memmgr.c similarity index 100% rename from core/furi/memmgr.c rename to furi/core/memmgr.c diff --git a/core/furi/memmgr.h b/furi/core/memmgr.h similarity index 100% rename from core/furi/memmgr.h rename to furi/core/memmgr.h diff --git a/core/furi/memmgr_heap.c b/furi/core/memmgr_heap.c similarity index 99% rename from core/furi/memmgr_heap.c rename to furi/core/memmgr_heap.c index 92e99b92..32b2875c 100644 --- a/core/furi/memmgr_heap.c +++ b/furi/core/memmgr_heap.c @@ -38,10 +38,9 @@ #include "check.h" #include #include -#include #include #include -#include +#include /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining all the API functions to use the MPU wrappers. That should only be done when @@ -222,7 +221,7 @@ static inline void traceFREE(void* pointer, size_t size) { size_t memmgr_heap_get_max_free_block() { size_t max_free_size = 0; BlockLink_t* pxBlock; - osKernelLock(); + vTaskSuspendAll(); pxBlock = xStart.pxNextFreeBlock; while(pxBlock->pxNextFreeBlock != NULL) { @@ -232,14 +231,14 @@ size_t memmgr_heap_get_max_free_block() { pxBlock = pxBlock->pxNextFreeBlock; } - osKernelUnlock(); + xTaskResumeAll(); return max_free_size; } void memmgr_heap_printf_free_blocks() { BlockLink_t* pxBlock; //TODO enable when we can do printf with a locked scheduler - //osKernelLock(); + //vTaskSuspendAll(); pxBlock = xStart.pxNextFreeBlock; while(pxBlock->pxNextFreeBlock != NULL) { @@ -247,7 +246,7 @@ void memmgr_heap_printf_free_blocks() { pxBlock = pxBlock->pxNextFreeBlock; } - //osKernelUnlock(); + //xTaskResumeAll(); } #ifdef HEAP_PRINT_DEBUG diff --git a/core/furi/memmgr_heap.h b/furi/core/memmgr_heap.h similarity index 97% rename from core/furi/memmgr_heap.h rename to furi/core/memmgr_heap.h index f76102ec..1521fce4 100644 --- a/core/furi/memmgr_heap.h +++ b/furi/core/memmgr_heap.h @@ -6,7 +6,7 @@ #pragma once #include -#include "furi/thread.h" +#include #ifdef __cplusplus extern "C" { diff --git a/furi/core/message_queue.c b/furi/core/message_queue.c new file mode 100644 index 00000000..2658d6ff --- /dev/null +++ b/furi/core/message_queue.c @@ -0,0 +1,178 @@ +#include "message_queue.h" +#include "core/common_defines.h" +#include +#include +#include "check.h" + +FuriMessageQueue* furi_message_queue_alloc(uint32_t msg_count, uint32_t msg_size) { + furi_assert((furi_is_irq_context() == 0U) && (msg_count > 0U) && (msg_size > 0U)); + + return ((FuriMessageQueue*)xQueueCreate(msg_count, msg_size)); +} + +void furi_message_queue_free(FuriMessageQueue* instance) { + furi_assert(furi_is_irq_context() == 0U); + furi_assert(instance); + + vQueueDelete((QueueHandle_t)instance); +} + +FuriStatus + furi_message_queue_put(FuriMessageQueue* instance, const void* msg_ptr, uint32_t timeout) { + QueueHandle_t hQueue = (QueueHandle_t)instance; + FuriStatus stat; + BaseType_t yield; + + stat = FuriStatusOk; + + if(furi_is_irq_context() != 0U) { + if((hQueue == NULL) || (msg_ptr == NULL) || (timeout != 0U)) { + stat = FuriStatusErrorParameter; + } else { + yield = pdFALSE; + + if(xQueueSendToBackFromISR(hQueue, msg_ptr, &yield) != pdTRUE) { + stat = FuriStatusErrorResource; + } else { + portYIELD_FROM_ISR(yield); + } + } + } else { + if((hQueue == NULL) || (msg_ptr == NULL)) { + stat = FuriStatusErrorParameter; + } else { + if(xQueueSendToBack(hQueue, msg_ptr, (TickType_t)timeout) != pdPASS) { + if(timeout != 0U) { + stat = FuriStatusErrorTimeout; + } else { + stat = FuriStatusErrorResource; + } + } + } + } + + /* Return execution status */ + return (stat); +} + +FuriStatus furi_message_queue_get(FuriMessageQueue* instance, void* msg_ptr, uint32_t timeout) { + QueueHandle_t hQueue = (QueueHandle_t)instance; + FuriStatus stat; + BaseType_t yield; + + stat = FuriStatusOk; + + if(furi_is_irq_context() != 0U) { + if((hQueue == NULL) || (msg_ptr == NULL) || (timeout != 0U)) { + stat = FuriStatusErrorParameter; + } else { + yield = pdFALSE; + + if(xQueueReceiveFromISR(hQueue, msg_ptr, &yield) != pdPASS) { + stat = FuriStatusErrorResource; + } else { + portYIELD_FROM_ISR(yield); + } + } + } else { + if((hQueue == NULL) || (msg_ptr == NULL)) { + stat = FuriStatusErrorParameter; + } else { + if(xQueueReceive(hQueue, msg_ptr, (TickType_t)timeout) != pdPASS) { + if(timeout != 0U) { + stat = FuriStatusErrorTimeout; + } else { + stat = FuriStatusErrorResource; + } + } + } + } + + /* Return execution status */ + return (stat); +} + +uint32_t furi_message_queue_get_capacity(FuriMessageQueue* instance) { + StaticQueue_t* mq = (StaticQueue_t*)instance; + uint32_t capacity; + + if(mq == NULL) { + capacity = 0U; + } else { + /* capacity = pxQueue->uxLength */ + capacity = mq->uxDummy4[1]; + } + + /* Return maximum number of messages */ + return (capacity); +} + +uint32_t furi_message_queue_get_message_size(FuriMessageQueue* instance) { + StaticQueue_t* mq = (StaticQueue_t*)instance; + uint32_t size; + + if(mq == NULL) { + size = 0U; + } else { + /* size = pxQueue->uxItemSize */ + size = mq->uxDummy4[2]; + } + + /* Return maximum message size */ + return (size); +} + +uint32_t furi_message_queue_get_count(FuriMessageQueue* instance) { + QueueHandle_t hQueue = (QueueHandle_t)instance; + UBaseType_t count; + + if(hQueue == NULL) { + count = 0U; + } else if(furi_is_irq_context() != 0U) { + count = uxQueueMessagesWaitingFromISR(hQueue); + } else { + count = uxQueueMessagesWaiting(hQueue); + } + + /* Return number of queued messages */ + return ((uint32_t)count); +} + +uint32_t furi_message_queue_get_space(FuriMessageQueue* instance) { + StaticQueue_t* mq = (StaticQueue_t*)instance; + uint32_t space; + uint32_t isrm; + + if(mq == NULL) { + space = 0U; + } else if(furi_is_irq_context() != 0U) { + isrm = taskENTER_CRITICAL_FROM_ISR(); + + /* space = pxQueue->uxLength - pxQueue->uxMessagesWaiting; */ + space = mq->uxDummy4[1] - mq->uxDummy4[0]; + + taskEXIT_CRITICAL_FROM_ISR(isrm); + } else { + space = (uint32_t)uxQueueSpacesAvailable((QueueHandle_t)mq); + } + + /* Return number of available slots */ + return (space); +} + +FuriStatus furi_message_queue_reset(FuriMessageQueue* instance) { + QueueHandle_t hQueue = (QueueHandle_t)instance; + FuriStatus stat; + + if(furi_is_irq_context() != 0U) { + stat = FuriStatusErrorISR; + } else if(hQueue == NULL) { + stat = FuriStatusErrorParameter; + } else { + stat = FuriStatusOk; + (void)xQueueReset(hQueue); + } + + /* Return execution status */ + return (stat); +} diff --git a/furi/core/message_queue.h b/furi/core/message_queue.h new file mode 100644 index 00000000..392a145f --- /dev/null +++ b/furi/core/message_queue.h @@ -0,0 +1,95 @@ +/** + * @file message_queue.h + * FuriMessageQueue + */ +#pragma once + +#include "core/base.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void FuriMessageQueue; + +/** Allocate furi message queue + * + * @param[in] msg_count The message count + * @param[in] msg_size The message size + * + * @return pointer to FuriMessageQueue instance + */ +FuriMessageQueue* furi_message_queue_alloc(uint32_t msg_count, uint32_t msg_size); + +/** Free queue + * + * @param instance pointer to FuriMessageQueue instance + */ +void furi_message_queue_free(FuriMessageQueue* instance); + +/** Put message into queue + * + * @param instance pointer to FuriMessageQueue instance + * @param[in] msg_ptr The message pointer + * @param[in] timeout The timeout + * @param[in] msg_prio The message prio + * + * @return The furi status. + */ +FuriStatus + furi_message_queue_put(FuriMessageQueue* instance, const void* msg_ptr, uint32_t timeout); + +/** Get message from queue + * + * @param instance pointer to FuriMessageQueue instance + * @param msg_ptr The message pointer + * @param msg_prio The message prioority + * @param[in] timeout The timeout + * + * @return The furi status. + */ +FuriStatus furi_message_queue_get(FuriMessageQueue* instance, void* msg_ptr, uint32_t timeout); + +/** Get queue capacity + * + * @param instance pointer to FuriMessageQueue instance + * + * @return capacity in object count + */ +uint32_t furi_message_queue_get_capacity(FuriMessageQueue* instance); + +/** Get message size + * + * @param instance pointer to FuriMessageQueue instance + * + * @return Message size in bytes + */ +uint32_t furi_message_queue_get_message_size(FuriMessageQueue* instance); + +/** Get message count in queue + * + * @param instance pointer to FuriMessageQueue instance + * + * @return Message count + */ +uint32_t furi_message_queue_get_count(FuriMessageQueue* instance); + +/** Get queue available space + * + * @param instance pointer to FuriMessageQueue instance + * + * @return Message count + */ +uint32_t furi_message_queue_get_space(FuriMessageQueue* instance); + +/** Reset queue + * + * @param instance pointer to FuriMessageQueue instance + * + * @return The furi status. + */ +FuriStatus furi_message_queue_reset(FuriMessageQueue* instance); + +#ifdef __cplusplus +} +#endif diff --git a/furi/core/mutex.c b/furi/core/mutex.c new file mode 100644 index 00000000..78ea0519 --- /dev/null +++ b/furi/core/mutex.c @@ -0,0 +1,122 @@ +#include "mutex.h" +#include "check.h" +#include "common_defines.h" + +#include + +FuriMutex* furi_mutex_alloc(FuriMutexType type) { + furi_assert(!FURI_IS_IRQ_MODE()); + + SemaphoreHandle_t hMutex = NULL; + + if(type == FuriMutexTypeNormal) { + hMutex = xSemaphoreCreateMutex(); + } else if(type == FuriMutexTypeRecursive) { + hMutex = xSemaphoreCreateRecursiveMutex(); + } else { + furi_crash("Programming error"); + } + + furi_check(hMutex != NULL); + + if(type == FuriMutexTypeRecursive) { + /* Set LSB as 'recursive mutex flag' */ + hMutex = (SemaphoreHandle_t)((uint32_t)hMutex | 1U); + } + + /* Return mutex ID */ + return ((FuriMutex*)hMutex); +} + +void furi_mutex_free(FuriMutex* instance) { + furi_assert(!FURI_IS_IRQ_MODE()); + vSemaphoreDelete((SemaphoreHandle_t)((uint32_t)instance & ~1U)); +} + +FuriStatus furi_mutex_acquire(FuriMutex* instance, uint32_t timeout) { + SemaphoreHandle_t hMutex; + FuriStatus stat; + uint32_t rmtx; + + hMutex = (SemaphoreHandle_t)((uint32_t)instance & ~1U); + + /* Extract recursive mutex flag */ + rmtx = (uint32_t)instance & 1U; + + stat = FuriStatusOk; + + if(FURI_IS_IRQ_MODE() != 0U) { + stat = FuriStatusErrorISR; + } else if(hMutex == NULL) { + stat = FuriStatusErrorParameter; + } else { + if(rmtx != 0U) { + if(xSemaphoreTakeRecursive(hMutex, timeout) != pdPASS) { + if(timeout != 0U) { + stat = FuriStatusErrorTimeout; + } else { + stat = FuriStatusErrorResource; + } + } + } else { + if(xSemaphoreTake(hMutex, timeout) != pdPASS) { + if(timeout != 0U) { + stat = FuriStatusErrorTimeout; + } else { + stat = FuriStatusErrorResource; + } + } + } + } + + /* Return execution status */ + return (stat); +} + +FuriStatus furi_mutex_release(FuriMutex* instance) { + SemaphoreHandle_t hMutex; + FuriStatus stat; + uint32_t rmtx; + + hMutex = (SemaphoreHandle_t)((uint32_t)instance & ~1U); + + /* Extract recursive mutex flag */ + rmtx = (uint32_t)instance & 1U; + + stat = FuriStatusOk; + + if(FURI_IS_IRQ_MODE() != 0U) { + stat = FuriStatusErrorISR; + } else if(hMutex == NULL) { + stat = FuriStatusErrorParameter; + } else { + if(rmtx != 0U) { + if(xSemaphoreGiveRecursive(hMutex) != pdPASS) { + stat = FuriStatusErrorResource; + } + } else { + if(xSemaphoreGive(hMutex) != pdPASS) { + stat = FuriStatusErrorResource; + } + } + } + + /* Return execution status */ + return (stat); +} + +FuriThreadId furi_mutex_get_owner(FuriMutex* instance) { + SemaphoreHandle_t hMutex; + FuriThreadId owner; + + hMutex = (SemaphoreHandle_t)((uint32_t)instance & ~1U); + + if((FURI_IS_IRQ_MODE() != 0U) || (hMutex == NULL)) { + owner = 0; + } else { + owner = (FuriThreadId)xSemaphoreGetMutexHolder(hMutex); + } + + /* Return owner thread ID */ + return (owner); +} diff --git a/furi/core/mutex.h b/furi/core/mutex.h new file mode 100644 index 00000000..aa55fa7b --- /dev/null +++ b/furi/core/mutex.h @@ -0,0 +1,62 @@ +/** + * @file mutex.h + * FuriMutex + */ +#pragma once + +#include "base.h" +#include "thread.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + FuriMutexTypeNormal, + FuriMutexTypeRecursive, +} FuriMutexType; + +typedef void FuriMutex; + +/** Allocate FuriMutex + * + * @param[in] type The mutex type + * + * @return pointer to FuriMutex instance + */ +FuriMutex* furi_mutex_alloc(FuriMutexType type); + +/** Free FuriMutex + * + * @param instance The pointer to FuriMutex instance + */ +void furi_mutex_free(FuriMutex* instance); + +/** Acquire mutex + * + * @param instance The pointer to FuriMutex instance + * @param[in] timeout The timeout + * + * @return The furi status. + */ +FuriStatus furi_mutex_acquire(FuriMutex* instance, uint32_t timeout); + +/** Release mutex + * + * @param instance The pointer to FuriMutex instance + * + * @return The furi status. + */ +FuriStatus furi_mutex_release(FuriMutex* instance); + +/** Get mutex owner thread id + * + * @param instance The pointer to FuriMutex instance + * + * @return The furi thread identifier. + */ +FuriThreadId furi_mutex_get_owner(FuriMutex* instance); + +#ifdef __cplusplus +} +#endif diff --git a/core/furi/pubsub.c b/furi/core/pubsub.c similarity index 80% rename from core/furi/pubsub.c rename to furi/core/pubsub.c index 88839ec2..44ef20c7 100644 --- a/core/furi/pubsub.c +++ b/furi/core/pubsub.c @@ -14,13 +14,13 @@ LIST_DEF(FuriPubSubSubscriptionList, FuriPubSubSubscription, M_POD_OPLIST); struct FuriPubSub { FuriPubSubSubscriptionList_t items; - osMutexId_t mutex; + FuriMutex* mutex; }; FuriPubSub* furi_pubsub_alloc() { FuriPubSub* pubsub = malloc(sizeof(FuriPubSub)); - pubsub->mutex = osMutexNew(NULL); + pubsub->mutex = furi_mutex_alloc(FuriMutexTypeNormal); furi_assert(pubsub->mutex); FuriPubSubSubscriptionList_init(pubsub->items); @@ -35,14 +35,14 @@ void furi_pubsub_free(FuriPubSub* pubsub) { FuriPubSubSubscriptionList_clear(pubsub->items); - furi_check(osMutexDelete(pubsub->mutex) == osOK); + furi_mutex_free(pubsub->mutex); free(pubsub); } FuriPubSubSubscription* furi_pubsub_subscribe(FuriPubSub* pubsub, FuriPubSubCallback callback, void* callback_context) { - furi_check(osMutexAcquire(pubsub->mutex, osWaitForever) == osOK); + furi_check(furi_mutex_acquire(pubsub->mutex, FuriWaitForever) == FuriStatusOk); // put uninitialized item to the list FuriPubSubSubscription* item = FuriPubSubSubscriptionList_push_raw(pubsub->items); @@ -50,7 +50,7 @@ FuriPubSubSubscription* item->callback = callback; item->callback_context = callback_context; - furi_check(osMutexRelease(pubsub->mutex) == osOK); + furi_check(furi_mutex_release(pubsub->mutex) == FuriStatusOk); return item; } @@ -59,7 +59,7 @@ void furi_pubsub_unsubscribe(FuriPubSub* pubsub, FuriPubSubSubscription* pubsub_ furi_assert(pubsub); furi_assert(pubsub_subscription); - furi_check(osMutexAcquire(pubsub->mutex, osWaitForever) == osOK); + furi_check(furi_mutex_acquire(pubsub->mutex, FuriWaitForever) == FuriStatusOk); bool result = false; // iterate over items @@ -76,12 +76,12 @@ void furi_pubsub_unsubscribe(FuriPubSub* pubsub, FuriPubSubSubscription* pubsub_ } } - furi_check(osMutexRelease(pubsub->mutex) == osOK); + furi_check(furi_mutex_release(pubsub->mutex) == FuriStatusOk); furi_check(result); } void furi_pubsub_publish(FuriPubSub* pubsub, void* message) { - furi_check(osMutexAcquire(pubsub->mutex, osWaitForever) == osOK); + furi_check(furi_mutex_acquire(pubsub->mutex, FuriWaitForever) == FuriStatusOk); // iterate over subscribers FuriPubSubSubscriptionList_it_t it; @@ -91,5 +91,5 @@ void furi_pubsub_publish(FuriPubSub* pubsub, void* message) { item->callback(message, item->callback_context); } - furi_check(osMutexRelease(pubsub->mutex) == osOK); + furi_check(furi_mutex_release(pubsub->mutex) == FuriStatusOk); } diff --git a/core/furi/pubsub.h b/furi/core/pubsub.h similarity index 97% rename from core/furi/pubsub.h rename to furi/core/pubsub.h index 446d423f..69ca574a 100644 --- a/core/furi/pubsub.h +++ b/furi/core/pubsub.h @@ -1,3 +1,7 @@ +/** + * @file pubsub.h + * FuriPubSub + */ #pragma once #ifdef __cplusplus diff --git a/core/furi/record.c b/furi/core/record.c similarity index 84% rename from core/furi/record.c rename to furi/core/record.c index d7afbf9c..666d5076 100644 --- a/core/furi/record.c +++ b/furi/core/record.c @@ -2,7 +2,7 @@ #include "check.h" #include "memmgr.h" #include "mutex.h" -#include "event_flags.h" +#include "event_flag.h" #include #include @@ -10,7 +10,7 @@ #define FURI_RECORD_FLAG_READY (0x1) typedef struct { - osEventFlagsId_t flags; + FuriEventFlag* flags; void* data; size_t holders_count; } FuriRecordData; @@ -18,7 +18,7 @@ typedef struct { DICT_DEF2(FuriRecordDataDict, string_t, STRING_OPLIST, FuriRecordData, M_POD_OPLIST) typedef struct { - osMutexId_t mutex; + FuriMutex* mutex; FuriRecordDataDict_t records; } FuriRecord; @@ -26,7 +26,7 @@ static FuriRecord* furi_record = NULL; void furi_record_init() { furi_record = malloc(sizeof(FuriRecord)); - furi_record->mutex = osMutexNew(NULL); + furi_record->mutex = furi_mutex_alloc(FuriMutexTypeNormal); furi_check(furi_record->mutex); FuriRecordDataDict_init(furi_record->records); } @@ -36,7 +36,7 @@ static FuriRecordData* furi_record_data_get_or_create(string_t name_str) { FuriRecordData* record_data = FuriRecordDataDict_get(furi_record->records, name_str); if(!record_data) { FuriRecordData new_record; - new_record.flags = osEventFlagsNew(NULL); + new_record.flags = furi_event_flag_alloc(); new_record.data = NULL; new_record.holders_count = 0; FuriRecordDataDict_set_at(furi_record->records, name_str, new_record); @@ -46,11 +46,11 @@ static FuriRecordData* furi_record_data_get_or_create(string_t name_str) { } static void furi_record_lock() { - furi_check(osMutexAcquire(furi_record->mutex, osWaitForever) == osOK); + furi_check(furi_mutex_acquire(furi_record->mutex, FuriWaitForever) == FuriStatusOk); } static void furi_record_unlock() { - furi_check(osMutexRelease(furi_record->mutex) == osOK); + furi_check(furi_mutex_release(furi_record->mutex) == FuriStatusOk); } bool furi_record_exists(const char* name) { @@ -83,7 +83,7 @@ void furi_record_create(const char* name, void* data) { FuriRecordData* record_data = furi_record_data_get_or_create(name_str); furi_assert(record_data->data == NULL); record_data->data = data; - osEventFlagsSet(record_data->flags, FURI_RECORD_FLAG_READY); + furi_event_flag_set(record_data->flags, FURI_RECORD_FLAG_READY); furi_record_unlock(); @@ -103,7 +103,7 @@ bool furi_record_destroy(const char* name) { FuriRecordData* record_data = FuriRecordDataDict_get(furi_record->records, name_str); furi_assert(record_data); if(record_data->holders_count == 0) { - furi_check(osOK == osEventFlagsDelete(record_data->flags)); + furi_event_flag_free(record_data->flags); FuriRecordDataDict_erase(furi_record->records, name_str); ret = true; } @@ -130,11 +130,11 @@ void* furi_record_open(const char* name) { // Wait for record to become ready furi_check( - osEventFlagsWait( + furi_event_flag_wait( record_data->flags, FURI_RECORD_FLAG_READY, - osFlagsWaitAny | osFlagsNoClear, - osWaitForever) == FURI_RECORD_FLAG_READY); + FuriFlagWaitAny | FuriFlagNoClear, + FuriWaitForever) == FURI_RECORD_FLAG_READY); string_clear(name_str); diff --git a/core/furi/record.h b/furi/core/record.h similarity index 100% rename from core/furi/record.h rename to furi/core/record.h diff --git a/furi/core/semaphore.c b/furi/core/semaphore.c new file mode 100644 index 00000000..a204cbe6 --- /dev/null +++ b/furi/core/semaphore.c @@ -0,0 +1,115 @@ +#include "semaphore.h" +#include "check.h" +#include "common_defines.h" + +#include + +FuriSemaphore* furi_semaphore_alloc(uint32_t max_count, uint32_t initial_count) { + furi_assert(!FURI_IS_IRQ_MODE()); + furi_assert((max_count > 0U) && (initial_count <= max_count)); + + SemaphoreHandle_t hSemaphore = NULL; + if(max_count == 1U) { + hSemaphore = xSemaphoreCreateBinary(); + if((hSemaphore != NULL) && (initial_count != 0U)) { + if(xSemaphoreGive(hSemaphore) != pdPASS) { + vSemaphoreDelete(hSemaphore); + hSemaphore = NULL; + } + } + } else { + hSemaphore = xSemaphoreCreateCounting(max_count, initial_count); + } + + furi_check(hSemaphore); + + /* Return semaphore ID */ + return ((FuriSemaphore*)hSemaphore); +} + +void furi_semaphore_free(FuriSemaphore* instance) { + furi_assert(instance); + furi_assert(!FURI_IS_IRQ_MODE()); + + SemaphoreHandle_t hSemaphore = (SemaphoreHandle_t)instance; + + vSemaphoreDelete(hSemaphore); +} + +FuriStatus furi_semaphore_acquire(FuriSemaphore* instance, uint32_t timeout) { + furi_assert(instance); + + SemaphoreHandle_t hSemaphore = (SemaphoreHandle_t)instance; + FuriStatus stat; + BaseType_t yield; + + stat = FuriStatusOk; + + if(FURI_IS_IRQ_MODE() != 0U) { + if(timeout != 0U) { + stat = FuriStatusErrorParameter; + } else { + yield = pdFALSE; + + if(xSemaphoreTakeFromISR(hSemaphore, &yield) != pdPASS) { + stat = FuriStatusErrorResource; + } else { + portYIELD_FROM_ISR(yield); + } + } + } else { + if(xSemaphoreTake(hSemaphore, (TickType_t)timeout) != pdPASS) { + if(timeout != 0U) { + stat = FuriStatusErrorTimeout; + } else { + stat = FuriStatusErrorResource; + } + } + } + + /* Return execution status */ + return (stat); +} + +FuriStatus furi_semaphore_release(FuriSemaphore* instance) { + furi_assert(instance); + + SemaphoreHandle_t hSemaphore = (SemaphoreHandle_t)instance; + FuriStatus stat; + BaseType_t yield; + + stat = FuriStatusOk; + + if(FURI_IS_IRQ_MODE() != 0U) { + yield = pdFALSE; + + if(xSemaphoreGiveFromISR(hSemaphore, &yield) != pdTRUE) { + stat = FuriStatusErrorResource; + } else { + portYIELD_FROM_ISR(yield); + } + } else { + if(xSemaphoreGive(hSemaphore) != pdPASS) { + stat = FuriStatusErrorResource; + } + } + + /* Return execution status */ + return (stat); +} + +uint32_t furi_semaphore_get_count(FuriSemaphore* instance) { + furi_assert(instance); + + SemaphoreHandle_t hSemaphore = (SemaphoreHandle_t)instance; + uint32_t count; + + if(FURI_IS_IRQ_MODE() != 0U) { + count = (uint32_t)uxSemaphoreGetCountFromISR(hSemaphore); + } else { + count = (uint32_t)uxSemaphoreGetCount(hSemaphore); + } + + /* Return number of tokens */ + return (count); +} diff --git a/furi/core/semaphore.h b/furi/core/semaphore.h new file mode 100644 index 00000000..19d056bf --- /dev/null +++ b/furi/core/semaphore.h @@ -0,0 +1,58 @@ +/** + * @file semaphore.h + * FuriSemaphore + */ +#pragma once + +#include "base.h" +#include "thread.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void FuriSemaphore; + +/** Allocate semaphore + * + * @param[in] max_count The maximum count + * @param[in] initial_count The initial count + * + * @return pointer to FuriSemaphore instance + */ +FuriSemaphore* furi_semaphore_alloc(uint32_t max_count, uint32_t initial_count); + +/** Free semaphore + * + * @param instance The pointer to FuriSemaphore instance + */ +void furi_semaphore_free(FuriSemaphore* instance); + +/** Acquire semaphore + * + * @param instance The pointer to FuriSemaphore instance + * @param[in] timeout The timeout + * + * @return The furi status. + */ +FuriStatus furi_semaphore_acquire(FuriSemaphore* instance, uint32_t timeout); + +/** Release semaphore + * + * @param instance The pointer to FuriSemaphore instance + * + * @return The furi status. + */ +FuriStatus furi_semaphore_release(FuriSemaphore* instance); + +/** Get semaphore count + * + * @param instance The pointer to FuriSemaphore instance + * + * @return Semaphore count + */ +uint32_t furi_semaphore_get_count(FuriSemaphore* instance); + +#ifdef __cplusplus +} +#endif diff --git a/core/furi/stdglue.c b/furi/core/stdglue.c similarity index 83% rename from core/furi/stdglue.c rename to furi/core/stdglue.c index 8c1d0813..573277aa 100644 --- a/core/furi/stdglue.c +++ b/furi/core/stdglue.c @@ -16,7 +16,7 @@ DICT_DEF2( M_PTR_OPLIST) typedef struct { - osMutexId_t mutex; + FuriMutex* mutex; FuriStdglueCallbackDict_t thread_outputs; } FuriStdglue; @@ -25,10 +25,9 @@ static FuriStdglue* furi_stdglue = NULL; static ssize_t stdout_write(void* _cookie, const char* data, size_t size) { furi_assert(furi_stdglue); bool consumed = false; - osKernelState_t state = osKernelGetState(); FuriThreadId task_id = furi_thread_get_current_id(); - if(state == osKernelRunning && task_id && - osMutexAcquire(furi_stdglue->mutex, osWaitForever) == osOK) { + if(xTaskGetSchedulerState() == taskSCHEDULER_RUNNING && task_id && + furi_mutex_acquire(furi_stdglue->mutex, FuriWaitForever) == FuriStatusOk) { // We are in the thread context // Handle thread callbacks FuriStdglueWriteCallback* callback_ptr = @@ -37,7 +36,7 @@ static ssize_t stdout_write(void* _cookie, const char* data, size_t size) { (*callback_ptr)(_cookie, data, size); consumed = true; } - furi_check(osMutexRelease(furi_stdglue->mutex) == osOK); + furi_check(furi_mutex_release(furi_stdglue->mutex) == FuriStatusOk); } // Flush if(data == 0) { @@ -57,7 +56,7 @@ static ssize_t stdout_write(void* _cookie, const char* data, size_t size) { void furi_stdglue_init() { furi_stdglue = malloc(sizeof(FuriStdglue)); // Init outputs structures - furi_stdglue->mutex = osMutexNew(NULL); + furi_stdglue->mutex = furi_mutex_alloc(FuriMutexTypeNormal); furi_check(furi_stdglue->mutex); FuriStdglueCallbackDict_init(furi_stdglue->thread_outputs); // Prepare and set stdout descriptor @@ -78,14 +77,14 @@ bool furi_stdglue_set_thread_stdout_callback(FuriStdglueWriteCallback callback) furi_assert(furi_stdglue); FuriThreadId task_id = furi_thread_get_current_id(); if(task_id) { - furi_check(osMutexAcquire(furi_stdglue->mutex, osWaitForever) == osOK); + furi_check(furi_mutex_acquire(furi_stdglue->mutex, FuriWaitForever) == FuriStatusOk); if(callback) { FuriStdglueCallbackDict_set_at( furi_stdglue->thread_outputs, (uint32_t)task_id, callback); } else { FuriStdglueCallbackDict_erase(furi_stdglue->thread_outputs, (uint32_t)task_id); } - furi_check(osMutexRelease(furi_stdglue->mutex) == osOK); + furi_check(furi_mutex_release(furi_stdglue->mutex) == FuriStatusOk); return true; } else { return false; diff --git a/core/furi/stdglue.h b/furi/core/stdglue.h similarity index 100% rename from core/furi/stdglue.h rename to furi/core/stdglue.h diff --git a/core/furi/thread.c b/furi/core/thread.c similarity index 91% rename from core/furi/thread.c rename to furi/core/thread.c index 266a3855..097cedef 100644 --- a/core/furi/thread.c +++ b/furi/core/thread.c @@ -1,4 +1,5 @@ #include "thread.h" +#include "kernel.h" #include "memmgr.h" #include "memmgr_heap.h" #include "check.h" @@ -57,7 +58,7 @@ static void furi_thread_body(void* context) { thread->ret = thread->callback(thread->context); if(thread->heap_trace_enabled == true) { - osDelay(33); + furi_delay_ms(33); thread->heap_size = memmgr_heap_get_thread_memory((FuriThreadId)task_handle); memmgr_heap_disable_thread_trace((FuriThreadId)task_handle); } @@ -157,10 +158,10 @@ bool furi_thread_join(FuriThread* thread) { furi_assert(thread); while(thread->state != FuriThreadStateStopped) { - osDelay(10); + furi_delay_ms(10); } - return osOK; + return FuriStatusOk; } FuriThreadId furi_thread_get_id(FuriThread* thread) { @@ -216,9 +217,9 @@ uint32_t furi_thread_flags_set(FuriThreadId thread_id, uint32_t flags) { BaseType_t yield; if((hTask == NULL) || ((flags & THREAD_FLAGS_INVALID_BITS) != 0U)) { - rflags = (uint32_t)osErrorParameter; + rflags = (uint32_t)FuriStatusErrorParameter; } else { - rflags = (uint32_t)osError; + rflags = (uint32_t)FuriStatusError; if(FURI_IS_IRQ_MODE()) { yield = pdFALSE; @@ -242,9 +243,9 @@ uint32_t furi_thread_flags_clear(uint32_t flags) { uint32_t rflags, cflags; if(FURI_IS_IRQ_MODE()) { - rflags = (uint32_t)osErrorISR; + rflags = (uint32_t)FuriStatusErrorISR; } else if((flags & THREAD_FLAGS_INVALID_BITS) != 0U) { - rflags = (uint32_t)osErrorParameter; + rflags = (uint32_t)FuriStatusErrorParameter; } else { hTask = xTaskGetCurrentTaskHandle(); @@ -255,10 +256,10 @@ uint32_t furi_thread_flags_clear(uint32_t flags) { if(xTaskNotifyIndexed(hTask, THREAD_NOTIFY_INDEX, cflags, eSetValueWithOverwrite) != pdPASS) { - rflags = (uint32_t)osError; + rflags = (uint32_t)FuriStatusError; } } else { - rflags = (uint32_t)osError; + rflags = (uint32_t)FuriStatusError; } } @@ -271,13 +272,13 @@ uint32_t furi_thread_flags_get(void) { uint32_t rflags; if(FURI_IS_IRQ_MODE()) { - rflags = (uint32_t)osErrorISR; + rflags = (uint32_t)FuriStatusErrorISR; } else { hTask = xTaskGetCurrentTaskHandle(); if(xTaskNotifyAndQueryIndexed(hTask, THREAD_NOTIFY_INDEX, 0, eNoAction, &rflags) != pdPASS) { - rflags = (uint32_t)osError; + rflags = (uint32_t)FuriStatusError; } } @@ -291,11 +292,11 @@ uint32_t furi_thread_flags_wait(uint32_t flags, uint32_t options, uint32_t timeo BaseType_t rval; if(FURI_IS_IRQ_MODE()) { - rflags = (uint32_t)osErrorISR; + rflags = (uint32_t)FuriStatusErrorISR; } else if((flags & THREAD_FLAGS_INVALID_BITS) != 0U) { - rflags = (uint32_t)osErrorParameter; + rflags = (uint32_t)FuriStatusErrorParameter; } else { - if((options & osFlagsNoClear) == osFlagsNoClear) { + if((options & FuriFlagNoClear) == FuriFlagNoClear) { clear = 0U; } else { clear = flags; @@ -312,12 +313,12 @@ uint32_t furi_thread_flags_wait(uint32_t flags, uint32_t options, uint32_t timeo rflags &= flags; rflags |= nval; - if((options & osFlagsWaitAll) == osFlagsWaitAll) { + if((options & FuriFlagWaitAll) == FuriFlagWaitAll) { if((flags & rflags) == flags) { break; } else { if(timeout == 0U) { - rflags = (uint32_t)osErrorResource; + rflags = (uint32_t)FuriStatusErrorResource; break; } } @@ -326,7 +327,7 @@ uint32_t furi_thread_flags_wait(uint32_t flags, uint32_t options, uint32_t timeo break; } else { if(timeout == 0U) { - rflags = (uint32_t)osErrorResource; + rflags = (uint32_t)FuriStatusErrorResource; break; } } @@ -342,9 +343,9 @@ uint32_t furi_thread_flags_wait(uint32_t flags, uint32_t options, uint32_t timeo } } else { if(timeout == 0) { - rflags = (uint32_t)osErrorResource; + rflags = (uint32_t)FuriStatusErrorResource; } else { - rflags = (uint32_t)osErrorTimeout; + rflags = (uint32_t)FuriStatusErrorTimeout; } } } while(rval != pdFAIL); diff --git a/core/furi/thread.h b/furi/core/thread.h similarity index 99% rename from core/furi/thread.h rename to furi/core/thread.h index 11dd997c..34eb39f0 100644 --- a/core/furi/thread.h +++ b/furi/core/thread.h @@ -6,6 +6,7 @@ #pragma once #include "base.h" +#include "common_defines.h" #ifdef __cplusplus extern "C" { diff --git a/furi/core/timer.c b/furi/core/timer.c new file mode 100644 index 00000000..807f477e --- /dev/null +++ b/furi/core/timer.c @@ -0,0 +1,142 @@ +#include "timer.h" +#include "check.h" + +#include "core/common_defines.h" +#include +#include + +typedef struct { + FuriTimerCallback func; + void* context; +} TimerCallback_t; + +static void TimerCallback(TimerHandle_t hTimer) { + TimerCallback_t* callb; + + /* Retrieve pointer to callback function and context */ + callb = (TimerCallback_t*)pvTimerGetTimerID(hTimer); + + /* Remove dynamic allocation flag */ + callb = (TimerCallback_t*)((uint32_t)callb & ~1U); + + if(callb != NULL) { + callb->func(callb->context); + } +} + +FuriTimer* furi_timer_alloc(FuriTimerCallback func, FuriTimerType type, void* context) { + furi_assert((furi_is_irq_context() == 0U) && (func != NULL)); + + TimerHandle_t hTimer; + TimerCallback_t* callb; + UBaseType_t reload; + uint32_t callb_dyn; + + hTimer = NULL; + callb = NULL; + callb_dyn = 0U; + + /* Dynamic memory allocation is available: if memory for callback and */ + /* its context is not provided, allocate it from dynamic memory pool */ + if(callb == NULL) { + callb = (TimerCallback_t*)pvPortMalloc(sizeof(TimerCallback_t)); + + if(callb != NULL) { + /* Callback memory was allocated from dynamic pool, set flag */ + callb_dyn = 1U; + } + } + + if(callb != NULL) { + callb->func = func; + callb->context = context; + + if(type == FuriTimerTypeOnce) { + reload = pdFALSE; + } else { + reload = pdTRUE; + } + + /* Store callback memory dynamic allocation flag */ + callb = (TimerCallback_t*)((uint32_t)callb | callb_dyn); + // TimerCallback function is always provided as a callback and is used to call application + // specified function with its context both stored in structure callb. + hTimer = xTimerCreate(NULL, 1, reload, callb, TimerCallback); + if((hTimer == NULL) && (callb != NULL) && (callb_dyn == 1U)) { + /* Failed to create a timer, release allocated resources */ + callb = (TimerCallback_t*)((uint32_t)callb & ~1U); + vPortFree(callb); + } + } + + /* Return timer ID */ + return ((FuriTimer*)hTimer); +} + +void furi_timer_free(FuriTimer* instance) { + furi_assert(!furi_is_irq_context()); + furi_assert(instance); + + TimerHandle_t hTimer = (TimerHandle_t)instance; + TimerCallback_t* callb; + + callb = (TimerCallback_t*)pvTimerGetTimerID(hTimer); + + if(xTimerDelete(hTimer, portMAX_DELAY) == pdPASS) { + if((uint32_t)callb & 1U) { + /* Callback memory was allocated from dynamic pool, clear flag */ + callb = (TimerCallback_t*)((uint32_t)callb & ~1U); + + /* Return allocated memory to dynamic pool */ + vPortFree(callb); + } + } +} + +FuriStatus furi_timer_start(FuriTimer* instance, uint32_t ticks) { + furi_assert(!furi_is_irq_context()); + furi_assert(instance); + + TimerHandle_t hTimer = (TimerHandle_t)instance; + FuriStatus stat; + + if(xTimerChangePeriod(hTimer, ticks, portMAX_DELAY) == pdPASS) { + stat = FuriStatusOk; + } else { + stat = FuriStatusErrorResource; + } + + /* Return execution status */ + return (stat); +} + +FuriStatus furi_timer_stop(FuriTimer* instance) { + furi_assert(!furi_is_irq_context()); + furi_assert(instance); + + TimerHandle_t hTimer = (TimerHandle_t)instance; + FuriStatus stat; + + if(xTimerIsTimerActive(hTimer) == pdFALSE) { + stat = FuriStatusErrorResource; + } else { + if(xTimerStop(hTimer, portMAX_DELAY) == pdPASS) { + stat = FuriStatusOk; + } else { + stat = FuriStatusError; + } + } + + /* Return execution status */ + return (stat); +} + +uint32_t furi_timer_is_running(FuriTimer* instance) { + furi_assert(!furi_is_irq_context()); + furi_assert(instance); + + TimerHandle_t hTimer = (TimerHandle_t)instance; + + /* Return 0: not running, 1: running */ + return (uint32_t)xTimerIsTimerActive(hTimer); +} diff --git a/furi/core/timer.h b/furi/core/timer.h new file mode 100644 index 00000000..e79c1868 --- /dev/null +++ b/furi/core/timer.h @@ -0,0 +1,61 @@ +#pragma once + +#include "core/base.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (*FuriTimerCallback)(void* context); + +typedef enum { + FuriTimerTypeOnce = 0, ///< One-shot timer. + FuriTimerTypePeriodic = 1 ///< Repeating timer. +} FuriTimerType; + +typedef void FuriTimer; + +/** Allocate timer + * + * @param[in] func The callback function + * @param[in] type The timer type + * @param context The callback context + * + * @return The pointer to FuriTimer instance + */ +FuriTimer* furi_timer_alloc(FuriTimerCallback func, FuriTimerType type, void* context); + +/** Free timer + * + * @param instance The pointer to FuriTimer instance + */ +void furi_timer_free(FuriTimer* instance); + +/** Start timer + * + * @param instance The pointer to FuriTimer instance + * @param[in] ticks The ticks + * + * @return The furi status. + */ +FuriStatus furi_timer_start(FuriTimer* instance, uint32_t ticks); + +/** Stop timer + * + * @param instance The pointer to FuriTimer instance + * + * @return The furi status. + */ +FuriStatus furi_timer_stop(FuriTimer* instance); + +/** Is timer running + * + * @param instance The pointer to FuriTimer instance + * + * @return 0: not running, 1: running + */ +uint32_t furi_timer_is_running(FuriTimer* instance); + +#ifdef __cplusplus +} +#endif diff --git a/core/furi/valuemutex.c b/furi/core/valuemutex.c similarity index 79% rename from core/furi/valuemutex.c rename to furi/core/valuemutex.c index 6010c963..af2a0755 100644 --- a/core/furi/valuemutex.c +++ b/furi/core/valuemutex.c @@ -6,7 +6,7 @@ bool init_mutex(ValueMutex* valuemutex, void* value, size_t size) { // mutex without name, // no attributes (unfortunatly robust mutex is not supported by FreeRTOS), // with dynamic memory allocation - valuemutex->mutex = osMutexNew(NULL); + valuemutex->mutex = furi_mutex_alloc(FuriMutexTypeNormal); if(valuemutex->mutex == NULL) return false; valuemutex->value = value; @@ -16,15 +16,16 @@ bool init_mutex(ValueMutex* valuemutex, void* value, size_t size) { } bool delete_mutex(ValueMutex* valuemutex) { - if(osMutexAcquire(valuemutex->mutex, osWaitForever) == osOK) { - return osMutexDelete(valuemutex->mutex) == osOK; + if(furi_mutex_acquire(valuemutex->mutex, FuriWaitForever) == FuriStatusOk) { + furi_mutex_free(valuemutex->mutex); + return true; } else { return false; } } void* acquire_mutex(ValueMutex* valuemutex, uint32_t timeout) { - if(osMutexAcquire(valuemutex->mutex, timeout) == osOK) { + if(furi_mutex_acquire(valuemutex->mutex, timeout) == FuriStatusOk) { return valuemutex->value; } else { return NULL; @@ -34,7 +35,7 @@ void* acquire_mutex(ValueMutex* valuemutex, uint32_t timeout) { bool release_mutex(ValueMutex* valuemutex, const void* value) { if(value != valuemutex->value) return false; - if(osMutexRelease(valuemutex->mutex) != osOK) return false; + if(furi_mutex_release(valuemutex->mutex) != FuriStatusOk) return false; return true; } diff --git a/core/furi/valuemutex.h b/furi/core/valuemutex.h similarity index 93% rename from core/furi/valuemutex.h rename to furi/core/valuemutex.h index bd149316..41762fdd 100644 --- a/core/furi/valuemutex.h +++ b/furi/core/valuemutex.h @@ -1,6 +1,5 @@ #pragma once -#include #include #include "mutex.h" @@ -19,7 +18,7 @@ extern "C" { typedef struct { void* value; size_t size; - osMutexId_t mutex; + FuriMutex* mutex; } ValueMutex; /** @@ -43,7 +42,7 @@ void* acquire_mutex(ValueMutex* valuemutex, uint32_t timeout); * Helper: infinitly wait for mutex */ static inline void* acquire_mutex_block(ValueMutex* valuemutex) { - return acquire_mutex(valuemutex, osWaitForever); + return acquire_mutex(valuemutex, FuriWaitForever); } /** @@ -75,11 +74,11 @@ bool read_mutex(ValueMutex* valuemutex, void* data, size_t len, uint32_t timeout bool write_mutex(ValueMutex* valuemutex, void* data, size_t len, uint32_t timeout); inline static bool write_mutex_block(ValueMutex* valuemutex, void* data, size_t len) { - return write_mutex(valuemutex, data, len, osWaitForever); + return write_mutex(valuemutex, data, len, FuriWaitForever); } inline static bool read_mutex_block(ValueMutex* valuemutex, void* data, size_t len) { - return read_mutex(valuemutex, data, len, osWaitForever); + return read_mutex(valuemutex, data, len, FuriWaitForever); } #ifdef __cplusplus @@ -118,7 +117,7 @@ void provider_app(void* _p) { } release_mutex(&example_mutex, value); - osDelay(100); + furi_delay_ms(100); } } @@ -143,7 +142,7 @@ void consumer_app(void* _p) { printf("counter value: %d\n", counter); } - osDelay(1000); + furi_delay_ms(1000); } } ``` diff --git a/core/flipper.c b/furi/flipper.c similarity index 100% rename from core/flipper.c rename to furi/flipper.c diff --git a/core/flipper.h b/furi/flipper.h similarity index 100% rename from core/flipper.h rename to furi/flipper.h diff --git a/furi/furi.c b/furi/furi.c new file mode 100644 index 00000000..e6848624 --- /dev/null +++ b/furi/furi.c @@ -0,0 +1,27 @@ +#include "furi.h" +#include +#include "queue.h" + +void furi_init() { + furi_assert(!furi_is_irq_context()); + furi_assert(xTaskGetSchedulerState() == taskSCHEDULER_NOT_STARTED); + + furi_log_init(); + furi_record_init(); + furi_stdglue_init(); +} + +void furi_run() { + furi_assert(!furi_is_irq_context()); + furi_assert(xTaskGetSchedulerState() == taskSCHEDULER_NOT_STARTED); + +#if(__ARM_ARCH_7A__ == 0U) + /* Service Call interrupt might be configured before kernel start */ + /* and when its priority is lower or equal to BASEPRI, svc intruction */ + /* causes a Hard Fault. */ + NVIC_SetPriority(SVCall_IRQn, 0U); +#endif + + /* Start the kernel scheduler */ + vTaskStartScheduler(); +} diff --git a/furi/furi.h b/furi/furi.h new file mode 100644 index 00000000..d78129a8 --- /dev/null +++ b/furi/furi.h @@ -0,0 +1,37 @@ +#pragma once + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +// FreeRTOS timer, REMOVE AFTER REFACTORING +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void furi_init(); + +void furi_run(); + +#ifdef __cplusplus +} +#endif diff --git a/lib/FreeRTOS-glue/cmsis_os2.c b/lib/FreeRTOS-glue/cmsis_os2.c deleted file mode 100644 index bee37572..00000000 --- a/lib/FreeRTOS-glue/cmsis_os2.c +++ /dev/null @@ -1,1120 +0,0 @@ -/* -------------------------------------------------------------------------- - * Copyright (c) 2013-2021 Arm Limited. All rights reserved. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the License); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Name: cmsis_os2.c - * Purpose: CMSIS RTOS2 wrapper for FreeRTOS - * - *---------------------------------------------------------------------------*/ - -#include - -#include - -#include "cmsis_os2.h" // ::CMSIS:RTOS2 -#include "cmsis_compiler.h" // Compiler agnostic definitions - -#include "FreeRTOS.h" // ARM.FreeRTOS::RTOS:Core -#include "timers.h" // ARM.FreeRTOS::RTOS:Timers -#include "queue.h" - -#include "freertos_os2.h" // Configuration check and setup - -#include CMSIS_device_header - -#ifndef CMSIS_TASK_NOTIFY_INDEX -#define CMSIS_TASK_NOTIFY_INDEX 0 -#endif - -/*---------------------------------------------------------------------------*/ -#ifndef __ARM_ARCH_6M__ - #define __ARM_ARCH_6M__ 0 -#endif -#ifndef __ARM_ARCH_7M__ - #define __ARM_ARCH_7M__ 0 -#endif -#ifndef __ARM_ARCH_7EM__ - #define __ARM_ARCH_7EM__ 0 -#endif -#ifndef __ARM_ARCH_8M_MAIN__ - #define __ARM_ARCH_8M_MAIN__ 0 -#endif -#ifndef __ARM_ARCH_7A__ - #define __ARM_ARCH_7A__ 0 -#endif - -#if ((__ARM_ARCH_7M__ == 1U) || \ - (__ARM_ARCH_7EM__ == 1U) || \ - (__ARM_ARCH_8M_MAIN__ == 1U)) -#define IS_IRQ_MASKED() ((__get_PRIMASK() != 0U) || (__get_BASEPRI() != 0U)) -#elif (__ARM_ARCH_6M__ == 1U) -#define IS_IRQ_MASKED() (__get_PRIMASK() != 0U) -#elif (__ARM_ARCH_7A__ == 1U) -/* CPSR mask bits */ -#define CPSR_MASKBIT_I 0x80U - -#define IS_IRQ_MASKED() ((__get_CPSR() & CPSR_MASKBIT_I) != 0U) -#else -#define IS_IRQ_MASKED() (__get_PRIMASK() != 0U) -#endif - -#if (__ARM_ARCH_7A__ == 1U) -/* CPSR mode bitmasks */ -#define CPSR_MODE_USER 0x10U -#define CPSR_MODE_SYSTEM 0x1FU - -#define IS_IRQ_MODE() ((__get_mode() != CPSR_MODE_USER) && (__get_mode() != CPSR_MODE_SYSTEM)) -#else -#define IS_IRQ_MODE() (__get_IPSR() != 0U) -#endif - -/* Limits */ -#define MAX_BITS_TASK_NOTIFY 31U - -#define THREAD_FLAGS_INVALID_BITS (~((1UL << MAX_BITS_TASK_NOTIFY) - 1U)) - -/* Kernel version and identification string definition (major.minor.rev: mmnnnrrrr dec) */ -#define KERNEL_VERSION (((uint32_t)tskKERNEL_VERSION_MAJOR * 10000000UL) | \ - ((uint32_t)tskKERNEL_VERSION_MINOR * 10000UL) | \ - ((uint32_t)tskKERNEL_VERSION_BUILD * 1UL)) - -#define KERNEL_ID ("FreeRTOS " tskKERNEL_VERSION_NUMBER) - -/* Timer callback information structure definition */ -typedef struct { - osTimerFunc_t func; - void *arg; -} TimerCallback_t; - -/* Kernel initialization state */ -static osKernelState_t KernelState = osKernelInactive; - -/* - Heap region definition used by heap_5 variant - - Define configAPPLICATION_ALLOCATED_HEAP as nonzero value in FreeRTOSConfig.h if - heap regions are already defined and vPortDefineHeapRegions is called in application. - - Otherwise vPortDefineHeapRegions will be called by osKernelInitialize using - definition configHEAP_5_REGIONS as parameter. Overriding configHEAP_5_REGIONS - is possible by defining it globally or in FreeRTOSConfig.h. -*/ -#if defined(USE_FreeRTOS_HEAP_5) -#if (configAPPLICATION_ALLOCATED_HEAP == 0) - /* - FreeRTOS heap is not defined by the application. - Single region of size configTOTAL_HEAP_SIZE (defined in FreeRTOSConfig.h) - is provided by default. Define configHEAP_5_REGIONS to provide custom - HeapRegion_t array. - */ - #define HEAP_5_REGION_SETUP 1 - - #ifndef configHEAP_5_REGIONS - #define configHEAP_5_REGIONS xHeapRegions - - static uint8_t ucHeap[configTOTAL_HEAP_SIZE]; - - static HeapRegion_t xHeapRegions[] = { - { ucHeap, configTOTAL_HEAP_SIZE }, - { NULL, 0 } - }; - #else - /* Global definition is provided to override default heap array */ - extern HeapRegion_t configHEAP_5_REGIONS[]; - #endif -#else - /* - The application already defined the array used for the FreeRTOS heap and - called vPortDefineHeapRegions to initialize heap. - */ - #define HEAP_5_REGION_SETUP 0 -#endif /* configAPPLICATION_ALLOCATED_HEAP */ -#endif /* USE_FreeRTOS_HEAP_5 */ - -/* - Setup SVC to reset value. -*/ -__STATIC_INLINE void SVC_Setup (void) { -#if (__ARM_ARCH_7A__ == 0U) - /* Service Call interrupt might be configured before kernel start */ - /* and when its priority is lower or equal to BASEPRI, svc intruction */ - /* causes a Hard Fault. */ - NVIC_SetPriority (SVCall_IRQn, 0U); -#endif -} - -/* - Function macro used to retrieve semaphore count from ISR -*/ -#ifndef uxSemaphoreGetCountFromISR -#define uxSemaphoreGetCountFromISR( xSemaphore ) uxQueueMessagesWaitingFromISR( ( QueueHandle_t ) ( xSemaphore ) ) -#endif - -/* - Determine if CPU executes from interrupt context or if interrupts are masked. -*/ -__STATIC_INLINE uint32_t IRQ_Context (void) { - uint32_t irq; - BaseType_t state; - - irq = 0U; - - if (IS_IRQ_MODE()) { - /* Called from interrupt context */ - irq = 1U; - } - else { - /* Get FreeRTOS scheduler state */ - state = xTaskGetSchedulerState(); - - if (state != taskSCHEDULER_NOT_STARTED) { - /* Scheduler was started */ - if (IS_IRQ_MASKED()) { - /* Interrupts are masked */ - irq = 1U; - } - } - } - - /* Return context, 0: thread context, 1: IRQ context */ - return (irq); -} - - -/* ==== Kernel Management Functions ==== */ - -/* - Initialize the RTOS Kernel. -*/ -osStatus_t osKernelInitialize (void) { - osStatus_t stat; - BaseType_t state; - - if (IRQ_Context() != 0U) { - stat = osErrorISR; - } - else { - state = xTaskGetSchedulerState(); - - /* Initialize if scheduler not started and not initialized before */ - if ((state == taskSCHEDULER_NOT_STARTED) && (KernelState == osKernelInactive)) { - #if defined(USE_TRACE_EVENT_RECORDER) - /* Initialize the trace macro debugging output channel */ - EvrFreeRTOSSetup(0U); - #endif - #if defined(USE_FreeRTOS_HEAP_5) && (HEAP_5_REGION_SETUP == 1) - /* Initialize the memory regions when using heap_5 variant */ - vPortDefineHeapRegions (configHEAP_5_REGIONS); - #endif - KernelState = osKernelReady; - stat = osOK; - } else { - stat = osError; - } - } - - /* Return execution status */ - return (stat); -} - -/* - Get RTOS Kernel Information. -*/ -osStatus_t osKernelGetInfo (osVersion_t *version, char *id_buf, uint32_t id_size) { - - if (version != NULL) { - /* Version encoding is major.minor.rev: mmnnnrrrr dec */ - version->api = KERNEL_VERSION; - version->kernel = KERNEL_VERSION; - } - - if ((id_buf != NULL) && (id_size != 0U)) { - /* Buffer for retrieving identification string is provided */ - if (id_size > sizeof(KERNEL_ID)) { - id_size = sizeof(KERNEL_ID); - } - /* Copy kernel identification string into provided buffer */ - memcpy(id_buf, KERNEL_ID, id_size); - } - - /* Return execution status */ - return (osOK); -} - -/* - Get the current RTOS Kernel state. -*/ -osKernelState_t osKernelGetState (void) { - osKernelState_t state; - - switch (xTaskGetSchedulerState()) { - case taskSCHEDULER_RUNNING: - state = osKernelRunning; - break; - - case taskSCHEDULER_SUSPENDED: - state = osKernelLocked; - break; - - case taskSCHEDULER_NOT_STARTED: - default: - if (KernelState == osKernelReady) { - /* Ready, osKernelInitialize was already called */ - state = osKernelReady; - } else { - /* Not initialized */ - state = osKernelInactive; - } - break; - } - - /* Return current state */ - return (state); -} - -/* - Start the RTOS Kernel scheduler. -*/ -osStatus_t osKernelStart (void) { - osStatus_t stat; - BaseType_t state; - - if (IRQ_Context() != 0U) { - stat = osErrorISR; - } - else { - state = xTaskGetSchedulerState(); - - /* Start scheduler if initialized and not started before */ - if ((state == taskSCHEDULER_NOT_STARTED) && (KernelState == osKernelReady)) { - /* Ensure SVC priority is at the reset value */ - SVC_Setup(); - /* Change state to ensure correct API flow */ - KernelState = osKernelRunning; - /* Start the kernel scheduler */ - vTaskStartScheduler(); - stat = osOK; - } else { - stat = osError; - } - } - - /* Return execution status */ - return (stat); -} - -/* - Lock the RTOS Kernel scheduler. -*/ -int32_t osKernelLock (void) { - int32_t lock; - - if (IRQ_Context() != 0U) { - lock = (int32_t)osErrorISR; - } - else { - switch (xTaskGetSchedulerState()) { - case taskSCHEDULER_SUSPENDED: - lock = 1; - break; - - case taskSCHEDULER_RUNNING: - vTaskSuspendAll(); - lock = 0; - break; - - case taskSCHEDULER_NOT_STARTED: - default: - lock = (int32_t)osError; - break; - } - } - - /* Return previous lock state */ - return (lock); -} - -/* - Unlock the RTOS Kernel scheduler. -*/ -int32_t osKernelUnlock (void) { - int32_t lock; - - if (IRQ_Context() != 0U) { - lock = (int32_t)osErrorISR; - } - else { - switch (xTaskGetSchedulerState()) { - case taskSCHEDULER_SUSPENDED: - lock = 1; - - if (xTaskResumeAll() != pdTRUE) { - if (xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED) { - lock = (int32_t)osError; - } - } - break; - - case taskSCHEDULER_RUNNING: - lock = 0; - break; - - case taskSCHEDULER_NOT_STARTED: - default: - lock = (int32_t)osError; - break; - } - } - - /* Return previous lock state */ - return (lock); -} - -/* - Restore the RTOS Kernel scheduler lock state. -*/ -int32_t osKernelRestoreLock (int32_t lock) { - - if (IRQ_Context() != 0U) { - lock = (int32_t)osErrorISR; - } - else { - switch (xTaskGetSchedulerState()) { - case taskSCHEDULER_SUSPENDED: - case taskSCHEDULER_RUNNING: - if (lock == 1) { - vTaskSuspendAll(); - } - else { - if (lock != 0) { - lock = (int32_t)osError; - } - else { - if (xTaskResumeAll() != pdTRUE) { - if (xTaskGetSchedulerState() != taskSCHEDULER_RUNNING) { - lock = (int32_t)osError; - } - } - } - } - break; - - case taskSCHEDULER_NOT_STARTED: - default: - lock = (int32_t)osError; - break; - } - } - - /* Return new lock state */ - return (lock); -} - -/* - Get the RTOS kernel tick count. -*/ -uint32_t osKernelGetTickCount (void) { - TickType_t ticks; - - if (IRQ_Context() != 0U) { - ticks = xTaskGetTickCountFromISR(); - } else { - ticks = xTaskGetTickCount(); - } - - /* Return kernel tick count */ - return (ticks); -} - -/* - Get the RTOS kernel tick frequency. -*/ -uint32_t osKernelGetTickFreq (void) { - /* Return frequency in hertz */ - return (configTICK_RATE_HZ); -} - -/* - Get the RTOS kernel system timer frequency. -*/ -uint32_t osKernelGetSysTimerFreq (void) { - /* Return frequency in hertz */ - return (configCPU_CLOCK_HZ); -} - -/* ==== Generic Wait Functions ==== */ - -/* - Wait for Timeout (Time Delay). -*/ -osStatus_t osDelay (uint32_t ticks) { - osStatus_t stat; - - if (IRQ_Context() != 0U) { - stat = osErrorISR; - } - else { - stat = osOK; - - if (ticks != 0U) { - vTaskDelay(ticks); - } - } - - /* Return execution status */ - return (stat); -} - -/* - Wait until specified time. -*/ -osStatus_t osDelayUntil (uint32_t ticks) { - TickType_t tcnt, delay; - osStatus_t stat; - - if (IRQ_Context() != 0U) { - stat = osErrorISR; - } - else { - stat = osOK; - tcnt = xTaskGetTickCount(); - - /* Determine remaining number of ticks to delay */ - delay = (TickType_t)ticks - tcnt; - - /* Check if target tick has not expired */ - if((delay != 0U) && (0 == (delay >> (8 * sizeof(TickType_t) - 1)))) { - if (xTaskDelayUntil (&tcnt, delay) == pdFALSE) { - /* Did not delay */ - stat = osError; - } - } - else - { - /* No delay or already expired */ - stat = osErrorParameter; - } - } - - /* Return execution status */ - return (stat); -} - - -/* ==== Timer Management Functions ==== */ - -#if (configUSE_OS2_TIMER == 1) - -static void TimerCallback (TimerHandle_t hTimer) { - TimerCallback_t *callb; - - /* Retrieve pointer to callback function and argument */ - callb = (TimerCallback_t *)pvTimerGetTimerID (hTimer); - - /* Remove dynamic allocation flag */ - callb = (TimerCallback_t *)((uint32_t)callb & ~1U); - - if (callb != NULL) { - callb->func (callb->arg); - } -} - -/* - Create and Initialize a timer. -*/ -osTimerId_t osTimerNew (osTimerFunc_t func, osTimerType_t type, void *argument, const osTimerAttr_t *attr) { - const char *name; - TimerHandle_t hTimer; - TimerCallback_t *callb; - UBaseType_t reload; - int32_t mem; - uint32_t callb_dyn; - - hTimer = NULL; - - if ((IRQ_Context() == 0U) && (func != NULL)) { - callb = NULL; - callb_dyn = 0U; - - #if (configSUPPORT_STATIC_ALLOCATION == 1) - /* Static memory allocation is available: check if memory for control block */ - /* is provided and if it also contains space for callback and its argument */ - if ((attr != NULL) && (attr->cb_mem != NULL)) { - if (attr->cb_size >= (sizeof(StaticTimer_t) + sizeof(TimerCallback_t))) { - callb = (TimerCallback_t *)((uint32_t)attr->cb_mem + sizeof(StaticTimer_t)); - } - } - #endif - - #if (configSUPPORT_DYNAMIC_ALLOCATION == 1) - /* Dynamic memory allocation is available: if memory for callback and */ - /* its argument is not provided, allocate it from dynamic memory pool */ - if (callb == NULL) { - callb = (TimerCallback_t *)pvPortMalloc (sizeof(TimerCallback_t)); - - if (callb != NULL) { - /* Callback memory was allocated from dynamic pool, set flag */ - callb_dyn = 1U; - } - } - #endif - - if (callb != NULL) { - callb->func = func; - callb->arg = argument; - - if (type == osTimerOnce) { - reload = pdFALSE; - } else { - reload = pdTRUE; - } - - mem = -1; - name = NULL; - - if (attr != NULL) { - if (attr->name != NULL) { - name = attr->name; - } - - if ((attr->cb_mem != NULL) && (attr->cb_size >= sizeof(StaticTimer_t))) { - /* The memory for control block is provided, use static object */ - mem = 1; - } - else { - if ((attr->cb_mem == NULL) && (attr->cb_size == 0U)) { - /* Control block will be allocated from the dynamic pool */ - mem = 0; - } - } - } - else { - mem = 0; - } - /* Store callback memory dynamic allocation flag */ - callb = (TimerCallback_t *)((uint32_t)callb | callb_dyn); - /* - TimerCallback function is always provided as a callback and is used to call application - specified function with its argument both stored in structure callb. - */ - if (mem == 1) { - #if (configSUPPORT_STATIC_ALLOCATION == 1) - hTimer = xTimerCreateStatic (name, 1, reload, callb, TimerCallback, (StaticTimer_t *)attr->cb_mem); - #endif - } - else { - if (mem == 0) { - #if (configSUPPORT_DYNAMIC_ALLOCATION == 1) - hTimer = xTimerCreate (name, 1, reload, callb, TimerCallback); - #endif - } - } - - #if (configSUPPORT_DYNAMIC_ALLOCATION == 1) - if ((hTimer == NULL) && (callb != NULL) && (callb_dyn == 1U)) { - /* Failed to create a timer, release allocated resources */ - callb = (TimerCallback_t *)((uint32_t)callb & ~1U); - - vPortFree (callb); - } - #endif - } - } - - /* Return timer ID */ - return ((osTimerId_t)hTimer); -} - -/* - Get name of a timer. -*/ -const char *osTimerGetName (osTimerId_t timer_id) { - TimerHandle_t hTimer = (TimerHandle_t)timer_id; - const char *p; - - if ((IRQ_Context() != 0U) || (hTimer == NULL)) { - p = NULL; - } else { - p = pcTimerGetName (hTimer); - } - - /* Return name as null-terminated string */ - return (p); -} - -/* - Start or restart a timer. -*/ -osStatus_t osTimerStart (osTimerId_t timer_id, uint32_t ticks) { - TimerHandle_t hTimer = (TimerHandle_t)timer_id; - osStatus_t stat; - - if (IRQ_Context() != 0U) { - stat = osErrorISR; - } - else if (hTimer == NULL) { - stat = osErrorParameter; - } - else { - if (xTimerChangePeriod (hTimer, ticks, portMAX_DELAY) == pdPASS) { - stat = osOK; - } else { - stat = osErrorResource; - } - } - - /* Return execution status */ - return (stat); -} - -/* - Stop a timer. -*/ -osStatus_t osTimerStop (osTimerId_t timer_id) { - TimerHandle_t hTimer = (TimerHandle_t)timer_id; - osStatus_t stat; - - if (IRQ_Context() != 0U) { - stat = osErrorISR; - } - else if (hTimer == NULL) { - stat = osErrorParameter; - } - else { - if (xTimerIsTimerActive (hTimer) == pdFALSE) { - stat = osErrorResource; - } - else { - if (xTimerStop (hTimer, portMAX_DELAY) == pdPASS) { - stat = osOK; - } else { - stat = osError; - } - } - } - - /* Return execution status */ - return (stat); -} - -/* - Check if a timer is running. -*/ -uint32_t osTimerIsRunning (osTimerId_t timer_id) { - TimerHandle_t hTimer = (TimerHandle_t)timer_id; - uint32_t running; - - if ((IRQ_Context() != 0U) || (hTimer == NULL)) { - running = 0U; - } else { - running = (uint32_t)xTimerIsTimerActive (hTimer); - } - - /* Return 0: not running, 1: running */ - return (running); -} - -/* - Delete a timer. -*/ -osStatus_t osTimerDelete (osTimerId_t timer_id) { - TimerHandle_t hTimer = (TimerHandle_t)timer_id; - osStatus_t stat; -#ifndef USE_FreeRTOS_HEAP_1 -#if (configSUPPORT_DYNAMIC_ALLOCATION == 1) - TimerCallback_t *callb; -#endif - - if (IRQ_Context() != 0U) { - stat = osErrorISR; - } - else if (hTimer == NULL) { - stat = osErrorParameter; - } - else { - #if (configSUPPORT_DYNAMIC_ALLOCATION == 1) - callb = (TimerCallback_t *)pvTimerGetTimerID (hTimer); - #endif - - if (xTimerDelete (hTimer, portMAX_DELAY) == pdPASS) { - #if (configSUPPORT_DYNAMIC_ALLOCATION == 1) - if ((uint32_t)callb & 1U) { - /* Callback memory was allocated from dynamic pool, clear flag */ - callb = (TimerCallback_t *)((uint32_t)callb & ~1U); - - /* Return allocated memory to dynamic pool */ - vPortFree (callb); - } - #endif - stat = osOK; - } else { - stat = osErrorResource; - } - } -#else - stat = osError; -#endif - - /* Return execution status */ - return (stat); -} -#endif /* (configUSE_OS2_TIMER == 1) */ - - -/* ==== Message Queue Management Functions ==== */ - -/* - Create and Initialize a Message Queue object. - - Limitations: - - The memory for control block and and message data must be provided in the - osThreadAttr_t structure in order to allocate object statically. -*/ -osMessageQueueId_t osMessageQueueNew (uint32_t msg_count, uint32_t msg_size, const osMessageQueueAttr_t *attr) { - QueueHandle_t hQueue; - int32_t mem; - - hQueue = NULL; - - if ((IRQ_Context() == 0U) && (msg_count > 0U) && (msg_size > 0U)) { - mem = -1; - - if (attr != NULL) { - if ((attr->cb_mem != NULL) && (attr->cb_size >= sizeof(StaticQueue_t)) && - (attr->mq_mem != NULL) && (attr->mq_size >= (msg_count * msg_size))) { - /* The memory for control block and message data is provided, use static object */ - mem = 1; - } - else { - if ((attr->cb_mem == NULL) && (attr->cb_size == 0U) && - (attr->mq_mem == NULL) && (attr->mq_size == 0U)) { - /* Control block will be allocated from the dynamic pool */ - mem = 0; - } - } - } - else { - mem = 0; - } - - if (mem == 1) { - #if (configSUPPORT_STATIC_ALLOCATION == 1) - hQueue = xQueueCreateStatic (msg_count, msg_size, attr->mq_mem, attr->cb_mem); - #endif - } - else { - if (mem == 0) { - #if (configSUPPORT_DYNAMIC_ALLOCATION == 1) - hQueue = xQueueCreate (msg_count, msg_size); - #endif - } - } - - #if (configQUEUE_REGISTRY_SIZE > 0) - if (hQueue != NULL) { - if ((attr != NULL) && (attr->name != NULL)) { - /* Only non-NULL name objects are added to the Queue Registry */ - vQueueAddToRegistry (hQueue, attr->name); - } - } - #endif - - } - - /* Return message queue ID */ - return ((osMessageQueueId_t)hQueue); -} - -/* - Put a Message into a Queue or timeout if Queue is full. - - Limitations: - - Message priority is ignored -*/ -osStatus_t osMessageQueuePut (osMessageQueueId_t mq_id, const void *msg_ptr, uint8_t msg_prio, uint32_t timeout) { - QueueHandle_t hQueue = (QueueHandle_t)mq_id; - osStatus_t stat; - BaseType_t yield; - - (void)msg_prio; /* Message priority is ignored */ - - stat = osOK; - - if (IRQ_Context() != 0U) { - if ((hQueue == NULL) || (msg_ptr == NULL) || (timeout != 0U)) { - stat = osErrorParameter; - } - else { - yield = pdFALSE; - - if (xQueueSendToBackFromISR (hQueue, msg_ptr, &yield) != pdTRUE) { - stat = osErrorResource; - } else { - portYIELD_FROM_ISR (yield); - } - } - } - else { - if ((hQueue == NULL) || (msg_ptr == NULL)) { - stat = osErrorParameter; - } - else { - if (xQueueSendToBack (hQueue, msg_ptr, (TickType_t)timeout) != pdPASS) { - if (timeout != 0U) { - stat = osErrorTimeout; - } else { - stat = osErrorResource; - } - } - } - } - - /* Return execution status */ - return (stat); -} - -/* - Get a Message from a Queue or timeout if Queue is empty. - - Limitations: - - Message priority is ignored -*/ -osStatus_t osMessageQueueGet (osMessageQueueId_t mq_id, void *msg_ptr, uint8_t *msg_prio, uint32_t timeout) { - QueueHandle_t hQueue = (QueueHandle_t)mq_id; - osStatus_t stat; - BaseType_t yield; - - (void)msg_prio; /* Message priority is ignored */ - - stat = osOK; - - if (IRQ_Context() != 0U) { - if ((hQueue == NULL) || (msg_ptr == NULL) || (timeout != 0U)) { - stat = osErrorParameter; - } - else { - yield = pdFALSE; - - if (xQueueReceiveFromISR (hQueue, msg_ptr, &yield) != pdPASS) { - stat = osErrorResource; - } else { - portYIELD_FROM_ISR (yield); - } - } - } - else { - if ((hQueue == NULL) || (msg_ptr == NULL)) { - stat = osErrorParameter; - } - else { - if (xQueueReceive (hQueue, msg_ptr, (TickType_t)timeout) != pdPASS) { - if (timeout != 0U) { - stat = osErrorTimeout; - } else { - stat = osErrorResource; - } - } - } - } - - /* Return execution status */ - return (stat); -} - -/* - Get maximum number of messages in a Message Queue. -*/ -uint32_t osMessageQueueGetCapacity (osMessageQueueId_t mq_id) { - StaticQueue_t *mq = (StaticQueue_t *)mq_id; - uint32_t capacity; - - if (mq == NULL) { - capacity = 0U; - } else { - /* capacity = pxQueue->uxLength */ - capacity = mq->uxDummy4[1]; - } - - /* Return maximum number of messages */ - return (capacity); -} - -/* - Get maximum message size in a Message Queue. -*/ -uint32_t osMessageQueueGetMsgSize (osMessageQueueId_t mq_id) { - StaticQueue_t *mq = (StaticQueue_t *)mq_id; - uint32_t size; - - if (mq == NULL) { - size = 0U; - } else { - /* size = pxQueue->uxItemSize */ - size = mq->uxDummy4[2]; - } - - /* Return maximum message size */ - return (size); -} - -/* - Get number of queued messages in a Message Queue. -*/ -uint32_t osMessageQueueGetCount (osMessageQueueId_t mq_id) { - QueueHandle_t hQueue = (QueueHandle_t)mq_id; - UBaseType_t count; - - if (hQueue == NULL) { - count = 0U; - } - else if (IRQ_Context() != 0U) { - count = uxQueueMessagesWaitingFromISR (hQueue); - } - else { - count = uxQueueMessagesWaiting (hQueue); - } - - /* Return number of queued messages */ - return ((uint32_t)count); -} - -/* - Get number of available slots for messages in a Message Queue. -*/ -uint32_t osMessageQueueGetSpace (osMessageQueueId_t mq_id) { - StaticQueue_t *mq = (StaticQueue_t *)mq_id; - uint32_t space; - uint32_t isrm; - - if (mq == NULL) { - space = 0U; - } - else if (IRQ_Context() != 0U) { - isrm = taskENTER_CRITICAL_FROM_ISR(); - - /* space = pxQueue->uxLength - pxQueue->uxMessagesWaiting; */ - space = mq->uxDummy4[1] - mq->uxDummy4[0]; - - taskEXIT_CRITICAL_FROM_ISR(isrm); - } - else { - space = (uint32_t)uxQueueSpacesAvailable ((QueueHandle_t)mq); - } - - /* Return number of available slots */ - return (space); -} - -/* - Reset a Message Queue to initial empty state. -*/ -osStatus_t osMessageQueueReset (osMessageQueueId_t mq_id) { - QueueHandle_t hQueue = (QueueHandle_t)mq_id; - osStatus_t stat; - - if (IRQ_Context() != 0U) { - stat = osErrorISR; - } - else if (hQueue == NULL) { - stat = osErrorParameter; - } - else { - stat = osOK; - (void)xQueueReset (hQueue); - } - - /* Return execution status */ - return (stat); -} - -/* - Delete a Message Queue object. -*/ -osStatus_t osMessageQueueDelete (osMessageQueueId_t mq_id) { - QueueHandle_t hQueue = (QueueHandle_t)mq_id; - osStatus_t stat; - -#ifndef USE_FreeRTOS_HEAP_1 - if (IRQ_Context() != 0U) { - stat = osErrorISR; - } - else if (hQueue == NULL) { - stat = osErrorParameter; - } - else { - #if (configQUEUE_REGISTRY_SIZE > 0) - vQueueUnregisterQueue (hQueue); - #endif - - stat = osOK; - vQueueDelete (hQueue); - } -#else - stat = osError; -#endif - - /* Return execution status */ - return (stat); -} - -/* Callback function prototypes */ -extern void vApplicationIdleHook (void); -extern void vApplicationMallocFailedHook (void); -extern void vApplicationDaemonTaskStartupHook (void); - -/** - Dummy implementation of the callback function vApplicationIdleHook(). -*/ -#if (configUSE_IDLE_HOOK == 1) -__WEAK void vApplicationIdleHook (void){} -#endif - -/** - Dummy implementation of the callback function vApplicationTickHook(). -*/ -#if (configUSE_TICK_HOOK == 1) - __WEAK void vApplicationTickHook (void){} -#endif - -/** - Dummy implementation of the callback function vApplicationMallocFailedHook(). -*/ -#if (configUSE_MALLOC_FAILED_HOOK == 1) -__WEAK void vApplicationMallocFailedHook (void) { - /* Assert when malloc failed hook is enabled but no application defined function exists */ - configASSERT(0); -} -#endif - -/** - Dummy implementation of the callback function vApplicationDaemonTaskStartupHook(). -*/ -#if (configUSE_DAEMON_TASK_STARTUP_HOOK == 1) -__WEAK void vApplicationDaemonTaskStartupHook (void){} -#endif - -/** - Dummy implementation of the callback function vApplicationStackOverflowHook(). -*/ -#if (configCHECK_FOR_STACK_OVERFLOW > 0) -__WEAK void vApplicationStackOverflowHook (TaskHandle_t xTask, char *pcTaskName) { - (void)xTask; - (void)pcTaskName; - - /* Assert when stack overflow is enabled but no application defined function exists */ - configASSERT(0); -} -#endif diff --git a/lib/FreeRTOS-glue/cmsis_os2.h b/lib/FreeRTOS-glue/cmsis_os2.h deleted file mode 100644 index 044c9851..00000000 --- a/lib/FreeRTOS-glue/cmsis_os2.h +++ /dev/null @@ -1,302 +0,0 @@ -/* - * Copyright (c) 2013-2020 Arm Limited. All rights reserved. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the License); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ---------------------------------------------------------------------- - * - * $Date: 12. June 2020 - * $Revision: V2.1.3 - * - * Project: CMSIS-RTOS2 API - * Title: cmsis_os2.h header file - * - * Version 2.1.3 - * Additional functions allowed to be called from Interrupt Service Routines: - * - osThreadGetId - * Version 2.1.2 - * Additional functions allowed to be called from Interrupt Service Routines: - * - osKernelGetInfo, osKernelGetState - * Version 2.1.1 - * Additional functions allowed to be called from Interrupt Service Routines: - * - osKernelGetTickCount, osKernelGetTickFreq - * Changed Kernel Tick type to uint32_t: - * - updated: osKernelGetTickCount, osDelayUntil - * Version 2.1.0 - * Support for critical and uncritical sections (nesting safe): - * - updated: osKernelLock, osKernelUnlock - * - added: osKernelRestoreLock - * Updated Thread and Event Flags: - * - changed flags parameter and return type from int32_t to uint32_t - * Version 2.0.0 - * Initial Release - *---------------------------------------------------------------------------*/ - -#ifndef CMSIS_OS2_H_ -#define CMSIS_OS2_H_ - -#ifndef __NO_RETURN -#if defined(__CC_ARM) -#define __NO_RETURN __declspec(noreturn) -#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) -#define __NO_RETURN __attribute__((__noreturn__)) -#elif defined(__GNUC__) -#define __NO_RETURN __attribute__((__noreturn__)) -#elif defined(__ICCARM__) -#define __NO_RETURN __noreturn -#else -#define __NO_RETURN -#endif -#endif - -#include - -#ifdef __cplusplus -extern "C" -{ -#endif - - -// ==== Enumerations, structures, defines ==== - -/// Version information. -typedef struct { - uint32_t api; ///< API version (major.minor.rev: mmnnnrrrr dec). - uint32_t kernel; ///< Kernel version (major.minor.rev: mmnnnrrrr dec). -} osVersion_t; - -/// Kernel state. -typedef enum { - osKernelInactive = 0, ///< Inactive. - osKernelReady = 1, ///< Ready. - osKernelRunning = 2, ///< Running. - osKernelLocked = 3, ///< Locked. - osKernelSuspended = 4, ///< Suspended. - osKernelError = -1, ///< Error. - osKernelReserved = 0x7FFFFFFF ///< Prevents enum down-size compiler optimization. -} osKernelState_t; - -/// Timer callback function. -typedef void (*osTimerFunc_t) (void *argument); - -/// Timer type. -typedef enum { - osTimerOnce = 0, ///< One-shot timer. - osTimerPeriodic = 1 ///< Repeating timer. -} osTimerType_t; - - -/// \details Timer ID identifies the timer. -typedef void *osTimerId_t; - -/// \details Message Queue ID identifies the message queue. -typedef void *osMessageQueueId_t; - - -#ifndef TZ_MODULEID_T -#define TZ_MODULEID_T -/// \details Data type that identifies secure software modules called by a process. -typedef uint32_t TZ_ModuleId_t; -#endif - - -/// Attributes structure for timer. -typedef struct { - const char *name; ///< name of the timer - uint32_t attr_bits; ///< attribute bits - void *cb_mem; ///< memory for control block - uint32_t cb_size; ///< size of provided memory for control block -} osTimerAttr_t; - -/// Attributes structure for message queue. -typedef struct { - const char *name; ///< name of the message queue - uint32_t attr_bits; ///< attribute bits - void *cb_mem; ///< memory for control block - uint32_t cb_size; ///< size of provided memory for control block - void *mq_mem; ///< memory for data storage - uint32_t mq_size; ///< size of provided memory for data storage -} osMessageQueueAttr_t; - - -// ==== Kernel Management Functions ==== - -/// Initialize the RTOS Kernel. -/// \return status code that indicates the execution status of the function. -osStatus_t osKernelInitialize (void); - -/// Get RTOS Kernel Information. -/// \param[out] version pointer to buffer for retrieving version information. -/// \param[out] id_buf pointer to buffer for retrieving kernel identification string. -/// \param[in] id_size size of buffer for kernel identification string. -/// \return status code that indicates the execution status of the function. -osStatus_t osKernelGetInfo (osVersion_t *version, char *id_buf, uint32_t id_size); - -/// Get the current RTOS Kernel state. -/// \return current RTOS Kernel state. -osKernelState_t osKernelGetState (void); - -/// Start the RTOS Kernel scheduler. -/// \return status code that indicates the execution status of the function. -osStatus_t osKernelStart (void); - -/// Lock the RTOS Kernel scheduler. -/// \return previous lock state (1 - locked, 0 - not locked, error code if negative). -int32_t osKernelLock (void); - -/// Unlock the RTOS Kernel scheduler. -/// \return previous lock state (1 - locked, 0 - not locked, error code if negative). -int32_t osKernelUnlock (void); - -/// Restore the RTOS Kernel scheduler lock state. -/// \param[in] lock lock state obtained by \ref osKernelLock or \ref osKernelUnlock. -/// \return new lock state (1 - locked, 0 - not locked, error code if negative). -int32_t osKernelRestoreLock (int32_t lock); - -/// Suspend the RTOS Kernel scheduler. -/// \return time in ticks, for how long the system can sleep or power-down. -uint32_t osKernelSuspend (void); - -/// Resume the RTOS Kernel scheduler. -/// \param[in] sleep_ticks time in ticks for how long the system was in sleep or power-down mode. -void osKernelResume (uint32_t sleep_ticks); - -/// Get the RTOS kernel tick count. -/// \return RTOS kernel current tick count. -uint32_t osKernelGetTickCount (void); - -/// Get the RTOS kernel tick frequency. -/// \return frequency of the kernel tick in hertz, i.e. kernel ticks per second. -uint32_t osKernelGetTickFreq (void); - -/// Get the RTOS kernel system timer frequency. -/// \return frequency of the system timer in hertz, i.e. timer ticks per second. -uint32_t osKernelGetSysTimerFreq (void); - -// ==== Generic Wait Functions ==== - -/// Wait for Timeout (Time Delay). -/// \param[in] ticks \ref CMSIS_RTOS_TimeOutValue "time ticks" value -/// \return status code that indicates the execution status of the function. -osStatus_t osDelay (uint32_t ticks); - -/// Wait until specified time. -/// \param[in] ticks absolute time in ticks -/// \return status code that indicates the execution status of the function. -osStatus_t osDelayUntil (uint32_t ticks); - - -// ==== Timer Management Functions ==== - -/// Create and Initialize a timer. -/// \param[in] func function pointer to callback function. -/// \param[in] type \ref osTimerOnce for one-shot or \ref osTimerPeriodic for periodic behavior. -/// \param[in] argument argument to the timer callback function. -/// \param[in] attr timer attributes; NULL: default values. -/// \return timer ID for reference by other functions or NULL in case of error. -osTimerId_t osTimerNew (osTimerFunc_t func, osTimerType_t type, void *argument, const osTimerAttr_t *attr); - -/// Get name of a timer. -/// \param[in] timer_id timer ID obtained by \ref osTimerNew. -/// \return name as null-terminated string. -const char *osTimerGetName (osTimerId_t timer_id); - -/// Start or restart a timer. -/// \param[in] timer_id timer ID obtained by \ref osTimerNew. -/// \param[in] ticks \ref CMSIS_RTOS_TimeOutValue "time ticks" value of the timer. -/// \return status code that indicates the execution status of the function. -osStatus_t osTimerStart (osTimerId_t timer_id, uint32_t ticks); - -/// Stop a timer. -/// \param[in] timer_id timer ID obtained by \ref osTimerNew. -/// \return status code that indicates the execution status of the function. -osStatus_t osTimerStop (osTimerId_t timer_id); - -/// Check if a timer is running. -/// \param[in] timer_id timer ID obtained by \ref osTimerNew. -/// \return 0 not running, 1 running. -uint32_t osTimerIsRunning (osTimerId_t timer_id); - -/// Delete a timer. -/// \param[in] timer_id timer ID obtained by \ref osTimerNew. -/// \return status code that indicates the execution status of the function. -osStatus_t osTimerDelete (osTimerId_t timer_id); - -// ==== Message Queue Management Functions ==== - -/// Create and Initialize a Message Queue object. -/// \param[in] msg_count maximum number of messages in queue. -/// \param[in] msg_size maximum message size in bytes. -/// \param[in] attr message queue attributes; NULL: default values. -/// \return message queue ID for reference by other functions or NULL in case of error. -osMessageQueueId_t osMessageQueueNew (uint32_t msg_count, uint32_t msg_size, const osMessageQueueAttr_t *attr); - -/// Get name of a Message Queue object. -/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. -/// \return name as null-terminated string. -const char *osMessageQueueGetName (osMessageQueueId_t mq_id); - -/// Put a Message into a Queue or timeout if Queue is full. -/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. -/// \param[in] msg_ptr pointer to buffer with message to put into a queue. -/// \param[in] msg_prio message priority. -/// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. -/// \return status code that indicates the execution status of the function. -osStatus_t osMessageQueuePut (osMessageQueueId_t mq_id, const void *msg_ptr, uint8_t msg_prio, uint32_t timeout); - -/// Get a Message from a Queue or timeout if Queue is empty. -/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. -/// \param[out] msg_ptr pointer to buffer for message to get from a queue. -/// \param[out] msg_prio pointer to buffer for message priority or NULL. -/// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. -/// \return status code that indicates the execution status of the function. -osStatus_t osMessageQueueGet (osMessageQueueId_t mq_id, void *msg_ptr, uint8_t *msg_prio, uint32_t timeout); - -/// Get maximum number of messages in a Message Queue. -/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. -/// \return maximum number of messages. -uint32_t osMessageQueueGetCapacity (osMessageQueueId_t mq_id); - -/// Get maximum message size in a Message Queue. -/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. -/// \return maximum message size in bytes. -uint32_t osMessageQueueGetMsgSize (osMessageQueueId_t mq_id); - -/// Get number of queued messages in a Message Queue. -/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. -/// \return number of queued messages. -uint32_t osMessageQueueGetCount (osMessageQueueId_t mq_id); - -/// Get number of available slots for messages in a Message Queue. -/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. -/// \return number of available slots for messages. -uint32_t osMessageQueueGetSpace (osMessageQueueId_t mq_id); - -/// Reset a Message Queue to initial empty state. -/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. -/// \return status code that indicates the execution status of the function. -osStatus_t osMessageQueueReset (osMessageQueueId_t mq_id); - -/// Delete a Message Queue object. -/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. -/// \return status code that indicates the execution status of the function. -osStatus_t osMessageQueueDelete (osMessageQueueId_t mq_id); - - -#ifdef __cplusplus -} -#endif - -#endif // CMSIS_OS2_H_ diff --git a/lib/FreeRTOS-glue/freertos_os2.h b/lib/FreeRTOS-glue/freertos_os2.h deleted file mode 100644 index 1e70b3fc..00000000 --- a/lib/FreeRTOS-glue/freertos_os2.h +++ /dev/null @@ -1,319 +0,0 @@ -/* -------------------------------------------------------------------------- - * Copyright (c) 2013-2021 Arm Limited. All rights reserved. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the License); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Name: freertos_os2.h - * Purpose: CMSIS RTOS2 wrapper for FreeRTOS - * - *---------------------------------------------------------------------------*/ - -#ifndef FREERTOS_OS2_H_ -#define FREERTOS_OS2_H_ - -#include -#include - -#include "FreeRTOS.h" // ARM.FreeRTOS::RTOS:Core - -#if defined(_RTE_) -#include "RTE_Components.h" // Component selection -#include CMSIS_device_header - -/* Configuration and component setup check */ -#if defined(RTE_Compiler_EventRecorder) - #if !defined(EVR_FREERTOS_DISABLE) - #define USE_TRACE_EVENT_RECORDER - /* - FreeRTOS provides functions and hooks to support execution tracing. This - functionality is only enabled if configUSE_TRACE_FACILITY == 1. - Set #define configUSE_TRACE_FACILITY 1 in FreeRTOSConfig.h to enable trace events. - */ - #if (configUSE_TRACE_FACILITY == 0) - #error "Definition configUSE_TRACE_FACILITY must equal 1 to enable FreeRTOS trace events." - #endif - #endif -#endif - -#if defined(RTE_RTOS_FreeRTOS_HEAP_1) - #define USE_FreeRTOS_HEAP_1 -#endif - -#if defined(RTE_RTOS_FreeRTOS_HEAP_5) - #define USE_FreeRTOS_HEAP_5 -#endif -#endif /* _RTE_ */ - -/* - CMSIS-RTOS2 FreeRTOS image size optimization definitions. - - Note: Definitions configUSE_OS2 can be used to optimize FreeRTOS image size when - certain functionality is not required when using CMSIS-RTOS2 API. - In general optimization decisions are left to the tool chain but in cases - when coding style prevents it to optimize the code following optional - definitions can be used. -*/ - -/* - Option to exclude CMSIS-RTOS2 functions osThreadSuspend and osThreadResume from - the application image. -*/ -#ifndef configUSE_OS2_THREAD_SUSPEND_RESUME -#define configUSE_OS2_THREAD_SUSPEND_RESUME 1 -#endif - -/* - Option to exclude CMSIS-RTOS2 function furi_thread_enumerate from the application image. -*/ -#ifndef configUSE_OS2_THREAD_ENUMERATE -#define configUSE_OS2_THREAD_ENUMERATE 1 -#endif - -/* - Option to disable CMSIS-RTOS2 function osEventFlagsSet and osEventFlagsClear - operation from ISR. -*/ -#ifndef configUSE_OS2_EVENTFLAGS_FROM_ISR -#define configUSE_OS2_EVENTFLAGS_FROM_ISR 1 -#endif - -/* - Option to exclude CMSIS-RTOS2 Thread Flags API functions from the application image. -*/ -#ifndef configUSE_OS2_THREAD_FLAGS -#define configUSE_OS2_THREAD_FLAGS configUSE_TASK_NOTIFICATIONS -#endif - -/* - Option to exclude CMSIS-RTOS2 Timer API functions from the application image. -*/ -#ifndef configUSE_OS2_TIMER -#define configUSE_OS2_TIMER configUSE_TIMERS -#endif - -/* - Option to exclude CMSIS-RTOS2 Mutex API functions from the application image. -*/ -#ifndef configUSE_OS2_MUTEX -#define configUSE_OS2_MUTEX configUSE_MUTEXES -#endif - - -/* - CMSIS-RTOS2 FreeRTOS configuration check (FreeRTOSConfig.h). - - Note: CMSIS-RTOS API requires functions included by using following definitions. - In case if certain API function is not used compiler will optimize it away. -*/ -#if (INCLUDE_xSemaphoreGetMutexHolder == 0) - /* - CMSIS-RTOS2 function osMutexGetOwner uses FreeRTOS function xSemaphoreGetMutexHolder. In case if - osMutexGetOwner is not used in the application image, compiler will optimize it away. - Set #define INCLUDE_xSemaphoreGetMutexHolder 1 to fix this error. - */ - #error "Definition INCLUDE_xSemaphoreGetMutexHolder must equal 1 to implement Mutex Management API." -#endif -#if (INCLUDE_vTaskDelay == 0) - /* - CMSIS-RTOS2 function osDelay uses FreeRTOS function vTaskDelay. In case if - osDelay is not used in the application image, compiler will optimize it away. - Set #define INCLUDE_vTaskDelay 1 to fix this error. - */ - #error "Definition INCLUDE_vTaskDelay must equal 1 to implement Generic Wait Functions API." -#endif -#if (INCLUDE_xTaskDelayUntil == 0) - /* - CMSIS-RTOS2 function osDelayUntil uses FreeRTOS function xTaskDelayUntil. In case if - osDelayUntil is not used in the application image, compiler will optimize it away. - Set #define INCLUDE_xTaskDelayUntil 1 to fix this error. - */ - #error "Definition INCLUDE_xTaskDelayUntil must equal 1 to implement Generic Wait Functions API." -#endif -#if (INCLUDE_vTaskDelete == 0) - /* - CMSIS-RTOS2 function osThreadTerminate and osThreadExit uses FreeRTOS function - vTaskDelete. In case if they are not used in the application image, compiler - will optimize them away. - Set #define INCLUDE_vTaskDelete 1 to fix this error. - */ - #error "Definition INCLUDE_vTaskDelete must equal 1 to implement Thread Management API." -#endif -#if (INCLUDE_xTaskGetCurrentTaskHandle == 0) - /* - CMSIS-RTOS2 API uses FreeRTOS function xTaskGetCurrentTaskHandle to implement - functions osThreadGetId, furi_thread_flags_clear and furi_thread_flags_get. In case if these - functions are not used in the application image, compiler will optimize them away. - Set #define INCLUDE_xTaskGetCurrentTaskHandle 1 to fix this error. - */ - #error "Definition INCLUDE_xTaskGetCurrentTaskHandle must equal 1 to implement Thread Management API." -#endif -#if (INCLUDE_xTaskGetSchedulerState == 0) - /* - CMSIS-RTOS2 API uses FreeRTOS function xTaskGetSchedulerState to implement Kernel - tick handling and therefore it is vital that xTaskGetSchedulerState is included into - the application image. - Set #define INCLUDE_xTaskGetSchedulerState 1 to fix this error. - */ - #error "Definition INCLUDE_xTaskGetSchedulerState must equal 1 to implement Kernel Information and Control API." -#endif -#if (INCLUDE_uxTaskGetStackHighWaterMark == 0) - /* - CMSIS-RTOS2 function furi_thread_get_stack_space uses FreeRTOS function uxTaskGetStackHighWaterMark. - In case if furi_thread_get_stack_space is not used in the application image, compiler will - optimize it away. - Set #define INCLUDE_uxTaskGetStackHighWaterMark 1 to fix this error. - */ - #error "Definition INCLUDE_uxTaskGetStackHighWaterMark must equal 1 to implement Thread Management API." -#endif -#if (INCLUDE_uxTaskPriorityGet == 0) - /* - CMSIS-RTOS2 function osThreadGetPriority uses FreeRTOS function uxTaskPriorityGet. In case if - osThreadGetPriority is not used in the application image, compiler will optimize it away. - Set #define INCLUDE_uxTaskPriorityGet 1 to fix this error. - */ - #error "Definition INCLUDE_uxTaskPriorityGet must equal 1 to implement Thread Management API." -#endif -#if (INCLUDE_vTaskPrioritySet == 0) - /* - CMSIS-RTOS2 function osThreadSetPriority uses FreeRTOS function vTaskPrioritySet. In case if - osThreadSetPriority is not used in the application image, compiler will optimize it away. - Set #define INCLUDE_vTaskPrioritySet 1 to fix this error. - */ - #error "Definition INCLUDE_vTaskPrioritySet must equal 1 to implement Thread Management API." -#endif -#if (INCLUDE_eTaskGetState == 0) - /* - CMSIS-RTOS2 API uses FreeRTOS function vTaskDelayUntil to implement functions osThreadGetState - and osThreadTerminate. In case if these functions are not used in the application image, - compiler will optimize them away. - Set #define INCLUDE_eTaskGetState 1 to fix this error. - */ - #error "Definition INCLUDE_eTaskGetState must equal 1 to implement Thread Management API." -#endif -#if (INCLUDE_vTaskSuspend == 0) - /* - CMSIS-RTOS2 API uses FreeRTOS functions vTaskSuspend and vTaskResume to implement - functions osThreadSuspend and osThreadResume. In case if these functions are not - used in the application image, compiler will optimize them away. - Set #define INCLUDE_vTaskSuspend 1 to fix this error. - - Alternatively, if the application does not use osThreadSuspend and - osThreadResume they can be excluded from the image code by setting: - #define configUSE_OS2_THREAD_SUSPEND_RESUME 0 (in FreeRTOSConfig.h) - */ - #if (configUSE_OS2_THREAD_SUSPEND_RESUME == 1) - #error "Definition INCLUDE_vTaskSuspend must equal 1 to implement Kernel Information and Control API." - #endif -#endif -#if (INCLUDE_xTimerPendFunctionCall == 0) - /* - CMSIS-RTOS2 function osEventFlagsSet and osEventFlagsClear, when called from - the ISR, call FreeRTOS functions xEventGroupSetBitsFromISR and - xEventGroupClearBitsFromISR which are only enabled if timers are operational and - xTimerPendFunctionCall in enabled. - Set #define INCLUDE_xTimerPendFunctionCall 1 and #define configUSE_TIMERS 1 - to fix this error. - - Alternatively, if the application does not use osEventFlagsSet and osEventFlagsClear - from the ISR their operation from ISR can be restricted by setting: - #define configUSE_OS2_EVENTFLAGS_FROM_ISR 0 (in FreeRTOSConfig.h) - */ - #if (configUSE_OS2_EVENTFLAGS_FROM_ISR == 1) - #error "Definition INCLUDE_xTimerPendFunctionCall must equal 1 to implement Event Flags API." - #endif -#endif - -#if (configUSE_TIMERS == 0) - /* - CMSIS-RTOS2 Timer Management API functions use FreeRTOS timer functions to implement - timer management. In case if these functions are not used in the application image, - compiler will optimize them away. - Set #define configUSE_TIMERS 1 to fix this error. - - Alternatively, if the application does not use timer functions they can be - excluded from the image code by setting: - #define configUSE_OS2_TIMER 0 (in FreeRTOSConfig.h) - */ - #if (configUSE_OS2_TIMER == 1) - #error "Definition configUSE_TIMERS must equal 1 to implement Timer Management API." - #endif -#endif - -#if (configUSE_MUTEXES == 0) - /* - CMSIS-RTOS2 Mutex Management API functions use FreeRTOS mutex functions to implement - mutex management. In case if these functions are not used in the application image, - compiler will optimize them away. - Set #define configUSE_MUTEXES 1 to fix this error. - - Alternatively, if the application does not use mutex functions they can be - excluded from the image code by setting: - #define configUSE_OS2_MUTEX 0 (in FreeRTOSConfig.h) - */ - #if (configUSE_OS2_MUTEX == 1) - #error "Definition configUSE_MUTEXES must equal 1 to implement Mutex Management API." - #endif -#endif - -#if (configUSE_COUNTING_SEMAPHORES == 0) - /* - CMSIS-RTOS2 Memory Pool functions use FreeRTOS function xSemaphoreCreateCounting - to implement memory pools. In case if these functions are not used in the application image, - compiler will optimize them away. - Set #define configUSE_COUNTING_SEMAPHORES 1 to fix this error. - */ - #error "Definition configUSE_COUNTING_SEMAPHORES must equal 1 to implement Memory Pool API." -#endif -#if (configUSE_TASK_NOTIFICATIONS == 0) - /* - CMSIS-RTOS2 Thread Flags API functions use FreeRTOS Task Notification functions to implement - thread flag management. In case if these functions are not used in the application image, - compiler will optimize them away. - Set #define configUSE_TASK_NOTIFICATIONS 1 to fix this error. - - Alternatively, if the application does not use thread flags functions they can be - excluded from the image code by setting: - #define configUSE_OS2_THREAD_FLAGS 0 (in FreeRTOSConfig.h) - */ - #if (configUSE_OS2_THREAD_FLAGS == 1) - #error "Definition configUSE_TASK_NOTIFICATIONS must equal 1 to implement Thread Flags API." - #endif -#endif - -#if (configUSE_TRACE_FACILITY == 0) - /* - CMSIS-RTOS2 function furi_thread_enumerate requires FreeRTOS function uxTaskGetSystemState - which is only enabled if configUSE_TRACE_FACILITY == 1. - Set #define configUSE_TRACE_FACILITY 1 to fix this error. - - Alternatively, if the application does not use furi_thread_enumerate it can be - excluded from the image code by setting: - #define configUSE_OS2_THREAD_ENUMERATE 0 (in FreeRTOSConfig.h) - */ - #if (configUSE_OS2_THREAD_ENUMERATE == 1) - #error "Definition configUSE_TRACE_FACILITY must equal 1 to implement furi_thread_enumerate." - #endif -#endif - -#if (configUSE_16_BIT_TICKS == 1) - /* - CMSIS-RTOS2 wrapper for FreeRTOS relies on 32-bit tick timer which is also optimal on - a 32-bit CPU architectures. - Set #define configUSE_16_BIT_TICKS 0 to fix this error. - */ - #error "Definition configUSE_16_BIT_TICKS must be zero to implement CMSIS-RTOS2 API." -#endif - -#endif /* FREERTOS_OS2_H_ */ diff --git a/lib/ST25RFAL002/platform.c b/lib/ST25RFAL002/platform.c index 1facfa2a..af9dc6ff 100644 --- a/lib/ST25RFAL002/platform.c +++ b/lib/ST25RFAL002/platform.c @@ -26,7 +26,7 @@ int32_t rfal_platform_irq_thread(void* context) { UNUSED(context); while(1) { - uint32_t flags = furi_thread_flags_wait(0x1, osFlagsWaitAny, osWaitForever); + uint32_t flags = furi_thread_flags_wait(0x1, FuriFlagWaitAny, FuriWaitForever); if(flags & 0x1) { rfal_platform.callback(); } diff --git a/lib/ST25RFAL002/platform.h b/lib/ST25RFAL002/platform.h index 832e034e..d86bba73 100644 --- a/lib/ST25RFAL002/platform.h +++ b/lib/ST25RFAL002/platform.h @@ -4,7 +4,6 @@ #include #include #include -#include #include "timer.h" #include "math.h" #include @@ -104,10 +103,9 @@ void rfal_platform_spi_release(); timerCalculateTimer(t) /*!< Create a timer with the given time (ms) */ #define platformTimerIsExpired(timer) \ timerIsExpired(timer) /*!< Checks if the given timer is expired */ -#define platformDelay(t) osDelay(t) /*!< Performs a delay for the given time (ms) */ +#define platformDelay(t) furi_delay_ms(t) /*!< Performs a delay for the given time (ms) */ -#define platformGetSysTick() \ - osKernelGetTickCount() /*!< Get System Tick (1 tick = 1 ms) */ +#define platformGetSysTick() furi_get_tick() /*!< Get System Tick (1 tick = 1 ms) */ #define platformAssert(exp) assert_param(exp) /*!< Asserts whether the given expression is true*/ diff --git a/lib/ST25RFAL002/timer.c b/lib/ST25RFAL002/timer.c index b7fe1c28..ea0678a6 100644 --- a/lib/ST25RFAL002/timer.c +++ b/lib/ST25RFAL002/timer.c @@ -41,7 +41,7 @@ ****************************************************************************** */ #include "timer.h" -#include +#include /* ****************************************************************************** @@ -65,7 +65,7 @@ static uint32_t timerStopwatchTick; /*******************************************************************************/ uint32_t timerCalculateTimer(uint16_t time) { - return (furi_hal_get_tick() + time); + return (furi_get_tick() + time); } /*******************************************************************************/ @@ -73,7 +73,7 @@ bool timerIsExpired(uint32_t timer) { uint32_t uDiff; int32_t sDiff; - uDiff = (timer - furi_hal_get_tick()); /* Calculate the diff between the timers */ + uDiff = (timer - furi_get_tick()); /* Calculate the diff between the timers */ sDiff = uDiff; /* Convert the diff to a signed var */ /* Check if the given timer has expired already */ @@ -96,10 +96,10 @@ void timerDelay(uint16_t tOut) { /*******************************************************************************/ void timerStopwatchStart(void) { - timerStopwatchTick = furi_hal_get_tick(); + timerStopwatchTick = furi_get_tick(); } /*******************************************************************************/ uint32_t timerStopwatchMeasure(void) { - return (uint32_t)(furi_hal_get_tick() - timerStopwatchTick); + return (uint32_t)(furi_get_tick() - timerStopwatchTick); } diff --git a/lib/app-scened-template/record_controller.hpp b/lib/app-scened-template/record_controller.hpp index 9dfa9657..9b14274a 100644 --- a/lib/app-scened-template/record_controller.hpp +++ b/lib/app-scened-template/record_controller.hpp @@ -1,5 +1,5 @@ #pragma once -#include +#include /** * @brief Class for opening, casting, holding and closing records diff --git a/lib/app-scened-template/view_controller.hpp b/lib/app-scened-template/view_controller.hpp index e74673d8..d08751c5 100644 --- a/lib/app-scened-template/view_controller.hpp +++ b/lib/app-scened-template/view_controller.hpp @@ -1,7 +1,7 @@ #pragma once #include "view_modules/generic_view_module.h" #include -#include +#include #include #include #include "typeindex_no_rtti.hpp" @@ -15,7 +15,7 @@ template class ViewController { public: ViewController() { - event_queue = osMessageQueueNew(10, sizeof(typename TApp::Event), NULL); + event_queue = furi_message_queue_alloc(10, sizeof(typename TApp::Event)); view_dispatcher = view_dispatcher_alloc(); previous_view_callback_pointer = cbc::obtain_connector( @@ -36,7 +36,7 @@ public: } view_dispatcher_free(view_dispatcher); - osMessageQueueDelete(event_queue); + furi_message_queue_free(event_queue); } /** @@ -81,7 +81,7 @@ public: * @param event event pointer */ void receive_event(typename TApp::Event* event) { - if(osMessageQueueGet(event_queue, event, NULL, 100) != osOK) { + if(furi_message_queue_get(event_queue, event, 100) != FuriStatusOk) { event->type = TApp::EventType::Tick; } } @@ -92,8 +92,8 @@ public: * @param event event pointer */ void send_event(typename TApp::Event* event) { - osStatus_t result = osMessageQueuePut(event_queue, event, 0, osWaitForever); - furi_check(result == osOK); + FuriStatus result = furi_message_queue_put(event_queue, event, FuriWaitForever); + furi_check(result == FuriStatusOk); } private: @@ -107,7 +107,7 @@ private: * @brief App event queue * */ - osMessageQueueId_t event_queue; + FuriMessageQueue* event_queue; /** * @brief Main ViewDispatcher pointer diff --git a/lib/drivers/bq27220.c b/lib/drivers/bq27220.c index 18f3f028..f64120fa 100644 --- a/lib/drivers/bq27220.c +++ b/lib/drivers/bq27220.c @@ -1,8 +1,7 @@ #include "bq27220.h" #include "bq27220_reg.h" -#include -#include +#include #include #define TAG "Gauge" @@ -42,7 +41,7 @@ bool bq27220_set_parameter_u16(FuriHalI2cBusHandle* handle, uint16_t address, ui ret = furi_hal_i2c_write_mem( handle, BQ27220_ADDRESS, CommandSelectSubclass, buffer, 4, BQ27220_I2C_TIMEOUT); - furi_hal_delay_us(10000); + furi_delay_us(10000); uint8_t checksum = bq27220_get_checksum(buffer, 4); buffer[0] = checksum; @@ -50,7 +49,7 @@ bool bq27220_set_parameter_u16(FuriHalI2cBusHandle* handle, uint16_t address, ui ret &= furi_hal_i2c_write_mem( handle, BQ27220_ADDRESS, CommandMACDataSum, buffer, 2, BQ27220_I2C_TIMEOUT); - furi_hal_delay_us(10000); + furi_delay_us(10000); return ret; } @@ -96,7 +95,7 @@ bool bq27220_init(FuriHalI2cBusHandle* handle, const ParamCEDV* cedv) { bq27220_set_parameter_u16(handle, AddressEDV2, cedv->EDV2); bq27220_control(handle, Control_EXIT_CFG_UPDATE_REINIT); - furi_hal_delay_us(10000); + furi_delay_us(10000); design_cap = bq27220_get_design_capacity(handle); if(cedv->design_cap == design_cap) { FURI_LOG_I(TAG, "Battery profile update success"); diff --git a/lib/drivers/cc1101.c b/lib/drivers/cc1101.c index a0c9d44a..f28165e8 100644 --- a/lib/drivers/cc1101.c +++ b/lib/drivers/cc1101.c @@ -1,6 +1,4 @@ #include "cc1101.h" -#include -#include #include #include diff --git a/lib/drivers/lp5562.c b/lib/drivers/lp5562.c index 7eef2a83..f5d765fa 100644 --- a/lib/drivers/lp5562.c +++ b/lib/drivers/lp5562.c @@ -1,5 +1,5 @@ #include "lp5562.h" -#include "furi/common_defines.h" +#include #include "lp5562_reg.h" #include @@ -27,7 +27,7 @@ void lp5562_enable(FuriHalI2cBusHandle* handle) { Reg00_Enable reg = {.CHIP_EN = true, .LOG_EN = true}; furi_hal_i2c_write_reg_8(handle, LP5562_ADDRESS, 0x00, *(uint8_t*)®, LP5562_I2C_TIMEOUT); //>488μs delay is required after writing to 0x00 register, otherwise program engine will not work - furi_hal_delay_us(500); + furi_delay_us(500); } void lp5562_set_channel_current(FuriHalI2cBusHandle* handle, LP5562Channel channel, uint8_t value) { @@ -127,7 +127,7 @@ void lp5562_execute_program( reg_val &= ~(0x3 << bit_offset); reg_val |= (0x01 << bit_offset); // load furi_hal_i2c_write_reg_8(handle, LP5562_ADDRESS, 0x01, reg_val, LP5562_I2C_TIMEOUT); - furi_hal_delay_us(100); + furi_delay_us(100); // Program load for(uint8_t i = 0; i < 16; i++) { diff --git a/lib/flipper_format/flipper_format.c b/lib/flipper_format/flipper_format.c index df848ead..846129cd 100644 --- a/lib/flipper_format/flipper_format.c +++ b/lib/flipper_format/flipper_format.c @@ -1,4 +1,4 @@ -#include +#include #include #include #include diff --git a/lib/flipper_format/flipper_format_stream.c b/lib/flipper_format/flipper_format_stream.c index 5c210536..81189b69 100644 --- a/lib/flipper_format/flipper_format_stream.c +++ b/lib/flipper_format/flipper_format_stream.c @@ -1,6 +1,6 @@ #include #include -#include +#include #include "flipper_format_stream.h" #include "flipper_format_stream_i.h" diff --git a/lib/freertos.scons b/lib/freertos.scons index 992c4f87..1c5a5bf5 100644 --- a/lib/freertos.scons +++ b/lib/freertos.scons @@ -20,7 +20,6 @@ libenv.ApplyLibFlags() sources = libenv.Glob("FreeRTOS-Kernel/*.c", source=True) sources += [ "FreeRTOS-Kernel/portable/GCC/ARM_CM4F/port.c", - "FreeRTOS-glue/cmsis_os2.c", ] lib = libenv.StaticLibrary("${FW_LIB_NAME}", sources) diff --git a/lib/infrared/encoder_decoder/common/infrared_common_decoder.c b/lib/infrared/encoder_decoder/common/infrared_common_decoder.c index 1d944285..bff4c73d 100644 --- a/lib/infrared/encoder_decoder/common/infrared_common_decoder.c +++ b/lib/infrared/encoder_decoder/common/infrared_common_decoder.c @@ -1,5 +1,5 @@ -#include "furi/check.h" -#include "furi/common_defines.h" +#include +#include #include "infrared.h" #include "infrared_common_i.h" #include diff --git a/lib/infrared/encoder_decoder/common/infrared_common_encoder.c b/lib/infrared/encoder_decoder/common/infrared_common_encoder.c index f755222d..dcf63acc 100644 --- a/lib/infrared/encoder_decoder/common/infrared_common_encoder.c +++ b/lib/infrared/encoder_decoder/common/infrared_common_encoder.c @@ -1,4 +1,4 @@ -#include "furi/check.h" +#include #include "infrared.h" #include "infrared_common_i.h" #include diff --git a/lib/infrared/encoder_decoder/infrared.c b/lib/infrared/encoder_decoder/infrared.c index 59b11d5c..71bd6bb6 100644 --- a/lib/infrared/encoder_decoder/infrared.c +++ b/lib/infrared/encoder_decoder/infrared.c @@ -1,5 +1,5 @@ #include "infrared.h" -#include "furi/check.h" +#include #include "common/infrared_common_i.h" #include "infrared_protocol_defs_i.h" #include diff --git a/lib/infrared/encoder_decoder/nec/infrared_encoder_nec.c b/lib/infrared/encoder_decoder/nec/infrared_encoder_nec.c index e1afae7b..d0039c33 100644 --- a/lib/infrared/encoder_decoder/nec/infrared_encoder_nec.c +++ b/lib/infrared/encoder_decoder/nec/infrared_encoder_nec.c @@ -1,4 +1,4 @@ -#include "furi/check.h" +#include #include "infrared.h" #include "common/infrared_common_i.h" #include diff --git a/lib/infrared/encoder_decoder/rc5/infrared_encoder_rc5.c b/lib/infrared/encoder_decoder/rc5/infrared_encoder_rc5.c index f063f7e5..7b55cdc4 100644 --- a/lib/infrared/encoder_decoder/rc5/infrared_encoder_rc5.c +++ b/lib/infrared/encoder_decoder/rc5/infrared_encoder_rc5.c @@ -1,4 +1,4 @@ -#include "furi/memmgr.h" +#include #include "infrared.h" #include "common/infrared_common_i.h" #include "infrared_protocol_defs_i.h" diff --git a/lib/infrared/encoder_decoder/rc6/infrared_encoder_rc6.c b/lib/infrared/encoder_decoder/rc6/infrared_encoder_rc6.c index 7d8ff975..f1240b17 100644 --- a/lib/infrared/encoder_decoder/rc6/infrared_encoder_rc6.c +++ b/lib/infrared/encoder_decoder/rc6/infrared_encoder_rc6.c @@ -1,4 +1,4 @@ -#include "furi/memmgr.h" +#include #include "infrared.h" #include "common/infrared_common_i.h" #include "infrared_protocol_defs_i.h" diff --git a/lib/infrared/encoder_decoder/samsung/infrared_encoder_samsung.c b/lib/infrared/encoder_decoder/samsung/infrared_encoder_samsung.c index 88745ff5..75b037f0 100644 --- a/lib/infrared/encoder_decoder/samsung/infrared_encoder_samsung.c +++ b/lib/infrared/encoder_decoder/samsung/infrared_encoder_samsung.c @@ -1,4 +1,4 @@ -#include "furi/check.h" +#include #include "common/infrared_common_i.h" #include #include "../infrared_i.h" diff --git a/lib/infrared/encoder_decoder/sirc/infrared_encoder_sirc.c b/lib/infrared/encoder_decoder/sirc/infrared_encoder_sirc.c index 8ae9e371..2c2bda1a 100644 --- a/lib/infrared/encoder_decoder/sirc/infrared_encoder_sirc.c +++ b/lib/infrared/encoder_decoder/sirc/infrared_encoder_sirc.c @@ -1,4 +1,4 @@ -#include "furi/check.h" +#include #include "infrared.h" #include "common/infrared_common_i.h" #include diff --git a/lib/infrared/worker/infrared_transmit.c b/lib/infrared/worker/infrared_transmit.c index d4c87ce5..695be8d1 100644 --- a/lib/infrared/worker/infrared_transmit.c +++ b/lib/infrared/worker/infrared_transmit.c @@ -4,7 +4,6 @@ #include #include #include -#include static uint32_t infrared_tx_number_of_transmissions = 0; static uint32_t infrared_tx_raw_timings_index = 0; diff --git a/lib/infrared/worker/infrared_worker.c b/lib/infrared/worker/infrared_worker.c index b24b7480..becd8d88 100644 --- a/lib/infrared/worker/infrared_worker.c +++ b/lib/infrared/worker/infrared_worker.c @@ -1,5 +1,5 @@ -#include "furi/check.h" -#include "furi/common_defines.h" +#include +#include #include "sys/_stdint.h" #include "infrared_worker.h" #include @@ -167,7 +167,7 @@ static int32_t infrared_worker_rx_thread(void* thread_context) { TickType_t last_blink_time = 0; while(1) { - events = furi_thread_flags_wait(INFRARED_WORKER_ALL_RX_EVENTS, 0, osWaitForever); + events = furi_thread_flags_wait(INFRARED_WORKER_ALL_RX_EVENTS, 0, FuriWaitForever); furi_check(events & INFRARED_WORKER_ALL_RX_EVENTS); /* at least one caught */ if(events & INFRARED_WORKER_RX_RECEIVED) { @@ -506,7 +506,7 @@ static int32_t infrared_worker_tx_thread(void* thread_context) { break; case InfraredWorkerStateRunTx: - events = furi_thread_flags_wait(INFRARED_WORKER_ALL_TX_EVENTS, 0, osWaitForever); + events = furi_thread_flags_wait(INFRARED_WORKER_ALL_TX_EVENTS, 0, FuriWaitForever); furi_check(events & INFRARED_WORKER_ALL_TX_EVENTS); /* at least one caught */ if(events & INFRARED_WORKER_EXIT) { diff --git a/lib/nfc_protocols/emv.c b/lib/nfc_protocols/emv.c index b69675fd..935c9f63 100644 --- a/lib/nfc_protocols/emv.c +++ b/lib/nfc_protocols/emv.c @@ -1,6 +1,6 @@ #include "emv.h" -#include +#include #define TAG "Emv" diff --git a/lib/one_wire/ibutton/encoder/encoder_cyfral.c b/lib/one_wire/ibutton/encoder/encoder_cyfral.c index f6cbe630..0b506b2b 100644 --- a/lib/one_wire/ibutton/encoder/encoder_cyfral.c +++ b/lib/one_wire/ibutton/encoder/encoder_cyfral.c @@ -2,7 +2,7 @@ #include #define CYFRAL_DATA_SIZE sizeof(uint16_t) -#define CYFRAL_PERIOD (125 * furi_hal_delay_instructions_per_microsecond()) +#define CYFRAL_PERIOD (125 * furi_hal_cortex_instructions_per_microsecond()) #define CYFRAL_0_LOW (CYFRAL_PERIOD * 0.66f) #define CYFRAL_0_HI (CYFRAL_PERIOD * 0.33f) #define CYFRAL_1_LOW (CYFRAL_PERIOD * 0.33f) diff --git a/lib/one_wire/ibutton/encoder/encoder_metakom.c b/lib/one_wire/ibutton/encoder/encoder_metakom.c index 3b597e7c..5b978ebe 100644 --- a/lib/one_wire/ibutton/encoder/encoder_metakom.c +++ b/lib/one_wire/ibutton/encoder/encoder_metakom.c @@ -2,7 +2,7 @@ #include #define METAKOM_DATA_SIZE sizeof(uint32_t) -#define METAKOM_PERIOD (125 * furi_hal_delay_instructions_per_microsecond()) +#define METAKOM_PERIOD (125 * furi_hal_cortex_instructions_per_microsecond()) #define METAKOM_0_LOW (METAKOM_PERIOD * 0.33f) #define METAKOM_0_HI (METAKOM_PERIOD * 0.66f) #define METAKOM_1_LOW (METAKOM_PERIOD * 0.66f) diff --git a/lib/one_wire/ibutton/ibutton_worker.c b/lib/one_wire/ibutton/ibutton_worker.c index 82c3d688..755ed32f 100644 --- a/lib/one_wire/ibutton/ibutton_worker.c +++ b/lib/one_wire/ibutton/ibutton_worker.c @@ -32,7 +32,7 @@ iButtonWorker* ibutton_worker_alloc() { worker->pulse_decoder = pulse_decoder_alloc(); worker->protocol_cyfral = protocol_cyfral_alloc(); worker->protocol_metakom = protocol_metakom_alloc(); - worker->messages = osMessageQueueNew(1, sizeof(iButtonMessage), NULL); + worker->messages = furi_message_queue_alloc(1, sizeof(iButtonMessage)); worker->mode_index = iButtonWorkerIdle; worker->last_dwt_value = 0; worker->read_cb = NULL; @@ -90,22 +90,26 @@ void ibutton_worker_emulate_set_callback( void ibutton_worker_read_start(iButtonWorker* worker, iButtonKey* key) { iButtonMessage message = {.type = iButtonMessageRead, .data.key = key}; - furi_check(osMessageQueuePut(worker->messages, &message, 0, osWaitForever) == osOK); + furi_check( + furi_message_queue_put(worker->messages, &message, FuriWaitForever) == FuriStatusOk); } void ibutton_worker_write_start(iButtonWorker* worker, iButtonKey* key) { iButtonMessage message = {.type = iButtonMessageWrite, .data.key = key}; - furi_check(osMessageQueuePut(worker->messages, &message, 0, osWaitForever) == osOK); + furi_check( + furi_message_queue_put(worker->messages, &message, FuriWaitForever) == FuriStatusOk); } void ibutton_worker_emulate_start(iButtonWorker* worker, iButtonKey* key) { iButtonMessage message = {.type = iButtonMessageEmulate, .data.key = key}; - furi_check(osMessageQueuePut(worker->messages, &message, 0, osWaitForever) == osOK); + furi_check( + furi_message_queue_put(worker->messages, &message, FuriWaitForever) == FuriStatusOk); } void ibutton_worker_stop(iButtonWorker* worker) { iButtonMessage message = {.type = iButtonMessageStop}; - furi_check(osMessageQueuePut(worker->messages, &message, 0, osWaitForever) == osOK); + furi_check( + furi_message_queue_put(worker->messages, &message, FuriWaitForever) == FuriStatusOk); } void ibutton_worker_free(iButtonWorker* worker) { @@ -123,7 +127,7 @@ void ibutton_worker_free(iButtonWorker* worker) { encoder_cyfral_free(worker->encoder_cyfral); encoder_metakom_free(worker->encoder_metakom); - osMessageQueueDelete(worker->messages); + furi_message_queue_free(worker->messages); furi_thread_free(worker->thread); free(worker->key_data); @@ -136,7 +140,8 @@ void ibutton_worker_start_thread(iButtonWorker* worker) { void ibutton_worker_stop_thread(iButtonWorker* worker) { iButtonMessage message = {.type = iButtonMessageEnd}; - furi_check(osMessageQueuePut(worker->messages, &message, 0, osWaitForever) == osOK); + furi_check( + furi_message_queue_put(worker->messages, &message, FuriWaitForever) == FuriStatusOk); furi_thread_join(worker->thread); } @@ -148,7 +153,7 @@ void ibutton_worker_switch_mode(iButtonWorker* worker, iButtonWorkerMode mode) { void ibutton_worker_notify_emulate(iButtonWorker* worker) { iButtonMessage message = {.type = iButtonMessageNotifyEmulate}; - furi_check(osMessageQueuePut(worker->messages, &message, 0, 0) == osOK); + furi_check(furi_message_queue_put(worker->messages, &message, 0) == FuriStatusOk); } void ibutton_worker_set_key_p(iButtonWorker* worker, iButtonKey* key) { @@ -159,14 +164,14 @@ static int32_t ibutton_worker_thread(void* thread_context) { iButtonWorker* worker = thread_context; bool running = true; iButtonMessage message; - osStatus_t status; + FuriStatus status; ibutton_worker_modes[worker->mode_index].start(worker); while(running) { - status = osMessageQueueGet( - worker->messages, &message, NULL, ibutton_worker_modes[worker->mode_index].quant); - if(status == osOK) { + status = furi_message_queue_get( + worker->messages, &message, ibutton_worker_modes[worker->mode_index].quant); + if(status == FuriStatusOk) { switch(message.type) { case iButtonMessageEnd: ibutton_worker_switch_mode(worker, iButtonWorkerIdle); @@ -195,7 +200,7 @@ static int32_t ibutton_worker_thread(void* thread_context) { } break; } - } else if(status == osErrorTimeout) { + } else if(status == FuriStatusErrorTimeout) { ibutton_worker_modes[worker->mode_index].tick(worker); } else { furi_crash("iButton worker error"); diff --git a/lib/one_wire/ibutton/ibutton_worker_i.h b/lib/one_wire/ibutton/ibutton_worker_i.h index 48d03595..28588443 100644 --- a/lib/one_wire/ibutton/ibutton_worker_i.h +++ b/lib/one_wire/ibutton/ibutton_worker_i.h @@ -52,7 +52,7 @@ struct iButtonWorker { OneWireDevice* device; iButtonWriter* writer; iButtonWorkerMode mode_index; - osMessageQueueId_t messages; + FuriMessageQueue* messages; FuriThread* thread; PulseDecoder* pulse_decoder; diff --git a/lib/one_wire/ibutton/ibutton_worker_modes.c b/lib/one_wire/ibutton/ibutton_worker_modes.c index 5ee76862..78e05d0e 100644 --- a/lib/one_wire/ibutton/ibutton_worker_modes.c +++ b/lib/one_wire/ibutton/ibutton_worker_modes.c @@ -21,7 +21,7 @@ void ibutton_worker_mode_write_stop(iButtonWorker* worker); const iButtonWorkerModeType ibutton_worker_modes[] = { { - .quant = osWaitForever, + .quant = FuriWaitForever, .start = ibutton_worker_mode_idle_start, .tick = ibutton_worker_mode_idle_tick, .stop = ibutton_worker_mode_idle_stop, @@ -86,7 +86,7 @@ bool ibutton_worker_read_comparator(iButtonWorker* worker) { furi_hal_rfid_comp_start(); // TODO: rework with thread events, "pulse_decoder_get_decoded_index_with_timeout" - furi_hal_delay_ms(100); + furi_delay_ms(100); int32_t decoded_index = pulse_decoder_get_decoded_index(worker->pulse_decoder); if(decoded_index >= 0) { pulse_decoder_get_data( @@ -121,7 +121,7 @@ bool ibutton_worker_read_comparator(iButtonWorker* worker) { bool ibutton_worker_read_dallas(iButtonWorker* worker) { bool result = false; onewire_host_start(worker->host); - furi_hal_delay_ms(100); + furi_delay_ms(100); FURI_CRITICAL_ENTER(); if(onewire_host_search(worker->host, worker->key_data, NORMAL_SEARCH)) { onewire_host_reset_search(worker->host); diff --git a/lib/one_wire/ibutton/ibutton_writer.c b/lib/one_wire/ibutton/ibutton_writer.c index fe19db71..203c4fc0 100644 --- a/lib/one_wire/ibutton/ibutton_writer.c +++ b/lib/one_wire/ibutton/ibutton_writer.c @@ -11,13 +11,13 @@ struct iButtonWriter { static void writer_write_one_bit(iButtonWriter* writer, bool value, uint32_t delay) { onewire_host_write_bit(writer->host, value); - furi_hal_delay_us(delay); + furi_delay_us(delay); } static void writer_write_byte_ds1990(iButtonWriter* writer, uint8_t data) { for(uint8_t n_bit = 0; n_bit < 8; n_bit++) { onewire_host_write_bit(writer->host, data & 1); - furi_hal_delay_us(5000); + furi_delay_us(5000); data = data >> 1; } } @@ -68,7 +68,7 @@ static bool writer_write_TM2004(iButtonWriter* writer, iButtonKey* key) { // TODO: check answer CRC // pulse indicating that data is correct - furi_hal_delay_us(600); + furi_delay_us(600); writer_write_one_bit(writer, 1, 50000); // read written key byte @@ -104,7 +104,7 @@ static bool writer_write_1990_1(iButtonWriter* writer, iButtonKey* key) { // unlock onewire_host_reset(writer->host); onewire_host_write(writer->host, RW1990_1_CMD_WRITE_RECORD_FLAG); - furi_hal_delay_us(10); + furi_delay_us(10); writer_write_one_bit(writer, 0, 5000); // write key @@ -113,7 +113,7 @@ static bool writer_write_1990_1(iButtonWriter* writer, iButtonKey* key) { for(uint8_t i = 0; i < ibutton_key_get_data_size(key); i++) { // inverted key for RW1990.1 writer_write_byte_ds1990(writer, ~ibutton_key_get_data_p(key)[i]); - furi_hal_delay_us(30000); + furi_delay_us(30000); } // lock @@ -139,7 +139,7 @@ static bool writer_write_1990_2(iButtonWriter* writer, iButtonKey* key) { // unlock onewire_host_reset(writer->host); onewire_host_write(writer->host, RW1990_2_CMD_WRITE_RECORD_FLAG); - furi_hal_delay_us(10); + furi_delay_us(10); writer_write_one_bit(writer, 1, 5000); // write key @@ -147,7 +147,7 @@ static bool writer_write_1990_2(iButtonWriter* writer, iButtonKey* key) { onewire_host_write(writer->host, RW1990_2_CMD_WRITE_ROM); for(uint8_t i = 0; i < ibutton_key_get_data_size(key); i++) { writer_write_byte_ds1990(writer, ibutton_key_get_data_p(key)[i]); - furi_hal_delay_us(30000); + furi_delay_us(30000); } // lock @@ -191,7 +191,7 @@ static bool writer_write_TM01( //} else { for(uint8_t i = 0; i < key->get_type_data_size(); i++) { write_byte_ds1990(key->get_data()[i]); - furi_hal_delay_us(10000); + furi_delay_us(10000); } //} @@ -271,9 +271,9 @@ void ibutton_writer_free(iButtonWriter* writer) { iButtonWriterResult ibutton_writer_write(iButtonWriter* writer, iButtonKey* key) { iButtonWriterResult result = iButtonWriterNoDetect; - osKernelLock(); + furi_kernel_lock(); bool blank_present = onewire_host_reset(writer->host); - osKernelUnlock(); + furi_kernel_unlock(); if(blank_present) { switch(ibutton_key_get_type(key)) { diff --git a/lib/one_wire/ibutton/pulse_protocols/protocol_cyfral.c b/lib/one_wire/ibutton/pulse_protocols/protocol_cyfral.c index a992f00d..7c289790 100644 --- a/lib/one_wire/ibutton/pulse_protocols/protocol_cyfral.c +++ b/lib/one_wire/ibutton/pulse_protocols/protocol_cyfral.c @@ -1,8 +1,8 @@ #include "protocol_cyfral.h" #include #include -#include -#include +#include +#include #define CYFRAL_DATA_SIZE 2 #define CYFRAL_MAX_PERIOD_US 230 @@ -104,7 +104,7 @@ static void cyfral_reset(void* context) { cyfral->nibble = 0; cyfral->data_valid = true; - cyfral->max_period = CYFRAL_MAX_PERIOD_US * furi_hal_delay_instructions_per_microsecond(); + cyfral->max_period = CYFRAL_MAX_PERIOD_US * furi_hal_cortex_instructions_per_microsecond(); } static bool cyfral_process_bit( diff --git a/lib/one_wire/ibutton/pulse_protocols/protocol_metakom.c b/lib/one_wire/ibutton/pulse_protocols/protocol_metakom.c index d76ef886..9df9e20b 100644 --- a/lib/one_wire/ibutton/pulse_protocols/protocol_metakom.c +++ b/lib/one_wire/ibutton/pulse_protocols/protocol_metakom.c @@ -1,8 +1,7 @@ #include "protocol_metakom.h" #include #include -#include -#include +#include #define METAKOM_DATA_SIZE 4 #define METAKOM_PERIOD_SAMPLE_COUNT 10 diff --git a/lib/one_wire/one_wire_host.c b/lib/one_wire/one_wire_host.c index 1bb0a1cc..654b9e45 100644 --- a/lib/one_wire/one_wire_host.c +++ b/lib/one_wire/one_wire_host.c @@ -31,23 +31,23 @@ bool onewire_host_reset(OneWireHost* host) { furi_hal_ibutton_pin_high(); do { if(--retries == 0) return 0; - furi_hal_delay_us(2); + furi_delay_us(2); } while(!furi_hal_ibutton_pin_get_level()); // pre delay - furi_hal_delay_us(OWH_RESET_DELAY_PRE); + furi_delay_us(OWH_RESET_DELAY_PRE); // drive low furi_hal_ibutton_pin_low(); - furi_hal_delay_us(OWH_RESET_DRIVE); + furi_delay_us(OWH_RESET_DRIVE); // release furi_hal_ibutton_pin_high(); - furi_hal_delay_us(OWH_RESET_RELEASE); + furi_delay_us(OWH_RESET_RELEASE); // read and post delay r = !furi_hal_ibutton_pin_get_level(); - furi_hal_delay_us(OWH_RESET_DELAY_POST); + furi_delay_us(OWH_RESET_DELAY_POST); return r; } @@ -58,15 +58,15 @@ bool onewire_host_read_bit(OneWireHost* host) { // drive low furi_hal_ibutton_pin_low(); - furi_hal_delay_us(OWH_READ_DRIVE); + furi_delay_us(OWH_READ_DRIVE); // release furi_hal_ibutton_pin_high(); - furi_hal_delay_us(OWH_READ_RELEASE); + furi_delay_us(OWH_READ_RELEASE); // read and post delay result = furi_hal_ibutton_pin_get_level(); - furi_hal_delay_us(OWH_READ_DELAY_POST); + furi_delay_us(OWH_READ_DELAY_POST); return result; } @@ -94,19 +94,19 @@ void onewire_host_write_bit(OneWireHost* host, bool value) { if(value) { // drive low furi_hal_ibutton_pin_low(); - furi_hal_delay_us(OWH_WRITE_1_DRIVE); + furi_delay_us(OWH_WRITE_1_DRIVE); // release furi_hal_ibutton_pin_high(); - furi_hal_delay_us(OWH_WRITE_1_RELEASE); + furi_delay_us(OWH_WRITE_1_RELEASE); } else { // drive low furi_hal_ibutton_pin_low(); - furi_hal_delay_us(OWH_WRITE_0_DRIVE); + furi_delay_us(OWH_WRITE_0_DRIVE); // release furi_hal_ibutton_pin_high(); - furi_hal_delay_us(OWH_WRITE_0_RELEASE); + furi_delay_us(OWH_WRITE_0_RELEASE); } } diff --git a/lib/one_wire/one_wire_slave.c b/lib/one_wire/one_wire_slave.c index 1f389623..af04cfda 100644 --- a/lib/one_wire/one_wire_slave.c +++ b/lib/one_wire/one_wire_slave.c @@ -2,8 +2,7 @@ #include "one_wire_slave_i.h" #include "one_wire_device.h" #include -#include -#include +#include #define OWS_RESET_MIN 270 #define OWS_RESET_MAX 960 @@ -39,14 +38,14 @@ struct OneWireSlave { uint32_t onewire_slave_wait_while_gpio_is(OneWireSlave* bus, uint32_t time, const bool pin_value) { UNUSED(bus); uint32_t start = DWT->CYCCNT; - uint32_t time_ticks = time * furi_hal_delay_instructions_per_microsecond(); + uint32_t time_ticks = time * furi_hal_cortex_instructions_per_microsecond(); uint32_t time_captured; do { time_captured = DWT->CYCCNT; if(furi_hal_ibutton_pin_get_level() != pin_value) { uint32_t remaining_time = time_ticks - (time_captured - start); - remaining_time /= furi_hal_delay_instructions_per_microsecond(); + remaining_time /= furi_hal_cortex_instructions_per_microsecond(); return remaining_time; } } while((time_captured - start) < time_ticks); @@ -60,7 +59,7 @@ bool onewire_slave_show_presence(OneWireSlave* bus) { // show presence furi_hal_ibutton_pin_low(); - furi_hal_delay_us(OWS_PRESENCE_MIN); + furi_delay_us(OWS_PRESENCE_MIN); furi_hal_ibutton_pin_high(); // somebody also can show presence @@ -127,7 +126,7 @@ bool onewire_slave_send_bit(OneWireSlave* bus, bool value) { } // hold line for ZERO or ONE time - furi_hal_delay_us(time); + furi_delay_us(time); furi_hal_ibutton_pin_high(); return true; @@ -213,7 +212,7 @@ static void exti_cb(void* context) { if(input_state) { uint32_t pulse_length = - (DWT->CYCCNT - pulse_start) / furi_hal_delay_instructions_per_microsecond(); + (DWT->CYCCNT - pulse_start) / furi_hal_cortex_instructions_per_microsecond(); if(pulse_length >= OWS_RESET_MIN) { if(pulse_length <= OWS_RESET_MAX) { // reset cycle ok diff --git a/lib/one_wire/pulse_protocols/pulse_decoder.c b/lib/one_wire/pulse_protocols/pulse_decoder.c index e8197a08..c7d3b09e 100644 --- a/lib/one_wire/pulse_protocols/pulse_decoder.c +++ b/lib/one_wire/pulse_protocols/pulse_decoder.c @@ -1,7 +1,7 @@ #include #include "pulse_decoder.h" #include -#include +#include #define MAX_PROTOCOL 5 diff --git a/lib/subghz/blocks/encoder.c b/lib/subghz/blocks/encoder.c index 3cefc2c1..f3349b5f 100644 --- a/lib/subghz/blocks/encoder.c +++ b/lib/subghz/blocks/encoder.c @@ -1,6 +1,6 @@ #include "encoder.h" #include "math.h" -#include +#include #define TAG "SubGhzBlockEncoder" @@ -42,4 +42,4 @@ size_t subghz_protocol_blocks_get_upload( upload[size_upload++] = level_duration_make( subghz_protocol_blocks_get_bit_array(data_array, index_bit - 1), duration); return size_upload; -} \ No newline at end of file +} diff --git a/lib/subghz/protocols/princeton_for_testing.c b/lib/subghz/protocols/princeton_for_testing.c index 5c3f7151..43078d2e 100644 --- a/lib/subghz/protocols/princeton_for_testing.c +++ b/lib/subghz/protocols/princeton_for_testing.c @@ -76,9 +76,8 @@ void subghz_encoder_princeton_for_testing_set( instance->count_key = instance->count_key_package + 3; - if((furi_hal_get_tick() - instance->time_stop) < instance->timeout) { - instance->time_stop = - (instance->timeout - (furi_hal_get_tick() - instance->time_stop)) * 1000; + if((furi_get_tick() - instance->time_stop) < instance->timeout) { + instance->time_stop = (instance->timeout - (furi_get_tick() - instance->time_stop)) * 1000; } else { instance->time_stop = 0; } diff --git a/lib/subghz/protocols/raw.c b/lib/subghz/protocols/raw.c index 516aa633..ebc84c11 100644 --- a/lib/subghz/protocols/raw.c +++ b/lib/subghz/protocols/raw.c @@ -287,7 +287,7 @@ static bool subghz_protocol_encoder_raw_worker_init(SubGhzProtocolEncoderRAW* in if(subghz_file_encoder_worker_start( instance->file_worker_encoder, string_get_cstr(instance->file_name))) { //the worker needs a file in order to open and read part of the file - osDelay(100); + furi_delay_ms(100); instance->is_runing = true; } else { subghz_protocol_encoder_raw_stop(instance); diff --git a/lib/subghz/subghz_file_encoder_worker.c b/lib/subghz/subghz_file_encoder_worker.c index 0ec4c861..457c8b02 100644 --- a/lib/subghz/subghz_file_encoder_worker.c +++ b/lib/subghz/subghz_file_encoder_worker.c @@ -153,19 +153,19 @@ static int32_t subghz_file_encoder_worker_thread(void* context) { break; } } - osDelay(5); + furi_delay_ms(5); } //waiting for the end of the transfer FURI_LOG_I(TAG, "End read file"); while(!furi_hal_subghz_is_async_tx_complete() && instance->worker_running) { - osDelay(5); + furi_delay_ms(5); } FURI_LOG_I(TAG, "End transmission"); while(instance->worker_running) { if(instance->worker_stoping) { if(instance->callback_end) instance->callback_end(instance->context_end); } - osDelay(50); + furi_delay_ms(50); } flipper_format_file_close(instance->flipper_format); diff --git a/lib/subghz/subghz_tx_rx_worker.c b/lib/subghz/subghz_tx_rx_worker.c index 0f687f15..74a6183c 100644 --- a/lib/subghz/subghz_tx_rx_worker.c +++ b/lib/subghz/subghz_tx_rx_worker.c @@ -68,11 +68,11 @@ bool subghz_tx_rx_worker_rx(SubGhzTxRxWorker* instance, uint8_t* data, uint8_t* if(instance->status != SubGhzTxRxWorkerStatusRx) { furi_hal_subghz_rx(); instance->status = SubGhzTxRxWorkerStatusRx; - osDelay(1); + furi_delay_tick(1); } //waiting for reception to complete while(furi_hal_gpio_read(&gpio_cc1101_g0)) { - osDelay(1); + furi_delay_tick(1); if(!--timeout) { FURI_LOG_W(TAG, "RX cc1101_g0 timeout"); furi_hal_subghz_flush_rx(); @@ -106,14 +106,14 @@ void subghz_tx_rx_worker_tx(SubGhzTxRxWorker* instance, uint8_t* data, size_t si furi_hal_subghz_tx(); //start send instance->status = SubGhzTxRxWorkerStatusTx; while(!furi_hal_gpio_read(&gpio_cc1101_g0)) { // Wait for GDO0 to be set -> sync transmitted - osDelay(1); + furi_delay_tick(1); if(!--timeout) { FURI_LOG_W(TAG, "TX !cc1101_g0 timeout"); break; } } while(furi_hal_gpio_read(&gpio_cc1101_g0)) { // Wait for GDO0 to be cleared -> end of packet - osDelay(1); + furi_delay_tick(1); if(!--timeout) { FURI_LOG_W(TAG, "TX cc1101_g0 timeout"); break; @@ -189,7 +189,7 @@ static int32_t subghz_tx_rx_worker_thread(void* context) { } if(timeout_tx) timeout_tx--; - osDelay(1); + furi_delay_tick(1); } furi_hal_subghz_set_path(FuriHalSubGhzPathIsolate); diff --git a/lib/toolbox/stream/stream.c b/lib/toolbox/stream/stream.c index 982c4983..088996f0 100644 --- a/lib/toolbox/stream/stream.c +++ b/lib/toolbox/stream/stream.c @@ -1,8 +1,8 @@ #include "stream.h" #include "stream_i.h" #include "file_stream.h" -#include -#include +#include +#include void stream_free(Stream* stream) { furi_assert(stream); diff --git a/lib/toolbox/stream/string_stream.c b/lib/toolbox/stream/string_stream.c index 3244b7ba..f3e1364d 100644 --- a/lib/toolbox/stream/string_stream.c +++ b/lib/toolbox/stream/string_stream.c @@ -1,7 +1,7 @@ #include "stream.h" #include "stream_i.h" #include "string_stream.h" -#include +#include typedef struct { Stream stream_base; diff --git a/lib/toolbox/tar/tar_archive.c b/lib/toolbox/tar/tar_archive.c index 91d2c812..cc107530 100644 --- a/lib/toolbox/tar/tar_archive.c +++ b/lib/toolbox/tar/tar_archive.c @@ -213,7 +213,7 @@ static int archive_extract_foreach_cb(mtar_t* tar, const mtar_header_t* header, } FURI_LOG_W(TAG, "Failed to open '%s', reties: %d", string_get_cstr(fname), n_tries); storage_file_close(out_file); - osDelay(FILE_OPEN_RETRY_DELAY); + furi_delay_ms(FILE_OPEN_RETRY_DELAY); } if(!storage_file_is_open(out_file)) { @@ -265,7 +265,7 @@ bool tar_archive_add_file( } FURI_LOG_W(TAG, "Failed to open '%s', reties: %d", fs_file_path, n_tries); storage_file_close(src_file); - osDelay(FILE_OPEN_RETRY_DELAY); + furi_delay_ms(FILE_OPEN_RETRY_DELAY); } if(!storage_file_is_open(src_file) || diff --git a/lib/u8g2/u8g2_glue.c b/lib/u8g2/u8g2_glue.c index 33d30f29..77f37f14 100644 --- a/lib/u8g2/u8g2_glue.c +++ b/lib/u8g2/u8g2_glue.c @@ -10,10 +10,10 @@ uint8_t u8g2_gpio_and_delay_stm32(u8x8_t* u8x8, uint8_t msg, uint8_t arg_int, vo /* HAL initialization contains all what we need so we can skip this part. */ break; case U8X8_MSG_DELAY_MILLI: - furi_hal_delay_ms(arg_int); + furi_delay_ms(arg_int); break; case U8X8_MSG_DELAY_10MICRO: - furi_hal_delay_us(10); + furi_delay_us(10); break; case U8X8_MSG_DELAY_100NANO: asm("nop"); From ec57dd310a6ad9657c08d143bd82a66da532dc78 Mon Sep 17 00:00:00 2001 From: adisbladis Date: Wed, 20 Jul 2022 20:48:10 +0800 Subject: [PATCH 15/37] fbt: Respect SOURCE_DATE_EPOCH when setting build date (#1421) * fbt: using SOURCE_DATE_EPOCH from environment for build timestamp (if set) Co-authored-by: hedger --- scripts/version.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/scripts/version.py b/scripts/version.py index 87bf7ed8..896b58a4 100644 --- a/scripts/version.py +++ b/scripts/version.py @@ -5,7 +5,7 @@ from flipper.app import App import subprocess import os import json -from datetime import date +from datetime import date, datetime class GitVersion: @@ -77,9 +77,15 @@ class Main(App): def generate(self): current_info = GitVersion(self.args.sourcedir).get_version_info() + + if "SOURCE_DATE_EPOCH" in os.environ: + build_date = datetime.utcfromtimestamp(int(os.environ["SOURCE_DATE_EPOCH"])) + else: + build_date = date.today() + current_info.update( { - "BUILD_DATE": date.today().strftime("%d-%m-%Y"), + "BUILD_DATE": build_date.strftime("%d-%m-%Y"), "TARGET": self.args.target, } ) From 16e598b2c08bf3156370f15fef5b5dd002780f68 Mon Sep 17 00:00:00 2001 From: Georgii Surkov <37121527+gsurkov@users.noreply.github.com> Date: Fri, 22 Jul 2022 19:00:25 +0300 Subject: [PATCH 16/37] [FL-2655, FL-2650] Buffered file streams (#1424) * Initial buffered file stream implementation * Fix logical errors * Fix more logical errors * Minimally working implementation * Adapt infrared unit tests for buffered streams * Increase read buffer size from 512 to 1K * Correct naming and formatting * More code improvements * Allow passing access and open modes for buffered streams * Implement tests for buffered streams * Better file and method names * Add comments and correct formatting * Use buffered streams in Infrared * Fix compilation error --- applications/infrared/infrared_brute_force.c | 9 +- applications/infrared/infrared_remote.c | 4 +- .../unit_tests/infrared/infrared_test.c | 11 +- applications/unit_tests/stream/stream_test.c | 96 +++++++++++ lib/flipper_format/flipper_format.c | 19 +++ lib/flipper_format/flipper_format.h | 23 +++ lib/toolbox/stream/buffered_file_stream.c | 155 ++++++++++++++++++ lib/toolbox/stream/buffered_file_stream.h | 47 ++++++ lib/toolbox/stream/stream_cache.c | 71 ++++++++ lib/toolbox/stream/stream_cache.h | 77 +++++++++ 10 files changed, 501 insertions(+), 11 deletions(-) create mode 100644 lib/toolbox/stream/buffered_file_stream.c create mode 100644 lib/toolbox/stream/buffered_file_stream.h create mode 100644 lib/toolbox/stream/stream_cache.c create mode 100644 lib/toolbox/stream/stream_cache.h diff --git a/applications/infrared/infrared_brute_force.c b/applications/infrared/infrared_brute_force.c index 55bf5c7f..1e5f557a 100644 --- a/applications/infrared/infrared_brute_force.c +++ b/applications/infrared/infrared_brute_force.c @@ -51,9 +51,9 @@ bool infrared_brute_force_calculate_messages(InfraredBruteForce* brute_force) { bool success = false; Storage* storage = furi_record_open("storage"); - FlipperFormat* ff = flipper_format_file_alloc(storage); + FlipperFormat* ff = flipper_format_buffered_file_alloc(storage); - success = flipper_format_file_open_existing(ff, brute_force->db_filename); + success = flipper_format_buffered_file_open_existing(ff, brute_force->db_filename); if(success) { string_t signal_name; string_init(signal_name); @@ -95,8 +95,9 @@ bool infrared_brute_force_start( if(*record_count) { Storage* storage = furi_record_open("storage"); - brute_force->ff = flipper_format_file_alloc(storage); - success = flipper_format_file_open_existing(brute_force->ff, brute_force->db_filename); + brute_force->ff = flipper_format_buffered_file_alloc(storage); + success = + flipper_format_buffered_file_open_existing(brute_force->ff, brute_force->db_filename); if(!success) { flipper_format_free(brute_force->ff); brute_force->ff = NULL; diff --git a/applications/infrared/infrared_remote.c b/applications/infrared/infrared_remote.c index d693be17..957e2457 100644 --- a/applications/infrared/infrared_remote.c +++ b/applications/infrared/infrared_remote.c @@ -140,13 +140,13 @@ bool infrared_remote_store(InfraredRemote* remote) { bool infrared_remote_load(InfraredRemote* remote, string_t path) { Storage* storage = furi_record_open("storage"); - FlipperFormat* ff = flipper_format_file_alloc(storage); + FlipperFormat* ff = flipper_format_buffered_file_alloc(storage); string_t buf; string_init(buf); FURI_LOG_I(TAG, "load file: \'%s\'", string_get_cstr(path)); - bool success = flipper_format_file_open_existing(ff, string_get_cstr(path)); + bool success = flipper_format_buffered_file_open_existing(ff, string_get_cstr(path)); if(success) { uint32_t version; diff --git a/applications/unit_tests/infrared/infrared_test.c b/applications/unit_tests/infrared/infrared_test.c index 312305b6..cdae742f 100644 --- a/applications/unit_tests/infrared/infrared_test.c +++ b/applications/unit_tests/infrared/infrared_test.c @@ -22,7 +22,7 @@ static void infrared_test_alloc() { test = malloc(sizeof(InfraredTest)); test->decoder_handler = infrared_alloc_decoder(); test->encoder_handler = infrared_alloc_encoder(); - test->ff = flipper_format_file_alloc(storage); + test->ff = flipper_format_buffered_file_alloc(storage); string_init(test->file_path); } @@ -52,7 +52,8 @@ static bool infrared_test_prepare_file(const char* protocol_name) { do { uint32_t format_version; - if(!flipper_format_file_open_existing(test->ff, string_get_cstr(test->file_path))) break; + if(!flipper_format_buffered_file_open_existing(test->ff, string_get_cstr(test->file_path))) + break; if(!flipper_format_read_header(test->ff, file_type, &format_version)) break; if(string_cmp_str(file_type, "IR tests file") || format_version != 1) break; success = true; @@ -230,7 +231,7 @@ static void infrared_test_run_encoder(InfraredProtocol protocol, uint32_t test_i test->ff, string_get_cstr(buf), &expected_timings, &expected_timings_count), "Failed to load raw signal from file"); - flipper_format_file_close(test->ff); + flipper_format_buffered_file_close(test->ff); string_clear(buf); uint32_t j = 0; @@ -280,7 +281,7 @@ static void infrared_test_run_encoder_decoder(InfraredProtocol protocol, uint32_ test->ff, string_get_cstr(buf), &input_messages, &input_messages_count), "Failed to load messages from file"); - flipper_format_file_close(test->ff); + flipper_format_buffered_file_close(test->ff); string_clear(buf); for(uint32_t message_counter = 0; message_counter < input_messages_count; ++message_counter) { @@ -343,7 +344,7 @@ static void infrared_test_run_decoder(InfraredProtocol protocol, uint32_t test_i infrared_test_load_messages(test->ff, string_get_cstr(buf), &messages, &messages_count), "Failed to load messages from file"); - flipper_format_file_close(test->ff); + flipper_format_buffered_file_close(test->ff); string_clear(buf); InfraredMessage message_decoded_check_local; diff --git a/applications/unit_tests/stream/stream_test.c b/applications/unit_tests/stream/stream_test.c index b5e8a18b..65f1409a 100644 --- a/applications/unit_tests/stream/stream_test.c +++ b/applications/unit_tests/stream/stream_test.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include "../minunit.h" @@ -282,6 +283,13 @@ MU_TEST(stream_composite_test) { mu_check(file_stream_open(stream, "/ext/filestream.str", FSAM_READ_WRITE, FSOM_CREATE_ALWAYS)); MU_RUN_TEST_1(stream_composite_subtest, stream); stream_free(stream); + + // test buffered file stream + stream = buffered_file_stream_alloc(storage); + mu_check(buffered_file_stream_open( + stream, "/ext/filestream.str", FSAM_READ_WRITE, FSOM_CREATE_ALWAYS)); + MU_RUN_TEST_1(stream_composite_subtest, stream); + stream_free(stream); furi_record_close("storage"); } @@ -366,13 +374,101 @@ MU_TEST(stream_split_test) { mu_check(file_stream_open(stream, "/ext/filestream.str", FSAM_READ_WRITE, FSOM_CREATE_ALWAYS)); MU_RUN_TEST_1(stream_split_subtest, stream); stream_free(stream); + + // test buffered stream + stream = buffered_file_stream_alloc(storage); + mu_check(buffered_file_stream_open( + stream, "/ext/filestream.str", FSAM_READ_WRITE, FSOM_CREATE_ALWAYS)); + MU_RUN_TEST_1(stream_split_subtest, stream); + stream_free(stream); + furi_record_close("storage"); } +MU_TEST(stream_buffered_large_file_test) { + string_t input_data; + string_t output_data; + string_init(input_data); + string_init(output_data); + + Storage* storage = furi_record_open("storage"); + + // generate test data consisting of several identical lines + const size_t data_size = 4096; + const size_t line_size = strlen(stream_test_data); + const size_t rep_count = data_size / line_size + 1; + + for(size_t i = 0; i < rep_count; ++i) { + string_cat_printf(input_data, "%s\n", stream_test_data); + } + + // write test data to file + Stream* stream = buffered_file_stream_alloc(storage); + mu_check(buffered_file_stream_open( + stream, "/ext/filestream.str", FSAM_READ_WRITE, FSOM_CREATE_ALWAYS)); + mu_assert_int_eq(0, stream_size(stream)); + mu_assert_int_eq(string_size(input_data), stream_write_string(stream, input_data)); + mu_assert_int_eq(string_size(input_data), stream_size(stream)); + + const size_t substr_start = 8; + const size_t substr_len = 11; + + mu_check(stream_seek(stream, substr_start, StreamOffsetFromStart)); + mu_assert_int_eq(substr_start, stream_tell(stream)); + + // copy one substring from test data + char test_substr[substr_len + 1]; + memset(test_substr, 0, substr_len + 1); + memcpy(test_substr, stream_test_data + substr_start, substr_len); + + char buf[substr_len + 1]; + memset(buf, 0, substr_len + 1); + + // read substring + mu_assert_int_eq(substr_len, stream_read(stream, (uint8_t*)buf, substr_len)); + mu_assert_string_eq(test_substr, buf); + memset(buf, 0, substr_len + 1); + + // forward seek to cause a cache miss + mu_check(stream_seek( + stream, (line_size + 1) * (rep_count - 1) - substr_len, StreamOffsetFromCurrent)); + // read same substring from a different line + mu_assert_int_eq(substr_len, stream_read(stream, (uint8_t*)buf, substr_len)); + mu_assert_string_eq(test_substr, buf); + memset(buf, 0, substr_len + 1); + + // backward seek to cause a cache miss + mu_check(stream_seek( + stream, -((line_size + 1) * (rep_count - 1) + substr_len), StreamOffsetFromCurrent)); + mu_assert_int_eq(substr_len, stream_read(stream, (uint8_t*)buf, substr_len)); + mu_assert_string_eq(test_substr, buf); + + // read the whole file + mu_check(stream_rewind(stream)); + string_t tmp; + string_init(tmp); + while(stream_read_line(stream, tmp)) { + string_cat(output_data, tmp); + } + string_clear(tmp); + + // check against generated data + mu_assert_int_eq(string_size(input_data), string_size(output_data)); + mu_check(string_equal_p(input_data, output_data)); + mu_check(stream_eof(stream)); + + stream_free(stream); + + furi_record_close("storage"); + string_clear(input_data); + string_clear(output_data); +} + MU_TEST_SUITE(stream_suite) { MU_RUN_TEST(stream_write_read_save_load_test); MU_RUN_TEST(stream_composite_test); MU_RUN_TEST(stream_split_test); + MU_RUN_TEST(stream_buffered_large_file_test); } int run_minunit_test_stream() { diff --git a/lib/flipper_format/flipper_format.c b/lib/flipper_format/flipper_format.c index 846129cd..62005127 100644 --- a/lib/flipper_format/flipper_format.c +++ b/lib/flipper_format/flipper_format.c @@ -2,6 +2,7 @@ #include #include #include +#include #include "flipper_format.h" #include "flipper_format_i.h" #include "flipper_format_stream.h" @@ -36,11 +37,24 @@ FlipperFormat* flipper_format_file_alloc(Storage* storage) { return flipper_format; } +FlipperFormat* flipper_format_buffered_file_alloc(Storage* storage) { + FlipperFormat* flipper_format = malloc(sizeof(FlipperFormat)); + flipper_format->stream = buffered_file_stream_alloc(storage); + flipper_format->strict_mode = false; + return flipper_format; +} + bool flipper_format_file_open_existing(FlipperFormat* flipper_format, const char* path) { furi_assert(flipper_format); return file_stream_open(flipper_format->stream, path, FSAM_READ_WRITE, FSOM_OPEN_EXISTING); } +bool flipper_format_buffered_file_open_existing(FlipperFormat* flipper_format, const char* path) { + furi_assert(flipper_format); + return buffered_file_stream_open( + flipper_format->stream, path, FSAM_READ_WRITE, FSOM_OPEN_EXISTING); +} + bool flipper_format_file_open_append(FlipperFormat* flipper_format, const char* path) { furi_assert(flipper_format); @@ -87,6 +101,11 @@ bool flipper_format_file_close(FlipperFormat* flipper_format) { return file_stream_close(flipper_format->stream); } +bool flipper_format_buffered_file_close(FlipperFormat* flipper_format) { + furi_assert(flipper_format); + return buffered_file_stream_close(flipper_format->stream); +} + void flipper_format_free(FlipperFormat* flipper_format) { furi_assert(flipper_format); stream_free(flipper_format->stream); diff --git a/lib/flipper_format/flipper_format.h b/lib/flipper_format/flipper_format.h index e32a5219..3f7b71af 100644 --- a/lib/flipper_format/flipper_format.h +++ b/lib/flipper_format/flipper_format.h @@ -115,6 +115,12 @@ FlipperFormat* flipper_format_string_alloc(); */ FlipperFormat* flipper_format_file_alloc(Storage* storage); +/** + * Allocate FlipperFormat as file, buffered read-only mode. + * @return FlipperFormat* pointer to a FlipperFormat instance + */ +FlipperFormat* flipper_format_buffered_file_alloc(Storage* storage); + /** * Open existing file. * Use only if FlipperFormat allocated as a file. @@ -124,6 +130,15 @@ FlipperFormat* flipper_format_file_alloc(Storage* storage); */ bool flipper_format_file_open_existing(FlipperFormat* flipper_format, const char* path); +/** + * Open existing file, read-only with buffered read operations. + * Use only if FlipperFormat allocated as a file. + * @param flipper_format Pointer to a FlipperFormat instance + * @param path File path + * @return True on success + */ +bool flipper_format_buffered_file_open_existing(FlipperFormat* flipper_format, const char* path); + /** * Open existing file for writing and add values to the end of file. * Use only if FlipperFormat allocated as a file. @@ -159,6 +174,14 @@ bool flipper_format_file_open_new(FlipperFormat* flipper_format, const char* pat */ bool flipper_format_file_close(FlipperFormat* flipper_format); +/** + * Closes the file, use only if FlipperFormat allocated as a buffered file. + * @param flipper_format + * @return true + * @return false + */ +bool flipper_format_buffered_file_close(FlipperFormat* flipper_format); + /** * Free FlipperFormat. * @param flipper_format Pointer to a FlipperFormat instance diff --git a/lib/toolbox/stream/buffered_file_stream.c b/lib/toolbox/stream/buffered_file_stream.c new file mode 100644 index 00000000..5db276d3 --- /dev/null +++ b/lib/toolbox/stream/buffered_file_stream.c @@ -0,0 +1,155 @@ +#include "buffered_file_stream.h" + +#include "stream_i.h" +#include "file_stream.h" +#include "stream_cache.h" + +typedef struct { + Stream stream_base; + Stream* file_stream; + StreamCache* cache; +} BufferedFileStream; + +static void buffered_file_stream_free(BufferedFileStream* stream); +static bool buffered_file_stream_eof(BufferedFileStream* stream); +static void buffered_file_stream_clean(BufferedFileStream* stream); +static bool + buffered_file_stream_seek(BufferedFileStream* stream, int32_t offset, StreamOffset offset_type); +static size_t buffered_file_stream_tell(BufferedFileStream* stream); +static size_t buffered_file_stream_size(BufferedFileStream* stream); +static size_t + buffered_file_stream_write(BufferedFileStream* stream, const uint8_t* data, size_t size); +static size_t buffered_file_stream_read(BufferedFileStream* stream, uint8_t* data, size_t size); +static bool buffered_file_stream_delete_and_insert( + BufferedFileStream* stream, + size_t delete_size, + StreamWriteCB write_callback, + const void* ctx); + +const StreamVTable buffered_file_stream_vtable = { + .free = (StreamFreeFn)buffered_file_stream_free, + .eof = (StreamEOFFn)buffered_file_stream_eof, + .clean = (StreamCleanFn)buffered_file_stream_clean, + .seek = (StreamSeekFn)buffered_file_stream_seek, + .tell = (StreamTellFn)buffered_file_stream_tell, + .size = (StreamSizeFn)buffered_file_stream_size, + .write = (StreamWriteFn)buffered_file_stream_write, + .read = (StreamReadFn)buffered_file_stream_read, + .delete_and_insert = (StreamDeleteAndInsertFn)buffered_file_stream_delete_and_insert, +}; + +Stream* buffered_file_stream_alloc(Storage* storage) { + BufferedFileStream* stream = malloc(sizeof(BufferedFileStream)); + + stream->file_stream = file_stream_alloc(storage); + stream->cache = stream_cache_alloc(); + + stream->stream_base.vtable = &buffered_file_stream_vtable; + return (Stream*)stream; +} + +bool buffered_file_stream_open( + Stream* _stream, + const char* path, + FS_AccessMode access_mode, + FS_OpenMode open_mode) { + furi_assert(_stream); + BufferedFileStream* stream = (BufferedFileStream*)_stream; + stream_cache_drop(stream->cache); + furi_check(stream->stream_base.vtable == &buffered_file_stream_vtable); + return file_stream_open(stream->file_stream, path, access_mode, open_mode); +} + +bool buffered_file_stream_close(Stream* _stream) { + furi_assert(_stream); + BufferedFileStream* stream = (BufferedFileStream*)_stream; + furi_check(stream->stream_base.vtable == &buffered_file_stream_vtable); + return file_stream_close(stream->file_stream); +} + +FS_Error buffered_file_stream_get_error(Stream* _stream) { + furi_assert(_stream); + BufferedFileStream* stream = (BufferedFileStream*)_stream; + furi_check(stream->stream_base.vtable == &buffered_file_stream_vtable); + return file_stream_get_error(stream->file_stream); +} + +static void buffered_file_stream_free(BufferedFileStream* stream) { + furi_assert(stream); + stream_free(stream->file_stream); + stream_cache_free(stream->cache); + free(stream); +} + +static bool buffered_file_stream_eof(BufferedFileStream* stream) { + return stream_cache_at_end(stream->cache) && stream_eof(stream->file_stream); +} + +static void buffered_file_stream_clean(BufferedFileStream* stream) { + stream_cache_drop(stream->cache); + stream_clean(stream->file_stream); +} + +static bool buffered_file_stream_seek( + BufferedFileStream* stream, + int32_t offset, + StreamOffset offset_type) { + bool success = false; + int32_t new_offset = offset; + + if(offset_type == StreamOffsetFromCurrent) { + new_offset -= stream_cache_seek(stream->cache, offset); + if(new_offset < 0) { + new_offset -= (int32_t)stream_cache_size(stream->cache); + } + } + + if((new_offset != 0) || (offset_type != StreamOffsetFromCurrent)) { + stream_cache_drop(stream->cache); + success = stream_seek(stream->file_stream, new_offset, offset_type); + } else { + success = true; + } + + return success; +} + +static size_t buffered_file_stream_tell(BufferedFileStream* stream) { + return stream_tell(stream->file_stream) + stream_cache_pos(stream->cache) - + stream_cache_size(stream->cache); +} + +static size_t buffered_file_stream_size(BufferedFileStream* stream) { + return stream_cache_size(stream->cache) + stream_size(stream->file_stream); +} + +static size_t + buffered_file_stream_write(BufferedFileStream* stream, const uint8_t* data, size_t size) { + stream_cache_drop(stream->cache); + return stream_write(stream->file_stream, data, size); +} + +static size_t buffered_file_stream_read(BufferedFileStream* stream, uint8_t* data, size_t size) { + size_t need_to_read = size; + + while(need_to_read) { + need_to_read -= + stream_cache_read(stream->cache, data + (size - need_to_read), need_to_read); + if(need_to_read) { + if(!stream_cache_fill(stream->cache, stream->file_stream)) { + break; + } + } + } + + return size - need_to_read; +} + +static bool buffered_file_stream_delete_and_insert( + BufferedFileStream* stream, + size_t delete_size, + StreamWriteCB write_callback, + const void* ctx) { + stream_cache_drop(stream->cache); + return stream_delete_and_insert(stream->file_stream, delete_size, write_callback, ctx); +} diff --git a/lib/toolbox/stream/buffered_file_stream.h b/lib/toolbox/stream/buffered_file_stream.h new file mode 100644 index 00000000..e6ad7209 --- /dev/null +++ b/lib/toolbox/stream/buffered_file_stream.h @@ -0,0 +1,47 @@ +#pragma once +#include +#include +#include "stream.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Allocate a file stream with buffered read operations + * @return Stream* + */ +Stream* buffered_file_stream_alloc(Storage* storage); + +/** + * Opens an existing file or creates a new one. + * @param stream pointer to file stream object. + * @param path path to file + * @param access_mode access mode from FS_AccessMode + * @param open_mode open mode from FS_OpenMode + * @return success flag. You need to close the file even if the open operation failed. + */ +bool buffered_file_stream_open( + Stream* stream, + const char* path, + FS_AccessMode access_mode, + FS_OpenMode open_mode); + +/** + * Closes the file. + * @param stream + * @return true + * @return false + */ +bool buffered_file_stream_close(Stream* stream); + +/** + * Retrieves the error id from the file object + * @param stream pointer to stream object. + * @return FS_Error error id + */ +FS_Error buffered_file_stream_get_error(Stream* stream); + +#ifdef __cplusplus +} +#endif diff --git a/lib/toolbox/stream/stream_cache.c b/lib/toolbox/stream/stream_cache.c new file mode 100644 index 00000000..164ac466 --- /dev/null +++ b/lib/toolbox/stream/stream_cache.c @@ -0,0 +1,71 @@ +#include "stream_cache.h" + +#define STREAM_CACHE_MAX_SIZE 1024U + +struct StreamCache { + uint8_t data[STREAM_CACHE_MAX_SIZE]; + size_t data_size; + size_t position; +}; + +StreamCache* stream_cache_alloc() { + StreamCache* cache = malloc(sizeof(StreamCache)); + cache->data_size = 0; + cache->position = 0; + return cache; +} +void stream_cache_free(StreamCache* cache) { + furi_assert(cache); + cache->data_size = 0; + cache->position = 0; + free(cache); +} + +void stream_cache_drop(StreamCache* cache) { + cache->data_size = 0; + cache->position = 0; +} + +bool stream_cache_at_end(StreamCache* cache) { + furi_assert(cache->data_size >= cache->position); + return cache->data_size == cache->position; +} + +size_t stream_cache_size(StreamCache* cache) { + return cache->data_size; +} + +size_t stream_cache_pos(StreamCache* cache) { + return cache->position; +} + +size_t stream_cache_fill(StreamCache* cache, Stream* stream) { + const size_t size_read = stream_read(stream, cache->data, STREAM_CACHE_MAX_SIZE); + cache->data_size = size_read; + cache->position = 0; + return size_read; +} + +size_t stream_cache_read(StreamCache* cache, uint8_t* data, size_t size) { + furi_assert(cache->data_size >= cache->position); + const size_t size_read = MIN(size, cache->data_size - cache->position); + if(size_read > 0) { + memcpy(data, cache->data + cache->position, size_read); + cache->position += size_read; + } + return size_read; +} + +int32_t stream_cache_seek(StreamCache* cache, int32_t offset) { + furi_assert(cache->data_size >= cache->position); + int32_t actual_offset = 0; + + if(offset > 0) { + actual_offset = MIN(cache->data_size - cache->position, (size_t)offset); + } else if(offset < 0) { + actual_offset = -MIN(cache->position, (size_t)abs(offset)); + } + + cache->position += actual_offset; + return actual_offset; +} diff --git a/lib/toolbox/stream/stream_cache.h b/lib/toolbox/stream/stream_cache.h new file mode 100644 index 00000000..20c18d80 --- /dev/null +++ b/lib/toolbox/stream/stream_cache.h @@ -0,0 +1,77 @@ +#pragma once + +#include "stream.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct StreamCache StreamCache; + +/** + * Allocate stream cache. + * @return StreamCache* pointer to a StreamCache instance + */ +StreamCache* stream_cache_alloc(); + +/** + * Free stream cache. + * @param cache Pointer to a StreamCache instance + */ +void stream_cache_free(StreamCache* cache); + +/** + * Drop the cache contents and set it to initial state. + * @param cache Pointer to a StreamCache instance + */ +void stream_cache_drop(StreamCache* cache); + +/** + * Determine if the internal cursor is at end the end of cached data. + * @param cache Pointer to a StreamCache instance + * @return True if cursor is at end, otherwise false. + */ +bool stream_cache_at_end(StreamCache* cache); + +/** + * Get the current size of cached data. + * @param cache Pointer to a StreamCache instance + * @return Size of cached data. + */ +size_t stream_cache_size(StreamCache* cache); + +/** + * Get the internal cursor position. + * @param cache Pointer to a StreamCache instance + * @return Cursor position inside the cache. + */ +size_t stream_cache_pos(StreamCache* cache); + +/** + * Load the cache with new data from a stream. + * @param cache Pointer to a StreamCache instance + * @param stream Pointer to a Stream instance + * @return Size of newly cached data. + */ +size_t stream_cache_fill(StreamCache* cache, Stream* stream); + +/** + * Read cached data and advance the internal cursor. + * @param cache Pointer to a StreamCache instance. + * @param data Pointer to a data buffer. Must be initialized. + * @param size Maximum size in bytes to read from the cache. + * @return Actual size that was read. + */ +size_t stream_cache_read(StreamCache* cache, uint8_t* data, size_t size); + +/** + * Move the internal cursor relatively to its current position. + * @param cache Pointer to a StreamCache instance. + * @param offset Cursor offset. + * @return Actual cursor offset. Equal to offset parameter on hit. + */ +int32_t stream_cache_seek(StreamCache* cache, int32_t offset); + +#ifdef __cplusplus +} +#endif From 253b98c8f014e4fa91a129eaba3a986f91ac5b12 Mon Sep 17 00:00:00 2001 From: ESurge Date: Fri, 22 Jul 2022 20:35:14 -0700 Subject: [PATCH 17/37] Added condition to cli "log" command to end if serial terminal is disconnected. (#1425) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Added condition to cli "log" command. If USB is disconnected while "log" command is running, it will end the command. * Reverted change on cli_commands.c Added condition in cli.c for cli_cmd_interrupt_received function to react appropriately when serial terminal is disconnected. Added condition in subghz_cli.c for subghz chat cmd to exit gracefully when serial terminal is disconnected. * Formatting Co-authored-by: あく --- applications/cli/cli.c | 24 +++++++++++++----------- applications/subghz/subghz_cli.c | 5 +++++ 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/applications/cli/cli.c b/applications/cli/cli.c index a0b239d3..7d0f8dab 100644 --- a/applications/cli/cli.c +++ b/applications/cli/cli.c @@ -69,17 +69,6 @@ size_t cli_read_timeout(Cli* cli, uint8_t* buffer, size_t size, uint32_t timeout } } -bool cli_cmd_interrupt_received(Cli* cli) { - furi_assert(cli); - char c = '\0'; - if(cli->session != NULL) { - if(cli->session->rx((uint8_t*)&c, 1, 0) == 1) { - return c == CliSymbolAsciiETX; - } - } - return false; -} - bool cli_is_connected(Cli* cli) { furi_assert(cli); if(cli->session != NULL) { @@ -88,6 +77,19 @@ bool cli_is_connected(Cli* cli) { return false; } +bool cli_cmd_interrupt_received(Cli* cli) { + furi_assert(cli); + char c = '\0'; + if(cli_is_connected(cli)) { + if(cli->session->rx((uint8_t*)&c, 1, 0) == 1) { + return c == CliSymbolAsciiETX; + } + } else { + return true; + } + return false; +} + void cli_print_usage(const char* cmd, const char* usage, const char* arg) { furi_assert(cmd); furi_assert(arg); diff --git a/applications/subghz/subghz_cli.c b/applications/subghz/subghz_cli.c index 541b5c50..3944fc5b 100644 --- a/applications/subghz/subghz_cli.c +++ b/applications/subghz/subghz_cli.c @@ -676,6 +676,11 @@ static void subghz_cli_command_chat(Cli* cli, string_t args) { break; } } + if(cli_is_connected(cli)) { + printf("\r\n"); + chat_event.event = SubGhzChatEventUserExit; + subghz_chat_worker_put_event_chat(subghz_chat, &chat_event); + } } string_clear(input); From 7c49f604f986f13790051822c72ae7de1730827c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zo=C3=AB=20Prosvetova?= <109866245+ZoeMeetAgain@users.noreply.github.com> Date: Sat, 23 Jul 2022 18:33:39 +0200 Subject: [PATCH 18/37] Fix toolchain typos (#1435) --- scripts/toolchain/fbtenv.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/toolchain/fbtenv.sh b/scripts/toolchain/fbtenv.sh index df2b2457..55bc89b0 100755 --- a/scripts/toolchain/fbtenv.sh +++ b/scripts/toolchain/fbtenv.sh @@ -16,7 +16,7 @@ get_kernel_type() echo "In MinGW shell use \"fbt.cmd\" instead of \"fbt\""; exit 1; else - echo "Your system is not supported. Sorry. Please report us your configuration."; + echo "Sorry, your system is not supported. Please report your configuration to us."; exit 1; fi } @@ -41,7 +41,7 @@ download_toolchain() main() { if [ -z "${SCRIPT_PATH:-}" ]; then - echo "Mannual running this script is now allowed."; + echo "Manual running of this script is not allowed."; exit 1; fi get_kernel_type; # sets TOOLCHAIN_PATH From c22d66590e86ba27f99b79332f0ea1fd46e8ec83 Mon Sep 17 00:00:00 2001 From: Georgii Surkov <37121527+gsurkov@users.noreply.github.com> Date: Mon, 25 Jul 2022 14:23:47 +0300 Subject: [PATCH 19/37] [FL-2682] Allow spaces in file names #1444 --- lib/toolbox/path.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/toolbox/path.c b/lib/toolbox/path.c index 607671fb..767742ac 100644 --- a/lib/toolbox/path.c +++ b/lib/toolbox/path.c @@ -102,7 +102,7 @@ bool path_contains_only_ascii(const char* path) { } else if((*name_pos >= 'a') && (*name_pos <= 'z')) { name_pos++; continue; - } else if(strchr(".!#\\$%&'()-@^_`{}~", *name_pos) != NULL) { + } else if(strchr(" .!#\\$%&'()-@^_`{}~", *name_pos) != NULL) { name_pos++; continue; } @@ -111,4 +111,4 @@ bool path_contains_only_ascii(const char* path) { } return true; -} \ No newline at end of file +} From 3ee592cae724ca2823c96be4070cbc8ae0001e4f Mon Sep 17 00:00:00 2001 From: Ruben van Baarle Date: Mon, 25 Jul 2022 13:48:06 +0200 Subject: [PATCH 20/37] Fix SubGHz chat immediately closing #1440 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It's just an if condition which should've been inverted Co-authored-by: あく --- applications/subghz/subghz_cli.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/applications/subghz/subghz_cli.c b/applications/subghz/subghz_cli.c index 3944fc5b..eadef9f4 100644 --- a/applications/subghz/subghz_cli.c +++ b/applications/subghz/subghz_cli.c @@ -676,7 +676,7 @@ static void subghz_cli_command_chat(Cli* cli, string_t args) { break; } } - if(cli_is_connected(cli)) { + if(!cli_is_connected(cli)) { printf("\r\n"); chat_event.event = SubGhzChatEventUserExit; subghz_chat_worker_put_event_chat(subghz_chat, &chat_event); From f5d6a8084b2ff90608cf9fee65185b31f2080993 Mon Sep 17 00:00:00 2001 From: Nikolay Minaylov Date: Mon, 25 Jul 2022 15:11:34 +0300 Subject: [PATCH 21/37] [FL-2668] GUI message screens update #1428 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: SG Co-authored-by: あく --- .../bad_usb/scenes/bad_usb_scene_error.c | 16 ++++++----- .../scenes/gpio_scene_usb_uart_close_rpc.c | 26 +++++------------- .../lfrfid/scene/lfrfid_app_scene_write.cpp | 12 ++++---- .../scenes/storage_settings_scene_benchmark.c | 10 ++----- .../storage_settings_scene_format_confirm.c | 10 ++----- .../storage_settings_scene_formatting.c | 3 +- .../scenes/storage_settings_scene_sd_info.c | 10 ++----- .../storage_settings_scene_unmount_confirm.c | 12 +++----- .../scenes/storage_settings_scene_unmounted.c | 12 ++++---- .../subghz/scenes/subghz_scene_set_type.c | 2 +- .../scenes/subghz_scene_show_error_sub.c | 4 +-- .../subghz/scenes/subghz_scene_transmitter.c | 2 +- applications/subghz/subghz_i.c | 18 +++++++----- applications/u2f/scenes/u2f_scene_error.c | 16 ++++++----- .../icons/Common/ActiveConnection_50x64.png | Bin 0 -> 3842 bytes 15 files changed, 66 insertions(+), 87 deletions(-) mode change 100755 => 100644 applications/storage_settings/scenes/storage_settings_scene_unmounted.c create mode 100644 assets/icons/Common/ActiveConnection_50x64.png diff --git a/applications/bad_usb/scenes/bad_usb_scene_error.c b/applications/bad_usb/scenes/bad_usb_scene_error.c index c8e1c361..abd7b38b 100644 --- a/applications/bad_usb/scenes/bad_usb_scene_error.c +++ b/applications/bad_usb/scenes/bad_usb_scene_error.c @@ -27,20 +27,22 @@ void bad_usb_scene_error_on_enter(void* context) { AlignTop, FontSecondary, "No SD card or\napp data found.\nThis app will not\nwork without\nrequired files."); + widget_add_button_element( + app->widget, GuiButtonTypeLeft, "Back", bad_usb_scene_error_event_callback, app); } else if(app->error == BadUsbAppErrorCloseRpc) { + widget_add_icon_element(app->widget, 78, 0, &I_ActiveConnection_50x64); + widget_add_string_multiline_element( + app->widget, 3, 2, AlignLeft, AlignTop, FontPrimary, "Connection\nis active!"); widget_add_string_multiline_element( app->widget, - 63, - 10, - AlignCenter, + 3, + 30, + AlignLeft, AlignTop, FontSecondary, - "Disconnect from\ncompanion app\nto use this function"); + "Disconnect from\nPC or phone to\nuse this function."); } - widget_add_button_element( - app->widget, GuiButtonTypeLeft, "Back", bad_usb_scene_error_event_callback, app); - view_dispatcher_switch_to_view(app->view_dispatcher, BadUsbAppViewError); } diff --git a/applications/gpio/scenes/gpio_scene_usb_uart_close_rpc.c b/applications/gpio/scenes/gpio_scene_usb_uart_close_rpc.c index e09f2fd3..2cb53cab 100644 --- a/applications/gpio/scenes/gpio_scene_usb_uart_close_rpc.c +++ b/applications/gpio/scenes/gpio_scene_usb_uart_close_rpc.c @@ -1,32 +1,20 @@ #include "../gpio_app_i.h" #include "../gpio_custom_event.h" -static void gpio_scene_usb_uart_close_rpc_event_callback( - GuiButtonType result, - InputType type, - void* context) { - furi_assert(context); - GpioApp* app = context; - - if((result == GuiButtonTypeLeft) && (type == InputTypeShort)) { - view_dispatcher_send_custom_event(app->view_dispatcher, GpioCustomEventErrorBack); - } -} - void gpio_scene_usb_uart_close_rpc_on_enter(void* context) { GpioApp* app = context; + widget_add_icon_element(app->widget, 78, 0, &I_ActiveConnection_50x64); + widget_add_string_multiline_element( + app->widget, 3, 2, AlignLeft, AlignTop, FontPrimary, "Connection\nis active!"); widget_add_string_multiline_element( app->widget, - 63, - 10, - AlignCenter, + 3, + 30, + AlignLeft, AlignTop, FontSecondary, - "Disconnect from\ncompanion app\nto use this function"); - - widget_add_button_element( - app->widget, GuiButtonTypeLeft, "Back", gpio_scene_usb_uart_close_rpc_event_callback, app); + "Disconnect from\nPC or phone to\nuse this function."); view_dispatcher_switch_to_view(app->view_dispatcher, GpioAppViewUsbUartCloseRpc); } diff --git a/applications/lfrfid/scene/lfrfid_app_scene_write.cpp b/applications/lfrfid/scene/lfrfid_app_scene_write.cpp index d6c9e9f4..ff7b49a4 100644 --- a/applications/lfrfid/scene/lfrfid_app_scene_write.cpp +++ b/applications/lfrfid/scene/lfrfid_app_scene_write.cpp @@ -41,13 +41,13 @@ bool LfRfidAppSceneWrite::on_event(LfRfidApp* app, LfRfidApp::Event* event) { case RfidWorker::WriteResult::NotWritable: if(!card_not_supported) { auto popup = app->view_controller.get(); - popup->set_icon(0, 0, NULL); - popup->set_header("Still trying to write", 64, 7, AlignCenter, AlignTop); + popup->set_icon(72, 14, &I_DolphinFirstStart8_56x51); + popup->set_header("Still trying to write...", 64, 3, AlignCenter, AlignTop); popup->set_text( - "This card may be protected\nor does not support this\ntype of writing", - 64, - 23, - AlignCenter, + "Make sure this\ncard is writable\nand not\nprotected.", + 3, + 17, + AlignLeft, AlignTop); card_not_supported = true; } diff --git a/applications/storage_settings/scenes/storage_settings_scene_benchmark.c b/applications/storage_settings/scenes/storage_settings_scene_benchmark.c index e7c55ad1..947bb4e5 100644 --- a/applications/storage_settings/scenes/storage_settings_scene_benchmark.c +++ b/applications/storage_settings/scenes/storage_settings_scene_benchmark.c @@ -122,14 +122,10 @@ void storage_settings_scene_benchmark_on_enter(void* context) { view_dispatcher_switch_to_view(app->view_dispatcher, StorageSettingsViewDialogEx); if(sd_status != FSE_OK) { - dialog_ex_set_header(dialog_ex, "SD card not mounted", 64, 10, AlignCenter, AlignCenter); + dialog_ex_set_icon(dialog_ex, 72, 14, &I_DolphinFirstStart8_56x51); + dialog_ex_set_header(dialog_ex, "SD card not mounted", 64, 3, AlignCenter, AlignTop); dialog_ex_set_text( - dialog_ex, - "If an SD card is inserted,\r\npull it out and reinsert it", - 64, - 32, - AlignCenter, - AlignCenter); + dialog_ex, "Try to reinsert\nor format SD\ncard.", 3, 19, AlignLeft, AlignTop); dialog_ex_set_center_button_text(dialog_ex, "Ok"); } else { storage_settings_scene_benchmark(app); diff --git a/applications/storage_settings/scenes/storage_settings_scene_format_confirm.c b/applications/storage_settings/scenes/storage_settings_scene_format_confirm.c index 1ebe8dfb..6388a682 100644 --- a/applications/storage_settings/scenes/storage_settings_scene_format_confirm.c +++ b/applications/storage_settings/scenes/storage_settings_scene_format_confirm.c @@ -14,14 +14,10 @@ void storage_settings_scene_format_confirm_on_enter(void* context) { FS_Error sd_status = storage_sd_status(app->fs_api); if(sd_status == FSE_NOT_READY) { - dialog_ex_set_header(dialog_ex, "SD card not mounted", 64, 10, AlignCenter, AlignCenter); + dialog_ex_set_icon(dialog_ex, 72, 14, &I_DolphinFirstStart8_56x51); + dialog_ex_set_header(dialog_ex, "SD card not mounted", 64, 3, AlignCenter, AlignTop); dialog_ex_set_text( - dialog_ex, - "If an SD card is inserted,\r\npull it out and reinsert it", - 64, - 32, - AlignCenter, - AlignCenter); + dialog_ex, "Try to reinsert\nor format SD\ncard.", 3, 19, AlignLeft, AlignTop); dialog_ex_set_center_button_text(dialog_ex, "Ok"); } else { dialog_ex_set_header(dialog_ex, "Format SD card?", 64, 10, AlignCenter, AlignCenter); diff --git a/applications/storage_settings/scenes/storage_settings_scene_formatting.c b/applications/storage_settings/scenes/storage_settings_scene_formatting.c index 2cbf97ee..c4e15b26 100755 --- a/applications/storage_settings/scenes/storage_settings_scene_formatting.c +++ b/applications/storage_settings/scenes/storage_settings_scene_formatting.c @@ -47,7 +47,8 @@ void storage_settings_scene_formatting_on_enter(void* context) { dialog_ex_set_text( dialog_ex, storage_error_get_desc(error), 64, 32, AlignCenter, AlignCenter); } else { - dialog_ex_set_header(dialog_ex, "Format complete!", 64, 32, AlignCenter, AlignCenter); + dialog_ex_set_icon(dialog_ex, 72, 14, &I_DolphinFirstStart8_56x51); + dialog_ex_set_header(dialog_ex, "Format\ncomplete!", 14, 15, AlignLeft, AlignTop); } dialog_ex_set_center_button_text(dialog_ex, "OK"); } diff --git a/applications/storage_settings/scenes/storage_settings_scene_sd_info.c b/applications/storage_settings/scenes/storage_settings_scene_sd_info.c index 69ad1ea5..1c861538 100644 --- a/applications/storage_settings/scenes/storage_settings_scene_sd_info.c +++ b/applications/storage_settings/scenes/storage_settings_scene_sd_info.c @@ -18,14 +18,10 @@ void storage_settings_scene_sd_info_on_enter(void* context) { dialog_ex_set_result_callback(dialog_ex, storage_settings_scene_sd_info_dialog_callback); if(sd_status != FSE_OK) { - dialog_ex_set_header(dialog_ex, "SD card not mounted", 64, 10, AlignCenter, AlignCenter); + dialog_ex_set_icon(dialog_ex, 72, 14, &I_DolphinFirstStart8_56x51); + dialog_ex_set_header(dialog_ex, "SD card not mounted", 64, 3, AlignCenter, AlignTop); dialog_ex_set_text( - dialog_ex, - "If an SD card is inserted,\r\npull it out and reinsert it", - 64, - 32, - AlignCenter, - AlignCenter); + dialog_ex, "Try to reinsert\nor format SD\ncard.", 3, 19, AlignLeft, AlignTop); dialog_ex_set_center_button_text(dialog_ex, "Ok"); } else { string_printf( diff --git a/applications/storage_settings/scenes/storage_settings_scene_unmount_confirm.c b/applications/storage_settings/scenes/storage_settings_scene_unmount_confirm.c index 001ce768..27f55251 100644 --- a/applications/storage_settings/scenes/storage_settings_scene_unmount_confirm.c +++ b/applications/storage_settings/scenes/storage_settings_scene_unmount_confirm.c @@ -14,15 +14,11 @@ void storage_settings_scene_unmount_confirm_on_enter(void* context) { FS_Error sd_status = storage_sd_status(app->fs_api); if(sd_status == FSE_NOT_READY) { - dialog_ex_set_header(dialog_ex, "SD card not mounted", 64, 10, AlignCenter, AlignCenter); + dialog_ex_set_icon(dialog_ex, 72, 14, &I_DolphinFirstStart8_56x51); + dialog_ex_set_header(dialog_ex, "SD card not mounted", 64, 3, AlignCenter, AlignTop); dialog_ex_set_text( - dialog_ex, - "If an SD card is inserted,\r\npull it out and reinsert it", - 64, - 32, - AlignCenter, - AlignCenter); - dialog_ex_set_center_button_text(dialog_ex, "OK"); + dialog_ex, "Try to reinsert\nor format SD\ncard.", 3, 19, AlignLeft, AlignTop); + dialog_ex_set_center_button_text(dialog_ex, "Ok"); } else { dialog_ex_set_header(dialog_ex, "Unmount SD card?", 64, 10, AlignCenter, AlignCenter); dialog_ex_set_text( diff --git a/applications/storage_settings/scenes/storage_settings_scene_unmounted.c b/applications/storage_settings/scenes/storage_settings_scene_unmounted.c old mode 100755 new mode 100644 index ddd70d05..e5f69d45 --- a/applications/storage_settings/scenes/storage_settings_scene_unmounted.c +++ b/applications/storage_settings/scenes/storage_settings_scene_unmounted.c @@ -13,17 +13,15 @@ void storage_settings_scene_unmounted_on_enter(void* context) { DialogEx* dialog_ex = app->dialog_ex; dialog_ex_set_center_button_text(dialog_ex, "OK"); + dialog_ex_set_icon(dialog_ex, 72, 14, &I_DolphinFirstStart8_56x51); if(error == FSE_OK) { - dialog_ex_set_header(dialog_ex, "SD card unmounted", 64, 10, AlignCenter, AlignCenter); - dialog_ex_set_text( - dialog_ex, "Now the SD card\ncan be removed.", 64, 32, AlignCenter, AlignCenter); + dialog_ex_set_header(dialog_ex, "SD card unmounted", 64, 3, AlignCenter, AlignTop); + dialog_ex_set_text(dialog_ex, "You can remove\nSD card now.", 3, 22, AlignLeft, AlignTop); notification_message(app->notification, &sequence_blink_green_100); } else { - dialog_ex_set_header( - dialog_ex, "Cannot unmount SD Card", 64, 10, AlignCenter, AlignCenter); - dialog_ex_set_text( - dialog_ex, storage_error_get_desc(error), 64, 32, AlignCenter, AlignCenter); + dialog_ex_set_header(dialog_ex, "Cannot unmount SD Card", 64, 3, AlignCenter, AlignTop); + dialog_ex_set_text(dialog_ex, storage_error_get_desc(error), 3, 22, AlignLeft, AlignTop); notification_message(app->notification, &sequence_blink_red_100); } diff --git a/applications/subghz/scenes/subghz_scene_set_type.c b/applications/subghz/scenes/subghz_scene_set_type.c index a7a4491e..55db8011 100644 --- a/applications/subghz/scenes/subghz_scene_set_type.c +++ b/applications/subghz/scenes/subghz_scene_set_type.c @@ -26,7 +26,7 @@ bool subghz_scene_set_type_submenu_gen_data_protocol( subghz_receiver_search_decoder_base_by_name(subghz->txrx->receiver, protocol_name); if(subghz->txrx->decoder_result == NULL) { - string_set_str(subghz->error_str, "Protocol not found"); + string_set_str(subghz->error_str, "Protocol not\nfound!"); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowErrorSub); return false; } diff --git a/applications/subghz/scenes/subghz_scene_show_error_sub.c b/applications/subghz/scenes/subghz_scene_show_error_sub.c index 64cd5b5a..697588d0 100644 --- a/applications/subghz/scenes/subghz_scene_show_error_sub.c +++ b/applications/subghz/scenes/subghz_scene_show_error_sub.c @@ -11,8 +11,8 @@ void subghz_scene_show_error_sub_on_enter(void* context) { // Setup view Popup* popup = subghz->popup; - popup_set_icon(popup, 32, 12, &I_DolphinFirstStart7_61x51); - popup_set_header(popup, string_get_cstr(subghz->error_str), 64, 8, AlignCenter, AlignBottom); + popup_set_icon(popup, 72, 14, &I_DolphinFirstStart8_56x51); + popup_set_header(popup, string_get_cstr(subghz->error_str), 14, 15, AlignLeft, AlignTop); popup_set_timeout(popup, 1500); popup_set_context(popup, subghz); popup_set_callback(popup, subghz_scene_show_error_sub_popup_callback); diff --git a/applications/subghz/scenes/subghz_scene_transmitter.c b/applications/subghz/scenes/subghz_scene_transmitter.c index b8b22749..b3f8d079 100644 --- a/applications/subghz/scenes/subghz_scene_transmitter.c +++ b/applications/subghz/scenes/subghz_scene_transmitter.c @@ -94,7 +94,7 @@ bool subghz_scene_transmitter_on_event(void* context, SceneManagerEvent event) { subghz->scene_manager, SubGhzSceneStart); return true; } else if(event.event == SubGhzCustomEventViewTransmitterError) { - string_set_str(subghz->error_str, "Protocol not found"); + string_set_str(subghz->error_str, "Protocol not\nfound!"); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowErrorSub); } } else if(event.type == SceneManagerEventTypeTick) { diff --git a/applications/subghz/subghz_i.c b/applications/subghz/subghz_i.c index 0593cc6f..f6e4d4f5 100644 --- a/applications/subghz/subghz_i.c +++ b/applications/subghz/subghz_i.c @@ -205,15 +205,19 @@ void subghz_tx_stop(SubGhz* subghz) { void subghz_dialog_message_show_only_rx(SubGhz* subghz) { DialogsApp* dialogs = subghz->dialogs; DialogMessage* message = dialog_message_alloc(); + + dialog_message_set_header(message, "Transmission is blocked", 63, 3, AlignCenter, AlignTop); + dialog_message_set_text( message, - "This frequency can\nonly be used for RX\nin your region", - 38, - 23, - AlignCenter, - AlignCenter); - dialog_message_set_icon(message, &I_DolphinFirstStart7_61x51, 67, 12); - dialog_message_set_buttons(message, "Back", NULL, NULL); + "This frequency\nis restricted to\nreceiving only\nin your region.", + 3, + 17, + AlignLeft, + AlignTop); + + dialog_message_set_icon(message, &I_DolphinFirstStart8_56x51, 72, 14); + dialog_message_show(dialogs, message); dialog_message_free(message); } diff --git a/applications/u2f/scenes/u2f_scene_error.c b/applications/u2f/scenes/u2f_scene_error.c index d4018367..e10e9c09 100644 --- a/applications/u2f/scenes/u2f_scene_error.c +++ b/applications/u2f/scenes/u2f_scene_error.c @@ -22,20 +22,22 @@ void u2f_scene_error_on_enter(void* context) { AlignTop, FontSecondary, "No SD card or\napp data found.\nThis app will not\nwork without\nrequired files."); + widget_add_button_element( + app->widget, GuiButtonTypeLeft, "Back", u2f_scene_error_event_callback, app); } else if(app->error == U2fAppErrorCloseRpc) { + widget_add_icon_element(app->widget, 78, 0, &I_ActiveConnection_50x64); + widget_add_string_multiline_element( + app->widget, 3, 2, AlignLeft, AlignTop, FontPrimary, "Connection\nis active!"); widget_add_string_multiline_element( app->widget, - 63, - 10, - AlignCenter, + 3, + 30, + AlignLeft, AlignTop, FontSecondary, - "Disconnect from\ncompanion app\nto use this function"); + "Disconnect from\nPC or phone to\nuse this function."); } - widget_add_button_element( - app->widget, GuiButtonTypeLeft, "Back", u2f_scene_error_event_callback, app); - view_dispatcher_switch_to_view(app->view_dispatcher, U2fAppViewError); } diff --git a/assets/icons/Common/ActiveConnection_50x64.png b/assets/icons/Common/ActiveConnection_50x64.png new file mode 100644 index 0000000000000000000000000000000000000000..1d7686dddf8a33b724c7528ed36435514b7518b2 GIT binary patch literal 3842 zcmaJ@c|278_rI3PzAvFNMm&{e7)wmXzKj~%*ehv_!7y86EF(lkN?EdHO(@h*N=UY3 zZ7fkFOO`ANjU^;YzwvyZp6~CEU%&f$-FwgH-1qx^&gYzS@9SQ-wYK2rk>&vafZq~f zielZNtkaN-gLNhGzPAJb9uu62iLIrH35ZM~dExL_00Y=T+{c5+j+w|kQsr%QBj$9h<5`_= zvcrYX!$Oz~3!5J{Yi6=$wz_EDf)T3YU<@oW!^@U{0@_p^+Qfji z{lF9ZXP!JjG63Ldp~hg~AwMwx-BN!KFi@N{EC~$c9Vq4kZm|LBM=TDr8@>e2J4T|E z*&7;xT)H7xm9wFgEyA?|YQY{+y9Wr2b4d_1JP$;q8!LAJARTtVV==bq+y8?q5g)7dgSlylFvP4D0V9$wxB1&@2RYM*2Ee`$=9#$v)`Zg50U)VMn4d_fO_zVCwU-q9ZN|r>nZ~=g6Zsf5iM*H|)iP0MbvR)mm zX^><`?=>~#JKUfrWW0AW;sDRR{i#M$4h^sY&gV}!q;rKc#)ZmXsq661jES6$oFhx_ zJ-Xh>mnd2e79;EtHvsP9l1z`|1fvm}w<8KbvoT_J;N~_;0ei8rZ=xGQ zep!VgrhDtG;m?GjHW2j2){Pnq_2kH>b{y~70}Njj$x7d7$@TA{Y6`kVq~`hcNS7ai zM^xk$_MG|>Kn22X#9<o9w4gy=lixvN5r_{#|i7A{B^lOlzA`ErqJE@$p5SJfN;0w)#Olq-aYY%~RXz{(O_ z%;}2X6~bj973UHN?Vl#O zo<`6?X^E8yf(bUaH``xNR*J!zV(3vS=!YEM5?|Ykp^Tw_FKxV1c+#^>GnWeo=>-GDxZ+2$( z%J(2X{%HOytq6}JQhrhwr3&{~Nf`v8?m_r4=|hvevTZ0%U6c;Xw8 z6j+K=N_fi5LkCBHM}t1vLtckRj)ITQIfXqicYJ31xtROC#G}6AgN`qYwM)BDL8y4! zZaeq~S?sF6{&Z&Ub^0AAeJ7gJs?!I$W&hbZ9FmdU6nD#^1-PDhDcgqnxs9U@J1o=ZU`e~ zO8Q%M@AG%7`I#>>hf6*Z-j8&^o5LP$TB&Brw7b2AGmXA4uDeWJ==hvnm|57kk}v}~ z7kJL~+-B_|n`c>yIsIycwxOmoW3`Nn=VAJA?9Z-Q4*eE=_PZf>uhl)M1CPS%J z)5G^|{Z0d8l7FF1nj*R4APEU;{bZQNa~6 zW`U2XlEq1-OKyaT9X$qpsQT5e+@5-Yx~|+$pLE^yu8muYFTVNW#E@?VCD5Dhi$~!x z^O;o}ep6z1f z1nIeIxh90_MBNcddulLs1!Qas*>5vdNVGaAx_mV=%EqiN?^d2&S!LBpz1!2-PAO|T zBPYU4e)>e)mliGPwdO?V@dbnVUhr2K~e%8)od3fYrijw-bkkU&C;l!DLfKNDPqs70K9uQBSi z^L0a>_p(H2ZNd}Vswd9|s)AjY#=!MvFD2w-?InX$)!k6lp24`q-Y|v_<7w))?Su=; zaoLwPyc~zR(tH2DiPB|f&6MKgb_TKZ`{@@Lade8OBhxpn?~K!>W0EQEbTYlD^v4tP zs_6-5Yxlm;RT^P%@YBi4Hw$x!xq>+&eciSG@yS|WqrSJ%i~J=rOSh(E+zBT?QSXKL zuEuqicfRT5&_Zi1oav~b4=vx*&R+}3zU0Pm+AeuiS@%(Ku)lsJ=;DgNm4o6ZJ~5N$ zYo03wJNwm|g{=~Mzg-@Qm-djUuAdGcsj>*NY0inic>m(QH8bX%FO`HJeq3Mwl$(Ik zzI6xzBTr>UkOngsGJ>9yPahL#G@5$#*XV=Li=S=3-0ONh{JL{A{Zi#B*BpYT)C;Q* zpsVB)a^d%CnO|<^XCFLw(4wyLS2$DsGbW%_E8aOLH~R>DX=Czo(&s|Y!klbt1Ni&& zVcI%!E8Wk{&aKwlq&vqzlKKr<>Av2+@@XdCZLx;@9lY)_q)>UP1YQca2q$lkBOae2 z&0*IW3(k6_)bCbvCwiFgF8%av==1;Z{W#xnzWcSSAX9+*TFy@LuXoqRdo4OF`sB^! zZ^dWJ%F6Id*DiZ@C5;z8Efnp36YlhjHs}9nW^{XE^HjIX*1#g~Mr?O|DXn;g!hBTx z7}hG^DqGVVN>R;RsP-f;Y7m-&1&lmN9$1hi0qu=NVbPwn3+-4v0N^-+b8w-$SRr8;5deQ<~n3f4Zv+5r>d zhtc%}8|Z`df?+HH0+xyf1rzW@e^@Xa{I@QQW$(HnV9?(XsvjKupQK!@Y(XX@3Kn!+ z6{>|JenB{I4w0|DQ^+Y6b~LlOgJ=YP-Ao4YacQ|DgoJzi59d z3j5!D|4(6m2O1d*L1Fz#0Tc|YcV6~A`jDt3e;*PV1l3U0 z1Rb$LV{pV>&(XgrR#q@eqCXW)#9%E=;b4}CDh}rf(>5`OnnI83nw#sGsH>Zq7@2Dr znVK4znQH22Le)*pe{)Sqm;eHnNd3+A{4dw&kKEmXAdp#+O|cYQAlB2ILLz|v-Zc#O z=Uk5eQSTqF=bv-Y`6Cy?N(Qpq+yB+;-!9ew?VA4%FKhAd_+yEznWwOZTSahmj`d>f zwM9CZ{rdHbWjZ##3kLu;K}%C3hv32CR3nMkATHDNP50`@*G0JbZdhsG&#ag}kt-x* zbi6EjpiYUf^utT&I-ggwTw)8K9Wu<#NjKCWviOGnxNwI<3!$qd0;#|wTaC0<=DJ&4 z-o}fdK$^-X*DQay#`Ty87;GIAW(;r{nhujLM{vr&Ry`!wB1~-L(Uq&iu{k>R-V8os2N6zY@I0ry5ZRP(0CFwaUqp$rweNmLEX}M Date: Mon, 25 Jul 2022 15:11:24 +0200 Subject: [PATCH 22/37] Port over Issue templates to new YML format (#1433) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * WIP Push * Add feature request label to template * Punctuation helps * rename feature request and add in enhancement * wording * Add in extra markdown explanations Co-authored-by: SG Co-authored-by: あく --- .github/ISSUE_TEMPLATE/01_bug_report.yml | 46 +++++++++++++++++++ .github/ISSUE_TEMPLATE/02_enhancements.yml | 21 +++++++++ .github/ISSUE_TEMPLATE/03_feature_request.yml | 24 ++++++++++ .github/ISSUE_TEMPLATE/bug_report.md | 30 ------------ .github/ISSUE_TEMPLATE/config.yml | 5 ++ .github/ISSUE_TEMPLATE/discuss-issue.md | 12 ----- .github/ISSUE_TEMPLATE/feature_request.md | 20 -------- .github/ISSUE_TEMPLATE/in-progress.md | 10 ---- .github/ISSUE_TEMPLATE/need-help.md | 10 ---- 9 files changed, 96 insertions(+), 82 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/01_bug_report.yml create mode 100644 .github/ISSUE_TEMPLATE/02_enhancements.yml create mode 100644 .github/ISSUE_TEMPLATE/03_feature_request.yml delete mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/config.yml delete mode 100644 .github/ISSUE_TEMPLATE/discuss-issue.md delete mode 100644 .github/ISSUE_TEMPLATE/feature_request.md delete mode 100644 .github/ISSUE_TEMPLATE/in-progress.md delete mode 100644 .github/ISSUE_TEMPLATE/need-help.md diff --git a/.github/ISSUE_TEMPLATE/01_bug_report.yml b/.github/ISSUE_TEMPLATE/01_bug_report.yml new file mode 100644 index 00000000..4697c083 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/01_bug_report.yml @@ -0,0 +1,46 @@ +name: Bug report +description: File a bug reports regarding the firmware. +labels: ['bug'] +body: +- type: markdown + attributes: + value: | + Thank you for taking the time to fill out an issue, this template is meant for any issues related to the Flipper Zero firmware. + If you require help with the Flipper zero and its firmware, we ask that you join [our forum](https://forum.flipperzero.one) +- type: textarea + id: description + attributes: + label: Desctibe the bug. + description: "A clear and concise description of what the bug is." + validations: + required: true +- type: textarea + id: repro + attributes: + label: Reproduction + description: "How can this bug be reproduced?" + placeholder: | + 1. Switch on... + 2. Press button '....' + 3. Wait for the moon phase + 4. It burns + validations: + required: true +- type: input + id: target + attributes: + label: Target + description: Specify the target + # Target seems to be largely ignored by outside sources. +- type: textarea + id: logs + attributes: + label: Logs + description: Attach your debug logs here + render: Text + # Avoid rendering as Markdown here. +- type: textarea + id: anything-else + attributes: + label: Anything else? + description: Let us know if you have anything else to share. diff --git a/.github/ISSUE_TEMPLATE/02_enhancements.yml b/.github/ISSUE_TEMPLATE/02_enhancements.yml new file mode 100644 index 00000000..1768e193 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/02_enhancements.yml @@ -0,0 +1,21 @@ +name: Enhancements +description: Suggest improvements for any existing functionality within the firmware. +body: +- type: markdown + attributes: + value: | + Thank you for taking the time to fill out an issue. This template is meant for feature requests and improvements to already existing functionality. + If you require help with the Flipper zero and its firmware, we ask that you join [our forum](https://forum.flipperzero.one) +- type: textarea + id: proposal + attributes: + label: "Describe the enhancement you're suggesting." + description: | + Feel free to describe in as much detail as you wish. + validations: + required: true +- type: textarea + id: anything-else + attributes: + label: Anything else? + description: Let us know if you have anything else to share. diff --git a/.github/ISSUE_TEMPLATE/03_feature_request.yml b/.github/ISSUE_TEMPLATE/03_feature_request.yml new file mode 100644 index 00000000..2af11454 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/03_feature_request.yml @@ -0,0 +1,24 @@ +name: Feature Request +description: For feature requests regarding the firmware. +labels: ['feature request'] +body: +- type: markdown + attributes: + value: | + Thank you for taking the time to fill out an issue, this template is meant for any feature suggestions. + If you require help with the Flipper zero and its firmware, we ask that you join [our forum](https://forum.flipperzero.one) +- type: textarea + id: proposal + attributes: + label: "Description of the feature you're suggesting." + description: | + Please describe your feature request in as many details as possible. + - Describe what it should do. + - Note whetever it is to extend existing functionality or introduce new functionality. + validations: + required: true +- type: textarea + id: anything-else + attributes: + label: Anything else? + description: Let us know if you have anything else to share. diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index cf337499..00000000 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -name: Bug report -about: Create a report to help us improve -title: '' -labels: bug -assignees: '' - ---- - -**Describe the bug** -A clear and concise description of what the bug is. - -**To Reproduce** -Steps to reproduce the behavior: -1. Switch on... -2. Press button '....' -3. Wait for the moon phase -4. It burns - -**Expected behavior** -A clear and concise description of what you expected to happen. - -**Logs** -Add debug logs - -**Target** -Specify the target - -**Additional context** -Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 00000000..55ff9d29 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,5 @@ +blank_issues_enabled: true +contact_links: + - name: Need help? + url: https://forum.flipperzero.one + about: For any question regarding on how to use the Flipper Zero and its firmware. diff --git a/.github/ISSUE_TEMPLATE/discuss-issue.md b/.github/ISSUE_TEMPLATE/discuss-issue.md deleted file mode 100644 index d036533d..00000000 --- a/.github/ISSUE_TEMPLATE/discuss-issue.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -name: Discuss issue -about: Start discussion about improvements -title: '' -labels: discussion -assignees: '' - ---- - -# What are you want to add or change - -# What questions do you have diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index e301d68c..00000000 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -name: Feature request -about: Suggest an idea for this project -title: '' -labels: feature request -assignees: '' - ---- - -**Is your feature request related to a problem? Please describe.** -A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] - -**Describe the solution you'd like** -A clear and concise description of what you want to happen. - -**Describe alternatives you've considered** -A clear and concise description of any alternative solutions or features you've considered. - -**Additional context** -Add any other context or screenshots about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/in-progress.md b/.github/ISSUE_TEMPLATE/in-progress.md deleted file mode 100644 index e8cf0332..00000000 --- a/.github/ISSUE_TEMPLATE/in-progress.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -name: In progress -about: When you start doing your big deal -title: '' -labels: in progress -assignees: '' - ---- - -Shortly (or not) describe what are you will do diff --git a/.github/ISSUE_TEMPLATE/need-help.md b/.github/ISSUE_TEMPLATE/need-help.md deleted file mode 100644 index c7b1e286..00000000 --- a/.github/ISSUE_TEMPLATE/need-help.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -name: Need help -about: Ask the community for help if you confused and can't figure out something -title: '' -labels: need help -assignees: '' - ---- - -# Describe you problem here From d80edba8916210248cb2f0107f872cddc1dceb95 Mon Sep 17 00:00:00 2001 From: Nikolay Minaylov Date: Mon, 25 Jul 2022 17:16:45 +0300 Subject: [PATCH 23/37] RPC App: state message and GUI update (#1423) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * RPC App: state message and GUI update * Protobuf submodule update Co-authored-by: SG Co-authored-by: あく --- applications/ibutton/ibutton.c | 18 ++++-- applications/ibutton/ibutton_custom_event.h | 1 + .../ibutton/scenes/ibutton_scene_rpc.c | 39 +++++++++++-- applications/infrared/infrared.c | 17 ++++-- applications/infrared/infrared_custom_event.h | 1 + .../infrared/scenes/infrared_scene_rpc.c | 12 +++- applications/lfrfid/lfrfid_app.cpp | 2 + .../lfrfid/scene/lfrfid_app_scene_rpc.cpp | 23 +++++++- applications/nfc/helpers/nfc_custom_event.h | 1 + applications/nfc/nfc.c | 32 ++++++---- applications/nfc/scenes/nfc_scene_rpc.c | 25 ++++++-- applications/rpc/rpc_app.c | 29 +++++++++- applications/rpc/rpc_app.h | 4 ++ .../subghz/helpers/subghz_custom_event.h | 2 + applications/subghz/scenes/subghz_scene_rpc.c | 33 ++++++++--- applications/subghz/subghz.c | 58 ++++++++++++++----- assets/protobuf | 2 +- 17 files changed, 237 insertions(+), 62 deletions(-) diff --git a/applications/ibutton/ibutton.c b/applications/ibutton/ibutton.c index 0f54dc3e..0f14137c 100644 --- a/applications/ibutton/ibutton.c +++ b/applications/ibutton/ibutton.c @@ -118,6 +118,8 @@ static bool ibutton_rpc_command_callback(RpcAppSystemEvent event, const char* ar string_set_str(ibutton->file_path, arg); if(ibutton_load_key_data(ibutton, ibutton->file_path, false)) { ibutton_worker_emulate_start(ibutton->key_worker, ibutton->key); + view_dispatcher_send_custom_event( + ibutton->view_dispatcher, iButtonCustomEventRpcLoad); result = true; } } @@ -162,8 +164,6 @@ iButton* ibutton_alloc() { ibutton->view_dispatcher, ibutton_tick_event_callback, 100); ibutton->gui = furi_record_open("gui"); - view_dispatcher_attach_to_gui( - ibutton->view_dispatcher, ibutton->gui, ViewDispatcherTypeFullscreen); ibutton->storage = furi_record_open("storage"); ibutton->dialogs = furi_record_open("dialogs"); @@ -373,6 +373,7 @@ int32_t ibutton_app(void* p) { ibutton->rpc_ctx = (void*)rpc_ctx; rpc_mode = true; rpc_system_app_set_callback(ibutton->rpc_ctx, ibutton_rpc_command_callback, ibutton); + rpc_system_app_send_started(ibutton->rpc_ctx); } else { string_set_str(ibutton->file_path, (const char*)p); if(ibutton_load_key_data(ibutton, ibutton->file_path, true)) { @@ -383,17 +384,24 @@ int32_t ibutton_app(void* p) { } if(rpc_mode) { + view_dispatcher_attach_to_gui( + ibutton->view_dispatcher, ibutton->gui, ViewDispatcherTypeDesktop); scene_manager_next_scene(ibutton->scene_manager, iButtonSceneRpc); - } else if(key_loaded) { - scene_manager_next_scene(ibutton->scene_manager, iButtonSceneEmulate); } else { - scene_manager_next_scene(ibutton->scene_manager, iButtonSceneStart); + view_dispatcher_attach_to_gui( + ibutton->view_dispatcher, ibutton->gui, ViewDispatcherTypeFullscreen); + if(key_loaded) { + scene_manager_next_scene(ibutton->scene_manager, iButtonSceneEmulate); + } else { + scene_manager_next_scene(ibutton->scene_manager, iButtonSceneStart); + } } view_dispatcher_run(ibutton->view_dispatcher); if(ibutton->rpc_ctx) { rpc_system_app_set_callback(ibutton->rpc_ctx, NULL, NULL); + rpc_system_app_send_exited(ibutton->rpc_ctx); } ibutton_free(ibutton); return 0; diff --git a/applications/ibutton/ibutton_custom_event.h b/applications/ibutton/ibutton_custom_event.h index 1706e00f..25dfc31d 100644 --- a/applications/ibutton/ibutton_custom_event.h +++ b/applications/ibutton/ibutton_custom_event.h @@ -10,5 +10,6 @@ enum iButtonCustomEvent { iButtonCustomEventWorkerEmulated, iButtonCustomEventWorkerRead, + iButtonCustomEventRpcLoad, iButtonCustomEventRpcExit, }; diff --git a/applications/ibutton/scenes/ibutton_scene_rpc.c b/applications/ibutton/scenes/ibutton_scene_rpc.c index ceeca017..14f7df63 100644 --- a/applications/ibutton/scenes/ibutton_scene_rpc.c +++ b/applications/ibutton/scenes/ibutton_scene_rpc.c @@ -3,12 +3,14 @@ void ibutton_scene_rpc_on_enter(void* context) { iButton* ibutton = context; - Widget* widget = ibutton->widget; + Popup* popup = ibutton->popup; - widget_add_text_box_element( - widget, 0, 0, 128, 28, AlignCenter, AlignCenter, "RPC mode", false); + popup_set_header(popup, "iButton", 82, 28, AlignCenter, AlignBottom); + popup_set_text(popup, "RPC mode", 82, 32, AlignCenter, AlignTop); - view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewWidget); + popup_set_icon(popup, 2, 14, &I_iButtonKey_49x44); + + view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewPopup); notification_message(ibutton->notifications, &sequence_display_backlight_on); } @@ -17,12 +19,31 @@ bool ibutton_scene_rpc_on_event(void* context, SceneManagerEvent event) { UNUSED(context); UNUSED(event); iButton* ibutton = context; + Popup* popup = ibutton->popup; bool consumed = false; if(event.type == SceneManagerEventTypeCustom) { consumed = true; - if(event.event == iButtonCustomEventRpcExit) { + if(event.event == iButtonCustomEventRpcLoad) { + string_t key_name; + string_init(key_name); + if(string_end_with_str_p(ibutton->file_path, IBUTTON_APP_EXTENSION)) { + path_extract_filename(ibutton->file_path, key_name, true); + } + + if(!string_empty_p(key_name)) { + ibutton_text_store_set(ibutton, "emulating\n%s", string_get_cstr(key_name)); + } else { + ibutton_text_store_set(ibutton, "emulating"); + } + popup_set_text(popup, ibutton->text_store, 82, 32, AlignCenter, AlignTop); + + ibutton_notification_message(ibutton, iButtonNotificationMessageEmulateStart); + + string_clear(key_name); + } else if(event.event == iButtonCustomEventRpcExit) { + ibutton_notification_message(ibutton, iButtonNotificationMessageBlinkStop); view_dispatcher_stop(ibutton->view_dispatcher); } } @@ -32,5 +53,11 @@ bool ibutton_scene_rpc_on_event(void* context, SceneManagerEvent event) { void ibutton_scene_rpc_on_exit(void* context) { iButton* ibutton = context; - widget_reset(ibutton->widget); + Popup* popup = ibutton->popup; + + popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom); + popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); + popup_set_icon(popup, 0, 0, NULL); + + ibutton_notification_message(ibutton, iButtonNotificationMessageBlinkStop); } diff --git a/applications/infrared/infrared.c b/applications/infrared/infrared.c index 62206116..1dd0dfa6 100644 --- a/applications/infrared/infrared.c +++ b/applications/infrared/infrared.c @@ -65,6 +65,8 @@ static bool infrared->worker, infrared_worker_tx_get_signal_steady_callback, infrared); infrared_worker_tx_set_signal_sent_callback( infrared->worker, infrared_signal_sent_callback, infrared); + view_dispatcher_send_custom_event( + infrared->view_dispatcher, InfraredCustomEventTypeRpcLoaded); } } else if(event == RpcAppEventButtonPress) { if(arg) { @@ -141,7 +143,6 @@ static Infrared* infrared_alloc() { infrared->gui = furi_record_open("gui"); ViewDispatcher* view_dispatcher = infrared->view_dispatcher; - view_dispatcher_attach_to_gui(view_dispatcher, infrared->gui, ViewDispatcherTypeFullscreen); view_dispatcher_enable_queue(view_dispatcher); view_dispatcher_set_event_callback_context(view_dispatcher, infrared); view_dispatcher_set_custom_event_callback(view_dispatcher, infrared_custom_event_callback); @@ -202,6 +203,7 @@ static void infrared_free(Infrared* infrared) { if(infrared->rpc_ctx) { rpc_system_app_set_callback(infrared->rpc_ctx, NULL, NULL); + rpc_system_app_send_exited(infrared->rpc_ctx); infrared->rpc_ctx = NULL; } @@ -434,6 +436,7 @@ int32_t infrared_app(void* p) { infrared->rpc_ctx = (void*)rpc_ctx; rpc_system_app_set_callback( infrared->rpc_ctx, infrared_rpc_command_callback, infrared); + rpc_system_app_send_started(infrared->rpc_ctx); is_rpc_mode = true; } else { string_set_str(infrared->file_path, (const char*)p); @@ -447,11 +450,17 @@ int32_t infrared_app(void* p) { } if(is_rpc_mode) { + view_dispatcher_attach_to_gui( + infrared->view_dispatcher, infrared->gui, ViewDispatcherTypeDesktop); scene_manager_next_scene(infrared->scene_manager, InfraredSceneRpc); - } else if(is_remote_loaded) { - scene_manager_next_scene(infrared->scene_manager, InfraredSceneRemote); } else { - scene_manager_next_scene(infrared->scene_manager, InfraredSceneStart); + view_dispatcher_attach_to_gui( + infrared->view_dispatcher, infrared->gui, ViewDispatcherTypeFullscreen); + if(is_remote_loaded) { + scene_manager_next_scene(infrared->scene_manager, InfraredSceneRemote); + } else { + scene_manager_next_scene(infrared->scene_manager, InfraredSceneStart); + } } view_dispatcher_run(infrared->view_dispatcher); diff --git a/applications/infrared/infrared_custom_event.h b/applications/infrared/infrared_custom_event.h index 46d75a9e..29bd61f1 100644 --- a/applications/infrared/infrared_custom_event.h +++ b/applications/infrared/infrared_custom_event.h @@ -14,6 +14,7 @@ enum InfraredCustomEventType { InfraredCustomEventTypePopupClosed, InfraredCustomEventTypeButtonSelected, InfraredCustomEventTypeBackPressed, + InfraredCustomEventTypeRpcLoaded, }; #pragma pack(push, 1) diff --git a/applications/infrared/scenes/infrared_scene_rpc.c b/applications/infrared/scenes/infrared_scene_rpc.c index 3cab9f80..e31e7fb6 100644 --- a/applications/infrared/scenes/infrared_scene_rpc.c +++ b/applications/infrared/scenes/infrared_scene_rpc.c @@ -5,12 +5,14 @@ void infrared_scene_rpc_on_enter(void* context) { Infrared* infrared = context; Popup* popup = infrared->popup; - popup_set_text(popup, "Rpc mode", 64, 28, AlignCenter, AlignCenter); + popup_set_header(popup, "Infrared", 82, 28, AlignCenter, AlignBottom); + popup_set_text(popup, "RPC mode", 82, 32, AlignCenter, AlignTop); + + popup_set_icon(popup, 2, 14, &I_Warning_30x23); // TODO: icon popup_set_context(popup, context); popup_set_callback(popup, infrared_popup_closed_callback); - infrared_play_notification_message(infrared, InfraredNotificationMessageYellowOn); view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewPopup); notification_message(infrared->notifications, &sequence_display_backlight_on); @@ -26,6 +28,12 @@ bool infrared_scene_rpc_on_event(void* context, SceneManagerEvent event) { view_dispatcher_stop(infrared->view_dispatcher); } else if(event.event == InfraredCustomEventTypePopupClosed) { view_dispatcher_stop(infrared->view_dispatcher); + } else if(event.event == InfraredCustomEventTypeRpcLoaded) { + const char* remote_name = infrared_remote_get_name(infrared->remote); + + infrared_text_store_set(infrared, 0, "loaded\n%s", remote_name); + popup_set_text( + infrared->popup, infrared->text_store[0], 82, 32, AlignCenter, AlignTop); } } return consumed; diff --git a/applications/lfrfid/lfrfid_app.cpp b/applications/lfrfid/lfrfid_app.cpp index c491cf40..2ba36ea3 100644 --- a/applications/lfrfid/lfrfid_app.cpp +++ b/applications/lfrfid/lfrfid_app.cpp @@ -44,6 +44,7 @@ LfRfidApp::~LfRfidApp() { string_clear(file_path); if(rpc_ctx) { rpc_system_app_set_callback(rpc_ctx, NULL, NULL); + rpc_system_app_send_exited(rpc_ctx); } } @@ -91,6 +92,7 @@ void LfRfidApp::run(void* _args) { if(sscanf(args, "RPC %lX", &rpc_ctx_ptr) == 1) { rpc_ctx = (RpcAppSystem*)rpc_ctx_ptr; rpc_system_app_set_callback(rpc_ctx, rpc_command_callback, this); + rpc_system_app_send_started(rpc_ctx); scene_controller.add_scene(SceneType::Rpc, new LfRfidAppSceneRpc()); scene_controller.process(100, SceneType::Rpc); } else { diff --git a/applications/lfrfid/scene/lfrfid_app_scene_rpc.cpp b/applications/lfrfid/scene/lfrfid_app_scene_rpc.cpp index 80d47934..bc070ce6 100644 --- a/applications/lfrfid/scene/lfrfid_app_scene_rpc.cpp +++ b/applications/lfrfid/scene/lfrfid_app_scene_rpc.cpp @@ -2,10 +2,24 @@ #include #include +static const NotificationSequence sequence_blink_start_magenta = { + &message_blink_start_10, + &message_blink_set_color_magenta, + &message_do_not_reset, + NULL, +}; + +static const NotificationSequence sequence_blink_stop = { + &message_blink_stop, + NULL, +}; + void LfRfidAppSceneRpc::on_enter(LfRfidApp* app, bool /* need_restore */) { auto popup = app->view_controller.get(); - popup->set_header("RPC Mode", 64, 30, AlignCenter, AlignTop); + popup->set_header("LF RFID", 89, 30, AlignCenter, AlignTop); + popup->set_text("RPC mode", 89, 43, AlignCenter, AlignTop); + popup->set_icon(0, 3, &I_RFIDDolphinSend_97x61); app->view_controller.switch_to(); @@ -23,8 +37,14 @@ bool LfRfidAppSceneRpc::on_event(LfRfidApp* app, LfRfidApp::Event* event) { view_event.type = LfRfidApp::EventType::Back; app->view_controller.send_event(&view_event); } else if(event->type == LfRfidApp::EventType::EmulateStart) { + auto popup = app->view_controller.get(); consumed = true; emulating = true; + + app->text_store.set("emulating\n%s", app->worker.key.get_name()); + popup->set_text(app->text_store.text, 89, 43, AlignCenter, AlignTop); + + notification_message(app->notification, &sequence_blink_start_magenta); } return consumed; } @@ -32,6 +52,7 @@ bool LfRfidAppSceneRpc::on_event(LfRfidApp* app, LfRfidApp::Event* event) { void LfRfidAppSceneRpc::on_exit(LfRfidApp* app) { if(emulating) { app->worker.stop_emulate(); + notification_message(app->notification, &sequence_blink_stop); } app->view_controller.get()->clean(); } diff --git a/applications/nfc/helpers/nfc_custom_event.h b/applications/nfc/helpers/nfc_custom_event.h index 5de44001..b877732a 100644 --- a/applications/nfc/helpers/nfc_custom_event.h +++ b/applications/nfc/helpers/nfc_custom_event.h @@ -9,4 +9,5 @@ enum NfcCustomEvent { NfcCustomEventByteInputDone, NfcCustomEventTextInputDone, NfcCustomEventDictAttackDone, + NfcCustomEventRpcLoad, }; diff --git a/applications/nfc/nfc.c b/applications/nfc/nfc.c index 0dc4b3ae..fb739c61 100644 --- a/applications/nfc/nfc.c +++ b/applications/nfc/nfc.c @@ -31,6 +31,7 @@ void nfc_rpc_exit_callback(Nfc* nfc) { } if(nfc->rpc_ctx) { rpc_system_app_set_callback(nfc->rpc_ctx, NULL, NULL); + rpc_system_app_send_exited(nfc->rpc_ctx); nfc->rpc_ctx = NULL; } } @@ -82,6 +83,7 @@ static bool nfc_rpc_command_callback(RpcAppSystemEvent event, const char* arg, v nfc->worker, NfcWorkerStateEmulate, &nfc->dev->dev_data, NULL, nfc); } nfc->rpc_state = NfcRpcStateEmulating; + view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventRpcLoad); result = true; } } @@ -107,7 +109,6 @@ Nfc* nfc_alloc() { // Open GUI record nfc->gui = furi_record_open("gui"); - view_dispatcher_attach_to_gui(nfc->view_dispatcher, nfc->gui, ViewDispatcherTypeFullscreen); // Open Notification record nfc->notifications = furi_record_open("notification"); @@ -291,21 +292,30 @@ int32_t nfc_app(void* p) { if(sscanf(p, "RPC %lX", &rpc_ctx) == 1) { nfc->rpc_ctx = (void*)rpc_ctx; rpc_system_app_set_callback(nfc->rpc_ctx, nfc_rpc_command_callback, nfc); + rpc_system_app_send_started(nfc->rpc_ctx); + view_dispatcher_attach_to_gui( + nfc->view_dispatcher, nfc->gui, ViewDispatcherTypeDesktop); scene_manager_next_scene(nfc->scene_manager, NfcSceneRpc); - } else if(nfc_device_load(nfc->dev, p, true)) { - if(nfc->dev->format == NfcDeviceSaveFormatMifareUl) { - scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateMifareUl); - } else if(nfc->dev->format == NfcDeviceSaveFormatMifareClassic) { - scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateMifareClassic); - } else { - scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateUid); - } } else { - // Exit app - view_dispatcher_stop(nfc->view_dispatcher); + view_dispatcher_attach_to_gui( + nfc->view_dispatcher, nfc->gui, ViewDispatcherTypeFullscreen); + if(nfc_device_load(nfc->dev, p, true)) { + if(nfc->dev->format == NfcDeviceSaveFormatMifareUl) { + scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateMifareUl); + } else if(nfc->dev->format == NfcDeviceSaveFormatMifareClassic) { + scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateMifareClassic); + } else { + scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateUid); + } + } else { + // Exit app + view_dispatcher_stop(nfc->view_dispatcher); + } } nfc_device_set_loading_callback(nfc->dev, NULL, nfc); } else { + view_dispatcher_attach_to_gui( + nfc->view_dispatcher, nfc->gui, ViewDispatcherTypeFullscreen); scene_manager_next_scene(nfc->scene_manager, NfcSceneStart); } diff --git a/applications/nfc/scenes/nfc_scene_rpc.c b/applications/nfc/scenes/nfc_scene_rpc.c index b94bf424..582dff8e 100644 --- a/applications/nfc/scenes/nfc_scene_rpc.c +++ b/applications/nfc/scenes/nfc_scene_rpc.c @@ -2,24 +2,33 @@ void nfc_scene_rpc_on_enter(void* context) { Nfc* nfc = context; - Widget* widget = nfc->widget; + Popup* popup = nfc->popup; - widget_add_text_box_element( - widget, 0, 0, 128, 28, AlignCenter, AlignCenter, "RPC mode", false); + popup_set_header(popup, "NFC", 82, 28, AlignCenter, AlignBottom); + popup_set_text(popup, "RPC mode", 82, 32, AlignCenter, AlignTop); + + popup_set_icon(popup, 2, 14, &I_Warning_30x23); // TODO: icon + + view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup); notification_message(nfc->notifications, &sequence_display_backlight_on); - - view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewWidget); } bool nfc_scene_rpc_on_event(void* context, SceneManagerEvent event) { Nfc* nfc = context; + Popup* popup = nfc->popup; bool consumed = false; if(event.type == SceneManagerEventTypeCustom) { consumed = true; if(event.event == NfcCustomEventViewExit) { view_dispatcher_stop(nfc->view_dispatcher); + nfc_blink_stop(nfc); + } else if(event.event == NfcCustomEventRpcLoad) { + nfc_blink_start(nfc); + + nfc_text_store_set(nfc, "emulating\n%s", nfc->dev->dev_name); + popup_set_text(popup, nfc->text_store, 82, 32, AlignCenter, AlignTop); } } return consumed; @@ -27,8 +36,12 @@ bool nfc_scene_rpc_on_event(void* context, SceneManagerEvent event) { void nfc_scene_rpc_on_exit(void* context) { Nfc* nfc = context; + Popup* popup = nfc->popup; nfc_rpc_exit_callback(nfc); + nfc_blink_stop(nfc); - widget_reset(nfc->widget); + popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom); + popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); + popup_set_icon(popup, 0, 0, NULL); } diff --git a/applications/rpc/rpc_app.c b/applications/rpc/rpc_app.c index 84cb5410..525eedcf 100644 --- a/applications/rpc/rpc_app.c +++ b/applications/rpc/rpc_app.c @@ -12,6 +12,7 @@ struct RpcAppSystem { RpcSession* session; RpcAppSystemCallback app_callback; void* app_context; + PB_Main* state_msg; FuriTimer* timer; }; @@ -96,7 +97,7 @@ static void rpc_system_app_lock_status_process(const PB_Main* request, void* con pb_release(&PB_Main_msg, &response); } -static void rpc_system_app_exit(const PB_Main* request, void* context) { +static void rpc_system_app_exit_request(const PB_Main* request, void* context) { furi_assert(request); furi_assert(context); @@ -194,6 +195,24 @@ static void rpc_system_app_button_release(const PB_Main* request, void* context) rpc_send_and_release_empty(session, request->command_id, status); } +void rpc_system_app_send_started(RpcAppSystem* rpc_app) { + furi_assert(rpc_app); + RpcSession* session = rpc_app->session; + furi_assert(session); + + rpc_app->state_msg->content.app_state_response.state = PB_App_AppState_APP_STARTED; + rpc_send(session, rpc_app->state_msg); +} + +void rpc_system_app_send_exited(RpcAppSystem* rpc_app) { + furi_assert(rpc_app); + RpcSession* session = rpc_app->session; + furi_assert(session); + + rpc_app->state_msg->content.app_state_response.state = PB_App_AppState_APP_CLOSED; + rpc_send(session, rpc_app->state_msg); +} + void rpc_system_app_set_callback(RpcAppSystem* rpc_app, RpcAppSystemCallback callback, void* ctx) { furi_assert(rpc_app); @@ -209,6 +228,11 @@ void* rpc_system_app_alloc(RpcSession* session) { rpc_app->timer = furi_timer_alloc(rpc_system_app_timer_callback, FuriTimerTypeOnce, rpc_app); + // App exit message + rpc_app->state_msg = malloc(sizeof(PB_Main)); + rpc_app->state_msg->which_content = PB_Main_app_state_response_tag; + rpc_app->state_msg->command_status = PB_CommandStatus_OK; + RpcHandler rpc_handler = { .message_handler = NULL, .decode_submessage = NULL, @@ -221,7 +245,7 @@ void* rpc_system_app_alloc(RpcSession* session) { rpc_handler.message_handler = rpc_system_app_lock_status_process; rpc_add_handler(session, PB_Main_app_lock_status_request_tag, &rpc_handler); - rpc_handler.message_handler = rpc_system_app_exit; + rpc_handler.message_handler = rpc_system_app_exit_request; rpc_add_handler(session, PB_Main_app_exit_request_tag, &rpc_handler); rpc_handler.message_handler = rpc_system_app_load_file; @@ -247,5 +271,6 @@ void rpc_system_app_free(void* context) { rpc_app->app_callback(RpcAppEventSessionClose, NULL, rpc_app->app_context); } + free(rpc_app->state_msg); free(rpc_app); } diff --git a/applications/rpc/rpc_app.h b/applications/rpc/rpc_app.h index 396eef1a..4e00922f 100644 --- a/applications/rpc/rpc_app.h +++ b/applications/rpc/rpc_app.h @@ -19,6 +19,10 @@ typedef struct RpcAppSystem RpcAppSystem; void rpc_system_app_set_callback(RpcAppSystem* rpc_app, RpcAppSystemCallback callback, void* ctx); +void rpc_system_app_send_started(RpcAppSystem* rpc_app); + +void rpc_system_app_send_exited(RpcAppSystem* rpc_app); + #ifdef __cplusplus } #endif diff --git a/applications/subghz/helpers/subghz_custom_event.h b/applications/subghz/helpers/subghz_custom_event.h index 05f0f492..801a8ae9 100644 --- a/applications/subghz/helpers/subghz_custom_event.h +++ b/applications/subghz/helpers/subghz_custom_event.h @@ -46,6 +46,8 @@ typedef enum { SubGhzCustomEventSceneExit, SubGhzCustomEventSceneStay, + SubGhzCustomEventSceneRpcLoad, + SubGhzCustomEventViewReceiverOK, SubGhzCustomEventViewReceiverConfig, SubGhzCustomEventViewReceiverBack, diff --git a/applications/subghz/scenes/subghz_scene_rpc.c b/applications/subghz/scenes/subghz_scene_rpc.c index c7573fda..844f5c16 100644 --- a/applications/subghz/scenes/subghz_scene_rpc.c +++ b/applications/subghz/scenes/subghz_scene_rpc.c @@ -2,24 +2,40 @@ void subghz_scene_rpc_on_enter(void* context) { SubGhz* subghz = context; - Widget* widget = subghz->widget; + Popup* popup = subghz->popup; - widget_add_text_box_element( - widget, 0, 0, 128, 28, AlignCenter, AlignCenter, "RPC mode", false); + popup_set_header(popup, "Sub-GHz", 82, 28, AlignCenter, AlignBottom); + popup_set_text(popup, "RPC mode", 82, 32, AlignCenter, AlignTop); + + popup_set_icon(popup, 2, 14, &I_Warning_30x23); // TODO: icon + + view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdPopup); notification_message(subghz->notifications, &sequence_display_backlight_on); - - view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdWidget); } bool subghz_scene_rpc_on_event(void* context, SceneManagerEvent event) { SubGhz* subghz = context; + Popup* popup = subghz->popup; bool consumed = false; if(event.type == SceneManagerEventTypeCustom) { consumed = true; if(event.event == SubGhzCustomEventSceneExit) { view_dispatcher_stop(subghz->view_dispatcher); + } else if(event.event == SubGhzCustomEventSceneRpcLoad) { + string_t file_name; + string_init(file_name); + path_extract_filename(subghz->file_path, file_name, true); + + snprintf( + subghz->file_name_tmp, + SUBGHZ_MAX_LEN_NAME, + "loaded\n%s", + string_get_cstr(file_name)); + popup_set_text(popup, subghz->file_name_tmp, 82, 32, AlignCenter, AlignTop); + + string_clear(file_name); } } return consumed; @@ -27,8 +43,9 @@ bool subghz_scene_rpc_on_event(void* context, SceneManagerEvent event) { void subghz_scene_rpc_on_exit(void* context) { SubGhz* subghz = context; + Popup* popup = subghz->popup; - //subghz_rpc_exit_callback(subghz); - - widget_reset(subghz->widget); + popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom); + popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); + popup_set_icon(popup, 0, 0, NULL); } diff --git a/applications/subghz/subghz.c b/applications/subghz/subghz.c index 984ce472..76998eb0 100644 --- a/applications/subghz/subghz.c +++ b/applications/subghz/subghz.c @@ -5,6 +5,18 @@ #include "subghz_i.h" #include +static const NotificationSequence sequence_blink_start_magenta = { + &message_blink_start_10, + &message_blink_set_color_magenta, + &message_do_not_reset, + NULL, +}; + +static const NotificationSequence sequence_blink_stop = { + &message_blink_stop, + NULL, +}; + bool subghz_custom_event_callback(void* context, uint32_t event) { furi_assert(context); SubGhz* subghz = context; @@ -36,6 +48,7 @@ static bool subghz_rpc_command_callback(RpcAppSystemEvent event, const char* arg if(event == RpcAppEventSessionClose) { rpc_system_app_set_callback(subghz->rpc_ctx, NULL, NULL); subghz->rpc_ctx = NULL; + notification_message(subghz->notifications, &sequence_blink_stop); view_dispatcher_send_custom_event(subghz->view_dispatcher, SubGhzCustomEventSceneExit); if(subghz->txrx->txrx_state == SubGhzTxRxStateTx) { subghz_tx_stop(subghz); @@ -53,15 +66,19 @@ static bool subghz_rpc_command_callback(RpcAppSystemEvent event, const char* arg if(arg) { if(subghz_key_load(subghz, arg, false)) { string_set_str(subghz->file_path, arg); + view_dispatcher_send_custom_event( + subghz->view_dispatcher, SubGhzCustomEventSceneRpcLoad); result = true; } } } else if(event == RpcAppEventButtonPress) { if(subghz->txrx->txrx_state == SubGhzTxRxStateSleep) { + notification_message(subghz->notifications, &sequence_blink_start_magenta); result = subghz_tx_start(subghz, subghz->txrx->fff_data); } } else if(event == RpcAppEventButtonRelease) { if(subghz->txrx->txrx_state == SubGhzTxRxStateTx) { + notification_message(subghz->notifications, &sequence_blink_stop); subghz_tx_stop(subghz); subghz_sleep(subghz); result = true; @@ -83,8 +100,6 @@ SubGhz* subghz_alloc() { // View Dispatcher subghz->view_dispatcher = view_dispatcher_alloc(); view_dispatcher_enable_queue(subghz->view_dispatcher); - view_dispatcher_attach_to_gui( - subghz->view_dispatcher, subghz->gui, ViewDispatcherTypeFullscreen); subghz->scene_manager = scene_manager_alloc(&subghz_scene_handlers, subghz); view_dispatcher_set_event_callback_context(subghz->view_dispatcher, subghz); @@ -218,6 +233,8 @@ void subghz_free(SubGhz* subghz) { if(subghz->rpc_ctx) { rpc_system_app_set_callback(subghz->rpc_ctx, NULL, NULL); + rpc_system_app_send_exited(subghz->rpc_ctx); + notification_message(subghz->notifications, &sequence_blink_stop); subghz->rpc_ctx = NULL; } @@ -322,24 +339,33 @@ int32_t subghz_app(void* p) { if(sscanf(p, "RPC %lX", &rpc_ctx) == 1) { subghz->rpc_ctx = (void*)rpc_ctx; rpc_system_app_set_callback(subghz->rpc_ctx, subghz_rpc_command_callback, subghz); + rpc_system_app_send_started(subghz->rpc_ctx); + view_dispatcher_attach_to_gui( + subghz->view_dispatcher, subghz->gui, ViewDispatcherTypeDesktop); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneRpc); - } else if(subghz_key_load(subghz, p, true)) { - string_set_str(subghz->file_path, p); - - if((!strcmp(subghz->txrx->decoder_result->protocol->name, "RAW"))) { - //Load Raw TX - subghz->txrx->rx_key_state = SubGhzRxKeyStateRAWLoad; - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneReadRAW); - } else { - //Load transmitter TX - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneTransmitter); - } } else { - //exit app - scene_manager_stop(subghz->scene_manager); - view_dispatcher_stop(subghz->view_dispatcher); + view_dispatcher_attach_to_gui( + subghz->view_dispatcher, subghz->gui, ViewDispatcherTypeFullscreen); + if(subghz_key_load(subghz, p, true)) { + string_set_str(subghz->file_path, p); + + if((!strcmp(subghz->txrx->decoder_result->protocol->name, "RAW"))) { + //Load Raw TX + subghz->txrx->rx_key_state = SubGhzRxKeyStateRAWLoad; + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneReadRAW); + } else { + //Load transmitter TX + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneTransmitter); + } + } else { + //exit app + scene_manager_stop(subghz->scene_manager); + view_dispatcher_stop(subghz->view_dispatcher); + } } } else { + view_dispatcher_attach_to_gui( + subghz->view_dispatcher, subghz->gui, ViewDispatcherTypeFullscreen); string_set_str(subghz->file_path, SUBGHZ_APP_FOLDER); if(load_database) { scene_manager_next_scene(subghz->scene_manager, SubGhzSceneStart); diff --git a/assets/protobuf b/assets/protobuf index d9e34366..cc5918dc 160000 --- a/assets/protobuf +++ b/assets/protobuf @@ -1 +1 @@ -Subproject commit d9e343661dd36cfab792b78be1dea4e5950cb4dd +Subproject commit cc5918dc488ac3617012ce5377114e086b447324 From ac60d1808a055be65ca42ad64f89d3c721de8772 Mon Sep 17 00:00:00 2001 From: Wyatt Neal Date: Mon, 25 Jul 2022 10:35:02 -0400 Subject: [PATCH 24/37] fixing typos, satus -> status (#1422) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: あく --- applications/subghz/views/subghz_read_raw.c | 78 +++++++++---------- applications/subghz/views/subghz_read_raw.h | 2 +- .../subghz/views/subghz_test_static.c | 10 +-- 3 files changed, 45 insertions(+), 45 deletions(-) diff --git a/applications/subghz/views/subghz_read_raw.c b/applications/subghz/views/subghz_read_raw.c index a4807d77..de8f371b 100644 --- a/applications/subghz/views/subghz_read_raw.c +++ b/applications/subghz/views/subghz_read_raw.c @@ -26,7 +26,7 @@ typedef struct { bool rssi_history_end; uint8_t ind_write; uint8_t ind_sin; - SubGhzReadRAWStatus satus; + SubGhzReadRAWStatus status; } SubGhzReadRAWModel; void subghz_read_raw_set_callback( @@ -88,21 +88,21 @@ void subghz_read_raw_stop_send(SubGhzReadRAW* instance) { with_view_model( instance->view, (SubGhzReadRAWModel * model) { - switch(model->satus) { + switch(model->status) { case SubGhzReadRAWStatusTXRepeat: case SubGhzReadRAWStatusLoadKeyTXRepeat: instance->callback(SubGhzCustomEventViewReadRAWSendStart, instance->context); break; case SubGhzReadRAWStatusTX: - model->satus = SubGhzReadRAWStatusIDLE; + model->status = SubGhzReadRAWStatusIDLE; break; case SubGhzReadRAWStatusLoadKeyTX: - model->satus = SubGhzReadRAWStatusLoadKeyIDLE; + model->status = SubGhzReadRAWStatusLoadKeyIDLE; break; default: FURI_LOG_W(TAG, "unknown status"); - model->satus = SubGhzReadRAWStatusIDLE; + model->status = SubGhzReadRAWStatusIDLE; break; } return true; @@ -225,7 +225,7 @@ void subghz_read_raw_draw(Canvas* canvas, SubGhzReadRAWModel* model) { canvas_draw_line(canvas, 0, 48, 115, 48); canvas_draw_line(canvas, 115, 14, 115, 48); - switch(model->satus) { + switch(model->status) { case SubGhzReadRAWStatusIDLE: elements_button_left(canvas, "Erase"); elements_button_center(canvas, "Send"); @@ -289,26 +289,26 @@ bool subghz_read_raw_input(InputEvent* event, void* context) { with_view_model( instance->view, (SubGhzReadRAWModel * model) { uint8_t ret = false; - switch(model->satus) { + switch(model->status) { case SubGhzReadRAWStatusIDLE: // Start TX instance->callback(SubGhzCustomEventViewReadRAWSendStart, instance->context); - model->satus = SubGhzReadRAWStatusTXRepeat; + model->status = SubGhzReadRAWStatusTXRepeat; ret = true; break; case SubGhzReadRAWStatusTX: // Start TXRepeat - model->satus = SubGhzReadRAWStatusTXRepeat; + model->status = SubGhzReadRAWStatusTXRepeat; break; case SubGhzReadRAWStatusLoadKeyIDLE: // Start Load Key TX instance->callback(SubGhzCustomEventViewReadRAWSendStart, instance->context); - model->satus = SubGhzReadRAWStatusLoadKeyTXRepeat; + model->status = SubGhzReadRAWStatusLoadKeyTXRepeat; ret = true; break; case SubGhzReadRAWStatusLoadKeyTX: // Start Load Key TXRepeat - model->satus = SubGhzReadRAWStatusLoadKeyTXRepeat; + model->status = SubGhzReadRAWStatusLoadKeyTXRepeat; break; default: @@ -319,33 +319,33 @@ bool subghz_read_raw_input(InputEvent* event, void* context) { } else if(event->key == InputKeyOk && event->type == InputTypeRelease) { with_view_model( instance->view, (SubGhzReadRAWModel * model) { - if(model->satus == SubGhzReadRAWStatusTXRepeat) { + if(model->status == SubGhzReadRAWStatusTXRepeat) { // Stop repeat TX - model->satus = SubGhzReadRAWStatusTX; - } else if(model->satus == SubGhzReadRAWStatusLoadKeyTXRepeat) { + model->status = SubGhzReadRAWStatusTX; + } else if(model->status == SubGhzReadRAWStatusLoadKeyTXRepeat) { // Stop repeat TX - model->satus = SubGhzReadRAWStatusLoadKeyTX; + model->status = SubGhzReadRAWStatusLoadKeyTX; } return false; }); } else if(event->key == InputKeyBack && event->type == InputTypeShort) { with_view_model( instance->view, (SubGhzReadRAWModel * model) { - switch(model->satus) { + switch(model->status) { case SubGhzReadRAWStatusREC: //Stop REC instance->callback(SubGhzCustomEventViewReadRAWIDLE, instance->context); - model->satus = SubGhzReadRAWStatusIDLE; + model->status = SubGhzReadRAWStatusIDLE; break; case SubGhzReadRAWStatusLoadKeyTX: //Stop TxRx instance->callback(SubGhzCustomEventViewReadRAWTXRXStop, instance->context); - model->satus = SubGhzReadRAWStatusLoadKeyIDLE; + model->status = SubGhzReadRAWStatusLoadKeyIDLE; break; case SubGhzReadRAWStatusTX: //Stop TxRx instance->callback(SubGhzCustomEventViewReadRAWTXRXStop, instance->context); - model->satus = SubGhzReadRAWStatusIDLE; + model->status = SubGhzReadRAWStatusIDLE; break; case SubGhzReadRAWStatusLoadKeyIDLE: //Exit @@ -362,14 +362,14 @@ bool subghz_read_raw_input(InputEvent* event, void* context) { } else if(event->key == InputKeyLeft && event->type == InputTypeShort) { with_view_model( instance->view, (SubGhzReadRAWModel * model) { - if(model->satus == SubGhzReadRAWStatusStart) { + if(model->status == SubGhzReadRAWStatusStart) { //Config instance->callback(SubGhzCustomEventViewReadRAWConfig, instance->context); } else if( - (model->satus == SubGhzReadRAWStatusIDLE) || - (model->satus == SubGhzReadRAWStatusLoadKeyIDLE)) { + (model->status == SubGhzReadRAWStatusIDLE) || + (model->status == SubGhzReadRAWStatusLoadKeyIDLE)) { //Erase - model->satus = SubGhzReadRAWStatusStart; + model->status = SubGhzReadRAWStatusStart; model->rssi_history_end = false; model->ind_write = 0; string_set_str(model->sample_write, "0 spl."); @@ -381,10 +381,10 @@ bool subghz_read_raw_input(InputEvent* event, void* context) { } else if(event->key == InputKeyRight && event->type == InputTypeShort) { with_view_model( instance->view, (SubGhzReadRAWModel * model) { - if(model->satus == SubGhzReadRAWStatusIDLE) { + if(model->status == SubGhzReadRAWStatusIDLE) { //Save instance->callback(SubGhzCustomEventViewReadRAWSave, instance->context); - } else if(model->satus == SubGhzReadRAWStatusLoadKeyIDLE) { + } else if(model->status == SubGhzReadRAWStatusLoadKeyIDLE) { //More instance->callback(SubGhzCustomEventViewReadRAWMore, instance->context); } @@ -393,16 +393,16 @@ bool subghz_read_raw_input(InputEvent* event, void* context) { } else if(event->key == InputKeyOk && event->type == InputTypeShort) { with_view_model( instance->view, (SubGhzReadRAWModel * model) { - if(model->satus == SubGhzReadRAWStatusStart) { + if(model->status == SubGhzReadRAWStatusStart) { //Record instance->callback(SubGhzCustomEventViewReadRAWREC, instance->context); - model->satus = SubGhzReadRAWStatusREC; + model->status = SubGhzReadRAWStatusREC; model->ind_write = 0; model->rssi_history_end = false; - } else if(model->satus == SubGhzReadRAWStatusREC) { + } else if(model->status == SubGhzReadRAWStatusREC) { //Stop instance->callback(SubGhzCustomEventViewReadRAWIDLE, instance->context); - model->satus = SubGhzReadRAWStatusIDLE; + model->status = SubGhzReadRAWStatusIDLE; } return true; }); @@ -412,15 +412,15 @@ bool subghz_read_raw_input(InputEvent* event, void* context) { void subghz_read_raw_set_status( SubGhzReadRAW* instance, - SubGhzReadRAWStatus satus, + SubGhzReadRAWStatus status, const char* file_name) { furi_assert(instance); - switch(satus) { + switch(status) { case SubGhzReadRAWStatusStart: with_view_model( instance->view, (SubGhzReadRAWModel * model) { - model->satus = SubGhzReadRAWStatusStart; + model->status = SubGhzReadRAWStatusStart; model->rssi_history_end = false; model->ind_write = 0; string_reset(model->file_name); @@ -431,14 +431,14 @@ void subghz_read_raw_set_status( case SubGhzReadRAWStatusIDLE: with_view_model( instance->view, (SubGhzReadRAWModel * model) { - model->satus = SubGhzReadRAWStatusIDLE; + model->status = SubGhzReadRAWStatusIDLE; return true; }); break; case SubGhzReadRAWStatusLoadKeyTX: with_view_model( instance->view, (SubGhzReadRAWModel * model) { - model->satus = SubGhzReadRAWStatusLoadKeyIDLE; + model->status = SubGhzReadRAWStatusLoadKeyIDLE; model->rssi_history_end = false; model->ind_write = 0; string_set_str(model->file_name, file_name); @@ -449,7 +449,7 @@ void subghz_read_raw_set_status( case SubGhzReadRAWStatusSaveKey: with_view_model( instance->view, (SubGhzReadRAWModel * model) { - model->satus = SubGhzReadRAWStatusLoadKeyIDLE; + model->status = SubGhzReadRAWStatusLoadKeyIDLE; if(!model->ind_write) { string_set_str(model->file_name, file_name); string_set_str(model->sample_write, "RAW"); @@ -477,11 +477,11 @@ void subghz_read_raw_exit(void* context) { with_view_model( instance->view, (SubGhzReadRAWModel * model) { - if(model->satus != SubGhzReadRAWStatusIDLE && - model->satus != SubGhzReadRAWStatusStart && - model->satus != SubGhzReadRAWStatusLoadKeyIDLE) { + if(model->status != SubGhzReadRAWStatusIDLE && + model->status != SubGhzReadRAWStatusStart && + model->status != SubGhzReadRAWStatusLoadKeyIDLE) { instance->callback(SubGhzCustomEventViewReadRAWIDLE, instance->context); - model->satus = SubGhzReadRAWStatusStart; + model->status = SubGhzReadRAWStatusStart; } return true; }); diff --git a/applications/subghz/views/subghz_read_raw.h b/applications/subghz/views/subghz_read_raw.h index db75f1b4..1d4bb7dc 100644 --- a/applications/subghz/views/subghz_read_raw.h +++ b/applications/subghz/views/subghz_read_raw.h @@ -44,7 +44,7 @@ void subghz_read_raw_add_data_rssi(SubGhzReadRAW* instance, float rssi); void subghz_read_raw_set_status( SubGhzReadRAW* instance, - SubGhzReadRAWStatus satus, + SubGhzReadRAWStatus status, const char* file_name); View* subghz_read_raw_get_view(SubGhzReadRAW* subghz_static); diff --git a/applications/subghz/views/subghz_test_static.c b/applications/subghz/views/subghz_test_static.c index 26cf9b48..41de7262 100644 --- a/applications/subghz/views/subghz_test_static.c +++ b/applications/subghz/views/subghz_test_static.c @@ -25,7 +25,7 @@ static const uint32_t subghz_test_static_keys[] = { struct SubGhzTestStatic { View* view; - SubGhzTestStaticStatus satus_tx; + SubGhzTestStaticStatus status_tx; SubGhzEncoderPrinceton* encoder; SubGhzTestStaticCallback callback; void* context; @@ -113,10 +113,10 @@ bool subghz_test_static_input(InputEvent* event, void* context) { furi_hal_subghz_start_async_tx( subghz_encoder_princeton_for_testing_yield, instance->encoder); - instance->satus_tx = SubGhzTestStaticStatusTX; + instance->status_tx = SubGhzTestStaticStatusTX; } } else if(event->type == InputTypeRelease) { - if(instance->satus_tx == SubGhzTestStaticStatusTX) { + if(instance->status_tx == SubGhzTestStaticStatusTX) { FURI_LOG_I(TAG, "TX Stop"); subghz_encoder_princeton_for_testing_stop( instance->encoder, furi_get_tick()); @@ -124,7 +124,7 @@ bool subghz_test_static_input(InputEvent* event, void* context) { furi_hal_subghz_stop_async_tx(); notification_message(notification, &sequence_reset_red); } - instance->satus_tx = SubGhzTestStaticStatusIDLE; + instance->status_tx = SubGhzTestStaticStatusIDLE; } furi_record_close("notification"); } @@ -144,7 +144,7 @@ void subghz_test_static_enter(void* context) { furi_hal_gpio_init(&gpio_cc1101_g0, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); furi_hal_gpio_write(&gpio_cc1101_g0, false); - instance->satus_tx = SubGhzTestStaticStatusIDLE; + instance->status_tx = SubGhzTestStaticStatusIDLE; with_view_model( instance->view, (SubGhzTestStaticModel * model) { From 30820b83b5d6738c0867b11860ccbf92f8530183 Mon Sep 17 00:00:00 2001 From: Nikolay Minaylov Date: Mon, 25 Jul 2022 17:46:42 +0300 Subject: [PATCH 25/37] [FL-2464, FL-2466] RFID, ibutton text fix #1413 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: あく --- applications/ibutton/scenes/ibutton_scene_retry_confirm.c | 2 +- applications/infrared/scenes/infrared_scene_ask_back.c | 2 +- applications/infrared/scenes/infrared_scene_ask_retry.c | 2 +- applications/lfrfid/scene/lfrfid_app_scene_retry_confirm.cpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/applications/ibutton/scenes/ibutton_scene_retry_confirm.c b/applications/ibutton/scenes/ibutton_scene_retry_confirm.c index d2778ac1..fa2e1dec 100644 --- a/applications/ibutton/scenes/ibutton_scene_retry_confirm.c +++ b/applications/ibutton/scenes/ibutton_scene_retry_confirm.c @@ -21,7 +21,7 @@ void ibutton_scene_retry_confirm_on_enter(void* context) { widget_add_string_element( widget, 64, 19, AlignCenter, AlignBottom, FontPrimary, "Return to reading?"); widget_add_string_element( - widget, 64, 29, AlignCenter, AlignBottom, FontSecondary, "All unsaved data will be lost"); + widget, 64, 29, AlignCenter, AlignBottom, FontSecondary, "All unsaved data will be lost."); view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewWidget); } diff --git a/applications/infrared/scenes/infrared_scene_ask_back.c b/applications/infrared/scenes/infrared_scene_ask_back.c index 11cfcb04..c9c23684 100644 --- a/applications/infrared/scenes/infrared_scene_ask_back.c +++ b/applications/infrared/scenes/infrared_scene_ask_back.c @@ -16,7 +16,7 @@ void infrared_scene_ask_back_on_enter(void* context) { } dialog_ex_set_text( - dialog_ex, "All unsaved data\nwill be lost", 64, 31, AlignCenter, AlignCenter); + dialog_ex, "All unsaved data\nwill be lost.", 64, 31, AlignCenter, AlignCenter); dialog_ex_set_icon(dialog_ex, 0, 0, NULL); dialog_ex_set_left_button_text(dialog_ex, "Exit"); dialog_ex_set_center_button_text(dialog_ex, NULL); diff --git a/applications/infrared/scenes/infrared_scene_ask_retry.c b/applications/infrared/scenes/infrared_scene_ask_retry.c index 48a5cfcd..5157ee88 100644 --- a/applications/infrared/scenes/infrared_scene_ask_retry.c +++ b/applications/infrared/scenes/infrared_scene_ask_retry.c @@ -11,7 +11,7 @@ void infrared_scene_ask_retry_on_enter(void* context) { dialog_ex_set_header(dialog_ex, "Return to reading?", 64, 0, AlignCenter, AlignTop); dialog_ex_set_text( - dialog_ex, "All unsaved data\nwill be lost", 64, 31, AlignCenter, AlignCenter); + dialog_ex, "All unsaved data\nwill be lost.", 64, 31, AlignCenter, AlignCenter); dialog_ex_set_icon(dialog_ex, 0, 0, NULL); dialog_ex_set_left_button_text(dialog_ex, "Exit"); dialog_ex_set_center_button_text(dialog_ex, NULL); diff --git a/applications/lfrfid/scene/lfrfid_app_scene_retry_confirm.cpp b/applications/lfrfid/scene/lfrfid_app_scene_retry_confirm.cpp index e62b91bd..39430b97 100644 --- a/applications/lfrfid/scene/lfrfid_app_scene_retry_confirm.cpp +++ b/applications/lfrfid/scene/lfrfid_app_scene_retry_confirm.cpp @@ -19,7 +19,7 @@ void LfRfidAppSceneRetryConfirm::on_enter(LfRfidApp* app, bool /* need_restore * line_1->set_text("Return to reading?", 64, 19, 128 - 2, AlignCenter, AlignBottom, FontPrimary); line_2->set_text( - "All unsaved data will be lost", 64, 29, 0, AlignCenter, AlignBottom, FontSecondary); + "All unsaved data will be lost.", 64, 29, 0, AlignCenter, AlignBottom, FontSecondary); app->view_controller.switch_to(); } From f8e0ec42c53b7b0710d17f5efcd264c8b4c94927 Mon Sep 17 00:00:00 2001 From: Yukai Li Date: Mon, 25 Jul 2022 09:21:05 -0600 Subject: [PATCH 26/37] nfc: NTAG203 support (#1383) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * nfc: Fix original MFUL feature flags * nfc: Add NTAG203 read support * nfc: Update emulation lock byte handling for NTAG203 * nfc: Add NTAG203 counter emulation support * nfc: Add NTAG203 tag generator * nfc: Fix NTAG203 emulating GET_VERSION * nfc: Fix MFUL version reading * nfc: Complete NTAG203 counter emulation behavior * nfc: Complete NTAG203 emulation * nfc: Remove unnecessary init in MFUL emulation * nfc: Add notes about MFUL type enum Co-authored-by: gornekich Co-authored-by: あく --- applications/nfc/helpers/nfc_generators.c | 20 ++ applications/nfc/nfc_types.c | 2 + lib/nfc_protocols/mifare_ultralight.c | 257 +++++++++++++++++----- lib/nfc_protocols/mifare_ultralight.h | 15 ++ 4 files changed, 237 insertions(+), 57 deletions(-) diff --git a/applications/nfc/helpers/nfc_generators.c b/applications/nfc/helpers/nfc_generators.c index 67d9be7a..4121daf4 100644 --- a/applications/nfc/helpers/nfc_generators.c +++ b/applications/nfc/helpers/nfc_generators.c @@ -6,6 +6,8 @@ static const uint8_t version_bytes_mf0ulx1[] = {0x00, 0x04, 0x03, 0x00, 0x01, 0x00, 0x00, 0x03}; static const uint8_t version_bytes_ntag21x[] = {0x00, 0x04, 0x04, 0x02, 0x01, 0x00, 0x00, 0x03}; static const uint8_t version_bytes_ntag_i2c[] = {0x00, 0x04, 0x04, 0x05, 0x02, 0x00, 0x00, 0x03}; +static const uint8_t default_data_ntag203[] = + {0xE1, 0x10, 0x12, 0x00, 0x01, 0x03, 0xA0, 0x10, 0x44, 0x03, 0x00, 0xFE}; static const uint8_t default_data_ntag213[] = {0x01, 0x03, 0xA0, 0x0C, 0x34, 0x03, 0x00, 0xFE}; static const uint8_t default_data_ntag215_216[] = {0x03, 0x00, 0xFE}; static const uint8_t default_data_ntag_i2c[] = {0xE1, 0x10, 0x00, 0x00, 0x03, 0x00, 0xFE}; @@ -58,6 +60,18 @@ static void nfc_generate_mf_ul_orig(NfcDeviceData* data) { memset(&mful->data[4 * 4], 0xFF, 4); } +static void nfc_generate_mf_ul_ntag203(NfcDeviceData* data) { + nfc_generate_common_start(data); + nfc_generate_mf_ul_common(data); + + MfUltralightData* mful = &data->mf_ul_data; + mful->type = MfUltralightTypeNTAG203; + mful->data_size = 42 * 4; + nfc_generate_mf_ul_copy_uid_with_bcc(data); + mful->data[9] = 0x48; // Internal byte + memcpy(&mful->data[3 * 4], default_data_ntag203, sizeof(default_data_ntag203)); +} + static void nfc_generate_mf_ul_with_config_common(NfcDeviceData* data, uint8_t num_pages) { nfc_generate_common_start(data); nfc_generate_mf_ul_common(data); @@ -275,6 +289,11 @@ static const NfcGenerator mf_ul_h21_generator = { .generator_func = nfc_generate_mf_ul_h21, .next_scene = NfcSceneMifareUlMenu}; +static const NfcGenerator ntag203_generator = { + .name = "NTAG203", + .generator_func = nfc_generate_mf_ul_ntag203, + .next_scene = NfcSceneMifareUlMenu}; + static const NfcGenerator ntag213_generator = { .name = "NTAG213", .generator_func = nfc_generate_ntag213, @@ -316,6 +335,7 @@ const NfcGenerator* const nfc_generators[] = { &mf_ul_h11_generator, &mf_ul_21_generator, &mf_ul_h21_generator, + &ntag203_generator, &ntag213_generator, &ntag215_generator, &ntag216_generator, diff --git a/applications/nfc/nfc_types.c b/applications/nfc/nfc_types.c index 2d11c339..42762876 100644 --- a/applications/nfc/nfc_types.c +++ b/applications/nfc/nfc_types.c @@ -43,6 +43,8 @@ const char* nfc_mf_ul_type(MfUltralightType type, bool full_name) { return "NTAG I2C Plus 1K"; } else if(type == MfUltralightTypeNTAGI2CPlus2K) { return "NTAG I2C Plus 2K"; + } else if(type == MfUltralightTypeNTAG203) { + return "NTAG203"; } else if(type == MfUltralightTypeUL11 && full_name) { return "Mifare Ultralight 11"; } else if(type == MfUltralightTypeUL21 && full_name) { diff --git a/lib/nfc_protocols/mifare_ultralight.c b/lib/nfc_protocols/mifare_ultralight.c index 21dbd9c4..9dcd1d6a 100644 --- a/lib/nfc_protocols/mifare_ultralight.c +++ b/lib/nfc_protocols/mifare_ultralight.c @@ -35,9 +35,11 @@ static MfUltralightFeatures mf_ul_get_features(MfUltralightType type) { return MfUltralightSupportFastRead | MfUltralightSupportAuth | MfUltralightSupportFastWrite | MfUltralightSupportSignature | MfUltralightSupportSectorSelect; + case MfUltralightTypeNTAG203: + return MfUltralightSupportCompatWrite | MfUltralightSupportCounterInMemory; default: // Assumed original MFUL 512-bit - return MfUltralightSupportNone; + return MfUltralightSupportCompatWrite; } } @@ -46,6 +48,11 @@ static void mf_ul_set_default_version(MfUltralightReader* reader, MfUltralightDa reader->pages_to_read = 16; } +static void mf_ul_set_version_ntag203(MfUltralightReader* reader, MfUltralightData* data) { + data->type = MfUltralightTypeNTAG203; + reader->pages_to_read = 42; +} + bool mf_ultralight_read_version( FuriHalNfcTxRxContext* tx_rx, MfUltralightReader* reader, @@ -57,7 +64,7 @@ bool mf_ultralight_read_version( tx_rx->tx_data[0] = MF_UL_GET_VERSION_CMD; tx_rx->tx_bits = 8; tx_rx->tx_rx_type = FuriHalNfcTxRxTypeDefault; - if(!furi_hal_nfc_tx_rx(tx_rx, 50)) { + if(!furi_hal_nfc_tx_rx(tx_rx, 50) || tx_rx->rx_bits != 64) { FURI_LOG_D(TAG, "Failed reading version"); mf_ul_set_default_version(reader, data); furi_hal_nfc_sleep(); @@ -468,6 +475,23 @@ static bool mf_ultralight_sector_select(FuriHalNfcTxRxContext* tx_rx, uint8_t se return true; } +bool mf_ultralight_read_pages_direct( + FuriHalNfcTxRxContext* tx_rx, + uint8_t start_index, + uint8_t* data) { + FURI_LOG_D(TAG, "Reading pages %d - %d", start_index, start_index + 3); + tx_rx->tx_data[0] = MF_UL_READ_CMD; + tx_rx->tx_data[1] = start_index; + tx_rx->tx_bits = 16; + tx_rx->tx_rx_type = FuriHalNfcTxRxTypeDefault; + if(!furi_hal_nfc_tx_rx(tx_rx, 50) || tx_rx->rx_bits < 16 * 8) { + FURI_LOG_D(TAG, "Failed to read pages %d - %d", start_index, start_index + 3); + return false; + } + memcpy(data, tx_rx->rx_data, 16); + return true; +} + bool mf_ultralight_read_pages( FuriHalNfcTxRxContext* tx_rx, MfUltralightReader* reader, @@ -632,6 +656,17 @@ bool mf_ul_read_card( // Read Signature mf_ultralight_read_signature(tx_rx, data); } + } else { + // No GET_VERSION command, check for NTAG203 by reading last page (41) + uint8_t dummy[16]; + if(mf_ultralight_read_pages_direct(tx_rx, 41, dummy)) { + mf_ul_set_version_ntag203(reader, data); + reader->supported_features = mf_ul_get_features(data->type); + } else { + // We're really an original Mifare Ultralight, reset tag for safety + furi_hal_nfc_sleep(); + furi_hal_nfc_activate_nfca(300, NULL); + } } card_read = mf_ultralight_read_pages(tx_rx, reader, data); @@ -772,6 +807,8 @@ static bool mf_ul_ntag_i2c_plus_check_auth( static int16_t mf_ul_get_dynamic_lock_page_addr(MfUltralightData* data) { switch(data->type) { + case MfUltralightTypeNTAG203: + return 0x28; case MfUltralightTypeUL21: case MfUltralightTypeNTAG213: case MfUltralightTypeNTAG215: @@ -804,6 +841,10 @@ static bool mf_ul_check_lock(MfUltralightEmulator* emulator, int16_t write_page) // Check max page switch(emulator->data.type) { + case MfUltralightTypeNTAG203: + // Counter page can be locked and is after dynamic locks + if(write_page == 40) return true; + break; case MfUltralightTypeUL21: case MfUltralightTypeNTAG213: case MfUltralightTypeNTAG215: @@ -841,6 +882,19 @@ static bool mf_ul_check_lock(MfUltralightEmulator* emulator, int16_t write_page) switch(emulator->data.type) { // low byte LSB range, MSB range + case MfUltralightTypeNTAG203: + if(write_page >= 16 && write_page <= 27) + shift = (write_page - 16) / 4 + 1; + else if(write_page >= 28 && write_page <= 39) + shift = (write_page - 28) / 4 + 5; + else if(write_page == 41) + shift = 12; + else { + furi_assert(false); + shift = 0; + } + + break; case MfUltralightTypeUL21: case MfUltralightTypeNTAG213: // 16-17, 30-31 @@ -937,6 +991,42 @@ static void mf_ul_increment_single_counter(MfUltralightEmulator* emulator) { } } +static bool + mf_ul_emulate_ntag203_counter_write(MfUltralightEmulator* emulator, uint8_t* page_buff) { + // We'll reuse the existing counters for other NTAGs as staging + // Counter 0 stores original value, data is new value + uint32_t counter_value; + if(emulator->data.tearing[0] == MF_UL_TEARING_FLAG_DEFAULT) { + counter_value = emulator->data.data[MF_UL_NTAG203_COUNTER_PAGE * 4] | + (emulator->data.data[MF_UL_NTAG203_COUNTER_PAGE * 4 + 1] << 8); + } else { + // We've had a reset here, so load from original value + counter_value = emulator->data.counter[0]; + } + // Although the datasheet says increment by 0 is always possible, this is not the case on + // an actual tag. If the counter is at 0xFFFF, any writes are locked out. + if(counter_value == 0xFFFF) return false; + uint32_t increment = page_buff[0] | (page_buff[1] << 8); + if(counter_value == 0) { + counter_value = increment; + } else { + // Per datasheet specifying > 0x000F is supposed to NAK, but actual tag doesn't + increment &= 0x000F; + if(counter_value + increment > 0xFFFF) return false; + counter_value += increment; + } + // Commit to new value counter + emulator->data.data[MF_UL_NTAG203_COUNTER_PAGE * 4] = (uint8_t)counter_value; + emulator->data.data[MF_UL_NTAG203_COUNTER_PAGE * 4 + 1] = (uint8_t)(counter_value >> 8); + emulator->data.tearing[0] = MF_UL_TEARING_FLAG_DEFAULT; + if(counter_value == 0xFFFF) { + // Tag will lock out counter if final number is 0xFFFF, even if you try to roll it back + emulator->data.counter[1] = 0xFFFF; + } + emulator->data_changed = true; + return true; +} + static void mf_ul_emulate_write( MfUltralightEmulator* emulator, int16_t tag_addr, @@ -962,53 +1052,75 @@ static void mf_ul_emulate_write( *(uint32_t*)page_buff |= *(uint32_t*)&emulator->data.data[write_page * 4]; } else if(tag_addr == mf_ul_get_dynamic_lock_page_addr(&emulator->data)) { // Handle dynamic locks - uint16_t orig_locks = emulator->data.data[write_page * 4] | - (emulator->data.data[write_page * 4 + 1] << 8); - uint8_t orig_block_locks = emulator->data.data[write_page * 4 + 2]; - uint16_t new_locks = page_buff[0] | (page_buff[1] << 8); - uint8_t new_block_locks = page_buff[2]; + if(emulator->data.type == MfUltralightTypeNTAG203) { + // NTAG203 lock bytes are a bit different from the others + uint8_t orig_page_lock_byte = emulator->data.data[write_page * 4]; + uint8_t orig_cnt_lock_byte = emulator->data.data[write_page * 4 + 1]; + uint8_t new_page_lock_byte = page_buff[0]; + uint8_t new_cnt_lock_byte = page_buff[1]; - int block_lock_count; - switch(emulator->data.type) { - case MfUltralightTypeUL21: - block_lock_count = 5; - break; - case MfUltralightTypeNTAG213: - block_lock_count = 6; - break; - case MfUltralightTypeNTAG215: - block_lock_count = 4; - break; - case MfUltralightTypeNTAG216: - case MfUltralightTypeNTAGI2C1K: - case MfUltralightTypeNTAGI2CPlus1K: - block_lock_count = 7; - break; - case MfUltralightTypeNTAGI2C2K: - case MfUltralightTypeNTAGI2CPlus2K: - block_lock_count = 8; - break; - default: - furi_assert(false); - block_lock_count = 0; - break; + if(orig_page_lock_byte & 0x01) // Block lock bits 1-3 + new_page_lock_byte &= ~0x0E; + if(orig_page_lock_byte & 0x10) // Block lock bits 5-7 + new_page_lock_byte &= ~0xE0; + for(uint8_t i = 0; i < 4; ++i) { + if(orig_cnt_lock_byte & (1 << i)) // Block lock counter bit + new_cnt_lock_byte &= ~(1 << (4 + i)); + } + + new_page_lock_byte |= orig_page_lock_byte; + new_cnt_lock_byte |= orig_cnt_lock_byte; + page_buff[0] = new_page_lock_byte; + page_buff[1] = new_cnt_lock_byte; + } else { + uint16_t orig_locks = emulator->data.data[write_page * 4] | + (emulator->data.data[write_page * 4 + 1] << 8); + uint8_t orig_block_locks = emulator->data.data[write_page * 4 + 2]; + uint16_t new_locks = page_buff[0] | (page_buff[1] << 8); + uint8_t new_block_locks = page_buff[2]; + + int block_lock_count; + switch(emulator->data.type) { + case MfUltralightTypeUL21: + block_lock_count = 5; + break; + case MfUltralightTypeNTAG213: + block_lock_count = 6; + break; + case MfUltralightTypeNTAG215: + block_lock_count = 4; + break; + case MfUltralightTypeNTAG216: + case MfUltralightTypeNTAGI2C1K: + case MfUltralightTypeNTAGI2CPlus1K: + block_lock_count = 7; + break; + case MfUltralightTypeNTAGI2C2K: + case MfUltralightTypeNTAGI2CPlus2K: + block_lock_count = 8; + break; + default: + furi_assert(false); + block_lock_count = 0; + break; + } + + for(int i = 0; i < block_lock_count; ++i) { + if(orig_block_locks & (1 << i)) new_locks &= ~(3 << (2 * i)); + } + + new_locks |= orig_locks; + new_block_locks |= orig_block_locks; + + page_buff[0] = new_locks & 0xff; + page_buff[1] = new_locks >> 8; + page_buff[2] = new_block_locks; + if(emulator->data.type >= MfUltralightTypeUL21 && + emulator->data.type <= MfUltralightTypeNTAG216) + page_buff[3] = MF_UL_TEARING_FLAG_DEFAULT; + else + page_buff[3] = 0; } - - for(int i = 0; i < block_lock_count; ++i) { - if(orig_block_locks & (1 << i)) new_locks &= ~(3 << (2 * i)); - } - - new_locks |= orig_locks; - new_block_locks |= orig_block_locks; - - page_buff[0] = new_locks & 0xff; - page_buff[1] = new_locks >> 8; - page_buff[2] = new_block_locks; - if(emulator->data.type >= MfUltralightTypeUL21 && - emulator->data.type <= MfUltralightTypeNTAG216) - page_buff[3] = MF_UL_TEARING_FLAG_DEFAULT; - else - page_buff[3] = 0; } memcpy(&emulator->data.data[write_page * 4], page_buff, 4); @@ -1025,6 +1137,18 @@ void mf_ul_reset_emulation(MfUltralightEmulator* emulator, bool is_power_cycle) if(emulator->supported_features & MfUltralightSupportSingleCounter) { emulator->read_counter_incremented = false; } + + if(emulator->data.type == MfUltralightTypeNTAG203) { + // Apply lockout if counter ever reached 0xFFFF + if(emulator->data.counter[1] == 0xFFFF) { + emulator->data.data[MF_UL_NTAG203_COUNTER_PAGE * 4] = 0xFF; + emulator->data.data[MF_UL_NTAG203_COUNTER_PAGE * 4 + 1] = 0xFF; + } + // Copy original counter value from data + emulator->data.counter[0] = + emulator->data.data[MF_UL_NTAG203_COUNTER_PAGE * 4] | + (emulator->data.data[MF_UL_NTAG203_COUNTER_PAGE * 4 + 1] << 8); + } } else { if(emulator->config != NULL) { // ACCESS (less CFGLCK) and AUTH0 are updated when reactivated @@ -1034,6 +1158,10 @@ void mf_ul_reset_emulation(MfUltralightEmulator* emulator, bool is_power_cycle) emulator->config_cache.auth0 = emulator->config->auth0; } } + if(emulator->data.type == MfUltralightTypeNTAG203) { + // Mark counter as dirty + emulator->data.tearing[0] = 0; + } } void mf_ul_prepare_emulation(MfUltralightEmulator* emulator, MfUltralightData* data) { @@ -1077,12 +1205,20 @@ bool mf_ul_prepare_emulation_response( // Check composite commands if(emulator->comp_write_cmd_started) { - // Compatibility write is the only one composit command if(buff_rx_len == 16 * 8) { - mf_ul_emulate_write( - emulator, emulator->comp_write_page_addr, emulator->comp_write_page_addr, buff_rx); - send_ack = true; - command_parsed = true; + if(emulator->data.type == MfUltralightTypeNTAG203 && + emulator->comp_write_page_addr == MF_UL_NTAG203_COUNTER_PAGE) { + send_ack = mf_ul_emulate_ntag203_counter_write(emulator, buff_rx); + command_parsed = send_ack; + } else { + mf_ul_emulate_write( + emulator, + emulator->comp_write_page_addr, + emulator->comp_write_page_addr, + buff_rx); + send_ack = true; + command_parsed = true; + } } emulator->comp_write_cmd_started = false; } else if(emulator->sector_select_cmd_started) { @@ -1099,7 +1235,7 @@ bool mf_ul_prepare_emulation_response( } else if(buff_rx_len >= 8) { uint8_t cmd = buff_rx[0]; if(cmd == MF_UL_GET_VERSION_CMD) { - if(emulator->data.type != MfUltralightTypeUnknown) { + if(emulator->data.type >= MfUltralightTypeUL11) { if(buff_rx_len == 1 * 8) { tx_bytes = sizeof(emulator->data.version); memcpy(buff_tx, &emulator->data.version, tx_bytes); @@ -1409,9 +1545,15 @@ bool mf_ul_prepare_emulation_response( int16_t tag_addr = mf_ultralight_page_addr_to_tag_addr( emulator->curr_sector, orig_write_page); if(!mf_ul_check_lock(emulator, tag_addr)) break; - mf_ul_emulate_write(emulator, tag_addr, write_page, &buff_rx[2]); - send_ack = true; - command_parsed = true; + if(emulator->data.type == MfUltralightTypeNTAG203 && + orig_write_page == MF_UL_NTAG203_COUNTER_PAGE) { + send_ack = mf_ul_emulate_ntag203_counter_write(emulator, &buff_rx[2]); + command_parsed = send_ack; + } else { + mf_ul_emulate_write(emulator, tag_addr, write_page, &buff_rx[2]); + send_ack = true; + command_parsed = true; + } } while(false); } } else if(cmd == MF_UL_FAST_WRITE) { @@ -1590,7 +1732,8 @@ bool mf_ul_prepare_emulation_response( } } } else { - reset_idle = true; + // NTAG203 appears to NAK instead of just falling off on invalid commands + if(emulator->data.type != MfUltralightTypeNTAG203) reset_idle = true; FURI_LOG_D(TAG, "Received invalid command"); } } else { diff --git a/lib/nfc_protocols/mifare_ultralight.h b/lib/nfc_protocols/mifare_ultralight.h index 36b81fdf..77dbd1e4 100644 --- a/lib/nfc_protocols/mifare_ultralight.h +++ b/lib/nfc_protocols/mifare_ultralight.h @@ -26,15 +26,23 @@ #define MF_UL_NAK_INVALID_ARGUMENT (0x0) #define MF_UL_NAK_AUTHLIM_REACHED (0x4) +#define MF_UL_NTAG203_COUNTER_PAGE (41) + +// Important: order matters; some features are based on positioning in this enum typedef enum { MfUltralightTypeUnknown, + MfUltralightTypeNTAG203, + // Below have config pages and GET_VERSION support MfUltralightTypeUL11, MfUltralightTypeUL21, MfUltralightTypeNTAG213, MfUltralightTypeNTAG215, MfUltralightTypeNTAG216, + // Below also have sector select + // NTAG I2C's *does not* have regular config pages, so it's a bit of an odd duck MfUltralightTypeNTAGI2C1K, MfUltralightTypeNTAGI2C2K, + // NTAG I2C Plus has stucture expected from NTAG21x MfUltralightTypeNTAGI2CPlus1K, MfUltralightTypeNTAGI2CPlus2K, @@ -58,6 +66,8 @@ typedef enum { MfUltralightSupportSingleCounter = 1 << 10, // ASCII mirror is not a command, but handy to have as a flag MfUltralightSupportAsciiMirror = 1 << 11, + // NTAG203 counter that's in memory rather than through a command + MfUltralightSupportCounterInMemory = 1 << 12, } MfUltralightFeatures; typedef enum { @@ -173,6 +183,11 @@ bool mf_ultralight_read_version( MfUltralightReader* reader, MfUltralightData* data); +bool mf_ultralight_read_pages_direct( + FuriHalNfcTxRxContext* tx_rx, + uint8_t start_index, + uint8_t* data); + bool mf_ultralight_read_pages( FuriHalNfcTxRxContext* tx_rx, MfUltralightReader* reader, From cd77b93f26fd05996dc0a2381eaf23c37ef5e394 Mon Sep 17 00:00:00 2001 From: Eric Betts Date: Mon, 25 Jul 2022 08:36:38 -0700 Subject: [PATCH 27/37] Picopass: dump full card, extract some details (#1408) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Dump entire picopass card * Capture more iClass details * facility code bugfix Co-authored-by: あく --- applications/picopass/picopass_device.c | 60 +++++++++++-------- applications/picopass/picopass_device.h | 14 ++++- applications/picopass/picopass_worker.c | 54 ++++++++++------- .../scenes/picopass_scene_read_card_success.c | 13 ++-- lib/ST25RFAL002/include/rfal_picopass.h | 4 -- 5 files changed, 88 insertions(+), 57 deletions(-) diff --git a/applications/picopass/picopass_device.c b/applications/picopass/picopass_device.c index 8cce5288..75d9e290 100644 --- a/applications/picopass/picopass_device.c +++ b/applications/picopass/picopass_device.c @@ -10,6 +10,9 @@ static const uint32_t picopass_file_version = 1; PicopassDevice* picopass_device_alloc() { PicopassDevice* picopass_dev = malloc(sizeof(PicopassDevice)); + picopass_dev->dev_data.pacs.legacy = false; + picopass_dev->dev_data.pacs.se_enabled = false; + picopass_dev->dev_data.pacs.pin_length = 0; picopass_dev->storage = furi_record_open("storage"); picopass_dev->dialogs = furi_record_open("dialogs"); return picopass_dev; @@ -32,7 +35,7 @@ static bool picopass_device_save_file( bool saved = false; FlipperFormat* file = flipper_format_file_alloc(dev->storage); PicopassPacs* pacs = &dev->dev_data.pacs; - ApplicationArea* AA1 = &dev->dev_data.AA1; + PicopassBlock* AA1 = dev->dev_data.AA1; string_t temp_str; string_init(temp_str); @@ -54,40 +57,40 @@ static bool picopass_device_save_file( if(!flipper_format_file_open_always(file, string_get_cstr(temp_str))) break; if(dev->format == PicopassDeviceSaveFormatHF) { + uint32_t fc = pacs->record.FacilityCode; + uint32_t cn = pacs->record.CardNumber; // Write header if(!flipper_format_write_header_cstr(file, picopass_file_header, picopass_file_version)) break; if(pacs->record.valid) { - if(!flipper_format_write_uint32( - file, "Facility Code", (uint32_t*)&pacs->record.FacilityCode, 1)) - break; - if(!flipper_format_write_uint32( - file, "Card Number", (uint32_t*)&pacs->record.CardNumber, 1)) - break; + if(!flipper_format_write_uint32(file, "Facility Code", &fc, 1)) break; + if(!flipper_format_write_uint32(file, "Card Number", &cn, 1)) break; if(!flipper_format_write_hex( file, "Credential", pacs->credential, PICOPASS_BLOCK_LEN)) break; - if(!flipper_format_write_hex(file, "PIN", pacs->pin0, PICOPASS_BLOCK_LEN)) break; - if(!flipper_format_write_hex(file, "PIN(cont.)", pacs->pin1, PICOPASS_BLOCK_LEN)) - break; - - if(!flipper_format_write_comment_cstr(file, "Picopass blocks")) break; - // TODO: Save CSN, CFG, AA1, etc - bool block_saved = true; - for(size_t i = 0; i < 4; i++) { - string_printf(temp_str, "Block %d", i + 6); - if(!flipper_format_write_hex( - file, - string_get_cstr(temp_str), - AA1->block[i].data, - PICOPASS_BLOCK_LEN)) { - block_saved = false; + if(pacs->pin_length > 0) { + if(!flipper_format_write_hex(file, "PIN\t\t", pacs->pin0, PICOPASS_BLOCK_LEN)) + break; + if(!flipper_format_write_hex( + file, "PIN(cont.)\t", pacs->pin1, PICOPASS_BLOCK_LEN)) break; - } } - if(!block_saved) break; - if(!flipper_format_write_comment_cstr(file, "This is currently incomplete")) break; } + if(!flipper_format_write_comment_cstr(file, "Picopass blocks")) break; + bool block_saved = true; + + size_t app_limit = AA1[PICOPASS_CONFIG_BLOCK_INDEX].data[0] < PICOPASS_MAX_APP_LIMIT ? + AA1[PICOPASS_CONFIG_BLOCK_INDEX].data[0] : + PICOPASS_MAX_APP_LIMIT; + for(size_t i = 0; i < app_limit; i++) { + string_printf(temp_str, "Block %d", i); + if(!flipper_format_write_hex( + file, string_get_cstr(temp_str), AA1[i].data, PICOPASS_BLOCK_LEN)) { + block_saved = false; + break; + } + } + if(!block_saved) break; } else if(dev->format == PicopassDeviceSaveFormatLF) { const char* lf_header = "Flipper RFID key"; // Write header @@ -142,5 +145,10 @@ void picopass_device_free(PicopassDevice* picopass_dev) { } void picopass_device_data_clear(PicopassDeviceData* dev_data) { - memset(&dev_data->AA1, 0, sizeof(ApplicationArea)); + for(size_t i = 0; i < PICOPASS_MAX_APP_LIMIT; i++) { + memset(dev_data->AA1[i].data, 0, sizeof(dev_data->AA1[i].data)); + } + dev_data->pacs.legacy = false; + dev_data->pacs.se_enabled = false; + dev_data->pacs.pin_length = 0; } diff --git a/applications/picopass/picopass_device.h b/applications/picopass/picopass_device.h index a0f7a667..326e58e6 100644 --- a/applications/picopass/picopass_device.h +++ b/applications/picopass/picopass_device.h @@ -10,6 +10,11 @@ #define PICOPASS_DEV_NAME_MAX_LEN 22 #define PICOPASS_READER_DATA_MAX_SIZE 64 #define PICOPASS_BLOCK_LEN 8 +#define PICOPASS_MAX_APP_LIMIT 32 + +#define PICOPASS_CSN_BLOCK_INDEX 0 +#define PICOPASS_CONFIG_BLOCK_INDEX 1 +#define PICOPASS_AIA_BLOCK_INDEX 5 #define PICOPASS_APP_FOLDER "/any/picopass" #define PICOPASS_APP_EXTENSION ".picopass" @@ -35,7 +40,10 @@ typedef struct { } PicopassWiegandRecord; typedef struct { + bool legacy; + bool se_enabled; bool biometrics; + uint8_t pin_length; PicopassEncryption encryption; uint8_t credential[8]; uint8_t pin0[8]; @@ -44,7 +52,11 @@ typedef struct { } PicopassPacs; typedef struct { - ApplicationArea AA1; + uint8_t data[PICOPASS_BLOCK_LEN]; +} PicopassBlock; + +typedef struct { + PicopassBlock AA1[PICOPASS_MAX_APP_LIMIT]; PicopassPacs pacs; } PicopassDeviceData; diff --git a/applications/picopass/picopass_worker.c b/applications/picopass/picopass_worker.c index 645a1bce..7ecfbc3b 100644 --- a/applications/picopass/picopass_worker.c +++ b/applications/picopass/picopass_worker.c @@ -55,12 +55,11 @@ static ReturnCode picopass_worker_parse_wiegand(uint8_t* data, PicopassWiegandRe if(record->bitLength == 26) { uint8_t* v4 = data + 4; - v4[0] = 0; - uint32_t bot = v4[3] | (v4[2] << 8) | (v4[1] << 16) | (v4[0] << 24); record->CardNumber = (bot >> 1) & 0xFFFF; record->FacilityCode = (bot >> 17) & 0xFF; + FURI_LOG_D(TAG, "FC:%u CN: %u\n", record->FacilityCode, record->CardNumber); record->valid = true; } else { record->CardNumber = 0; @@ -165,7 +164,7 @@ ReturnCode picopass_detect_card(int timeout) { return ERR_NONE; } -ReturnCode picopass_read_card(ApplicationArea* AA1) { +ReturnCode picopass_read_card(PicopassBlock* AA1) { rfalPicoPassIdentifyRes idRes; rfalPicoPassSelectRes selRes; rfalPicoPassReadCheckRes rcRes; @@ -205,10 +204,20 @@ ReturnCode picopass_read_card(ApplicationArea* AA1) { return err; } - for(size_t i = 0; i < 4; i++) { - FURI_LOG_D(TAG, "rfalPicoPassPollerReadBlock block %d", i + 6); + rfalPicoPassReadBlockRes csn; + err = rfalPicoPassPollerReadBlock(PICOPASS_CSN_BLOCK_INDEX, &csn); + memcpy(AA1[PICOPASS_CSN_BLOCK_INDEX].data, csn.data, sizeof(csn.data)); + + rfalPicoPassReadBlockRes cfg; + err = rfalPicoPassPollerReadBlock(PICOPASS_CONFIG_BLOCK_INDEX, &cfg); + memcpy(AA1[PICOPASS_CONFIG_BLOCK_INDEX].data, cfg.data, sizeof(cfg.data)); + + size_t app_limit = cfg.data[0] < PICOPASS_MAX_APP_LIMIT ? cfg.data[0] : PICOPASS_MAX_APP_LIMIT; + + for(size_t i = 2; i < app_limit; i++) { + FURI_LOG_D(TAG, "rfalPicoPassPollerReadBlock block %d", i); rfalPicoPassReadBlockRes block; - err = rfalPicoPassPollerReadBlock(i + 6, &block); + err = rfalPicoPassPollerReadBlock(i, &block); if(err != ERR_NONE) { FURI_LOG_E(TAG, "rfalPicoPassPollerReadBlock error %d", err); return err; @@ -217,7 +226,7 @@ ReturnCode picopass_read_card(ApplicationArea* AA1) { FURI_LOG_D( TAG, "rfalPicoPassPollerReadBlock %d %02x%02x%02x%02x%02x%02x%02x%02x", - i + 6, + i, block.data[0], block.data[1], block.data[2], @@ -227,7 +236,7 @@ ReturnCode picopass_read_card(ApplicationArea* AA1) { block.data[6], block.data[7]); - memcpy(&(AA1->block[i]), &block, sizeof(block)); + memcpy(AA1[i].data, block.data, sizeof(block.data)); } return ERR_NONE; @@ -251,7 +260,7 @@ void picopass_worker_detect(PicopassWorker* picopass_worker) { picopass_device_data_clear(picopass_worker->dev_data); PicopassDeviceData* dev_data = picopass_worker->dev_data; - ApplicationArea* AA1 = &dev_data->AA1; + PicopassBlock* AA1 = dev_data->AA1; PicopassPacs* pacs = &dev_data->pacs; ReturnCode err; @@ -263,34 +272,39 @@ void picopass_worker_detect(PicopassWorker* picopass_worker) { FURI_LOG_E(TAG, "picopass_read_card error %d", err); } - pacs->biometrics = AA1->block[0].data[4]; - pacs->encryption = AA1->block[0].data[7]; + // Thank you proxmark! + pacs->legacy = (memcmp(AA1[5].data, "\xff\xff\xff\xff\xff\xff\xff\xff", 8) == 0); + pacs->se_enabled = (memcmp(AA1[5].data, "\xff\xff\xff\x00\x06\xff\xff\xff", 8) == 0); - if(pacs->encryption == 0x17) { + pacs->biometrics = AA1[6].data[4]; + pacs->pin_length = AA1[6].data[6] & 0x0F; + pacs->encryption = AA1[6].data[7]; + + if(pacs->encryption == PicopassDeviceEncryption3DES) { FURI_LOG_D(TAG, "3DES Encrypted"); - err = picopass_worker_decrypt(AA1->block[1].data, pacs->credential); + err = picopass_worker_decrypt(AA1[7].data, pacs->credential); if(err != ERR_NONE) { FURI_LOG_E(TAG, "decrypt error %d", err); break; } - err = picopass_worker_decrypt(AA1->block[2].data, pacs->pin0); + err = picopass_worker_decrypt(AA1[8].data, pacs->pin0); if(err != ERR_NONE) { FURI_LOG_E(TAG, "decrypt error %d", err); break; } - err = picopass_worker_decrypt(AA1->block[3].data, pacs->pin1); + err = picopass_worker_decrypt(AA1[9].data, pacs->pin1); if(err != ERR_NONE) { FURI_LOG_E(TAG, "decrypt error %d", err); break; } - } else if(pacs->encryption == 0x14) { + } else if(pacs->encryption == PicopassDeviceEncryptionNone) { FURI_LOG_D(TAG, "No Encryption"); - memcpy(pacs->credential, AA1->block[1].data, RFAL_PICOPASS_MAX_BLOCK_LEN); - memcpy(pacs->pin0, AA1->block[2].data, RFAL_PICOPASS_MAX_BLOCK_LEN); - memcpy(pacs->pin1, AA1->block[3].data, RFAL_PICOPASS_MAX_BLOCK_LEN); - } else if(pacs->encryption == 0x15) { + memcpy(pacs->credential, AA1[7].data, PICOPASS_BLOCK_LEN); + memcpy(pacs->pin0, AA1[8].data, PICOPASS_BLOCK_LEN); + memcpy(pacs->pin1, AA1[9].data, PICOPASS_BLOCK_LEN); + } else if(pacs->encryption == PicopassDeviceEncryptionDES) { FURI_LOG_D(TAG, "DES Encrypted"); } else { FURI_LOG_D(TAG, "Unknown encryption"); diff --git a/applications/picopass/scenes/picopass_scene_read_card_success.c b/applications/picopass/scenes/picopass_scene_read_card_success.c index 96a08031..3866d201 100644 --- a/applications/picopass/scenes/picopass_scene_read_card_success.c +++ b/applications/picopass/scenes/picopass_scene_read_card_success.c @@ -29,14 +29,17 @@ void picopass_scene_read_card_success_on_enter(void* context) { PicopassPacs* pacs = &picopass->dev->dev_data.pacs; Widget* widget = picopass->widget; + size_t bytesLength = 1 + pacs->record.bitLength / 8; string_set_str(credential_str, ""); - for(uint8_t i = 0; i < RFAL_PICOPASS_MAX_BLOCK_LEN; i++) { + for(uint8_t i = PICOPASS_BLOCK_LEN - bytesLength; i < PICOPASS_BLOCK_LEN; i++) { string_cat_printf(credential_str, " %02X", pacs->credential[i]); } if(pacs->record.valid) { string_cat_printf( - wiegand_str, "FC: %03u CN: %05u", pacs->record.FacilityCode, pacs->record.CardNumber); + wiegand_str, "FC: %u CN: %u", pacs->record.FacilityCode, pacs->record.CardNumber); + } else { + string_cat_printf(wiegand_str, "%d bits", pacs->record.bitLength); } widget_add_button_element( @@ -53,10 +56,8 @@ void picopass_scene_read_card_success_on_enter(void* context) { picopass_scene_read_card_success_widget_callback, picopass); - if(pacs->record.valid) { - widget_add_string_element( - widget, 64, 12, AlignCenter, AlignCenter, FontPrimary, string_get_cstr(wiegand_str)); - } + widget_add_string_element( + widget, 64, 12, AlignCenter, AlignCenter, FontPrimary, string_get_cstr(wiegand_str)); widget_add_string_element( widget, 64, 32, AlignCenter, AlignCenter, FontSecondary, string_get_cstr(credential_str)); diff --git a/lib/ST25RFAL002/include/rfal_picopass.h b/lib/ST25RFAL002/include/rfal_picopass.h index baa8ea6f..5b815025 100644 --- a/lib/ST25RFAL002/include/rfal_picopass.h +++ b/lib/ST25RFAL002/include/rfal_picopass.h @@ -51,10 +51,6 @@ typedef struct { uint8_t crc[2]; } rfalPicoPassReadBlockRes; -typedef struct { - rfalPicoPassReadBlockRes block[4]; -} ApplicationArea; - ReturnCode rfalPicoPassPollerInitialize(void); ReturnCode rfalPicoPassPollerCheckPresence(void); ReturnCode rfalPicoPassPollerIdentify(rfalPicoPassIdentifyRes* idRes); From d085af31c3ed9155058d6b5ea49f279d73eab541 Mon Sep 17 00:00:00 2001 From: AlexeyOplachko <45398541+AlexeyOplachko@users.noreply.github.com> Date: Mon, 25 Jul 2022 23:34:49 +0300 Subject: [PATCH 28/37] Fixing a typo in Bug Report Issue Template (#1449) --- .github/ISSUE_TEMPLATE/01_bug_report.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/01_bug_report.yml b/.github/ISSUE_TEMPLATE/01_bug_report.yml index 4697c083..844d62c4 100644 --- a/.github/ISSUE_TEMPLATE/01_bug_report.yml +++ b/.github/ISSUE_TEMPLATE/01_bug_report.yml @@ -10,7 +10,7 @@ body: - type: textarea id: description attributes: - label: Desctibe the bug. + label: Describe the bug. description: "A clear and concise description of what the bug is." validations: required: true From 27b698f081ecbda04e9337ba5b9ee7abae8cdb4e Mon Sep 17 00:00:00 2001 From: Szymon Lisowiec Date: Mon, 25 Jul 2022 23:31:34 +0200 Subject: [PATCH 29/37] fbt: Fixed build for users with space in username (#1437) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: あく Co-authored-by: hedger --- assets/SConscript | 2 +- fbt.cmd | 4 ++-- scripts/toolchain/fbtenv.cmd | 10 +++++----- site_scons/site_tools/fbt_assets.py | 8 ++++---- site_scons/site_tools/fbt_dist.py | 6 +++--- site_scons/site_tools/fbt_version.py | 2 +- site_scons/site_tools/fwbin.py | 2 +- 7 files changed, 17 insertions(+), 17 deletions(-) diff --git a/assets/SConscript b/assets/SConscript index d5465534..46cc2ca2 100644 --- a/assets/SConscript +++ b/assets/SConscript @@ -97,7 +97,7 @@ if assetsenv["IS_BASE_FIRMWARE"]: "#/assets/resources/Manifest", assetsenv.GlobRecursive("*", "resources", exclude="Manifest"), action=Action( - '${PYTHON3} ${ASSETS_COMPILER} manifest "${TARGET.dir.posix}"', + '${PYTHON3} "${ASSETS_COMPILER}" manifest "${TARGET.dir.posix}"', "${RESMANIFESTCOMSTR}", ), ) diff --git a/fbt.cmd b/fbt.cmd index 2339eaaa..484b1064 100644 --- a/fbt.cmd +++ b/fbt.cmd @@ -1,5 +1,5 @@ @echo off -call %~dp0scripts\toolchain\fbtenv.cmd env +call "%~dp0scripts\toolchain\fbtenv.cmd" env set SCONS_EP=%~dp0\lib\scons\scripts\scons.py @@ -14,4 +14,4 @@ if [%FBT_NO_SYNC%] == [] ( git submodule update --init set "SCONS_DEFAULT_FLAGS=-Q --warn=target-not-built" -python lib\scons\scripts\scons.py %SCONS_DEFAULT_FLAGS% %* \ No newline at end of file +python lib\scons\scripts\scons.py %SCONS_DEFAULT_FLAGS% %* diff --git a/scripts/toolchain/fbtenv.cmd b/scripts/toolchain/fbtenv.cmd index 34adb12c..1a9af5a4 100644 --- a/scripts/toolchain/fbtenv.cmd +++ b/scripts/toolchain/fbtenv.cmd @@ -18,14 +18,14 @@ set "FBT_TOOLCHAIN_ROOT=%FBT_ROOT%\toolchain\i686-windows" if not exist "%FBT_TOOLCHAIN_ROOT%" ( - powershell -ExecutionPolicy Bypass -File %FBT_ROOT%\scripts\toolchain\windows-toolchain-download.ps1 "%flipper_toolchain_version%" + powershell -ExecutionPolicy Bypass -File "%FBT_ROOT%\scripts\toolchain\windows-toolchain-download.ps1" "%flipper_toolchain_version%" ) if not exist "%FBT_TOOLCHAIN_ROOT%\VERSION" ( - powershell -ExecutionPolicy Bypass -File %FBT_ROOT%\scripts\toolchain\windows-toolchain-download.ps1 "%flipper_toolchain_version%" + powershell -ExecutionPolicy Bypass -File "%FBT_ROOT%\scripts\toolchain\windows-toolchain-download.ps1" "%flipper_toolchain_version%" ) -set /p REAL_TOOLCHAIN_VERSION=<%FBT_TOOLCHAIN_ROOT%\VERSION +set /p REAL_TOOLCHAIN_VERSION=<"%FBT_TOOLCHAIN_ROOT%\VERSION" if not "%REAL_TOOLCHAIN_VERSION%" == "%FLIPPER_TOOLCHAIN_VERSION%" ( - powershell -ExecutionPolicy Bypass -File %FBT_ROOT%\scripts\toolchain\windows-toolchain-download.ps1 "%flipper_toolchain_version%" + powershell -ExecutionPolicy Bypass -File "%FBT_ROOT%\scripts\toolchain\windows-toolchain-download.ps1" "%flipper_toolchain_version%" ) @@ -40,6 +40,6 @@ if not "%1" == "env" ( echo ********************************* echo * fbt build environment * echo ********************************* - cd %FBT_ROOT% + cd "%FBT_ROOT%" cmd /k ) diff --git a/site_scons/site_tools/fbt_assets.py b/site_scons/site_tools/fbt_assets.py index 0c2ce6f7..c844db36 100644 --- a/site_scons/site_tools/fbt_assets.py +++ b/site_scons/site_tools/fbt_assets.py @@ -109,14 +109,14 @@ def generate(env): BUILDERS={ "IconBuilder": Builder( action=Action( - "${PYTHON3} ${ASSETS_COMPILER} icons ${SOURCE.posix} ${TARGET.dir.posix}", + '${PYTHON3} "${ASSETS_COMPILER}" icons ${SOURCE.posix} ${TARGET.dir.posix}', "${ICONSCOMSTR}", ), emitter=icons_emitter, ), "ProtoBuilder": Builder( action=Action( - "${PYTHON3} ${NANOPB_COMPILER} -q -I${SOURCE.dir.posix} -D${TARGET.dir.posix} ${SOURCES.posix}", + '${PYTHON3} "${NANOPB_COMPILER}" -q -I${SOURCE.dir.posix} -D${TARGET.dir.posix} ${SOURCES.posix}', "${PROTOCOMSTR}", ), emitter=proto_emitter, @@ -125,14 +125,14 @@ def generate(env): ), "DolphinSymBuilder": Builder( action=Action( - '${PYTHON3} ${ASSETS_COMPILER} dolphin -s dolphin_${DOLPHIN_RES_TYPE} "${SOURCE}" "${_DOLPHIN_OUT_DIR}"', + '${PYTHON3} "${ASSETS_COMPILER}" dolphin -s dolphin_${DOLPHIN_RES_TYPE} "${SOURCE}" "${_DOLPHIN_OUT_DIR}"', "${DOLPHINCOMSTR}", ), emitter=dolphin_emitter, ), "DolphinExtBuilder": Builder( action=Action( - '${PYTHON3} ${ASSETS_COMPILER} dolphin "${SOURCE}" "${_DOLPHIN_OUT_DIR}"', + '${PYTHON3} "${ASSETS_COMPILER}" dolphin "${SOURCE}" "${_DOLPHIN_OUT_DIR}"', "${DOLPHINCOMSTR}", ), emitter=dolphin_emitter, diff --git a/site_scons/site_tools/fbt_dist.py b/site_scons/site_tools/fbt_dist.py index 15a653a6..7c28c69c 100644 --- a/site_scons/site_tools/fbt_dist.py +++ b/site_scons/site_tools/fbt_dist.py @@ -74,7 +74,7 @@ def DistCommand(env, name, source, **kw): command = env.Command( target, source, - '@${PYTHON3} ${ROOT_DIR.abspath}/scripts/sconsdist.py copy -p ${DIST_PROJECTS} -s "${DIST_SUFFIX}" ${DIST_EXTRA}', + '@${PYTHON3} "${ROOT_DIR.abspath}/scripts/sconsdist.py" copy -p ${DIST_PROJECTS} -s "${DIST_SUFFIX}" ${DIST_EXTRA}', **kw, ) env.Pseudo(target) @@ -96,7 +96,7 @@ def generate(env): "UsbInstall": Builder( action=[ Action( - "${PYTHON3} ${ROOT_DIR.abspath}/scripts/selfupdate.py dist/${DIST_DIR}/f${TARGET_HW}-update-${DIST_SUFFIX}/update.fuf" + '${PYTHON3} "${ROOT_DIR.abspath}/scripts/selfupdate.py" dist/${DIST_DIR}/f${TARGET_HW}-update-${DIST_SUFFIX}/update.fuf' ), Touch("${TARGET}"), ] @@ -105,7 +105,7 @@ def generate(env): action=Action( [ Mkdir("$TARGET"), - "${PYTHON3} ${ROOT_DIR.abspath}/scripts/assets.py " + '${PYTHON3} "${ROOT_DIR.abspath}/scripts/assets.py" ' "copro ${COPRO_CUBE_DIR} " "${TARGET} ${COPRO_MCU_FAMILY} " "--cube_ver=${COPRO_CUBE_VERSION} " diff --git a/site_scons/site_tools/fbt_version.py b/site_scons/site_tools/fbt_version.py index 5073c55d..909eea4f 100644 --- a/site_scons/site_tools/fbt_version.py +++ b/site_scons/site_tools/fbt_version.py @@ -16,7 +16,7 @@ def generate(env): BUILDERS={ "VersionBuilder": Builder( action=Action( - "${PYTHON3} ${ROOT_DIR.abspath}/scripts/version.py generate -t ${TARGET_HW} -o ${TARGET.dir.posix} --dir ${ROOT_DIR}", + '${PYTHON3} "${ROOT_DIR.abspath}/scripts/version.py" generate -t ${TARGET_HW} -o ${TARGET.dir.posix} --dir "${ROOT_DIR}"', "${VERSIONCOMSTR}", ), emitter=version_emitter, diff --git a/site_scons/site_tools/fwbin.py b/site_scons/site_tools/fwbin.py index 848571e3..37e64e56 100644 --- a/site_scons/site_tools/fwbin.py +++ b/site_scons/site_tools/fwbin.py @@ -30,7 +30,7 @@ def generate(env): ), "DFUBuilder": Builder( action=Action( - '${PYTHON3} ${BIN2DFU} -i "${SOURCE}" -o "${TARGET}" -a ${IMAGE_BASE_ADDRESS} -l "Flipper Zero F${TARGET_HW}"', + '${PYTHON3} "${BIN2DFU}" -i "${SOURCE}" -o "${TARGET}" -a ${IMAGE_BASE_ADDRESS} -l "Flipper Zero F${TARGET_HW}"', "${DFUCOMSTR}", ), suffix=".dfu", From e03b102af220d7cd0697e57838b8370b1fb60155 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Tue, 26 Jul 2022 02:09:04 +0300 Subject: [PATCH 30/37] Fix git submodules update called anyways (#1450) Ignoring FBT_NO_SYNC --- fbt.cmd | 1 - 1 file changed, 1 deletion(-) diff --git a/fbt.cmd b/fbt.cmd index 484b1064..f09b9838 100644 --- a/fbt.cmd +++ b/fbt.cmd @@ -11,7 +11,6 @@ if [%FBT_NO_SYNC%] == [] ( exit /b 1 ) ) -git submodule update --init set "SCONS_DEFAULT_FLAGS=-Q --warn=target-not-built" python lib\scons\scripts\scons.py %SCONS_DEFAULT_FLAGS% %* From 05b816429c6a1801e26d74467be65da81d44428d Mon Sep 17 00:00:00 2001 From: TijnMertens <110020473+TijnMertens@users.noreply.github.com> Date: Tue, 26 Jul 2022 11:13:04 +0200 Subject: [PATCH 31/37] Minor grammar and typo fix (#1454) --- documentation/fbt.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/documentation/fbt.md b/documentation/fbt.md index 575b0265..af10cd9c 100644 --- a/documentation/fbt.md +++ b/documentation/fbt.md @@ -1,7 +1,7 @@ # Flipper Build Tool FBT is the entry point for firmware-related commands and utilities. -It is invoked by `./fbt` in firmware project root directory. Internally, it is a wrapper around [scons](https://scons.org/) build system. +It is invoked by `./fbt` in the firmware project root directory. Internally, it is a wrapper around [scons](https://scons.org/) build system. ## Requirements @@ -66,21 +66,21 @@ FBT keeps track of internal dependencies, so you only need to build the highest- ## Command-line parameters - `--options optionfile.py` (default value `fbt_options.py`) - load file with multiple configuration values -- `--with-updater` - enables updater-related targets and dependency tracking. Enabling this options introduces extra startup time costs, so use it when bundling update packages. Or if you have a fast computer and don't care about a few extra seconds of startup time +- `--with-updater` - enables updater-related targets and dependency tracking. Enabling this option introduces extra startup time costs, so use it when bundling update packages. Or if you have a fast computer and don't care about a few extra seconds of startup time - `--extra-int-apps=app1,app2,appN` - forces listed apps to be built as internal with `firmware` target - `--extra-ext-apps=app1,app2,appN` - forces listed apps to be built as external with `firmware_extapps` target ## Configuration -Default configuration variables are set in configuration file `fbt_options.py`. +Default configuration variables are set in the configuration file `fbt_options.py`. Values set on command-line have higher precedence over configuration file. You can find out available options with `./fbt -h`. ### Firmware application set -You can create customized firmware builds by modifying application list to be included in the build. Application presets are configured with `FIRMWARE_APPS` option, which is a map(configuration_name:str -> application_list:tuple(str)). To specify application set to use in a build, set `FIRMWARE_APP_SET` to its name. -For example, to build firmware image with unit tests, run `./fbt FIRMWARE_APP_SET=unit_tests`. +You can create customized firmware builds by modifying the application list to be included in the build. Application presets are configured with the `FIRMWARE_APPS` option, which is a map(configuration_name:str -> application_list:tuple(str)). To specify application set to use in a build, set `FIRMWARE_APP_SET` to its name. +For example, to build a firmware image with unit tests, run `./fbt FIRMWARE_APP_SET=unit_tests`. Check out `fbt_options.py` for details. From 52a83fc929f125d24136e017661c671d21caac17 Mon Sep 17 00:00:00 2001 From: Georgii Surkov <37121527+gsurkov@users.noreply.github.com> Date: Tue, 26 Jul 2022 14:46:14 +0300 Subject: [PATCH 32/37] [FL-2688] Fix incorrect remote renaming behaviour #1455 --- applications/infrared/infrared.c | 1 + 1 file changed, 1 insertion(+) diff --git a/applications/infrared/infrared.c b/applications/infrared/infrared.c index 1dd0dfa6..cd4c148c 100644 --- a/applications/infrared/infrared.c +++ b/applications/infrared/infrared.c @@ -307,6 +307,7 @@ bool infrared_rename_current_remote(Infrared* infrared, const char* name) { FS_Error status = storage_common_rename( storage, infrared_remote_get_path(remote), string_get_cstr(new_path)); infrared_remote_set_name(remote, string_get_cstr(new_name)); + infrared_remote_set_path(remote, string_get_cstr(new_path)); string_clear(new_name); string_clear(new_path); From 056446dfed68931b9997cd3d7600f655809243c4 Mon Sep 17 00:00:00 2001 From: hedger Date: Tue, 26 Jul 2022 15:21:51 +0300 Subject: [PATCH 33/37] [FL-2675] /int space reservation (#1448) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * storage: added global #defines for /int, /ext & /any * storage: introduced PATH_EXT, PATH_INT& PATH_ANY macros * core apps: moved hardcoded config files names to separate headers; prefixed them with "."; updater: added file name migration to new naming convention on backup extraction * storage: fixed storage_merge_recursive handling of complex directory structures; storage_move_to_sd: changed data migration logic to all non-dot files & all folders * core: added macro aliases for core record names * Bumped protobuf commit pointer * storage: reserved 5 pages in /int; denying write&creation of non-dot files when running out of free space Co-authored-by: あく --- applications/about/about.c | 8 +- applications/archive/archive.c | 4 +- applications/archive/helpers/archive_apps.c | 17 +-- .../archive/helpers/archive_browser.c | 6 +- .../archive/helpers/archive_browser.h | 15 ++- .../archive/helpers/archive_favorites.c | 28 ++-- .../archive/helpers/archive_favorites.h | 4 +- applications/archive/helpers/archive_files.c | 8 +- .../archive/scenes/archive_scene_browser.c | 16 +-- .../archive/scenes/archive_scene_rename.c | 4 +- applications/bad_usb/bad_usb_app.c | 12 +- applications/bad_usb/bad_usb_app_i.h | 2 +- applications/bad_usb/bad_usb_script.c | 2 +- applications/bt/bt_cli.c | 26 ++-- applications/bt/bt_debug_app/bt_debug_app.c | 6 +- applications/bt/bt_hid_app/bt_hid.c | 12 +- applications/bt/bt_service/bt.c | 14 +- applications/bt/bt_service/bt.h | 2 + applications/bt/bt_service/bt_keys_filename.h | 3 + applications/bt/bt_service/bt_keys_storage.c | 3 +- applications/bt/bt_service/bt_keys_storage.h | 1 + applications/bt/bt_settings.c | 3 +- applications/bt/bt_settings.h | 2 + .../bt/bt_settings_app/bt_settings_app.c | 8 +- applications/bt/bt_settings_filename.h | 3 + applications/cli/cli.c | 6 +- applications/cli/cli.h | 2 + applications/cli/cli_commands.c | 12 +- applications/crypto/crypto_cli.c | 4 +- applications/debug_tools/blink_test.c | 8 +- .../debug_tools/display_test/display_test.c | 4 +- .../file_browser_test/file_browser_app.c | 10 +- .../scenes/file_browser_scene_start.c | 8 +- applications/debug_tools/keypad_test.c | 4 +- applications/debug_tools/text_box_test.c | 4 +- applications/debug_tools/uart_echo.c | 8 +- applications/debug_tools/usb_mouse.c | 2 +- applications/debug_tools/usb_test.c | 4 +- applications/debug_tools/vibro_test.c | 8 +- .../desktop/animations/animation_manager.c | 54 ++++---- .../desktop/animations/animation_storage.c | 12 +- applications/desktop/desktop.c | 27 ++-- .../desktop_settings/desktop_settings.h | 6 +- .../desktop_settings/desktop_settings_app.c | 4 +- .../desktop_settings_filename.h | 3 + .../desktop_settings_scene_pin_setup_done.c | 4 +- applications/desktop/helpers/pin_lock.c | 16 +-- applications/desktop/helpers/slideshow.c | 4 +- .../desktop/helpers/slideshow_filename.h | 3 + .../desktop/scenes/desktop_scene_debug.c | 4 +- .../desktop/scenes/desktop_scene_locked.c | 4 +- .../desktop/scenes/desktop_scene_pin_input.c | 4 +- .../desktop/scenes/desktop_scene_slideshow.c | 6 +- .../desktop/views/desktop_view_debug.c | 8 +- .../desktop/views/desktop_view_slideshow.c | 3 +- .../desktop/views/desktop_view_slideshow.h | 3 + applications/dialogs/dialogs.c | 2 +- applications/dialogs/dialogs.h | 2 + .../dialogs/dialogs_module_file_browser.c | 4 +- applications/dialogs/dialogs_module_message.c | 4 +- applications/dolphin/dolphin.c | 2 +- applications/dolphin/dolphin.h | 2 + applications/dolphin/helpers/dolphin_state.c | 5 +- .../dolphin/helpers/dolphin_state_filename.h | 3 + applications/dolphin/passport/passport.c | 8 +- applications/gpio/gpio_app.c | 8 +- applications/gpio/usb_uart_bridge.c | 16 +-- applications/gui/gui.c | 4 +- applications/gui/gui.h | 2 + .../gui/modules/file_browser_worker.c | 18 +-- applications/gui/modules/validators.c | 4 +- applications/ibutton/ibutton.c | 16 +-- applications/ibutton/ibutton_cli.c | 4 +- applications/ibutton/ibutton_i.h | 2 +- applications/infrared/infrared.c | 24 ++-- applications/infrared/infrared_brute_force.c | 10 +- applications/infrared/infrared_cli.c | 4 +- applications/infrared/infrared_i.h | 2 +- applications/infrared/infrared_remote.c | 12 +- .../scenes/infrared_scene_universal_tv.c | 2 +- applications/input/input.c | 4 +- applications/input/input.h | 2 + applications/lfrfid/lfrfid_app.cpp | 2 +- applications/loader/loader.c | 15 ++- applications/loader/loader.h | 2 + applications/music_player/music_player.c | 19 +-- applications/music_player/music_player_cli.c | 8 +- .../music_player/music_player_worker.c | 8 +- applications/nfc/helpers/nfc_debug_pcap.c | 2 +- applications/nfc/helpers/nfc_emv_parser.c | 7 +- .../nfc/helpers/nfc_mf_classic_dict.c | 2 +- applications/nfc/nfc.c | 8 +- applications/nfc/nfc_cli.c | 4 +- applications/nfc/nfc_device.c | 8 +- applications/nfc/nfc_device.h | 2 +- applications/nfc/nfc_worker.c | 4 +- applications/notification/notification.h | 2 + applications/notification/notification_app.c | 12 +- applications/notification/notification_app.h | 3 +- .../notification/notification_settings_app.c | 8 +- .../notification_settings_filename.h | 3 + applications/picopass/picopass.c | 8 +- applications/picopass/picopass_device.c | 10 +- applications/picopass/picopass_device.h | 2 +- applications/picopass/picopass_worker.c | 4 +- .../power/battery_test_app/battery_test_app.c | 12 +- applications/power/power_cli.c | 6 +- applications/power/power_service/power.c | 10 +- applications/power/power_service/power.h | 2 + .../power_settings_app/power_settings_app.c | 8 +- applications/rpc/rpc.c | 4 +- applications/rpc/rpc.h | 2 + applications/rpc/rpc_app.c | 8 +- applications/rpc/rpc_gui.c | 8 +- applications/rpc/rpc_storage.c | 46 +++---- applications/rpc/rpc_system.c | 4 +- applications/snake_game/snake_game.c | 4 +- applications/storage/storage.c | 8 +- applications/storage/storage.h | 15 ++- applications/storage/storage_cli.c | 82 ++++++------ applications/storage/storage_external_api.c | 26 ++-- applications/storage/storage_internal_api.c | 9 +- applications/storage/storage_processing.c | 34 ++--- applications/storage/storage_test_app.c | 26 ++-- applications/storage/storages/storage_ext.c | 22 ++-- applications/storage/storages/storage_int.c | 41 +++++- .../storage_move_to_sd/application.fam | 3 +- .../storage_move_to_sd/storage_move_to_sd.c | 120 ++++++++++-------- .../scenes/storage_settings_scene_benchmark.c | 2 +- .../storage_settings_scene_internal_info.c | 3 +- .../storage_settings/storage_settings.c | 12 +- applications/subghz/subghz.c | 22 ++-- applications/subghz/subghz_cli.c | 31 ++--- applications/subghz/subghz_i.c | 20 +-- applications/subghz/subghz_setting.c | 4 +- .../subghz/views/subghz_test_static.c | 4 +- applications/system/system_settings.c | 4 +- applications/u2f/u2f_app.c | 8 +- applications/u2f/u2f_data.c | 38 +++--- .../flipper_format_string_test.c | 6 +- .../flipper_format/flipper_format_test.c | 50 ++++---- .../unit_tests/infrared/infrared_test.c | 6 +- applications/unit_tests/nfc/nfc_test.c | 6 +- applications/unit_tests/rpc/rpc_test.c | 77 +++++------ .../unit_tests/storage/dirwalk_test.c | 20 +-- .../unit_tests/storage/storage_test.c | 82 ++++++------ applications/unit_tests/stream/stream_test.c | 32 ++--- applications/unit_tests/subghz/subghz_test.c | 91 +++++++------ applications/unit_tests/test_index.c | 12 +- applications/updater/cli/updater_cli.c | 16 +-- applications/updater/updater.c | 14 +- applications/updater/util/update_task.c | 4 +- .../updater/util/update_task_worker_backup.c | 13 +- firmware/targets/f7/Src/update.c | 7 +- lib/flipper_format/flipper_format.h | 4 +- lib/infrared/worker/infrared_worker.c | 4 +- lib/subghz/protocols/raw.c | 4 +- lib/subghz/subghz_file_encoder_worker.c | 4 +- lib/subghz/subghz_keystore.c | 16 +-- lib/subghz/types.h | 4 +- lib/toolbox/dir_walk.c | 2 +- lib/toolbox/path.c | 2 +- lib/toolbox/saved_struct.c | 8 +- lib/toolbox/stream/file_stream.c | 5 +- lib/toolbox/tar/tar_archive.c | 44 +++++-- lib/toolbox/tar/tar_archive.h | 7 +- lib/update_util/lfs_backup.c | 33 ++++- lib/update_util/update_manifest.c | 4 +- lib/update_util/update_manifest.h | 3 +- lib/update_util/update_operation.c | 24 ++-- site_scons/site_tools/fbt_apps.py | 2 +- 171 files changed, 1111 insertions(+), 910 deletions(-) create mode 100644 applications/bt/bt_service/bt_keys_filename.h create mode 100644 applications/bt/bt_settings_filename.h create mode 100644 applications/desktop/desktop_settings/desktop_settings_filename.h create mode 100644 applications/desktop/helpers/slideshow_filename.h create mode 100644 applications/dolphin/helpers/dolphin_state_filename.h create mode 100644 applications/notification/notification_settings_filename.h diff --git a/applications/about/about.c b/applications/about/about.c index 4d12ed02..26738fe0 100644 --- a/applications/about/about.c +++ b/applications/about/about.c @@ -156,10 +156,10 @@ const size_t about_screens_count = sizeof(about_screens) / sizeof(AboutDialogScr int32_t about_settings_app(void* p) { UNUSED(p); - DialogsApp* dialogs = furi_record_open("dialogs"); + DialogsApp* dialogs = furi_record_open(RECORD_DIALOGS); DialogMessage* message = dialog_message_alloc(); - Gui* gui = furi_record_open("gui"); + Gui* gui = furi_record_open(RECORD_GUI); ViewDispatcher* view_dispatcher = view_dispatcher_alloc(); EmptyScreen* empty_screen = empty_screen_alloc(); const uint32_t empty_screen_index = 0; @@ -198,12 +198,12 @@ int32_t about_settings_app(void* p) { } dialog_message_free(message); - furi_record_close("dialogs"); + furi_record_close(RECORD_DIALOGS); view_dispatcher_remove_view(view_dispatcher, empty_screen_index); view_dispatcher_free(view_dispatcher); empty_screen_free(empty_screen); - furi_record_close("gui"); + furi_record_close(RECORD_GUI); return 0; } \ No newline at end of file diff --git a/applications/archive/archive.c b/applications/archive/archive.c index 99b9bb02..bbe532c8 100644 --- a/applications/archive/archive.c +++ b/applications/archive/archive.c @@ -16,7 +16,7 @@ bool archive_back_event_callback(void* context) { ArchiveApp* archive_alloc() { ArchiveApp* archive = malloc(sizeof(ArchiveApp)); - archive->gui = furi_record_open("gui"); + archive->gui = furi_record_open(RECORD_GUI); archive->text_input = text_input_alloc(); string_init(archive->fav_move_str); @@ -62,7 +62,7 @@ void archive_free(ArchiveApp* archive) { text_input_free(archive->text_input); - furi_record_close("gui"); + furi_record_close(RECORD_GUI); archive->gui = NULL; free(archive); diff --git a/applications/archive/helpers/archive_apps.c b/applications/archive/helpers/archive_apps.c index 3393993d..9a3f825f 100644 --- a/applications/archive/helpers/archive_apps.c +++ b/applications/archive/helpers/archive_apps.c @@ -29,21 +29,22 @@ bool archive_app_is_available(void* context, const char* path) { if(app == ArchiveAppTypeU2f) { bool file_exists = false; - Storage* fs_api = furi_record_open("storage"); + Storage* fs_api = furi_record_open(RECORD_STORAGE); File* file = storage_file_alloc(fs_api); - file_exists = storage_file_open(file, "/any/u2f/key.u2f", FSAM_READ, FSOM_OPEN_EXISTING); + file_exists = + storage_file_open(file, ANY_PATH("u2f/key.u2f"), FSAM_READ, FSOM_OPEN_EXISTING); if(file_exists) { storage_file_close(file); file_exists = - storage_file_open(file, "/any/u2f/cnt.u2f", FSAM_READ, FSOM_OPEN_EXISTING); + storage_file_open(file, ANY_PATH("u2f/cnt.u2f"), FSAM_READ, FSOM_OPEN_EXISTING); if(file_exists) { storage_file_close(file); } } storage_file_free(file); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); return file_exists; } else { @@ -77,10 +78,10 @@ void archive_app_delete_file(void* context, const char* path) { bool res = false; if(app == ArchiveAppTypeU2f) { - Storage* fs_api = furi_record_open("storage"); - res = (storage_common_remove(fs_api, "/any/u2f/key.u2f") == FSE_OK); - res |= (storage_common_remove(fs_api, "/any/u2f/cnt.u2f") == FSE_OK); - furi_record_close("storage"); + Storage* fs_api = furi_record_open(RECORD_STORAGE); + res = (storage_common_remove(fs_api, ANY_PATH("u2f/key.u2f")) == FSE_OK); + res |= (storage_common_remove(fs_api, ANY_PATH("u2f/cnt.u2f")) == FSE_OK); + furi_record_close(RECORD_STORAGE); if(archive_is_favorite("/app:u2f/U2F Token")) { archive_favorites_delete("/app:u2f/U2F Token"); diff --git a/applications/archive/helpers/archive_browser.c b/applications/archive/helpers/archive_browser.c index 28284136..54759dad 100644 --- a/applications/archive/helpers/archive_browser.c +++ b/applications/archive/helpers/archive_browser.c @@ -391,18 +391,18 @@ void archive_favorites_move_mode(ArchiveBrowserView* browser, bool active) { } static bool archive_is_dir_exists(string_t path) { - if(string_equal_str_p(path, "/any")) { + if(string_equal_str_p(path, STORAGE_ANY_PATH_PREFIX)) { return true; } bool state = false; FileInfo file_info; - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); if(storage_common_stat(storage, string_get_cstr(path), &file_info) == FSE_OK) { if(file_info.flags & FSF_DIRECTORY) { state = true; } } - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); return state; } diff --git a/applications/archive/helpers/archive_browser.h b/applications/archive/helpers/archive_browser.h index c4283123..d6c79817 100644 --- a/applications/archive/helpers/archive_browser.h +++ b/applications/archive/helpers/archive_browser.h @@ -1,6 +1,7 @@ #pragma once #include "../archive_i.h" +#include #define TAB_RIGHT InputKeyRight // Default tab swith direction #define TAB_DEFAULT ArchiveTabFavorites // Start tab @@ -8,14 +9,14 @@ static const char* tab_default_paths[] = { [ArchiveTabFavorites] = "/app:favorites", - [ArchiveTabIButton] = "/any/ibutton", - [ArchiveTabNFC] = "/any/nfc", - [ArchiveTabSubGhz] = "/any/subghz", - [ArchiveTabLFRFID] = "/any/lfrfid", - [ArchiveTabInfrared] = "/any/infrared", - [ArchiveTabBadUsb] = "/any/badusb", + [ArchiveTabIButton] = ANY_PATH("ibutton"), + [ArchiveTabNFC] = ANY_PATH("nfc"), + [ArchiveTabSubGhz] = ANY_PATH("subghz"), + [ArchiveTabLFRFID] = ANY_PATH("lfrfid"), + [ArchiveTabInfrared] = ANY_PATH("infrared"), + [ArchiveTabBadUsb] = ANY_PATH("badusb"), [ArchiveTabU2f] = "/app:u2f", - [ArchiveTabBrowser] = "/any", + [ArchiveTabBrowser] = STORAGE_ANY_PATH_PREFIX, }; static const char* known_ext[] = { diff --git a/applications/archive/helpers/archive_favorites.c b/applications/archive/helpers/archive_favorites.c index af7927e9..fc0cad57 100644 --- a/applications/archive/helpers/archive_favorites.c +++ b/applications/archive/helpers/archive_favorites.c @@ -49,7 +49,7 @@ static bool archive_favorites_read_line(File* file, string_t str_result) { uint16_t archive_favorites_count(void* context) { furi_assert(context); - Storage* fs_api = furi_record_open("storage"); + Storage* fs_api = furi_record_open(RECORD_STORAGE); File* file = storage_file_alloc(fs_api); string_t buffer; @@ -74,7 +74,7 @@ uint16_t archive_favorites_count(void* context) { string_clear(buffer); storage_file_free(file); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); return lines; } @@ -82,7 +82,7 @@ uint16_t archive_favorites_count(void* context) { static bool archive_favourites_rescan() { string_t buffer; string_init(buffer); - Storage* fs_api = furi_record_open("storage"); + Storage* fs_api = furi_record_open(RECORD_STORAGE); File* file = storage_file_alloc(fs_api); File* fav_item_file = storage_file_alloc(fs_api); @@ -122,7 +122,7 @@ static bool archive_favourites_rescan() { storage_file_free(file); storage_file_free(fav_item_file); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); return result; } @@ -131,7 +131,7 @@ bool archive_favorites_read(void* context) { furi_assert(context); ArchiveBrowserView* browser = context; - Storage* fs_api = furi_record_open("storage"); + Storage* fs_api = furi_record_open(RECORD_STORAGE); File* file = storage_file_alloc(fs_api); File* fav_item_file = storage_file_alloc(fs_api); @@ -184,7 +184,7 @@ bool archive_favorites_read(void* context) { string_clear(buffer); storage_file_free(file); storage_file_free(fav_item_file); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); archive_set_item_count(browser, file_count); @@ -204,7 +204,7 @@ bool archive_favorites_delete(const char* format, ...) { va_end(args); string_init(buffer); - Storage* fs_api = furi_record_open("storage"); + Storage* fs_api = furi_record_open(RECORD_STORAGE); File* file = storage_file_alloc(fs_api); bool result = storage_file_open(file, ARCHIVE_FAV_PATH, FSAM_READ, FSOM_OPEN_EXISTING); @@ -233,7 +233,7 @@ bool archive_favorites_delete(const char* format, ...) { storage_common_remove(fs_api, ARCHIVE_FAV_TEMP_PATH); storage_file_free(file); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); return result; } @@ -247,7 +247,7 @@ bool archive_is_favorite(const char* format, ...) { va_end(args); string_init(buffer); - Storage* fs_api = furi_record_open("storage"); + Storage* fs_api = furi_record_open(RECORD_STORAGE); File* file = storage_file_alloc(fs_api); bool found = false; @@ -272,7 +272,7 @@ bool archive_is_favorite(const char* format, ...) { string_clear(buffer); string_clear(filename); storage_file_free(file); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); return found; } @@ -281,7 +281,7 @@ bool archive_favorites_rename(const char* src, const char* dst) { furi_assert(src); furi_assert(dst); - Storage* fs_api = furi_record_open("storage"); + Storage* fs_api = furi_record_open(RECORD_STORAGE); File* file = storage_file_alloc(fs_api); string_t path; @@ -318,7 +318,7 @@ bool archive_favorites_rename(const char* src, const char* dst) { storage_common_remove(fs_api, ARCHIVE_FAV_TEMP_PATH); storage_file_free(file); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); return result; } @@ -333,7 +333,7 @@ void archive_favorites_save(void* context) { furi_assert(context); ArchiveBrowserView* browser = context; - Storage* fs_api = furi_record_open("storage"); + Storage* fs_api = furi_record_open(RECORD_STORAGE); File* file = storage_file_alloc(fs_api); for(size_t i = 0; i < archive_file_get_array_size(browser); i++) { @@ -346,5 +346,5 @@ void archive_favorites_save(void* context) { storage_common_remove(fs_api, ARCHIVE_FAV_TEMP_PATH); storage_file_free(file); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); } diff --git a/applications/archive/helpers/archive_favorites.h b/applications/archive/helpers/archive_favorites.h index 681d0ec6..29eedcdb 100644 --- a/applications/archive/helpers/archive_favorites.h +++ b/applications/archive/helpers/archive_favorites.h @@ -2,8 +2,8 @@ #include -#define ARCHIVE_FAV_PATH "/any/favorites.txt" -#define ARCHIVE_FAV_TEMP_PATH "/any/favorites.tmp" +#define ARCHIVE_FAV_PATH ANY_PATH("favorites.txt") +#define ARCHIVE_FAV_TEMP_PATH ANY_PATH("favorites.tmp") uint16_t archive_favorites_count(void* context); bool archive_favorites_read(void* context); diff --git a/applications/archive/helpers/archive_files.c b/applications/archive/helpers/archive_files.c index 7ff54fed..9f8b4ee1 100644 --- a/applications/archive/helpers/archive_files.c +++ b/applications/archive/helpers/archive_files.c @@ -60,7 +60,7 @@ void archive_file_append(const char* path, const char* format, ...) { string_init_vprintf(string, format, args); va_end(args); - Storage* fs_api = furi_record_open("storage"); + Storage* fs_api = furi_record_open(RECORD_STORAGE); File* file = storage_file_alloc(fs_api); bool res = storage_file_open(file, path, FSAM_WRITE, FSOM_OPEN_APPEND); @@ -71,7 +71,7 @@ void archive_file_append(const char* path, const char* format, ...) { storage_file_close(file); storage_file_free(file); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); } void archive_delete_file(void* context, const char* format, ...) { @@ -84,7 +84,7 @@ void archive_delete_file(void* context, const char* format, ...) { va_end(args); ArchiveBrowserView* browser = context; - Storage* fs_api = furi_record_open("storage"); + Storage* fs_api = furi_record_open(RECORD_STORAGE); FileInfo fileinfo; storage_common_stat(fs_api, string_get_cstr(filename), &fileinfo); @@ -97,7 +97,7 @@ void archive_delete_file(void* context, const char* format, ...) { res = (storage_common_remove(fs_api, string_get_cstr(filename)) == FSE_OK); } - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); if(archive_is_favorite("%s", string_get_cstr(filename))) { archive_favorites_delete("%s", string_get_cstr(filename)); diff --git a/applications/archive/scenes/archive_scene_browser.c b/applications/archive/scenes/archive_scene_browser.c index e3581538..74861bea 100644 --- a/applications/archive/scenes/archive_scene_browser.c +++ b/applications/archive/scenes/archive_scene_browser.c @@ -36,7 +36,7 @@ static void archive_loader_callback(const void* message, void* context) { static void archive_run_in_app(ArchiveBrowserView* browser, ArchiveFile_t* selected) { UNUSED(browser); - Loader* loader = furi_record_open("loader"); + Loader* loader = furi_record_open(RECORD_LOADER); LoaderStatus status; if(selected->is_app) { @@ -54,7 +54,7 @@ static void archive_run_in_app(ArchiveBrowserView* browser, ArchiveFile_t* selec FURI_LOG_E(TAG, "loader_start failed: %d", status); } - furi_record_close("loader"); + furi_record_close(RECORD_LOADER); } void archive_scene_browser_callback(ArchiveBrowserEvent event, void* context) { @@ -71,10 +71,10 @@ void archive_scene_browser_on_enter(void* context) { archive_update_focus(browser, archive->text_store); view_dispatcher_switch_to_view(archive->view_dispatcher, ArchiveViewBrowser); - Loader* loader = furi_record_open("loader"); + Loader* loader = furi_record_open(RECORD_LOADER); archive->loader_stop_subscription = furi_pubsub_subscribe(loader_get_pubsub(loader), archive_loader_callback, archive); - furi_record_close("loader"); + furi_record_close(RECORD_LOADER); uint32_t state = scene_manager_get_scene_state(archive->scene_manager, ArchiveAppSceneBrowser); @@ -196,10 +196,10 @@ bool archive_scene_browser_on_event(void* context, SceneManagerEvent event) { if(!archive_is_home(browser)) { archive_leave_dir(browser); } else { - Loader* loader = furi_record_open("loader"); + Loader* loader = furi_record_open(RECORD_LOADER); furi_pubsub_unsubscribe( loader_get_pubsub(loader), archive->loader_stop_subscription); - furi_record_close("loader"); + furi_record_close(RECORD_LOADER); view_dispatcher_stop(archive->view_dispatcher); } @@ -216,7 +216,7 @@ bool archive_scene_browser_on_event(void* context, SceneManagerEvent event) { void archive_scene_browser_on_exit(void* context) { ArchiveApp* archive = (ArchiveApp*)context; - Loader* loader = furi_record_open("loader"); + Loader* loader = furi_record_open(RECORD_LOADER); furi_pubsub_unsubscribe(loader_get_pubsub(loader), archive->loader_stop_subscription); - furi_record_close("loader"); + furi_record_close(RECORD_LOADER); } diff --git a/applications/archive/scenes/archive_scene_rename.c b/applications/archive/scenes/archive_scene_rename.c index d292dd60..2a85f3ce 100644 --- a/applications/archive/scenes/archive_scene_rename.c +++ b/applications/archive/scenes/archive_scene_rename.c @@ -51,7 +51,7 @@ bool archive_scene_rename_on_event(void* context, SceneManagerEvent event) { if(event.type == SceneManagerEventTypeCustom) { if(event.event == SCENE_RENAME_CUSTOM_EVENT) { - Storage* fs_api = furi_record_open("storage"); + Storage* fs_api = furi_record_open(RECORD_STORAGE); const char* path_src = archive_get_name(archive->browser); ArchiveFile_t* file = archive_get_current_file(archive->browser); @@ -62,7 +62,7 @@ bool archive_scene_rename_on_event(void* context, SceneManagerEvent event) { string_cat_printf(path_dst, "/%s%s", archive->text_store, known_ext[file->type]); storage_common_rename(fs_api, path_src, string_get_cstr(path_dst)); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); if(file->fav) { archive_favorites_rename(path_src, string_get_cstr(path_dst)); diff --git a/applications/bad_usb/bad_usb_app.c b/applications/bad_usb/bad_usb_app.c index 65ccc575..7eb86181 100644 --- a/applications/bad_usb/bad_usb_app.c +++ b/applications/bad_usb/bad_usb_app.c @@ -32,9 +32,9 @@ BadUsbApp* bad_usb_app_alloc(char* arg) { string_set_str(app->file_path, arg); } - app->gui = furi_record_open("gui"); - app->notifications = furi_record_open("notification"); - app->dialogs = furi_record_open("dialogs"); + app->gui = furi_record_open(RECORD_GUI); + app->notifications = furi_record_open(RECORD_NOTIFICATION); + app->dialogs = furi_record_open(RECORD_DIALOGS); app->view_dispatcher = view_dispatcher_alloc(); view_dispatcher_enable_queue(app->view_dispatcher); @@ -92,9 +92,9 @@ void bad_usb_app_free(BadUsbApp* app) { scene_manager_free(app->scene_manager); // Close records - furi_record_close("gui"); - furi_record_close("notification"); - furi_record_close("dialogs"); + furi_record_close(RECORD_GUI); + furi_record_close(RECORD_NOTIFICATION); + furi_record_close(RECORD_DIALOGS); string_clear(app->file_path); diff --git a/applications/bad_usb/bad_usb_app_i.h b/applications/bad_usb/bad_usb_app_i.h index c82419e0..6b323d35 100644 --- a/applications/bad_usb/bad_usb_app_i.h +++ b/applications/bad_usb/bad_usb_app_i.h @@ -14,7 +14,7 @@ #include #include "views/bad_usb_view.h" -#define BAD_USB_APP_PATH_FOLDER "/any/badusb" +#define BAD_USB_APP_PATH_FOLDER ANY_PATH("badusb") #define BAD_USB_APP_EXTENSION ".txt" typedef enum { diff --git a/applications/bad_usb/bad_usb_script.c b/applications/bad_usb/bad_usb_script.c index a06f6d59..9d9d3e39 100644 --- a/applications/bad_usb/bad_usb_script.c +++ b/applications/bad_usb/bad_usb_script.c @@ -455,7 +455,7 @@ static int32_t bad_usb_worker(void* context) { FuriHalUsbInterface* usb_mode_prev = furi_hal_usb_get_config(); FURI_LOG_I(WORKER_TAG, "Init"); - File* script_file = storage_file_alloc(furi_record_open("storage")); + File* script_file = storage_file_alloc(furi_record_open(RECORD_STORAGE)); string_init(bad_usb->line); string_init(bad_usb->line_prev); diff --git a/applications/bt/bt_cli.c b/applications/bt/bt_cli.c index d12724d2..3aa1bc75 100644 --- a/applications/bt/bt_cli.c +++ b/applications/bt/bt_cli.c @@ -33,7 +33,7 @@ static void bt_cli_command_carrier_tx(Cli* cli, string_t args, void* context) { break; } - Bt* bt = furi_record_open("bt"); + Bt* bt = furi_record_open(RECORD_BT); bt_disconnect(bt); furi_hal_bt_reinit(); printf("Transmitting carrier at %d channel at %d dB power\r\n", channel, power); @@ -46,7 +46,7 @@ static void bt_cli_command_carrier_tx(Cli* cli, string_t args, void* context) { furi_hal_bt_stop_tone_tx(); bt_set_profile(bt, BtProfileSerial); - furi_record_close("bt"); + furi_record_close(RECORD_BT); } while(false); } @@ -60,7 +60,7 @@ static void bt_cli_command_carrier_rx(Cli* cli, string_t args, void* context) { break; } - Bt* bt = furi_record_open("bt"); + Bt* bt = furi_record_open(RECORD_BT); bt_disconnect(bt); furi_hal_bt_reinit(); printf("Receiving carrier at %d channel\r\n", channel); @@ -77,7 +77,7 @@ static void bt_cli_command_carrier_rx(Cli* cli, string_t args, void* context) { furi_hal_bt_stop_packet_test(); bt_set_profile(bt, BtProfileSerial); - furi_record_close("bt"); + furi_record_close(RECORD_BT); } while(false); } @@ -107,7 +107,7 @@ static void bt_cli_command_packet_tx(Cli* cli, string_t args, void* context) { break; } - Bt* bt = furi_record_open("bt"); + Bt* bt = furi_record_open(RECORD_BT); bt_disconnect(bt); furi_hal_bt_reinit(); printf( @@ -125,7 +125,7 @@ static void bt_cli_command_packet_tx(Cli* cli, string_t args, void* context) { printf("Transmitted %lu packets", furi_hal_bt_get_transmitted_packets()); bt_set_profile(bt, BtProfileSerial); - furi_record_close("bt"); + furi_record_close(RECORD_BT); } while(false); } @@ -144,7 +144,7 @@ static void bt_cli_command_packet_rx(Cli* cli, string_t args, void* context) { break; } - Bt* bt = furi_record_open("bt"); + Bt* bt = furi_record_open(RECORD_BT); bt_disconnect(bt); furi_hal_bt_reinit(); printf("Receiving packets at %d channel at %d M datarate\r\n", channel, datarate); @@ -160,7 +160,7 @@ static void bt_cli_command_packet_rx(Cli* cli, string_t args, void* context) { printf("Received %hu packets", packets_received); bt_set_profile(bt, BtProfileSerial); - furi_record_close("bt"); + furi_record_close(RECORD_BT); } while(false); } @@ -180,7 +180,7 @@ static void bt_cli_print_usage() { static void bt_cli(Cli* cli, string_t args, void* context) { UNUSED(context); - furi_record_open("bt"); + furi_record_open(RECORD_BT); string_t cmd; string_init(cmd); @@ -223,14 +223,14 @@ static void bt_cli(Cli* cli, string_t args, void* context) { } string_clear(cmd); - furi_record_close("bt"); + furi_record_close(RECORD_BT); } void bt_on_system_start() { #ifdef SRV_CLI - Cli* cli = furi_record_open("cli"); - cli_add_command(cli, "bt", CliCommandFlagDefault, bt_cli, NULL); - furi_record_close("cli"); + Cli* cli = furi_record_open(RECORD_CLI); + cli_add_command(cli, RECORD_BT, CliCommandFlagDefault, bt_cli, NULL); + furi_record_close(RECORD_CLI); #else UNUSED(bt_cli); #endif diff --git a/applications/bt/bt_debug_app/bt_debug_app.c b/applications/bt/bt_debug_app/bt_debug_app.c index 468f8a54..ac442de0 100644 --- a/applications/bt/bt_debug_app/bt_debug_app.c +++ b/applications/bt/bt_debug_app/bt_debug_app.c @@ -35,7 +35,7 @@ BtDebugApp* bt_debug_app_alloc() { bt_settings_load(&app->settings); // Gui - app->gui = furi_record_open("gui"); + app->gui = furi_record_open(RECORD_GUI); // View dispatcher app->view_dispatcher = view_dispatcher_alloc(); @@ -88,7 +88,7 @@ void bt_debug_app_free(BtDebugApp* app) { view_dispatcher_free(app->view_dispatcher); // Close gui record - furi_record_close("gui"); + furi_record_close(RECORD_GUI); app->gui = NULL; // Free rest @@ -99,7 +99,7 @@ int32_t bt_debug_app(void* p) { UNUSED(p); if(!furi_hal_bt_is_testing_supported()) { FURI_LOG_E(TAG, "Incorrect radio stack: radio testing fetures are absent."); - DialogsApp* dialogs = furi_record_open("dialogs"); + DialogsApp* dialogs = furi_record_open(RECORD_DIALOGS); dialog_message_show_storage_error(dialogs, "Incorrect\nRadioStack"); return 255; } diff --git a/applications/bt/bt_hid_app/bt_hid.c b/applications/bt/bt_hid_app/bt_hid.c index 47ee2268..29a25c86 100755 --- a/applications/bt/bt_hid_app/bt_hid.c +++ b/applications/bt/bt_hid_app/bt_hid.c @@ -70,13 +70,13 @@ BtHid* bt_hid_app_alloc() { BtHid* app = malloc(sizeof(BtHid)); // Gui - app->gui = furi_record_open("gui"); + app->gui = furi_record_open(RECORD_GUI); // Bt - app->bt = furi_record_open("bt"); + app->bt = furi_record_open(RECORD_BT); // Notifications - app->notifications = furi_record_open("notification"); + app->notifications = furi_record_open(RECORD_NOTIFICATION); // View dispatcher app->view_dispatcher = view_dispatcher_alloc(); @@ -161,11 +161,11 @@ void bt_hid_app_free(BtHid* app) { view_dispatcher_free(app->view_dispatcher); // Close records - furi_record_close("gui"); + furi_record_close(RECORD_GUI); app->gui = NULL; - furi_record_close("notification"); + furi_record_close(RECORD_NOTIFICATION); app->notifications = NULL; - furi_record_close("bt"); + furi_record_close(RECORD_BT); app->bt = NULL; // Free rest diff --git a/applications/bt/bt_service/bt.c b/applications/bt/bt_service/bt.c index d122aa17..6f0810dd 100644 --- a/applications/bt/bt_service/bt.c +++ b/applications/bt/bt_service/bt.c @@ -124,23 +124,23 @@ Bt* bt_alloc() { // Pin code view port bt->pin_code_view_port = bt_pin_code_view_port_alloc(bt); // Notification - bt->notification = furi_record_open("notification"); + bt->notification = furi_record_open(RECORD_NOTIFICATION); // Gui - bt->gui = furi_record_open("gui"); + bt->gui = furi_record_open(RECORD_GUI); gui_add_view_port(bt->gui, bt->statusbar_view_port, GuiLayerStatusBarLeft); gui_add_view_port(bt->gui, bt->pin_code_view_port, GuiLayerFullscreen); // Dialogs - bt->dialogs = furi_record_open("dialogs"); + bt->dialogs = furi_record_open(RECORD_DIALOGS); bt->dialog_message = dialog_message_alloc(); // Power - bt->power = furi_record_open("power"); + bt->power = furi_record_open(RECORD_POWER); FuriPubSub* power_pubsub = power_get_pubsub(bt->power); furi_pubsub_subscribe(power_pubsub, bt_battery_level_changed_callback, bt); // RPC - bt->rpc = furi_record_open("rpc"); + bt->rpc = furi_record_open(RECORD_RPC); bt->rpc_event = furi_event_flag_alloc(); // API evnent @@ -353,7 +353,7 @@ int32_t bt_srv() { if(furi_hal_rtc_get_boot_mode() != FuriHalRtcBootModeNormal) { FURI_LOG_W(TAG, "Skipped BT init: device in special startup mode"); ble_glue_wait_for_c2_start(FURI_HAL_BT_C2_START_TIMEOUT); - furi_record_create("bt", bt); + furi_record_create(RECORD_BT, bt); return 0; } @@ -381,7 +381,7 @@ int32_t bt_srv() { bt->status = BtStatusUnavailable; } - furi_record_create("bt", bt); + furi_record_create(RECORD_BT, bt); BtMessage message; while(1) { diff --git a/applications/bt/bt_service/bt.h b/applications/bt/bt_service/bt.h index 4ca6a32f..6e4e1b82 100644 --- a/applications/bt/bt_service/bt.h +++ b/applications/bt/bt_service/bt.h @@ -7,6 +7,8 @@ extern "C" { #endif +#define RECORD_BT "bt" + typedef struct Bt Bt; typedef enum { diff --git a/applications/bt/bt_service/bt_keys_filename.h b/applications/bt/bt_service/bt_keys_filename.h new file mode 100644 index 00000000..da1d3f54 --- /dev/null +++ b/applications/bt/bt_service/bt_keys_filename.h @@ -0,0 +1,3 @@ +#pragma once + +#define BT_KEYS_STORAGE_FILE_NAME ".bt.keys" diff --git a/applications/bt/bt_service/bt_keys_storage.c b/applications/bt/bt_service/bt_keys_storage.c index e4f426c8..91d97d67 100644 --- a/applications/bt/bt_service/bt_keys_storage.c +++ b/applications/bt/bt_service/bt_keys_storage.c @@ -2,8 +2,9 @@ #include #include +#include -#define BT_KEYS_STORAGE_PATH "/int/bt.keys" +#define BT_KEYS_STORAGE_PATH INT_PATH(BT_KEYS_STORAGE_FILE_NAME) #define BT_KEYS_STORAGE_VERSION (0) #define BT_KEYS_STORAGE_MAGIC (0x18) diff --git a/applications/bt/bt_service/bt_keys_storage.h b/applications/bt/bt_service/bt_keys_storage.h index 68d4476a..b82b1035 100644 --- a/applications/bt/bt_service/bt_keys_storage.h +++ b/applications/bt/bt_service/bt_keys_storage.h @@ -1,6 +1,7 @@ #pragma once #include "bt_i.h" +#include "bt_keys_filename.h" bool bt_keys_storage_load(Bt* bt); diff --git a/applications/bt/bt_settings.c b/applications/bt/bt_settings.c index dbb2fd05..1eaf6c7d 100644 --- a/applications/bt/bt_settings.c +++ b/applications/bt/bt_settings.c @@ -2,8 +2,9 @@ #include #include +#include -#define BT_SETTINGS_PATH "/int/bt.settings" +#define BT_SETTINGS_PATH INT_PATH(BT_SETTINGS_FILE_NAME) #define BT_SETTINGS_VERSION (0) #define BT_SETTINGS_MAGIC (0x19) diff --git a/applications/bt/bt_settings.h b/applications/bt/bt_settings.h index 1a98668a..260d9c0e 100644 --- a/applications/bt/bt_settings.h +++ b/applications/bt/bt_settings.h @@ -1,5 +1,7 @@ #pragma once +#include "bt_settings_filename.h" + #include #include diff --git a/applications/bt/bt_settings_app/bt_settings_app.c b/applications/bt/bt_settings_app/bt_settings_app.c index cb55e931..f211c712 100755 --- a/applications/bt/bt_settings_app/bt_settings_app.c +++ b/applications/bt/bt_settings_app/bt_settings_app.c @@ -17,8 +17,8 @@ BtSettingsApp* bt_settings_app_alloc() { // Load settings bt_settings_load(&app->settings); - app->gui = furi_record_open("gui"); - app->bt = furi_record_open("bt"); + app->gui = furi_record_open(RECORD_GUI); + app->bt = furi_record_open(RECORD_BT); // View Dispatcher and Scene Manager app->view_dispatcher = view_dispatcher_alloc(); @@ -70,8 +70,8 @@ void bt_settings_app_free(BtSettingsApp* app) { scene_manager_free(app->scene_manager); // Records - furi_record_close("gui"); - furi_record_close("bt"); + furi_record_close(RECORD_GUI); + furi_record_close(RECORD_BT); free(app); } diff --git a/applications/bt/bt_settings_filename.h b/applications/bt/bt_settings_filename.h new file mode 100644 index 00000000..e5fb7ec4 --- /dev/null +++ b/applications/bt/bt_settings_filename.h @@ -0,0 +1,3 @@ +#pragma once + +#define BT_SETTINGS_FILE_NAME ".bt.settings" diff --git a/applications/cli/cli.c b/applications/cli/cli.c index 7d0f8dab..4d9b8a5f 100644 --- a/applications/cli/cli.c +++ b/applications/cli/cli.c @@ -185,7 +185,7 @@ static void cli_execute_command(Cli* cli, CliCommand* command, string_t args) { // Ensure that we running alone if(!(command->flags & CliCommandFlagParallelSafe)) { - Loader* loader = furi_record_open("loader"); + Loader* loader = furi_record_open(RECORD_LOADER); bool safety_lock = loader_lock(loader); if(safety_lock) { // Execute command @@ -194,7 +194,7 @@ static void cli_execute_command(Cli* cli, CliCommand* command, string_t args) { } else { printf("Other application is running, close it first"); } - furi_record_close("loader"); + furi_record_close(RECORD_LOADER); } else { // Execute command command->callback(cli, args, command->context); @@ -466,7 +466,7 @@ int32_t cli_srv(void* p) { // Init basic cli commands cli_commands_init(cli); - furi_record_create("cli", cli); + furi_record_create(RECORD_CLI, cli); if(cli->session != NULL) { furi_stdglue_set_thread_stdout_callback(cli->session->tx_stdout); diff --git a/applications/cli/cli.h b/applications/cli/cli.h index 29f27392..549e72cc 100644 --- a/applications/cli/cli.h +++ b/applications/cli/cli.h @@ -33,6 +33,8 @@ typedef enum { CliCommandFlagInsomniaSafe = (1 << 1), /**< Safe to run with insomnia mode on */ } CliCommandFlag; +#define RECORD_CLI "cli" + /** Cli type anonymous structure */ typedef struct Cli Cli; diff --git a/applications/cli/cli_commands.c b/applications/cli/cli_commands.c index c99f4edc..19887796 100644 --- a/applications/cli/cli_commands.c +++ b/applications/cli/cli_commands.c @@ -166,13 +166,13 @@ void cli_command_vibro(Cli* cli, string_t args, void* context) { UNUSED(cli); UNUSED(context); if(!string_cmp(args, "0")) { - NotificationApp* notification = furi_record_open("notification"); + NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION); notification_message_block(notification, &sequence_reset_vibro); - furi_record_close("notification"); + furi_record_close(RECORD_NOTIFICATION); } else if(!string_cmp(args, "1")) { - NotificationApp* notification = furi_record_open("notification"); + NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION); notification_message_block(notification, &sequence_set_vibro_on); - furi_record_close("notification"); + furi_record_close(RECORD_NOTIFICATION); } else { cli_print_usage("vibro", "<1|0>", string_get_cstr(args)); } @@ -244,9 +244,9 @@ void cli_command_led(Cli* cli, string_t args, void* context) { }; // Send notification - NotificationApp* notification = furi_record_open("notification"); + NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION); notification_internal_message_block(notification, ¬ification_sequence); - furi_record_close("notification"); + furi_record_close(RECORD_NOTIFICATION); } void cli_command_ps(Cli* cli, string_t args, void* context) { diff --git a/applications/crypto/crypto_cli.c b/applications/crypto/crypto_cli.c index a5ea80f8..26e1fb9c 100644 --- a/applications/crypto/crypto_cli.c +++ b/applications/crypto/crypto_cli.c @@ -317,9 +317,9 @@ static void crypto_cli(Cli* cli, string_t args, void* context) { void crypto_on_system_start() { #ifdef SRV_CLI - Cli* cli = furi_record_open("cli"); + Cli* cli = furi_record_open(RECORD_CLI); cli_add_command(cli, "crypto", CliCommandFlagDefault, crypto_cli, NULL); - furi_record_close("cli"); + furi_record_close(RECORD_CLI); #else UNUSED(crypto_cli); #endif diff --git a/applications/debug_tools/blink_test.c b/applications/debug_tools/blink_test.c index 3870c11e..7dd2c9e9 100644 --- a/applications/debug_tools/blink_test.c +++ b/applications/debug_tools/blink_test.c @@ -88,10 +88,10 @@ int32_t blink_test_app(void* p) { furi_timer_start(timer, furi_kernel_get_tick_frequency()); // Register view port in GUI - Gui* gui = furi_record_open("gui"); + Gui* gui = furi_record_open(RECORD_GUI); gui_add_view_port(gui, view_port, GuiLayerFullscreen); - NotificationApp* notifications = furi_record_open("notification"); + NotificationApp* notifications = furi_record_open(RECORD_NOTIFICATION); uint8_t state = 0; BlinkEvent event; @@ -119,8 +119,8 @@ int32_t blink_test_app(void* p) { view_port_free(view_port); furi_message_queue_free(event_queue); - furi_record_close("notification"); - furi_record_close("gui"); + furi_record_close(RECORD_NOTIFICATION); + furi_record_close(RECORD_GUI); return 0; } diff --git a/applications/debug_tools/display_test/display_test.c b/applications/debug_tools/display_test/display_test.c index 95aea1de..947e4dc8 100644 --- a/applications/debug_tools/display_test/display_test.c +++ b/applications/debug_tools/display_test/display_test.c @@ -127,7 +127,7 @@ DisplayTest* display_test_alloc() { View* view = NULL; - instance->gui = furi_record_open("gui"); + instance->gui = furi_record_open(RECORD_GUI); instance->view_dispatcher = view_dispatcher_alloc(); view_dispatcher_enable_queue(instance->view_dispatcher); view_dispatcher_attach_to_gui( @@ -206,7 +206,7 @@ void display_test_free(DisplayTest* instance) { view_display_test_free(instance->view_display_test); view_dispatcher_free(instance->view_dispatcher); - furi_record_close("gui"); + furi_record_close(RECORD_GUI); free(instance); } diff --git a/applications/debug_tools/file_browser_test/file_browser_app.c b/applications/debug_tools/file_browser_test/file_browser_app.c index c9b63ecb..c7f461d4 100644 --- a/applications/debug_tools/file_browser_test/file_browser_app.c +++ b/applications/debug_tools/file_browser_test/file_browser_app.c @@ -29,8 +29,8 @@ FileBrowserApp* file_browser_app_alloc(char* arg) { UNUSED(arg); FileBrowserApp* app = malloc(sizeof(FileBrowserApp)); - app->gui = furi_record_open("gui"); - app->dialogs = furi_record_open("dialogs"); + app->gui = furi_record_open(RECORD_GUI); + app->dialogs = furi_record_open(RECORD_DIALOGS); app->view_dispatcher = view_dispatcher_alloc(); view_dispatcher_enable_queue(app->view_dispatcher); @@ -80,9 +80,9 @@ void file_browser_app_free(FileBrowserApp* app) { scene_manager_free(app->scene_manager); // Close records - furi_record_close("gui"); - furi_record_close("notification"); - furi_record_close("dialogs"); + furi_record_close(RECORD_GUI); + furi_record_close(RECORD_NOTIFICATION); + furi_record_close(RECORD_DIALOGS); string_clear(app->file_path); diff --git a/applications/debug_tools/file_browser_test/scenes/file_browser_scene_start.c b/applications/debug_tools/file_browser_test/scenes/file_browser_scene_start.c index bb71e83d..b3381f0a 100644 --- a/applications/debug_tools/file_browser_test/scenes/file_browser_scene_start.c +++ b/applications/debug_tools/file_browser_test/scenes/file_browser_scene_start.c @@ -1,6 +1,8 @@ #include "../file_browser_app_i.h" -#include "furi_hal.h" -#include "gui/modules/widget_elements/widget_element_i.h" + +#include +#include +#include static void file_browser_scene_start_ok_callback(GuiButtonType result, InputType type, void* context) { @@ -17,7 +19,7 @@ bool file_browser_scene_start_on_event(void* context, SceneManagerEvent event) { bool consumed = false; if(event.type == SceneManagerEventTypeCustom) { - string_set_str(app->file_path, "/any/badusb/demo_windows.txt"); + string_set_str(app->file_path, ANY_PATH("badusb/demo_windows.txt")); scene_manager_next_scene(app->scene_manager, FileBrowserSceneBrowser); consumed = true; } else if(event.type == SceneManagerEventTypeTick) { diff --git a/applications/debug_tools/keypad_test.c b/applications/debug_tools/keypad_test.c index 9a6e7f25..6708c82b 100644 --- a/applications/debug_tools/keypad_test.c +++ b/applications/debug_tools/keypad_test.c @@ -78,7 +78,7 @@ int32_t keypad_test_app(void* p) { view_port_input_callback_set(view_port, keypad_test_input_callback, event_queue); // Open GUI and register view_port - Gui* gui = furi_record_open("gui"); + Gui* gui = furi_record_open(RECORD_GUI); gui_add_view_port(gui, view_port, GuiLayerFullscreen); InputEvent event; @@ -149,7 +149,7 @@ int32_t keypad_test_app(void* p) { furi_message_queue_free(event_queue); delete_mutex(&state_mutex); - furi_record_close("gui"); + furi_record_close(RECORD_GUI); return 0; } diff --git a/applications/debug_tools/text_box_test.c b/applications/debug_tools/text_box_test.c index 837c34b6..d7194ffe 100644 --- a/applications/debug_tools/text_box_test.c +++ b/applications/debug_tools/text_box_test.c @@ -88,7 +88,7 @@ int32_t text_box_test_app(void* p) { view_port_input_callback_set(view_port, text_box_test_input_callback, event_queue); // Open GUI and register view_port - Gui* gui = furi_record_open("gui"); + Gui* gui = furi_record_open(RECORD_GUI); gui_add_view_port(gui, view_port, GuiLayerFullscreen); uint32_t test_renders_num = COUNT_OF(text_box_test_render); @@ -121,7 +121,7 @@ int32_t text_box_test_app(void* p) { furi_message_queue_free(event_queue); delete_mutex(&state_mutex); - furi_record_close("gui"); + furi_record_close(RECORD_GUI); return 0; } diff --git a/applications/debug_tools/uart_echo.c b/applications/debug_tools/uart_echo.c index 8f795c56..7a0f5c39 100644 --- a/applications/debug_tools/uart_echo.c +++ b/applications/debug_tools/uart_echo.c @@ -189,8 +189,8 @@ static UartEchoApp* uart_echo_app_alloc() { app->rx_stream = xStreamBufferCreate(2048, 1); // Gui - app->gui = furi_record_open("gui"); - app->notification = furi_record_open("notification"); + app->gui = furi_record_open(RECORD_GUI); + app->notification = furi_record_open(RECORD_NOTIFICATION); // View dispatcher app->view_dispatcher = view_dispatcher_alloc(); @@ -256,8 +256,8 @@ static void uart_echo_app_free(UartEchoApp* app) { view_dispatcher_free(app->view_dispatcher); // Close gui record - furi_record_close("gui"); - furi_record_close("notification"); + furi_record_close(RECORD_GUI); + furi_record_close(RECORD_NOTIFICATION); app->gui = NULL; vStreamBufferDelete(app->rx_stream); diff --git a/applications/debug_tools/usb_mouse.c b/applications/debug_tools/usb_mouse.c index 3174ccae..6e716e69 100644 --- a/applications/debug_tools/usb_mouse.c +++ b/applications/debug_tools/usb_mouse.c @@ -51,7 +51,7 @@ int32_t usb_mouse_app(void* p) { view_port_input_callback_set(view_port, usb_mouse_input_callback, event_queue); // Open GUI and register view_port - Gui* gui = furi_record_open("gui"); + Gui* gui = furi_record_open(RECORD_GUI); gui_add_view_port(gui, view_port, GuiLayerFullscreen); UsbMouseEvent event; diff --git a/applications/debug_tools/usb_test.c b/applications/debug_tools/usb_test.c index a4f42f47..ed86c37a 100644 --- a/applications/debug_tools/usb_test.c +++ b/applications/debug_tools/usb_test.c @@ -59,7 +59,7 @@ UsbTestApp* usb_test_app_alloc() { UsbTestApp* app = malloc(sizeof(UsbTestApp)); // Gui - app->gui = furi_record_open("gui"); + app->gui = furi_record_open(RECORD_GUI); // View dispatcher app->view_dispatcher = view_dispatcher_alloc(); @@ -106,7 +106,7 @@ void usb_test_app_free(UsbTestApp* app) { view_dispatcher_free(app->view_dispatcher); // Close gui record - furi_record_close("gui"); + furi_record_close(RECORD_GUI); app->gui = NULL; // Free rest diff --git a/applications/debug_tools/vibro_test.c b/applications/debug_tools/vibro_test.c index dbd35d60..e6c45ef6 100644 --- a/applications/debug_tools/vibro_test.c +++ b/applications/debug_tools/vibro_test.c @@ -32,10 +32,10 @@ int32_t vibro_test_app(void* p) { view_port_input_callback_set(view_port, vibro_test_input_callback, event_queue); // Register view port in GUI - Gui* gui = furi_record_open("gui"); + Gui* gui = furi_record_open(RECORD_GUI); gui_add_view_port(gui, view_port, GuiLayerFullscreen); - NotificationApp* notification = furi_record_open("notification"); + NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION); InputEvent event; @@ -60,8 +60,8 @@ int32_t vibro_test_app(void* p) { view_port_free(view_port); furi_message_queue_free(event_queue); - furi_record_close("notification"); - furi_record_close("gui"); + furi_record_close(RECORD_NOTIFICATION); + furi_record_close(RECORD_GUI); return 0; } diff --git a/applications/desktop/animations/animation_manager.c b/applications/desktop/animations/animation_manager.c index 9b702811..d755be9c 100644 --- a/applications/desktop/animations/animation_manager.c +++ b/applications/desktop/animations/animation_manager.c @@ -137,9 +137,9 @@ void animation_manager_check_blocking_process(AnimationManager* animation_manage bool blocked = animation_manager_check_blocking(animation_manager); if(!blocked) { - Dolphin* dolphin = furi_record_open("dolphin"); + Dolphin* dolphin = furi_record_open(RECORD_DOLPHIN); DolphinStats stats = dolphin_stats(dolphin); - furi_record_close("dolphin"); + furi_record_close(RECORD_DOLPHIN); const StorageAnimationManifestInfo* manifest_info = animation_storage_get_meta(animation_manager->current_animation); @@ -170,9 +170,9 @@ bool animation_manager_interact_process(AnimationManager* animation_manager) { animation_manager->levelup_pending = false; animation_manager->levelup_active = true; animation_manager_switch_to_one_shot_view(animation_manager); - Dolphin* dolphin = furi_record_open("dolphin"); + Dolphin* dolphin = furi_record_open(RECORD_DOLPHIN); dolphin_upgrade_level(dolphin); - furi_record_close("dolphin"); + furi_record_close(RECORD_DOLPHIN); } else if(animation_manager->levelup_active) { animation_manager->levelup_active = false; animation_manager_start_new_idle(animation_manager); @@ -205,7 +205,7 @@ static bool animation_manager_check_blocking(AnimationManager* animation_manager furi_assert(animation_manager); StorageAnimation* blocking_animation = NULL; - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); FS_Error sd_status = storage_sd_status(storage); if(sd_status == FSE_INTERNAL) { @@ -220,7 +220,7 @@ static bool animation_manager_check_blocking(AnimationManager* animation_manager furi_assert(blocking_animation); animation_manager->sd_shown_sd_ok = true; } else if(!animation_manager->sd_shown_no_db) { - bool db_exists = storage_common_stat(storage, "/ext/Manifest", NULL) == FSE_OK; + bool db_exists = storage_common_stat(storage, EXT_PATH("Manifest"), NULL) == FSE_OK; if(!db_exists) { blocking_animation = animation_storage_find_animation(NO_DB_ANIMATION_NAME); furi_assert(blocking_animation); @@ -234,9 +234,9 @@ static bool animation_manager_check_blocking(AnimationManager* animation_manager } } - Dolphin* dolphin = furi_record_open("dolphin"); + Dolphin* dolphin = furi_record_open(RECORD_DOLPHIN); DolphinStats stats = dolphin_stats(dolphin); - furi_record_close("dolphin"); + furi_record_close(RECORD_DOLPHIN); if(!blocking_animation && stats.level_up_is_pending) { blocking_animation = animation_storage_find_animation(NEW_MAIL_ANIMATION_NAME); furi_assert(blocking_animation); @@ -252,7 +252,7 @@ static bool animation_manager_check_blocking(AnimationManager* animation_manager animation_manager->state = AnimationManagerStateBlocked; } - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); return !!blocking_animation; } @@ -287,15 +287,15 @@ AnimationManager* animation_manager_alloc(void) { bubble_animation_view_set_interact_callback( animation_manager->animation_view, animation_manager_interact_callback, animation_manager); - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); animation_manager->pubsub_subscription_storage = furi_pubsub_subscribe( storage_get_pubsub(storage), animation_manager_check_blocking_callback, animation_manager); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); - Dolphin* dolphin = furi_record_open("dolphin"); + Dolphin* dolphin = furi_record_open(RECORD_DOLPHIN); animation_manager->pubsub_subscription_dolphin = furi_pubsub_subscribe( dolphin_get_pubsub(dolphin), animation_manager_check_blocking_callback, animation_manager); - furi_record_close("dolphin"); + furi_record_close(RECORD_DOLPHIN); animation_manager->sd_shown_sd_ok = true; if(!animation_manager_check_blocking(animation_manager)) { @@ -308,15 +308,15 @@ AnimationManager* animation_manager_alloc(void) { void animation_manager_free(AnimationManager* animation_manager) { furi_assert(animation_manager); - Dolphin* dolphin = furi_record_open("dolphin"); + Dolphin* dolphin = furi_record_open(RECORD_DOLPHIN); furi_pubsub_unsubscribe( dolphin_get_pubsub(dolphin), animation_manager->pubsub_subscription_dolphin); - furi_record_close("dolphin"); + furi_record_close(RECORD_DOLPHIN); - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); furi_pubsub_unsubscribe( storage_get_pubsub(storage), animation_manager->pubsub_subscription_storage); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); string_clear(animation_manager->freezed_animation_name); View* animation_view = bubble_animation_get_view(animation_manager->animation_view); @@ -340,16 +340,16 @@ static bool animation_manager_is_valid_idle_animation( bool result = true; if(!strcmp(info->name, BAD_BATTERY_ANIMATION_NAME)) { - Power* power = furi_record_open("power"); + Power* power = furi_record_open(RECORD_POWER); bool battery_is_well = power_is_battery_healthy(power); - furi_record_close("power"); + furi_record_close(RECORD_POWER); result = !battery_is_well; } if(!strcmp(info->name, NO_SD_ANIMATION_NAME)) { - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); FS_Error sd_status = storage_sd_status(storage); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); result = (sd_status == FSE_NOT_READY); } @@ -370,9 +370,9 @@ static StorageAnimation* StorageAnimationList_init(animation_list); animation_storage_fill_animation_list(&animation_list); - Dolphin* dolphin = furi_record_open("dolphin"); + Dolphin* dolphin = furi_record_open(RECORD_DOLPHIN); DolphinStats stats = dolphin_stats(dolphin); - furi_record_close("dolphin"); + furi_record_close(RECORD_DOLPHIN); uint32_t whole_weight = 0; StorageAnimationList_it_t it; @@ -492,9 +492,9 @@ void animation_manager_load_and_continue_animation(AnimationManager* animation_m StorageAnimation* restore_animation = animation_storage_find_animation( string_get_cstr(animation_manager->freezed_animation_name)); if(restore_animation) { - Dolphin* dolphin = furi_record_open("dolphin"); + Dolphin* dolphin = furi_record_open(RECORD_DOLPHIN); DolphinStats stats = dolphin_stats(dolphin); - furi_record_close("dolphin"); + furi_record_close(RECORD_DOLPHIN); const StorageAnimationManifestInfo* manifest_info = animation_storage_get_meta(restore_animation); bool valid = animation_manager_is_valid_idle_animation(manifest_info, &stats); @@ -543,9 +543,9 @@ void animation_manager_load_and_continue_animation(AnimationManager* animation_m static void animation_manager_switch_to_one_shot_view(AnimationManager* animation_manager) { furi_assert(animation_manager); furi_assert(!animation_manager->one_shot_view); - Dolphin* dolphin = furi_record_open("dolphin"); + Dolphin* dolphin = furi_record_open(RECORD_DOLPHIN); DolphinStats stats = dolphin_stats(dolphin); - furi_record_close("dolphin"); + furi_record_close(RECORD_DOLPHIN); animation_manager->one_shot_view = one_shot_view_alloc(); one_shot_view_set_interact_callback( diff --git a/applications/desktop/animations/animation_storage.c b/applications/desktop/animations/animation_storage.c index 36b20bc8..e0c6bf41 100644 --- a/applications/desktop/animations/animation_storage.c +++ b/applications/desktop/animations/animation_storage.c @@ -14,7 +14,7 @@ #include #define ANIMATION_META_FILE "meta.txt" -#define ANIMATION_DIR "/ext/dolphin" +#define ANIMATION_DIR EXT_PATH("dolphin") #define ANIMATION_MANIFEST_FILE ANIMATION_DIR "/manifest.txt" #define TAG "AnimationStorage" @@ -29,7 +29,7 @@ static bool animation_storage_load_single_manifest_info( furi_assert(manifest_info); bool result = false; - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); FlipperFormat* file = flipper_format_file_alloc(storage); flipper_format_set_strict_mode(file, true); string_t read_string; @@ -75,7 +75,7 @@ static bool animation_storage_load_single_manifest_info( string_clear(read_string); flipper_format_free(file); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); return result; } @@ -84,7 +84,7 @@ void animation_storage_fill_animation_list(StorageAnimationList_t* animation_lis furi_assert(sizeof(StorageAnimationList_t) == sizeof(void*)); furi_assert(!StorageAnimationList_size(*animation_list)); - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); FlipperFormat* file = flipper_format_file_alloc(storage); /* Forbid skipping fields */ flipper_format_set_strict_mode(file, true); @@ -134,7 +134,7 @@ void animation_storage_fill_animation_list(StorageAnimationList_t* animation_lis StorageAnimationList_push_back(*animation_list, (StorageAnimation*)&dolphin_internal[i]); } - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); } StorageAnimation* animation_storage_find_animation(const char* name) { @@ -434,7 +434,7 @@ static BubbleAnimation* animation_storage_load_animation(const char* name) { uint32_t height = 0; uint32_t width = 0; uint32_t* u32array = NULL; - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); FlipperFormat* ff = flipper_format_file_alloc(storage); /* Forbid skipping fields */ flipper_format_set_strict_mode(ff, true); diff --git a/applications/desktop/desktop.c b/applications/desktop/desktop.c index 83b4f0f3..578066a6 100644 --- a/applications/desktop/desktop.c +++ b/applications/desktop/desktop.c @@ -15,6 +15,7 @@ #include "desktop/views/desktop_view_pin_timeout.h" #include "desktop_i.h" #include "helpers/pin_lock.h" +#include "helpers/slideshow_filename.h" static void desktop_auto_lock_arm(Desktop*); static void desktop_auto_lock_inhibit(Desktop*); @@ -127,9 +128,9 @@ void desktop_lock(Desktop* desktop) { void desktop_unlock(Desktop* desktop) { view_port_enabled_set(desktop->lock_viewport, false); - Gui* gui = furi_record_open("gui"); + Gui* gui = furi_record_open(RECORD_GUI); gui_set_lockdown(gui, false); - furi_record_close("gui"); + furi_record_close(RECORD_GUI); desktop_view_locked_unlock(desktop->locked_view); scene_manager_search_and_switch_to_previous_scene(desktop->scene_manager, DesktopSceneMain); desktop_auto_lock_arm(desktop); @@ -139,7 +140,7 @@ Desktop* desktop_alloc() { Desktop* desktop = malloc(sizeof(Desktop)); desktop->animation_manager = animation_manager_alloc(); - desktop->gui = furi_record_open("gui"); + desktop->gui = furi_record_open(RECORD_GUI); desktop->scene_thread = furi_thread_alloc(); desktop->view_dispatcher = view_dispatcher_alloc(); desktop->scene_manager = scene_manager_alloc(&desktop_scene_handlers, desktop); @@ -218,17 +219,17 @@ Desktop* desktop_alloc() { gui_add_view_port(desktop->gui, desktop->lock_viewport, GuiLayerStatusBarLeft); // Special case: autostart application is already running - desktop->loader = furi_record_open("loader"); + desktop->loader = furi_record_open(RECORD_LOADER); if(loader_is_locked(desktop->loader) && animation_manager_is_animation_loaded(desktop->animation_manager)) { animation_manager_unload_and_stall_animation(desktop->animation_manager); } - desktop->notification = furi_record_open("notification"); + desktop->notification = furi_record_open(RECORD_NOTIFICATION); desktop->app_start_stop_subscription = furi_pubsub_subscribe( loader_get_pubsub(desktop->loader), desktop_loader_callback, desktop); - desktop->input_events_pubsub = furi_record_open("input_events"); + desktop->input_events_pubsub = furi_record_open(RECORD_INPUT_EVENTS); desktop->input_events_subscription = NULL; desktop->auto_lock_timer = @@ -250,9 +251,9 @@ void desktop_free(Desktop* desktop) { desktop->loader = NULL; desktop->input_events_pubsub = NULL; - furi_record_close("loader"); - furi_record_close("notification"); - furi_record_close("input_events"); + furi_record_close(RECORD_LOADER); + furi_record_close(RECORD_NOTIFICATION); + furi_record_close(RECORD_INPUT_EVENTS); view_dispatcher_remove_view(desktop->view_dispatcher, DesktopViewIdMain); view_dispatcher_remove_view(desktop->view_dispatcher, DesktopViewIdLockMenu); @@ -276,7 +277,7 @@ void desktop_free(Desktop* desktop) { popup_free(desktop->hw_mismatch_popup); desktop_view_pin_timeout_free(desktop->pin_timeout_view); - furi_record_close("gui"); + furi_record_close(RECORD_GUI); desktop->gui = NULL; furi_thread_free(desktop->scene_thread); @@ -289,9 +290,9 @@ void desktop_free(Desktop* desktop) { } static bool desktop_check_file_flag(const char* flag_path) { - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); bool exists = storage_common_stat(storage, flag_path, NULL) == FSE_OK; - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); return exists; } @@ -318,7 +319,7 @@ int32_t desktop_srv(void* p) { desktop_lock(desktop); } - if(desktop_check_file_flag("/int/slideshow")) { + if(desktop_check_file_flag(SLIDESHOW_FS_PATH)) { scene_manager_next_scene(desktop->scene_manager, DesktopSceneSlideshow); } diff --git a/applications/desktop/desktop_settings/desktop_settings.h b/applications/desktop/desktop_settings/desktop_settings.h index f2039924..800847d5 100644 --- a/applications/desktop/desktop_settings/desktop_settings.h +++ b/applications/desktop/desktop_settings/desktop_settings.h @@ -1,12 +1,16 @@ #pragma once +#include "desktop_settings_filename.h" + #include #include #include #include +#include #define DESKTOP_SETTINGS_VER (4) -#define DESKTOP_SETTINGS_PATH "/int/desktop.settings" + +#define DESKTOP_SETTINGS_PATH INT_PATH(DESKTOP_SETTINGS_FILE_NAME) #define DESKTOP_SETTINGS_MAGIC (0x17) #define PIN_MAX_LENGTH 12 diff --git a/applications/desktop/desktop_settings/desktop_settings_app.c b/applications/desktop/desktop_settings/desktop_settings_app.c index c52f1947..bc41be6e 100644 --- a/applications/desktop/desktop_settings/desktop_settings_app.c +++ b/applications/desktop/desktop_settings/desktop_settings_app.c @@ -21,7 +21,7 @@ static bool desktop_settings_back_event_callback(void* context) { DesktopSettingsApp* desktop_settings_app_alloc() { DesktopSettingsApp* app = malloc(sizeof(DesktopSettingsApp)); - app->gui = furi_record_open("gui"); + app->gui = furi_record_open(RECORD_GUI); app->view_dispatcher = view_dispatcher_alloc(); app->scene_manager = scene_manager_alloc(&desktop_settings_scene_handlers, app); view_dispatcher_enable_queue(app->view_dispatcher); @@ -83,7 +83,7 @@ void desktop_settings_app_free(DesktopSettingsApp* app) { view_dispatcher_free(app->view_dispatcher); scene_manager_free(app->scene_manager); // Records - furi_record_close("gui"); + furi_record_close(RECORD_GUI); free(app); } diff --git a/applications/desktop/desktop_settings/desktop_settings_filename.h b/applications/desktop/desktop_settings/desktop_settings_filename.h new file mode 100644 index 00000000..b9140f24 --- /dev/null +++ b/applications/desktop/desktop_settings/desktop_settings_filename.h @@ -0,0 +1,3 @@ +#pragma once + +#define DESKTOP_SETTINGS_FILE_NAME ".desktop.settings" diff --git a/applications/desktop/desktop_settings/scenes/desktop_settings_scene_pin_setup_done.c b/applications/desktop/desktop_settings/scenes/desktop_settings_scene_pin_setup_done.c index 7be0e51c..42408428 100644 --- a/applications/desktop/desktop_settings/scenes/desktop_settings_scene_pin_setup_done.c +++ b/applications/desktop/desktop_settings/scenes/desktop_settings_scene_pin_setup_done.c @@ -25,9 +25,9 @@ void desktop_settings_scene_pin_setup_done_on_enter(void* context) { app->settings.pin_code = app->pincode_buffer; SAVE_DESKTOP_SETTINGS(&app->settings); - NotificationApp* notification = furi_record_open("notification"); + NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION); notification_message(notification, &sequence_single_vibro); - furi_record_close("notification"); + furi_record_close(RECORD_NOTIFICATION); desktop_view_pin_input_set_context(app->pin_input_view, app); desktop_view_pin_input_set_back_callback(app->pin_input_view, NULL); diff --git a/applications/desktop/helpers/pin_lock.c b/applications/desktop/helpers/pin_lock.c index d63398d9..0495b675 100644 --- a/applications/desktop/helpers/pin_lock.c +++ b/applications/desktop/helpers/pin_lock.c @@ -44,9 +44,9 @@ static const uint8_t desktop_helpers_fails_timeout[] = { }; void desktop_pin_lock_error_notify() { - NotificationApp* notification = furi_record_open("notification"); + NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION); notification_message(notification, &sequence_pin_fail); - furi_record_close("notification"); + furi_record_close(RECORD_NOTIFICATION); } uint32_t desktop_pin_lock_get_fail_timeout() { @@ -67,9 +67,9 @@ void desktop_pin_lock(DesktopSettings* settings) { furi_hal_rtc_set_pin_fails(0); furi_hal_rtc_set_flag(FuriHalRtcFlagLock); - Cli* cli = furi_record_open("cli"); + Cli* cli = furi_record_open(RECORD_CLI); cli_session_close(cli); - furi_record_close("cli"); + furi_record_close(RECORD_CLI); settings->is_locked = 1; SAVE_DESKTOP_SETTINGS(settings); } @@ -78,9 +78,9 @@ void desktop_pin_unlock(DesktopSettings* settings) { furi_assert(settings); furi_hal_rtc_reset_flag(FuriHalRtcFlagLock); - Cli* cli = furi_record_open("cli"); + Cli* cli = furi_record_open(RECORD_CLI); cli_session_open(cli, &cli_vcp); - furi_record_close("cli"); + furi_record_close(RECORD_CLI); settings->is_locked = 0; SAVE_DESKTOP_SETTINGS(settings); } @@ -103,9 +103,9 @@ void desktop_pin_lock_init(DesktopSettings* settings) { } if(desktop_pin_lock_is_locked()) { - Cli* cli = furi_record_open("cli"); + Cli* cli = furi_record_open(RECORD_CLI); cli_session_close(cli); - furi_record_close("cli"); + furi_record_close(RECORD_CLI); } } diff --git a/applications/desktop/helpers/slideshow.c b/applications/desktop/helpers/slideshow.c index 4ec55a5a..63bd42b5 100644 --- a/applications/desktop/helpers/slideshow.c +++ b/applications/desktop/helpers/slideshow.c @@ -52,7 +52,7 @@ void slideshow_free(Slideshow* slideshow) { } bool slideshow_load(Slideshow* slideshow, const char* fspath) { - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); File* slideshow_file = storage_file_alloc(storage); slideshow->loaded = false; do { @@ -86,7 +86,7 @@ bool slideshow_load(Slideshow* slideshow, const char* fspath) { } } while(false); storage_file_free(slideshow_file); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); return slideshow->loaded; } diff --git a/applications/desktop/helpers/slideshow_filename.h b/applications/desktop/helpers/slideshow_filename.h new file mode 100644 index 00000000..2250d91d --- /dev/null +++ b/applications/desktop/helpers/slideshow_filename.h @@ -0,0 +1,3 @@ +#pragma once + +#define SLIDESHOW_FILE_NAME ".slideshow" diff --git a/applications/desktop/scenes/desktop_scene_debug.c b/applications/desktop/scenes/desktop_scene_debug.c index 4945f7ac..e79c56e1 100644 --- a/applications/desktop/scenes/desktop_scene_debug.c +++ b/applications/desktop/scenes/desktop_scene_debug.c @@ -22,7 +22,7 @@ void desktop_scene_debug_on_enter(void* context) { bool desktop_scene_debug_on_event(void* context, SceneManagerEvent event) { Desktop* desktop = (Desktop*)context; - Dolphin* dolphin = furi_record_open("dolphin"); + Dolphin* dolphin = furi_record_open(RECORD_DOLPHIN); bool consumed = false; if(event.type == SceneManagerEventTypeCustom) { @@ -55,7 +55,7 @@ bool desktop_scene_debug_on_event(void* context, SceneManagerEvent event) { } } - furi_record_close("dolphin"); + furi_record_close(RECORD_DOLPHIN); return consumed; } diff --git a/applications/desktop/scenes/desktop_scene_locked.c b/applications/desktop/scenes/desktop_scene_locked.c index f4c08d32..c377d40a 100644 --- a/applications/desktop/scenes/desktop_scene_locked.c +++ b/applications/desktop/scenes/desktop_scene_locked.c @@ -47,9 +47,9 @@ void desktop_scene_locked_on_enter(void* context) { if(state == SCENE_LOCKED_FIRST_ENTER) { bool pin_locked = desktop_pin_lock_is_locked(); view_port_enabled_set(desktop->lock_viewport, true); - Gui* gui = furi_record_open("gui"); + Gui* gui = furi_record_open(RECORD_GUI); gui_set_lockdown(gui, true); - furi_record_close("gui"); + furi_record_close(RECORD_GUI); if(pin_locked) { LOAD_DESKTOP_SETTINGS(&desktop->settings); diff --git a/applications/desktop/scenes/desktop_scene_pin_input.c b/applications/desktop/scenes/desktop_scene_pin_input.c index 7d980a85..9392309e 100644 --- a/applications/desktop/scenes/desktop_scene_pin_input.c +++ b/applications/desktop/scenes/desktop_scene_pin_input.c @@ -24,13 +24,13 @@ typedef struct { } DesktopScenePinInputState; static void desktop_scene_locked_light_red(bool value) { - NotificationApp* app = furi_record_open("notification"); + NotificationApp* app = furi_record_open(RECORD_NOTIFICATION); if(value) { notification_message(app, &sequence_set_only_red_255); } else { notification_message(app, &sequence_reset_red); } - furi_record_close("notification"); + furi_record_close(RECORD_NOTIFICATION); } static void diff --git a/applications/desktop/scenes/desktop_scene_slideshow.c b/applications/desktop/scenes/desktop_scene_slideshow.c index 70080127..18460a4c 100644 --- a/applications/desktop/scenes/desktop_scene_slideshow.c +++ b/applications/desktop/scenes/desktop_scene_slideshow.c @@ -26,9 +26,9 @@ bool desktop_scene_slideshow_on_event(void* context, SceneManagerEvent event) { if(event.type == SceneManagerEventTypeCustom) { switch(event.event) { case DesktopSlideshowCompleted: - storage = furi_record_open("storage"); - storage_common_remove(storage, "/int/slideshow"); - furi_record_close("storage"); + storage = furi_record_open(RECORD_STORAGE); + storage_common_remove(storage, SLIDESHOW_FS_PATH); + furi_record_close(RECORD_STORAGE); scene_manager_previous_scene(desktop->scene_manager); consumed = true; break; diff --git a/applications/desktop/views/desktop_view_debug.c b/applications/desktop/views/desktop_view_debug.c index 3a6c87f1..68c054c2 100644 --- a/applications/desktop/views/desktop_view_debug.c +++ b/applications/desktop/views/desktop_view_debug.c @@ -79,9 +79,9 @@ void desktop_debug_render(Canvas* canvas, void* model) { } else { char buffer[64]; - Dolphin* dolphin = furi_record_open("dolphin"); + Dolphin* dolphin = furi_record_open(RECORD_DOLPHIN); DolphinStats stats = dolphin_stats(dolphin); - furi_record_close("dolphin"); + furi_record_close(RECORD_DOLPHIN); uint32_t current_lvl = stats.level; uint32_t remaining = dolphin_state_xp_to_levelup(m->icounter); @@ -175,7 +175,7 @@ void desktop_debug_free(DesktopDebugView* debug_view) { } void desktop_debug_get_dolphin_data(DesktopDebugView* debug_view) { - Dolphin* dolphin = furi_record_open("dolphin"); + Dolphin* dolphin = furi_record_open(RECORD_DOLPHIN); DolphinStats stats = dolphin_stats(dolphin); with_view_model( debug_view->view, (DesktopDebugViewModel * model) { @@ -185,7 +185,7 @@ void desktop_debug_get_dolphin_data(DesktopDebugView* debug_view) { return true; }); - furi_record_close("dolphin"); + furi_record_close(RECORD_DOLPHIN); } void desktop_debug_reset_screen_idx(DesktopDebugView* debug_view) { diff --git a/applications/desktop/views/desktop_view_slideshow.c b/applications/desktop/views/desktop_view_slideshow.c index cd22b39d..943206e1 100644 --- a/applications/desktop/views/desktop_view_slideshow.c +++ b/applications/desktop/views/desktop_view_slideshow.c @@ -5,6 +5,7 @@ #include "../desktop_i.h" #include "desktop_view_slideshow.h" #include "../helpers/slideshow.h" +#include "../helpers/slideshow_filename.h" struct DesktopSlideshowView { View* view; @@ -60,7 +61,7 @@ static void desktop_view_slideshow_enter(void* context) { DesktopSlideshowViewModel* model = view_get_model(instance->view); model->slideshow = slideshow_alloc(); - if(!slideshow_load(model->slideshow, "/int/slideshow")) { + if(!slideshow_load(model->slideshow, SLIDESHOW_FS_PATH)) { instance->callback(DesktopSlideshowCompleted, instance->context); } view_commit_model(instance->view, false); diff --git a/applications/desktop/views/desktop_view_slideshow.h b/applications/desktop/views/desktop_view_slideshow.h index 5b45a6b7..624cbf00 100644 --- a/applications/desktop/views/desktop_view_slideshow.h +++ b/applications/desktop/views/desktop_view_slideshow.h @@ -3,6 +3,9 @@ #include #include "desktop_events.h" +#include "../helpers/slideshow_filename.h" + +#define SLIDESHOW_FS_PATH INT_PATH(SLIDESHOW_FILE_NAME) typedef struct DesktopSlideshowView DesktopSlideshowView; diff --git a/applications/dialogs/dialogs.c b/applications/dialogs/dialogs.c index da047d8a..381da163 100644 --- a/applications/dialogs/dialogs.c +++ b/applications/dialogs/dialogs.c @@ -29,7 +29,7 @@ static void dialogs_app_process_message(DialogsApp* app, DialogsAppMessage* mess int32_t dialogs_srv(void* p) { UNUSED(p); DialogsApp* app = dialogs_app_alloc(); - furi_record_create("dialogs", app); + furi_record_create(RECORD_DIALOGS, app); DialogsAppMessage message; while(1) { diff --git a/applications/dialogs/dialogs.h b/applications/dialogs/dialogs.h index 53606056..946ab6cf 100644 --- a/applications/dialogs/dialogs.h +++ b/applications/dialogs/dialogs.h @@ -9,6 +9,8 @@ extern "C" { /****************** COMMON ******************/ +#define RECORD_DIALOGS "dialogs" + typedef struct DialogsApp DialogsApp; /****************** FILE BROWSER ******************/ diff --git a/applications/dialogs/dialogs_module_file_browser.c b/applications/dialogs/dialogs_module_file_browser.c index ecd0ca79..f5355571 100644 --- a/applications/dialogs/dialogs_module_file_browser.c +++ b/applications/dialogs/dialogs_module_file_browser.c @@ -23,7 +23,7 @@ static void dialogs_app_file_browser_callback(void* context) { bool dialogs_app_process_module_file_browser(const DialogsAppMessageDataFileBrowser* data) { bool ret = false; - Gui* gui = furi_record_open("gui"); + Gui* gui = furi_record_open(RECORD_GUI); DialogsAppFileBrowserContext* file_browser_context = malloc(sizeof(DialogsAppFileBrowserContext)); @@ -53,7 +53,7 @@ bool dialogs_app_process_module_file_browser(const DialogsAppMessageDataFileBrow file_browser_free(file_browser); API_LOCK_FREE(file_browser_context->lock); free(file_browser_context); - furi_record_close("gui"); + furi_record_close(RECORD_GUI); return ret; } diff --git a/applications/dialogs/dialogs_module_message.c b/applications/dialogs/dialogs_module_message.c index ec2efd2e..8d1c3ba7 100644 --- a/applications/dialogs/dialogs_module_message.c +++ b/applications/dialogs/dialogs_module_message.c @@ -54,7 +54,7 @@ static void dialogs_app_message_callback(DialogExResult result, void* context) { DialogMessageButton dialogs_app_process_module_message(const DialogsAppMessageDataDialog* data) { DialogMessageButton ret = DialogMessageButtonBack; - Gui* gui = furi_record_open("gui"); + Gui* gui = furi_record_open(RECORD_GUI); const DialogMessage* message = data->message; DialogsAppMessageContext* message_context = malloc(sizeof(DialogsAppMessageContext)); message_context->lock = API_LOCK_INIT_LOCKED(); @@ -96,7 +96,7 @@ DialogMessageButton dialogs_app_process_module_message(const DialogsAppMessageDa dialog_ex_free(dialog_ex); API_LOCK_FREE(message_context->lock); free(message_context); - furi_record_close("gui"); + furi_record_close(RECORD_GUI); return ret; } diff --git a/applications/dolphin/dolphin.c b/applications/dolphin/dolphin.c index f495068b..41eeef3b 100644 --- a/applications/dolphin/dolphin.c +++ b/applications/dolphin/dolphin.c @@ -155,7 +155,7 @@ static void dolphin_update_clear_limits_timer_period(Dolphin* dolphin) { int32_t dolphin_srv(void* p) { UNUSED(p); Dolphin* dolphin = dolphin_alloc(); - furi_record_create("dolphin", dolphin); + furi_record_create(RECORD_DOLPHIN, dolphin); dolphin_state_load(dolphin->state); xTimerReset(dolphin->butthurt_timer, portMAX_DELAY); diff --git a/applications/dolphin/dolphin.h b/applications/dolphin/dolphin.h index 2abb166b..41a6a608 100644 --- a/applications/dolphin/dolphin.h +++ b/applications/dolphin/dolphin.h @@ -9,6 +9,8 @@ extern "C" { #endif +#define RECORD_DOLPHIN "dolphin" + typedef struct Dolphin Dolphin; typedef struct { diff --git a/applications/dolphin/helpers/dolphin_state.c b/applications/dolphin/helpers/dolphin_state.c index 8a569392..76f38a5f 100644 --- a/applications/dolphin/helpers/dolphin_state.c +++ b/applications/dolphin/helpers/dolphin_state.c @@ -1,5 +1,7 @@ #include "dolphin_state.h" #include "dolphin/helpers/dolphin_deed.h" +#include "dolphin_state_filename.h" + #include #include #include @@ -8,7 +10,8 @@ #include #define TAG "DolphinState" -#define DOLPHIN_STATE_PATH "/int/dolphin.state" + +#define DOLPHIN_STATE_PATH INT_PATH(DOLPHIN_STATE_FILE_NAME) #define DOLPHIN_STATE_HEADER_MAGIC 0xD0 #define DOLPHIN_STATE_HEADER_VERSION 0x01 #define LEVEL2_THRESHOLD 735 diff --git a/applications/dolphin/helpers/dolphin_state_filename.h b/applications/dolphin/helpers/dolphin_state_filename.h new file mode 100644 index 00000000..86822c0a --- /dev/null +++ b/applications/dolphin/helpers/dolphin_state_filename.h @@ -0,0 +1,3 @@ +#pragma once + +#define DOLPHIN_STATE_FILE_NAME ".dolphin.state" diff --git a/applications/dolphin/passport/passport.c b/applications/dolphin/passport/passport.c index b9be2d22..d43f150c 100644 --- a/applications/dolphin/passport/passport.c +++ b/applications/dolphin/passport/passport.c @@ -95,12 +95,12 @@ int32_t passport_app(void* p) { ViewPort* view_port = view_port_alloc(); - Dolphin* dolphin = furi_record_open("dolphin"); + Dolphin* dolphin = furi_record_open(RECORD_DOLPHIN); DolphinStats stats = dolphin_stats(dolphin); - furi_record_close("dolphin"); + furi_record_close(RECORD_DOLPHIN); view_port_draw_callback_set(view_port, render_callback, &stats); view_port_input_callback_set(view_port, input_callback, semaphore); - Gui* gui = furi_record_open("gui"); + Gui* gui = furi_record_open(RECORD_GUI); gui_add_view_port(gui, view_port, GuiLayerFullscreen); view_port_update(view_port); @@ -108,7 +108,7 @@ int32_t passport_app(void* p) { gui_remove_view_port(gui, view_port); view_port_free(view_port); - furi_record_close("gui"); + furi_record_close(RECORD_GUI); furi_semaphore_free(semaphore); return 0; diff --git a/applications/gpio/gpio_app.c b/applications/gpio/gpio_app.c index b5f5184a..b8afdc8e 100644 --- a/applications/gpio/gpio_app.c +++ b/applications/gpio/gpio_app.c @@ -24,7 +24,7 @@ static void gpio_app_tick_event_callback(void* context) { GpioApp* gpio_app_alloc() { GpioApp* app = malloc(sizeof(GpioApp)); - app->gui = furi_record_open("gui"); + app->gui = furi_record_open(RECORD_GUI); app->view_dispatcher = view_dispatcher_alloc(); app->scene_manager = scene_manager_alloc(&gpio_scene_handlers, app); @@ -40,7 +40,7 @@ GpioApp* gpio_app_alloc() { view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen); - app->notifications = furi_record_open("notification"); + app->notifications = furi_record_open(RECORD_NOTIFICATION); app->var_item_list = variable_item_list_alloc(); view_dispatcher_add_view( @@ -88,8 +88,8 @@ void gpio_app_free(GpioApp* app) { scene_manager_free(app->scene_manager); // Close records - furi_record_close("gui"); - furi_record_close("notification"); + furi_record_close(RECORD_GUI); + furi_record_close(RECORD_NOTIFICATION); free(app); } diff --git a/applications/gpio/usb_uart_bridge.c b/applications/gpio/usb_uart_bridge.c index c51be513..4623c4af 100644 --- a/applications/gpio/usb_uart_bridge.c +++ b/applications/gpio/usb_uart_bridge.c @@ -86,15 +86,15 @@ static void usb_uart_on_irq_cb(UartIrqEvent ev, uint8_t data, void* context) { static void usb_uart_vcp_init(UsbUartBridge* usb_uart, uint8_t vcp_ch) { furi_hal_usb_unlock(); if(vcp_ch == 0) { - Cli* cli = furi_record_open("cli"); + Cli* cli = furi_record_open(RECORD_CLI); cli_session_close(cli); - furi_record_close("cli"); + furi_record_close(RECORD_CLI); furi_check(furi_hal_usb_set_config(&usb_cdc_single, NULL) == true); } else { furi_check(furi_hal_usb_set_config(&usb_cdc_dual, NULL) == true); - Cli* cli = furi_record_open("cli"); + Cli* cli = furi_record_open(RECORD_CLI); cli_session_open(cli, &cli_vcp); - furi_record_close("cli"); + furi_record_close(RECORD_CLI); } furi_hal_cdc_set_callbacks(vcp_ch, (CdcCallbacks*)&cdc_cb, usb_uart); } @@ -103,9 +103,9 @@ static void usb_uart_vcp_deinit(UsbUartBridge* usb_uart, uint8_t vcp_ch) { UNUSED(usb_uart); furi_hal_cdc_set_callbacks(vcp_ch, NULL, NULL); if(vcp_ch != 0) { - Cli* cli = furi_record_open("cli"); + Cli* cli = furi_record_open(RECORD_CLI); cli_session_close(cli); - furi_record_close("cli"); + furi_record_close(RECORD_CLI); } } @@ -276,9 +276,9 @@ static int32_t usb_uart_worker(void* context) { furi_hal_usb_unlock(); furi_check(furi_hal_usb_set_config(&usb_cdc_single, NULL) == true); - Cli* cli = furi_record_open("cli"); + Cli* cli = furi_record_open(RECORD_CLI); cli_session_open(cli, &cli_vcp); - furi_record_close("cli"); + furi_record_close(RECORD_CLI); return 0; } diff --git a/applications/gui/gui.c b/applications/gui/gui.c index 50df399a..6b4b9a0a 100644 --- a/applications/gui/gui.c +++ b/applications/gui/gui.c @@ -485,7 +485,7 @@ Gui* gui_alloc() { // Input gui->input_queue = furi_message_queue_alloc(8, sizeof(InputEvent)); - gui->input_events = furi_record_open("input_events"); + gui->input_events = furi_record_open(RECORD_INPUT_EVENTS); furi_check(gui->input_events); furi_pubsub_subscribe(gui->input_events, gui_input_events_callback, gui); @@ -497,7 +497,7 @@ int32_t gui_srv(void* p) { UNUSED(p); Gui* gui = gui_alloc(); - furi_record_create("gui", gui); + furi_record_create(RECORD_GUI, gui); while(1) { uint32_t flags = diff --git a/applications/gui/gui.h b/applications/gui/gui.h index e3235242..f4886758 100644 --- a/applications/gui/gui.h +++ b/applications/gui/gui.h @@ -29,6 +29,8 @@ typedef enum { /** Gui Canvas Commit Callback */ typedef void (*GuiCanvasCommitCallback)(uint8_t* data, size_t size, void* context); +#define RECORD_GUI "gui" + typedef struct Gui Gui; /** Add view_port to view_port tree diff --git a/applications/gui/modules/file_browser_worker.c b/applications/gui/modules/file_browser_worker.c index ce3def41..d705e5c3 100644 --- a/applications/gui/modules/file_browser_worker.c +++ b/applications/gui/modules/file_browser_worker.c @@ -13,7 +13,7 @@ #define TAG "BrowserWorker" #define ASSETS_DIR "assets" -#define BROWSER_ROOT "/any" +#define BROWSER_ROOT STORAGE_ANY_PATH_PREFIX #define FILE_NAME_LEN_MAX 256 #define LONG_LOAD_THRESHOLD 100 @@ -53,13 +53,13 @@ struct BrowserWorker { static bool browser_path_is_file(string_t path) { bool state = false; FileInfo file_info; - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); if(storage_common_stat(storage, string_get_cstr(path), &file_info) == FSE_OK) { if((file_info.flags & FSF_DIRECTORY) == 0) { state = true; } } - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); return state; } @@ -97,7 +97,7 @@ static bool browser_filter_by_name(BrowserWorker* browser, string_t name, bool i static bool browser_folder_check_and_switch(string_t path) { FileInfo file_info; - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); bool is_root = false; while(1) { // Check if folder is existing and navigate back if not @@ -111,7 +111,7 @@ static bool browser_folder_check_and_switch(string_t path) { } is_root = browser_path_trim(path); } - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); return is_root; } @@ -125,7 +125,7 @@ static bool browser_folder_init( FileInfo file_info; uint32_t total_files_cnt = 0; - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); File* directory = storage_file_alloc(storage); char name_temp[FILE_NAME_LEN_MAX]; @@ -167,7 +167,7 @@ static bool browser_folder_init( storage_dir_close(directory); storage_file_free(directory); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); return state; } @@ -176,7 +176,7 @@ static bool browser_folder_load(BrowserWorker* browser, string_t path, uint32_t offset, uint32_t count) { FileInfo file_info; - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); File* directory = storage_file_alloc(storage); char name_temp[FILE_NAME_LEN_MAX]; @@ -241,7 +241,7 @@ static bool storage_dir_close(directory); storage_file_free(directory); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); return (items_cnt == count); } diff --git a/applications/gui/modules/validators.c b/applications/gui/modules/validators.c index 546423d0..ac293f8c 100644 --- a/applications/gui/modules/validators.c +++ b/applications/gui/modules/validators.c @@ -21,7 +21,7 @@ bool validator_is_file_callback(const char* text, string_t error, void* context) bool ret = true; string_t path; string_init_printf(path, "%s/%s%s", instance->app_path_folder, text, instance->app_extension); - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); if(storage_common_stat(storage, string_get_cstr(path), NULL) == FSE_OK) { ret = false; string_printf(error, "This name\nexists!\nChoose\nanother one."); @@ -29,7 +29,7 @@ bool validator_is_file_callback(const char* text, string_t error, void* context) ret = true; } string_clear(path); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); return ret; } diff --git a/applications/ibutton/ibutton.c b/applications/ibutton/ibutton.c index 0f14137c..30accd46 100644 --- a/applications/ibutton/ibutton.c +++ b/applications/ibutton/ibutton.c @@ -163,11 +163,11 @@ iButton* ibutton_alloc() { view_dispatcher_set_tick_event_callback( ibutton->view_dispatcher, ibutton_tick_event_callback, 100); - ibutton->gui = furi_record_open("gui"); + ibutton->gui = furi_record_open(RECORD_GUI); - ibutton->storage = furi_record_open("storage"); - ibutton->dialogs = furi_record_open("dialogs"); - ibutton->notifications = furi_record_open("notification"); + ibutton->storage = furi_record_open(RECORD_STORAGE); + ibutton->dialogs = furi_record_open(RECORD_DIALOGS); + ibutton->notifications = furi_record_open(RECORD_NOTIFICATION); ibutton->key = ibutton_key_alloc(); ibutton->key_worker = ibutton_worker_alloc(); @@ -224,16 +224,16 @@ void ibutton_free(iButton* ibutton) { view_dispatcher_free(ibutton->view_dispatcher); scene_manager_free(ibutton->scene_manager); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); ibutton->storage = NULL; - furi_record_close("notification"); + furi_record_close(RECORD_NOTIFICATION); ibutton->notifications = NULL; - furi_record_close("dialogs"); + furi_record_close(RECORD_DIALOGS); ibutton->dialogs = NULL; - furi_record_close("gui"); + furi_record_close(RECORD_GUI); ibutton->gui = NULL; ibutton_worker_stop_thread(ibutton->key_worker); diff --git a/applications/ibutton/ibutton_cli.c b/applications/ibutton/ibutton_cli.c index 324c636d..d36d3dff 100644 --- a/applications/ibutton/ibutton_cli.c +++ b/applications/ibutton/ibutton_cli.c @@ -12,10 +12,10 @@ static void onewire_cli(Cli* cli, string_t args, void* context); // app cli function void ibutton_on_system_start() { #ifdef SRV_CLI - Cli* cli = furi_record_open("cli"); + Cli* cli = furi_record_open(RECORD_CLI); cli_add_command(cli, "ikey", CliCommandFlagDefault, ibutton_cli, cli); cli_add_command(cli, "onewire", CliCommandFlagDefault, onewire_cli, cli); - furi_record_close("cli"); + furi_record_close(RECORD_CLI); #else UNUSED(ibutton_cli); UNUSED(onewire_cli); diff --git a/applications/ibutton/ibutton_i.h b/applications/ibutton/ibutton_i.h index 889d5a67..de3065c3 100644 --- a/applications/ibutton/ibutton_i.h +++ b/applications/ibutton/ibutton_i.h @@ -25,7 +25,7 @@ #define IBUTTON_FILE_NAME_SIZE 100 #define IBUTTON_TEXT_STORE_SIZE 128 -#define IBUTTON_APP_FOLDER "/any/ibutton" +#define IBUTTON_APP_FOLDER ANY_PATH("ibutton") #define IBUTTON_APP_EXTENSION ".ibtn" #define IBUTTON_APP_FILE_TYPE "Flipper iButton key" diff --git a/applications/infrared/infrared.c b/applications/infrared/infrared.c index cd4c148c..f211f006 100644 --- a/applications/infrared/infrared.c +++ b/applications/infrared/infrared.c @@ -85,7 +85,7 @@ static bool } static void infrared_find_vacant_remote_name(string_t name, const char* path) { - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); string_t base_path; string_init_set_str(base_path, path); @@ -122,7 +122,7 @@ static void infrared_find_vacant_remote_name(string_t name, const char* path) { } string_clear(base_path); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); } static Infrared* infrared_alloc() { @@ -140,7 +140,7 @@ static Infrared* infrared_alloc() { infrared->scene_manager = scene_manager_alloc(&infrared_scene_handlers, infrared); infrared->view_dispatcher = view_dispatcher_alloc(); - infrared->gui = furi_record_open("gui"); + infrared->gui = furi_record_open(RECORD_GUI); ViewDispatcher* view_dispatcher = infrared->view_dispatcher; view_dispatcher_enable_queue(view_dispatcher); @@ -149,9 +149,9 @@ static Infrared* infrared_alloc() { view_dispatcher_set_navigation_event_callback(view_dispatcher, infrared_back_event_callback); view_dispatcher_set_tick_event_callback(view_dispatcher, infrared_tick_event_callback, 100); - infrared->storage = furi_record_open("storage"); - infrared->dialogs = furi_record_open("dialogs"); - infrared->notifications = furi_record_open("notification"); + infrared->storage = furi_record_open(RECORD_STORAGE); + infrared->dialogs = furi_record_open(RECORD_DIALOGS); + infrared->notifications = furi_record_open(RECORD_NOTIFICATION); infrared->worker = infrared_worker_alloc(); infrared->remote = infrared_remote_alloc(); @@ -242,16 +242,16 @@ static void infrared_free(Infrared* infrared) { infrared_remote_free(infrared->remote); infrared_worker_free(infrared->worker); - furi_record_close("gui"); + furi_record_close(RECORD_GUI); infrared->gui = NULL; - furi_record_close("notification"); + furi_record_close(RECORD_NOTIFICATION); infrared->notifications = NULL; - furi_record_close("dialogs"); + furi_record_close(RECORD_DIALOGS); infrared->dialogs = NULL; - furi_record_close("gui"); + furi_record_close(RECORD_GUI); infrared->gui = NULL; string_clear(infrared->file_path); @@ -302,7 +302,7 @@ bool infrared_rename_current_remote(Infrared* infrared, const char* name) { } string_cat_printf(new_path, "/%s%s", string_get_cstr(new_name), INFRARED_APP_EXTENSION); - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); FS_Error status = storage_common_rename( storage, infrared_remote_get_path(remote), string_get_cstr(new_path)); @@ -312,7 +312,7 @@ bool infrared_rename_current_remote(Infrared* infrared, const char* name) { string_clear(new_name); string_clear(new_path); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); return (status == FSE_OK || status == FSE_EXIST); } diff --git a/applications/infrared/infrared_brute_force.c b/applications/infrared/infrared_brute_force.c index 1e5f557a..8dbc2301 100644 --- a/applications/infrared/infrared_brute_force.c +++ b/applications/infrared/infrared_brute_force.c @@ -50,7 +50,7 @@ bool infrared_brute_force_calculate_messages(InfraredBruteForce* brute_force) { furi_assert(brute_force->db_filename); bool success = false; - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); FlipperFormat* ff = flipper_format_buffered_file_alloc(storage); success = flipper_format_buffered_file_open_existing(ff, brute_force->db_filename); @@ -68,7 +68,7 @@ bool infrared_brute_force_calculate_messages(InfraredBruteForce* brute_force) { } flipper_format_free(ff); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); return success; } @@ -94,14 +94,14 @@ bool infrared_brute_force_start( } if(*record_count) { - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); brute_force->ff = flipper_format_buffered_file_alloc(storage); success = flipper_format_buffered_file_open_existing(brute_force->ff, brute_force->db_filename); if(!success) { flipper_format_free(brute_force->ff); brute_force->ff = NULL; - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); } } return success; @@ -117,7 +117,7 @@ void infrared_brute_force_stop(InfraredBruteForce* brute_force) { string_reset(brute_force->current_record_name); flipper_format_free(brute_force->ff); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); brute_force->ff = NULL; } diff --git a/applications/infrared/infrared_cli.c b/applications/infrared/infrared_cli.c index a2dfc2a3..c190aad3 100644 --- a/applications/infrared/infrared_cli.c +++ b/applications/infrared/infrared_cli.c @@ -192,9 +192,9 @@ static void infrared_cli_start_ir(Cli* cli, string_t args, void* context) { } void infrared_on_system_start() { #ifdef SRV_CLI - Cli* cli = (Cli*)furi_record_open("cli"); + Cli* cli = (Cli*)furi_record_open(RECORD_CLI); cli_add_command(cli, "ir", CliCommandFlagDefault, infrared_cli_start_ir, NULL); - furi_record_close("cli"); + furi_record_close(RECORD_CLI); #else UNUSED(infrared_cli_start_ir); #endif diff --git a/applications/infrared/infrared_i.h b/applications/infrared/infrared_i.h index c47753f8..d24cab06 100644 --- a/applications/infrared/infrared_i.h +++ b/applications/infrared/infrared_i.h @@ -39,7 +39,7 @@ #define INFRARED_MAX_BUTTON_NAME_LENGTH 22 #define INFRARED_MAX_REMOTE_NAME_LENGTH 22 -#define INFRARED_APP_FOLDER "/any/infrared" +#define INFRARED_APP_FOLDER ANY_PATH("infrared") #define INFRARED_APP_EXTENSION ".ir" #define INFRARED_DEFAULT_REMOTE_NAME "Remote" diff --git a/applications/infrared/infrared_remote.c b/applications/infrared/infrared_remote.c index 957e2457..4417c3c7 100644 --- a/applications/infrared/infrared_remote.c +++ b/applications/infrared/infrared_remote.c @@ -110,7 +110,7 @@ bool infrared_remote_delete_button(InfraredRemote* remote, size_t index) { } bool infrared_remote_store(InfraredRemote* remote) { - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); FlipperFormat* ff = flipper_format_file_alloc(storage); const char* path = string_get_cstr(remote->path); @@ -134,12 +134,12 @@ bool infrared_remote_store(InfraredRemote* remote) { } flipper_format_free(ff); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); return success; } bool infrared_remote_load(InfraredRemote* remote, string_t path) { - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); FlipperFormat* ff = flipper_format_buffered_file_alloc(storage); string_t buf; @@ -174,16 +174,16 @@ bool infrared_remote_load(InfraredRemote* remote, string_t path) { string_clear(buf); flipper_format_free(ff); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); return success; } bool infrared_remote_remove(InfraredRemote* remote) { - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); FS_Error status = storage_common_remove(storage, string_get_cstr(remote->path)); infrared_remote_reset(remote); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); return (status == FSE_OK || status == FSE_NOT_EXIST); } diff --git a/applications/infrared/scenes/infrared_scene_universal_tv.c b/applications/infrared/scenes/infrared_scene_universal_tv.c index 83b084c3..583f21fa 100644 --- a/applications/infrared/scenes/infrared_scene_universal_tv.c +++ b/applications/infrared/scenes/infrared_scene_universal_tv.c @@ -9,7 +9,7 @@ void infrared_scene_universal_tv_on_enter(void* context) { ButtonPanel* button_panel = infrared->button_panel; InfraredBruteForce* brute_force = infrared->brute_force; - infrared_brute_force_set_db_filename(brute_force, "/ext/infrared/assets/tv.ir"); + infrared_brute_force_set_db_filename(brute_force, EXT_PATH("infrared/assets/tv.ir")); button_panel_reserve(button_panel, 2, 3); uint32_t i = 0; diff --git a/applications/input/input.c b/applications/input/input.c index 7270a020..27e7bf21 100644 --- a/applications/input/input.c +++ b/applications/input/input.c @@ -68,10 +68,10 @@ int32_t input_srv() { input = malloc(sizeof(Input)); input->thread_id = furi_thread_get_current_id(); input->event_pubsub = furi_pubsub_alloc(); - furi_record_create("input_events", input->event_pubsub); + furi_record_create(RECORD_INPUT_EVENTS, input->event_pubsub); #ifdef SRV_CLI - input->cli = furi_record_open("cli"); + input->cli = furi_record_open(RECORD_CLI); if(input->cli) { cli_add_command(input->cli, "input", CliCommandFlagParallelSafe, input_cli, input); } diff --git a/applications/input/input.h b/applications/input/input.h index ad5263a8..001ab1e2 100644 --- a/applications/input/input.h +++ b/applications/input/input.h @@ -7,6 +7,8 @@ #include +#define RECORD_INPUT_EVENTS "input_events" + /** Input Types * Some of them are physical events and some logical */ diff --git a/applications/lfrfid/lfrfid_app.cpp b/applications/lfrfid/lfrfid_app.cpp index 2ba36ea3..329f052b 100644 --- a/applications/lfrfid/lfrfid_app.cpp +++ b/applications/lfrfid/lfrfid_app.cpp @@ -27,7 +27,7 @@ #include "rpc/rpc_app.h" -const char* LfRfidApp::app_folder = "/any/lfrfid"; +const char* LfRfidApp::app_folder = ANY_PATH("lfrfid"); const char* LfRfidApp::app_extension = ".rfid"; const char* LfRfidApp::app_filetype = "Flipper RFID key"; diff --git a/applications/loader/loader.c b/applications/loader/loader.c index f5db5586..3f4e876f 100644 --- a/applications/loader/loader.c +++ b/applications/loader/loader.c @@ -290,8 +290,9 @@ static Loader* loader_alloc() { instance->pubsub = furi_pubsub_alloc(); #ifdef SRV_CLI - instance->cli = furi_record_open("cli"); - cli_add_command(instance->cli, "loader", CliCommandFlagParallelSafe, loader_cli, instance); + instance->cli = furi_record_open(RECORD_CLI); + cli_add_command( + instance->cli, RECORD_LOADER, CliCommandFlagParallelSafe, loader_cli, instance); #else UNUSED(loader_cli); #endif @@ -299,7 +300,7 @@ static Loader* loader_alloc() { instance->loader_thread = furi_thread_get_current_id(); // Gui - instance->gui = furi_record_open("gui"); + instance->gui = furi_record_open(RECORD_GUI); instance->view_dispatcher = view_dispatcher_alloc(); view_dispatcher_attach_to_gui( instance->view_dispatcher, instance->gui, ViewDispatcherTypeFullscreen); @@ -343,7 +344,7 @@ static void loader_free(Loader* instance) { furi_assert(instance); if(instance->cli) { - furi_record_close("cli"); + furi_record_close(RECORD_CLI); } furi_pubsub_free(instance->pubsub); @@ -360,7 +361,7 @@ static void loader_free(Loader* instance) { view_dispatcher_remove_view(loader_instance->view_dispatcher, LoaderMenuViewSettings); view_dispatcher_free(loader_instance->view_dispatcher); - furi_record_close("gui"); + furi_record_close(RECORD_GUI); free(instance); instance = NULL; @@ -463,7 +464,7 @@ int32_t loader_srv(void* p) { FURI_LOG_I(TAG, "Started"); - furi_record_create("loader", loader_instance); + furi_record_create(RECORD_LOADER, loader_instance); #ifdef LOADER_AUTOSTART loader_start(loader_instance, LOADER_AUTOSTART, NULL); @@ -480,7 +481,7 @@ int32_t loader_srv(void* p) { } } - furi_record_destroy("loader"); + furi_record_destroy(RECORD_LOADER); loader_free(loader_instance); return 0; diff --git a/applications/loader/loader.h b/applications/loader/loader.h index 4bf835b4..8f95d81b 100644 --- a/applications/loader/loader.h +++ b/applications/loader/loader.h @@ -3,6 +3,8 @@ #include #include +#define RECORD_LOADER "loader" + typedef struct Loader Loader; typedef enum { diff --git a/applications/music_player/music_player.c b/applications/music_player/music_player.c index 26dfb812..ffdd2bea 100644 --- a/applications/music_player/music_player.c +++ b/applications/music_player/music_player.c @@ -1,15 +1,18 @@ -#include "assets_icons.h" -#include "m-string.h" +#include "music_player_worker.h" + #include #include +#include #include #include -#include "music_player_worker.h" +#include + +#include #define TAG "MusicPlayer" -#define MUSIC_PLAYER_APP_PATH_FOLDER "/any/music_player" +#define MUSIC_PLAYER_APP_PATH_FOLDER ANY_PATH("music_player") #define MUSIC_PLAYER_APP_EXTENSION "*" #define MUSIC_PLAYER_SEMITONE_HISTORY_SIZE 4 @@ -269,7 +272,7 @@ MusicPlayer* music_player_alloc() { view_port_input_callback_set(instance->view_port, input_callback, instance); // Open GUI and register view_port - instance->gui = furi_record_open("gui"); + instance->gui = furi_record_open(RECORD_GUI); gui_add_view_port(instance->gui, instance->view_port, GuiLayerFullscreen); return instance; @@ -277,7 +280,7 @@ MusicPlayer* music_player_alloc() { void music_player_free(MusicPlayer* instance) { gui_remove_view_port(instance->gui, instance->view_port); - furi_record_close("gui"); + furi_record_close(RECORD_GUI); view_port_free(instance->view_port); music_player_worker_free(instance->worker); @@ -302,7 +305,7 @@ int32_t music_player_app(void* p) { } else { string_set_str(file_path, MUSIC_PLAYER_APP_PATH_FOLDER); - DialogsApp* dialogs = furi_record_open("dialogs"); + DialogsApp* dialogs = furi_record_open(RECORD_DIALOGS); bool res = dialog_file_browser_show( dialogs, file_path, @@ -312,7 +315,7 @@ int32_t music_player_app(void* p) { &I_music_10px, false); - furi_record_close("dialogs"); + furi_record_close(RECORD_DIALOGS); if(!res) { FURI_LOG_E(TAG, "No file selected"); break; diff --git a/applications/music_player/music_player_cli.c b/applications/music_player/music_player_cli.c index 986c8781..78200443 100644 --- a/applications/music_player/music_player_cli.c +++ b/applications/music_player/music_player_cli.c @@ -6,7 +6,7 @@ static void music_player_cli(Cli* cli, string_t args, void* context) { UNUSED(context); MusicPlayerWorker* music_player_worker = music_player_worker_alloc(); - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); do { if(storage_common_stat(storage, string_get_cstr(args), NULL) == FSE_OK) { @@ -31,17 +31,17 @@ static void music_player_cli(Cli* cli, string_t args, void* context) { music_player_worker_stop(music_player_worker); } while(0); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); music_player_worker_free(music_player_worker); } void music_player_on_system_start() { #ifdef SRV_CLI - Cli* cli = furi_record_open("cli"); + Cli* cli = furi_record_open(RECORD_CLI); cli_add_command(cli, "music_player", CliCommandFlagDefault, music_player_cli, NULL); - furi_record_close("cli"); + furi_record_close(RECORD_CLI); #else UNUSED(music_player_cli); #endif diff --git a/applications/music_player/music_player_worker.c b/applications/music_player/music_player_worker.c index 835745b7..ca4f1d8c 100644 --- a/applications/music_player/music_player_worker.c +++ b/applications/music_player/music_player_worker.c @@ -329,7 +329,7 @@ bool music_player_worker_load_fmf_from_file(MusicPlayerWorker* instance, const c string_t temp_str; string_init(temp_str); - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); FlipperFormat* file = flipper_format_file_alloc(storage); do { @@ -367,7 +367,7 @@ bool music_player_worker_load_fmf_from_file(MusicPlayerWorker* instance, const c result = true; } while(false); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); flipper_format_free(file); string_clear(temp_str); @@ -381,7 +381,7 @@ bool music_player_worker_load_rtttl_from_file(MusicPlayerWorker* instance, const bool result = false; string_t content; string_init(content); - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); File* file = storage_file_alloc(storage); do { @@ -414,7 +414,7 @@ bool music_player_worker_load_rtttl_from_file(MusicPlayerWorker* instance, const } while(0); storage_file_free(file); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); string_clear(content); return result; diff --git a/applications/nfc/helpers/nfc_debug_pcap.c b/applications/nfc/helpers/nfc_debug_pcap.c index d340791b..48d72bfb 100644 --- a/applications/nfc/helpers/nfc_debug_pcap.c +++ b/applications/nfc/helpers/nfc_debug_pcap.c @@ -15,7 +15,7 @@ #define DATA_PICC_TO_PCD_CRC_DROPPED 0xFB #define DATA_PCD_TO_PICC_CRC_DROPPED 0xFA -#define NFC_DEBUG_PCAP_FILENAME "/ext/nfc/debug.pcap" +#define NFC_DEBUG_PCAP_FILENAME EXT_PATH("nfc/debug.pcap") #define NFC_DEBUG_PCAP_BUFFER_SIZE 64 struct NfcDebugPcapWorker { diff --git a/applications/nfc/helpers/nfc_emv_parser.c b/applications/nfc/helpers/nfc_emv_parser.c index 2e060999..0d7cb5a3 100755 --- a/applications/nfc/helpers/nfc_emv_parser.c +++ b/applications/nfc/helpers/nfc_emv_parser.c @@ -44,7 +44,7 @@ bool nfc_emv_parser_get_aid_name( for(uint8_t i = 0; i < aid_len; i++) { string_cat_printf(key, "%02X", aid[i]); } - if(nfc_emv_parser_search_data(storage, "/ext/nfc/assets/aid.nfc", key, aid_name)) { + if(nfc_emv_parser_search_data(storage, EXT_PATH("nfc/assets/aid.nfc"), key, aid_name)) { parsed = true; } string_clear(key); @@ -58,7 +58,8 @@ bool nfc_emv_parser_get_country_name( bool parsed = false; string_t key; string_init_printf(key, "%04X", country_code); - if(nfc_emv_parser_search_data(storage, "/ext/nfc/assets/country_code.nfc", key, country_name)) { + if(nfc_emv_parser_search_data( + storage, EXT_PATH("nfc/assets/country_code.nfc"), key, country_name)) { parsed = true; } string_clear(key); @@ -73,7 +74,7 @@ bool nfc_emv_parser_get_currency_name( string_t key; string_init_printf(key, "%04X", currency_code); if(nfc_emv_parser_search_data( - storage, "/ext/nfc/assets/currency_code.nfc", key, currency_name)) { + storage, EXT_PATH("nfc/assets/currency_code.nfc"), key, currency_name)) { parsed = true; } string_clear(key); diff --git a/applications/nfc/helpers/nfc_mf_classic_dict.c b/applications/nfc/helpers/nfc_mf_classic_dict.c index e9cfff39..be77dede 100644 --- a/applications/nfc/helpers/nfc_mf_classic_dict.c +++ b/applications/nfc/helpers/nfc_mf_classic_dict.c @@ -3,7 +3,7 @@ #include #include -#define NFC_MF_CLASSIC_DICT_PATH "/ext/nfc/assets/mf_classic_dict.nfc" +#define NFC_MF_CLASSIC_DICT_PATH EXT_PATH("nfc/assets/mf_classic_dict.nfc") #define NFC_MF_CLASSIC_KEY_LEN (13) diff --git a/applications/nfc/nfc.c b/applications/nfc/nfc.c index fb739c61..f6af3573 100644 --- a/applications/nfc/nfc.c +++ b/applications/nfc/nfc.c @@ -108,10 +108,10 @@ Nfc* nfc_alloc() { nfc->dev = nfc_device_alloc(); // Open GUI record - nfc->gui = furi_record_open("gui"); + nfc->gui = furi_record_open(RECORD_GUI); // Open Notification record - nfc->notifications = furi_record_open("notification"); + nfc->notifications = furi_record_open(RECORD_NOTIFICATION); // Submenu nfc->submenu = submenu_alloc(); @@ -224,11 +224,11 @@ void nfc_free(Nfc* nfc) { scene_manager_free(nfc->scene_manager); // GUI - furi_record_close("gui"); + furi_record_close(RECORD_GUI); nfc->gui = NULL; // Notifications - furi_record_close("notification"); + furi_record_close(RECORD_NOTIFICATION); nfc->notifications = NULL; free(nfc); diff --git a/applications/nfc/nfc_cli.c b/applications/nfc/nfc_cli.c index bed00776..133bd558 100755 --- a/applications/nfc/nfc_cli.c +++ b/applications/nfc/nfc_cli.c @@ -131,9 +131,9 @@ static void nfc_cli(Cli* cli, string_t args, void* context) { void nfc_on_system_start() { #ifdef SRV_CLI - Cli* cli = furi_record_open("cli"); + Cli* cli = furi_record_open(RECORD_CLI); cli_add_command(cli, "nfc", CliCommandFlagDefault, nfc_cli, NULL); - furi_record_close("cli"); + furi_record_close(RECORD_CLI); #else UNUSED(nfc_cli); #endif diff --git a/applications/nfc/nfc_device.c b/applications/nfc/nfc_device.c index e4f9ac56..a3bff23a 100644 --- a/applications/nfc/nfc_device.c +++ b/applications/nfc/nfc_device.c @@ -14,8 +14,8 @@ static const uint32_t nfc_mifare_classic_data_format_version = 1; NfcDevice* nfc_device_alloc() { NfcDevice* nfc_dev = malloc(sizeof(NfcDevice)); - nfc_dev->storage = furi_record_open("storage"); - nfc_dev->dialogs = furi_record_open("dialogs"); + nfc_dev->storage = furi_record_open(RECORD_STORAGE); + nfc_dev->dialogs = furi_record_open(RECORD_DIALOGS); string_init(nfc_dev->load_path); return nfc_dev; } @@ -23,8 +23,8 @@ NfcDevice* nfc_device_alloc() { void nfc_device_free(NfcDevice* nfc_dev) { furi_assert(nfc_dev); nfc_device_clear(nfc_dev); - furi_record_close("storage"); - furi_record_close("dialogs"); + furi_record_close(RECORD_STORAGE); + furi_record_close(RECORD_DIALOGS); string_clear(nfc_dev->load_path); free(nfc_dev); } diff --git a/applications/nfc/nfc_device.h b/applications/nfc/nfc_device.h index fee9b07e..5ffca5ca 100644 --- a/applications/nfc/nfc_device.h +++ b/applications/nfc/nfc_device.h @@ -14,7 +14,7 @@ #define NFC_DEV_NAME_MAX_LEN 22 #define NFC_READER_DATA_MAX_SIZE 64 -#define NFC_APP_FOLDER "/any/nfc" +#define NFC_APP_FOLDER ANY_PATH("nfc") #define NFC_APP_EXTENSION ".nfc" #define NFC_APP_SHADOW_EXTENSION ".shd" diff --git a/applications/nfc/nfc_worker.c b/applications/nfc/nfc_worker.c index 0ca26736..df1b5faf 100644 --- a/applications/nfc/nfc_worker.c +++ b/applications/nfc/nfc_worker.c @@ -19,7 +19,7 @@ NfcWorker* nfc_worker_alloc() { nfc_worker->callback = NULL; nfc_worker->context = NULL; - nfc_worker->storage = furi_record_open("storage"); + nfc_worker->storage = furi_record_open(RECORD_STORAGE); // Initialize rfal while(furi_hal_nfc_is_busy()) { @@ -39,7 +39,7 @@ void nfc_worker_free(NfcWorker* nfc_worker) { furi_thread_free(nfc_worker->thread); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); if(nfc_worker->debug_pcap_worker) nfc_debug_pcap_free(nfc_worker->debug_pcap_worker); diff --git a/applications/notification/notification.h b/applications/notification/notification.h index 14ca0ac2..b38620f0 100644 --- a/applications/notification/notification.h +++ b/applications/notification/notification.h @@ -7,6 +7,8 @@ extern "C" { #endif +#define RECORD_NOTIFICATION "notification" + typedef struct NotificationApp NotificationApp; typedef struct { float frequency; diff --git a/applications/notification/notification_app.c b/applications/notification/notification_app.c index 437d20ab..640bd7d7 100644 --- a/applications/notification/notification_app.c +++ b/applications/notification/notification_app.c @@ -398,7 +398,7 @@ void notification_process_internal_message(NotificationApp* app, NotificationApp static bool notification_load_settings(NotificationApp* app) { NotificationSettings settings; - File* file = storage_file_alloc(furi_record_open("storage")); + File* file = storage_file_alloc(furi_record_open(RECORD_STORAGE)); const size_t settings_size = sizeof(NotificationSettings); FURI_LOG_I(TAG, "loading settings from \"%s\"", NOTIFICATION_SETTINGS_PATH); @@ -430,14 +430,14 @@ static bool notification_load_settings(NotificationApp* app) { storage_file_close(file); storage_file_free(file); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); return fs_result; }; static bool notification_save_settings(NotificationApp* app) { NotificationSettings settings; - File* file = storage_file_alloc(furi_record_open("storage")); + File* file = storage_file_alloc(furi_record_open(RECORD_STORAGE)); const size_t settings_size = sizeof(NotificationSettings); FURI_LOG_I(TAG, "saving settings to \"%s\"", NOTIFICATION_SETTINGS_PATH); @@ -465,7 +465,7 @@ static bool notification_save_settings(NotificationApp* app) { storage_file_close(file); storage_file_free(file); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); return fs_result; }; @@ -512,7 +512,7 @@ static NotificationApp* notification_app_alloc() { app->settings.version = NOTIFICATION_SETTINGS_VERSION; // display backlight control - app->event_record = furi_record_open("input_events"); + app->event_record = furi_record_open(RECORD_INPUT_EVENTS); furi_pubsub_subscribe(app->event_record, input_event_callback, app); notification_message(app, &sequence_display_backlight_on); @@ -535,7 +535,7 @@ int32_t notification_srv(void* p) { notification_apply_internal_led_layer(&app->led[1], 0x00); notification_apply_internal_led_layer(&app->led[2], 0x00); - furi_record_create("notification", app); + furi_record_create(RECORD_NOTIFICATION, app); NotificationAppMessage message; while(1) { diff --git a/applications/notification/notification_app.h b/applications/notification/notification_app.h index f5c7cc46..88194bfb 100644 --- a/applications/notification/notification_app.h +++ b/applications/notification/notification_app.h @@ -2,6 +2,7 @@ #include #include "notification.h" #include "notification_messages.h" +#include "notification_settings_filename.h" #define NOTIFICATION_LED_COUNT 3 #define NOTIFICATION_EVENT_COMPLETE 0x00000001U @@ -32,7 +33,7 @@ typedef struct { } NotificationLedLayer; #define NOTIFICATION_SETTINGS_VERSION 0x01 -#define NOTIFICATION_SETTINGS_PATH "/int/notification.settings" +#define NOTIFICATION_SETTINGS_PATH INT_PATH(NOTIFICATION_SETTINGS_FILE_NAME) typedef struct { uint8_t version; diff --git a/applications/notification/notification_settings_app.c b/applications/notification/notification_settings_app.c index bcb1b6a2..894938f4 100644 --- a/applications/notification/notification_settings_app.c +++ b/applications/notification/notification_settings_app.c @@ -126,8 +126,8 @@ static uint32_t notification_app_settings_exit(void* context) { static NotificationAppSettings* alloc_settings() { NotificationAppSettings* app = malloc(sizeof(NotificationAppSettings)); - app->notification = furi_record_open("notification"); - app->gui = furi_record_open("gui"); + app->notification = furi_record_open(RECORD_NOTIFICATION); + app->gui = furi_record_open(RECORD_GUI); app->variable_item_list = variable_item_list_alloc(); View* view = variable_item_list_get_view(app->variable_item_list); @@ -184,8 +184,8 @@ static void free_settings(NotificationAppSettings* app) { variable_item_list_free(app->variable_item_list); view_dispatcher_free(app->view_dispatcher); - furi_record_close("gui"); - furi_record_close("notification"); + furi_record_close(RECORD_GUI); + furi_record_close(RECORD_NOTIFICATION); free(app); } diff --git a/applications/notification/notification_settings_filename.h b/applications/notification/notification_settings_filename.h new file mode 100644 index 00000000..d9ed596e --- /dev/null +++ b/applications/notification/notification_settings_filename.h @@ -0,0 +1,3 @@ +#pragma once + +#define NOTIFICATION_SETTINGS_FILE_NAME ".notification.settings" diff --git a/applications/picopass/picopass.c b/applications/picopass/picopass.c index 19189548..8c0db4e2 100644 --- a/applications/picopass/picopass.c +++ b/applications/picopass/picopass.c @@ -39,12 +39,12 @@ Picopass* picopass_alloc() { picopass->dev = picopass_device_alloc(); // Open GUI record - picopass->gui = furi_record_open("gui"); + picopass->gui = furi_record_open(RECORD_GUI); view_dispatcher_attach_to_gui( picopass->view_dispatcher, picopass->gui, ViewDispatcherTypeFullscreen); // Open Notification record - picopass->notifications = furi_record_open("notification"); + picopass->notifications = furi_record_open(RECORD_NOTIFICATION); // Submenu picopass->submenu = submenu_alloc(); @@ -105,11 +105,11 @@ void picopass_free(Picopass* picopass) { scene_manager_free(picopass->scene_manager); // GUI - furi_record_close("gui"); + furi_record_close(RECORD_GUI); picopass->gui = NULL; // Notifications - furi_record_close("notification"); + furi_record_close(RECORD_NOTIFICATION); picopass->notifications = NULL; free(picopass); diff --git a/applications/picopass/picopass_device.c b/applications/picopass/picopass_device.c index 75d9e290..9b422edd 100644 --- a/applications/picopass/picopass_device.c +++ b/applications/picopass/picopass_device.c @@ -13,8 +13,8 @@ PicopassDevice* picopass_device_alloc() { picopass_dev->dev_data.pacs.legacy = false; picopass_dev->dev_data.pacs.se_enabled = false; picopass_dev->dev_data.pacs.pin_length = 0; - picopass_dev->storage = furi_record_open("storage"); - picopass_dev->dialogs = furi_record_open("dialogs"); + picopass_dev->storage = furi_record_open(RECORD_STORAGE); + picopass_dev->dialogs = furi_record_open(RECORD_DIALOGS); return picopass_dev; } @@ -123,7 +123,7 @@ bool picopass_device_save(PicopassDevice* dev, const char* dev_name) { return picopass_device_save_file( dev, dev_name, PICOPASS_APP_FOLDER, PICOPASS_APP_EXTENSION, true); } else if(dev->format == PicopassDeviceSaveFormatLF) { - return picopass_device_save_file(dev, dev_name, "/any/lfrfid", ".rfid", true); + return picopass_device_save_file(dev, dev_name, ANY_PATH("lfrfid"), ".rfid", true); } return false; } @@ -138,8 +138,8 @@ void picopass_device_clear(PicopassDevice* dev) { void picopass_device_free(PicopassDevice* picopass_dev) { furi_assert(picopass_dev); picopass_device_clear(picopass_dev); - furi_record_close("storage"); - furi_record_close("dialogs"); + furi_record_close(RECORD_STORAGE); + furi_record_close(RECORD_DIALOGS); string_clear(picopass_dev->load_path); free(picopass_dev); } diff --git a/applications/picopass/picopass_device.h b/applications/picopass/picopass_device.h index 326e58e6..89e031ca 100644 --- a/applications/picopass/picopass_device.h +++ b/applications/picopass/picopass_device.h @@ -16,7 +16,7 @@ #define PICOPASS_CONFIG_BLOCK_INDEX 1 #define PICOPASS_AIA_BLOCK_INDEX 5 -#define PICOPASS_APP_FOLDER "/any/picopass" +#define PICOPASS_APP_FOLDER ANY_PATH("picopass") #define PICOPASS_APP_EXTENSION ".picopass" #define PICOPASS_APP_SHADOW_EXTENSION ".pas" diff --git a/applications/picopass/picopass_worker.c b/applications/picopass/picopass_worker.c index 7ecfbc3b..3079a98c 100644 --- a/applications/picopass/picopass_worker.c +++ b/applications/picopass/picopass_worker.c @@ -83,7 +83,7 @@ PicopassWorker* picopass_worker_alloc() { picopass_worker->callback = NULL; picopass_worker->context = NULL; - picopass_worker->storage = furi_record_open("storage"); + picopass_worker->storage = furi_record_open(RECORD_STORAGE); picopass_worker_change_state(picopass_worker, PicopassWorkerStateReady); @@ -95,7 +95,7 @@ void picopass_worker_free(PicopassWorker* picopass_worker) { furi_thread_free(picopass_worker->thread); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); free(picopass_worker); } diff --git a/applications/power/battery_test_app/battery_test_app.c b/applications/power/battery_test_app/battery_test_app.c index f24de32b..0b5bc578 100755 --- a/applications/power/battery_test_app/battery_test_app.c +++ b/applications/power/battery_test_app/battery_test_app.c @@ -35,9 +35,9 @@ BatteryTestApp* battery_test_alloc() { BatteryTestApp* app = malloc(sizeof(BatteryTestApp)); // Records - app->gui = furi_record_open("gui"); - app->power = furi_record_open("power"); - app->notifications = furi_record_open("notification"); + app->gui = furi_record_open(RECORD_GUI); + app->power = furi_record_open(RECORD_POWER); + app->notifications = furi_record_open(RECORD_NOTIFICATION); // View dispatcher app->view_dispatcher = view_dispatcher_alloc(); @@ -82,9 +82,9 @@ void battery_test_free(BatteryTestApp* app) { // View dispatcher view_dispatcher_free(app->view_dispatcher); // Records - furi_record_close("power"); - furi_record_close("gui"); - furi_record_close("notification"); + furi_record_close(RECORD_POWER); + furi_record_close(RECORD_GUI); + furi_record_close(RECORD_NOTIFICATION); free(app); } diff --git a/applications/power/power_cli.c b/applications/power/power_cli.c index 8c6a986d..6af39631 100644 --- a/applications/power/power_cli.c +++ b/applications/power/power_cli.c @@ -8,7 +8,7 @@ void power_cli_off(Cli* cli, string_t args) { UNUSED(cli); UNUSED(args); - Power* power = furi_record_open("power"); + Power* power = furi_record_open(RECORD_POWER); printf("It's now safe to disconnect USB from your flipper\r\n"); furi_delay_ms(666); power_off(power); @@ -138,11 +138,11 @@ void power_cli(Cli* cli, string_t args, void* context) { void power_on_system_start() { #ifdef SRV_CLI - Cli* cli = furi_record_open("cli"); + Cli* cli = furi_record_open(RECORD_CLI); cli_add_command(cli, "power", CliCommandFlagParallelSafe, power_cli, NULL); - furi_record_close("cli"); + furi_record_close(RECORD_CLI); #else UNUSED(power_cli); #endif diff --git a/applications/power/power_service/power.c b/applications/power/power_service/power.c index 991c2a81..ac68bfd7 100644 --- a/applications/power/power_service/power.c +++ b/applications/power/power_service/power.c @@ -41,8 +41,8 @@ Power* power_alloc() { Power* power = malloc(sizeof(Power)); // Records - power->notification = furi_record_open("notification"); - power->gui = furi_record_open("gui"); + power->notification = furi_record_open(RECORD_NOTIFICATION); + power->gui = furi_record_open(RECORD_GUI); // Pubsub power->event_pubsub = furi_pubsub_alloc(); @@ -89,8 +89,8 @@ void power_free(Power* power) { furi_pubsub_free(power->event_pubsub); // Records - furi_record_close("notification"); - furi_record_close("gui"); + furi_record_close(RECORD_NOTIFICATION); + furi_record_close(RECORD_GUI); free(power); } @@ -203,7 +203,7 @@ int32_t power_srv(void* p) { (void)p; Power* power = power_alloc(); power_update_info(power); - furi_record_create("power", power); + furi_record_create(RECORD_POWER, power); while(1) { // Update data from gauge and charger diff --git a/applications/power/power_service/power.h b/applications/power/power_service/power.h index cea1663f..c516f28f 100644 --- a/applications/power/power_service/power.h +++ b/applications/power/power_service/power.h @@ -4,6 +4,8 @@ #include #include +#define RECORD_POWER "power" + typedef struct Power Power; typedef enum { diff --git a/applications/power/power_settings_app/power_settings_app.c b/applications/power/power_settings_app/power_settings_app.c index 3edf3837..92c63704 100644 --- a/applications/power/power_settings_app/power_settings_app.c +++ b/applications/power/power_settings_app/power_settings_app.c @@ -22,8 +22,8 @@ PowerSettingsApp* power_settings_app_alloc(uint32_t first_scene) { PowerSettingsApp* app = malloc(sizeof(PowerSettingsApp)); // Records - app->gui = furi_record_open("gui"); - app->power = furi_record_open("power"); + app->gui = furi_record_open(RECORD_GUI); + app->power = furi_record_open(RECORD_POWER); // View dispatcher app->view_dispatcher = view_dispatcher_alloc(); @@ -69,8 +69,8 @@ void power_settings_app_free(PowerSettingsApp* app) { view_dispatcher_free(app->view_dispatcher); scene_manager_free(app->scene_manager); // Records - furi_record_close("power"); - furi_record_close("gui"); + furi_record_close(RECORD_POWER); + furi_record_close(RECORD_GUI); free(app); } diff --git a/applications/rpc/rpc.c b/applications/rpc/rpc.c index a85d0a42..f241a678 100644 --- a/applications/rpc/rpc.c +++ b/applications/rpc/rpc.c @@ -655,11 +655,11 @@ int32_t rpc_srv(void* p) { rpc->busy_mutex = furi_mutex_alloc(FuriMutexTypeNormal); - Cli* cli = furi_record_open("cli"); + Cli* cli = furi_record_open(RECORD_CLI); cli_add_command( cli, "start_rpc_session", CliCommandFlagParallelSafe, rpc_cli_command_start_session, rpc); - furi_record_create("rpc", rpc); + furi_record_create(RECORD_RPC, rpc); return 0; } diff --git a/applications/rpc/rpc.h b/applications/rpc/rpc.h index 38dd9af3..dea8b749 100644 --- a/applications/rpc/rpc.h +++ b/applications/rpc/rpc.h @@ -8,6 +8,8 @@ #define RPC_BUFFER_SIZE (1024) #define RPC_MAX_MESSAGE_SIZE (1536) +#define RECORD_RPC "rpc" + /** Rpc interface. Used for opening session only. */ typedef struct Rpc Rpc; /** Rpc session interface */ diff --git a/applications/rpc/rpc_app.c b/applications/rpc/rpc_app.c index 525eedcf..e349e61c 100644 --- a/applications/rpc/rpc_app.c +++ b/applications/rpc/rpc_app.c @@ -39,7 +39,7 @@ static void rpc_system_app_start_process(const PB_Main* request, void* context) PB_CommandStatus result = PB_CommandStatus_ERROR_APP_CANT_START; - Loader* loader = furi_record_open("loader"); + Loader* loader = furi_record_open(RECORD_LOADER); const char* app_name = request->content.app_start_request.name; if(app_name) { const char* app_args = request->content.app_start_request.args; @@ -64,7 +64,7 @@ static void rpc_system_app_start_process(const PB_Main* request, void* context) result = PB_CommandStatus_ERROR_INVALID_PARAMETERS; } - furi_record_close("loader"); + furi_record_close(RECORD_LOADER); rpc_send_and_release_empty(session, request->command_id, result); } @@ -80,7 +80,7 @@ static void rpc_system_app_lock_status_process(const PB_Main* request, void* con FURI_LOG_D(TAG, "LockStatus"); - Loader* loader = furi_record_open("loader"); + Loader* loader = furi_record_open(RECORD_LOADER); PB_Main response = { .has_next = false, @@ -91,7 +91,7 @@ static void rpc_system_app_lock_status_process(const PB_Main* request, void* con response.content.app_lock_status_response.locked = loader_is_locked(loader); - furi_record_close("loader"); + furi_record_close(RECORD_LOADER); rpc_send_and_release(session, &response); pb_release(&PB_Main_msg, &response); diff --git a/applications/rpc/rpc_gui.c b/applications/rpc/rpc_gui.c index 62a232d8..029ed010 100644 --- a/applications/rpc/rpc_gui.c +++ b/applications/rpc/rpc_gui.c @@ -198,10 +198,10 @@ static void return; } - FuriPubSub* input_events = furi_record_open("input_events"); + FuriPubSub* input_events = furi_record_open(RECORD_INPUT_EVENTS); furi_check(input_events); furi_pubsub_publish(input_events, &event); - furi_record_close("input_events"); + furi_record_close(RECORD_INPUT_EVENTS); rpc_send_and_release_empty(session, request->command_id, PB_CommandStatus_OK); } @@ -317,7 +317,7 @@ void* rpc_system_gui_alloc(RpcSession* session) { furi_assert(session); RpcGuiSystem* rpc_gui = malloc(sizeof(RpcGuiSystem)); - rpc_gui->gui = furi_record_open("gui"); + rpc_gui->gui = furi_record_open(RECORD_GUI); rpc_gui->session = session; RpcHandler rpc_handler = { @@ -374,6 +374,6 @@ void rpc_system_gui_free(void* context) { free(rpc_gui->transmit_frame); rpc_gui->transmit_frame = NULL; } - furi_record_close("gui"); + furi_record_close(RECORD_GUI); free(rpc_gui); } diff --git a/applications/rpc/rpc_storage.c b/applications/rpc/rpc_storage.c index 4ab681ae..89c94b03 100644 --- a/applications/rpc/rpc_storage.c +++ b/applications/rpc/rpc_storage.c @@ -49,7 +49,7 @@ static void rpc_system_storage_reset_state( if(rpc_storage->state == RpcStorageStateWriting) { storage_file_close(rpc_storage->file); storage_file_free(rpc_storage->file); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); } rpc_storage->state = RpcStorageStateIdle; @@ -117,7 +117,7 @@ static void rpc_system_storage_info_process(const PB_Main* request, void* contex PB_Main* response = malloc(sizeof(PB_Main)); response->command_id = request->command_id; - Storage* fs_api = furi_record_open("storage"); + Storage* fs_api = furi_record_open(RECORD_STORAGE); FS_Error error = storage_common_fs_info( fs_api, @@ -134,7 +134,7 @@ static void rpc_system_storage_info_process(const PB_Main* request, void* contex rpc_send_and_release(session, response); free(response); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); } static void rpc_system_storage_stat_process(const PB_Main* request, void* context) { @@ -153,7 +153,7 @@ static void rpc_system_storage_stat_process(const PB_Main* request, void* contex PB_Main* response = malloc(sizeof(PB_Main)); response->command_id = request->command_id; - Storage* fs_api = furi_record_open("storage"); + Storage* fs_api = furi_record_open(RECORD_STORAGE); const char* path = request->content.storage_stat_request.path; FileInfo fileinfo; @@ -173,7 +173,7 @@ static void rpc_system_storage_stat_process(const PB_Main* request, void* contex rpc_send_and_release(session, response); free(response); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); } static void rpc_system_storage_list_root(const PB_Main* request, void* context) { @@ -222,7 +222,7 @@ static void rpc_system_storage_list_process(const PB_Main* request, void* contex return; } - Storage* fs_api = furi_record_open("storage"); + Storage* fs_api = furi_record_open(RECORD_STORAGE); File* dir = storage_file_alloc(fs_api); PB_Main response = { @@ -276,7 +276,7 @@ static void rpc_system_storage_list_process(const PB_Main* request, void* contex storage_dir_close(dir); storage_file_free(dir); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); } static void rpc_system_storage_read_process(const PB_Main* request, void* context) { @@ -295,7 +295,7 @@ static void rpc_system_storage_read_process(const PB_Main* request, void* contex /* use same message memory to send reponse */ PB_Main* response = malloc(sizeof(PB_Main)); const char* path = request->content.storage_read_request.path; - Storage* fs_api = furi_record_open("storage"); + Storage* fs_api = furi_record_open(RECORD_STORAGE); File* file = storage_file_alloc(fs_api); bool result = false; @@ -335,7 +335,7 @@ static void rpc_system_storage_read_process(const PB_Main* request, void* contex storage_file_close(file); storage_file_free(file); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); } static void rpc_system_storage_write_process(const PB_Main* request, void* context) { @@ -365,7 +365,7 @@ static void rpc_system_storage_write_process(const PB_Main* request, void* conte } if(rpc_storage->state != RpcStorageStateWriting) { - rpc_storage->api = furi_record_open("storage"); + rpc_storage->api = furi_record_open(RECORD_STORAGE); rpc_storage->file = storage_file_alloc(rpc_storage->api); rpc_storage->current_command_id = request->command_id; rpc_storage->state = RpcStorageStateWriting; @@ -433,7 +433,7 @@ static void rpc_system_storage_delete_process(const PB_Main* request, void* cont PB_CommandStatus status = PB_CommandStatus_ERROR; rpc_system_storage_reset_state(rpc_storage, session, true); - Storage* fs_api = furi_record_open("storage"); + Storage* fs_api = furi_record_open(RECORD_STORAGE); char* path = request->content.storage_delete_request.path; if(!path) { @@ -456,7 +456,7 @@ static void rpc_system_storage_delete_process(const PB_Main* request, void* cont } } - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); rpc_send_and_release_empty(session, request->command_id, status); } @@ -474,7 +474,7 @@ static void rpc_system_storage_mkdir_process(const PB_Main* request, void* conte PB_CommandStatus status; rpc_system_storage_reset_state(rpc_storage, session, true); - Storage* fs_api = furi_record_open("storage"); + Storage* fs_api = furi_record_open(RECORD_STORAGE); char* path = request->content.storage_mkdir_request.path; if(path) { if(path_contains_only_ascii(path)) { @@ -486,7 +486,7 @@ static void rpc_system_storage_mkdir_process(const PB_Main* request, void* conte } else { status = PB_CommandStatus_ERROR_INVALID_PARAMETERS; } - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); rpc_send_and_release_empty(session, request->command_id, status); } @@ -510,7 +510,7 @@ static void rpc_system_storage_md5sum_process(const PB_Main* request, void* cont return; } - Storage* fs_api = furi_record_open("storage"); + Storage* fs_api = furi_record_open(RECORD_STORAGE); File* file = storage_file_alloc(fs_api); if(storage_file_open(file, filename, FSAM_READ, FSOM_OPEN_EXISTING)) { @@ -555,7 +555,7 @@ static void rpc_system_storage_md5sum_process(const PB_Main* request, void* cont storage_file_free(file); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); } static void rpc_system_storage_rename_process(const PB_Main* request, void* context) { @@ -572,7 +572,7 @@ static void rpc_system_storage_rename_process(const PB_Main* request, void* cont PB_CommandStatus status; rpc_system_storage_reset_state(rpc_storage, session, true); - Storage* fs_api = furi_record_open("storage"); + Storage* fs_api = furi_record_open(RECORD_STORAGE); if(path_contains_only_ascii(request->content.storage_rename_request.new_path)) { FS_Error error = storage_common_rename( @@ -584,7 +584,7 @@ static void rpc_system_storage_rename_process(const PB_Main* request, void* cont status = PB_CommandStatus_ERROR_STORAGE_INVALID_NAME; } - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); rpc_send_and_release_empty(session, request->command_id, status); } @@ -601,13 +601,13 @@ static void rpc_system_storage_backup_create_process(const PB_Main* request, voi response->command_id = request->command_id; response->has_next = false; - Storage* fs_api = furi_record_open("storage"); + Storage* fs_api = furi_record_open(RECORD_STORAGE); bool backup_ok = lfs_backup_create(fs_api, request->content.storage_backup_create_request.archive_path); response->command_status = backup_ok ? PB_CommandStatus_OK : PB_CommandStatus_ERROR; - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); rpc_send_and_release(session, response); free(response); @@ -627,13 +627,13 @@ static void rpc_system_storage_backup_restore_process(const PB_Main* request, vo response->has_next = false; response->command_status = PB_CommandStatus_OK; - Storage* fs_api = furi_record_open("storage"); + Storage* fs_api = furi_record_open(RECORD_STORAGE); bool backup_ok = lfs_backup_unpack(fs_api, request->content.storage_backup_restore_request.archive_path); response->command_status = backup_ok ? PB_CommandStatus_OK : PB_CommandStatus_ERROR; - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); rpc_send_and_release(session, response); free(response); @@ -643,7 +643,7 @@ void* rpc_system_storage_alloc(RpcSession* session) { furi_assert(session); RpcStorageSystem* rpc_storage = malloc(sizeof(RpcStorageSystem)); - rpc_storage->api = furi_record_open("storage"); + rpc_storage->api = furi_record_open(RECORD_STORAGE); rpc_storage->session = session; rpc_storage->state = RpcStorageStateIdle; diff --git a/applications/rpc/rpc_system.c b/applications/rpc/rpc_system.c index 350602fd..38a28828 100644 --- a/applications/rpc/rpc_system.c +++ b/applications/rpc/rpc_system.c @@ -193,9 +193,9 @@ static void RpcSession* session = (RpcSession*)context; furi_assert(session); - NotificationApp* notification = furi_record_open("notification"); + NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION); notification_message(notification, &sequence_audiovisual_alert); - furi_record_close("notification"); + furi_record_close(RECORD_NOTIFICATION); rpc_send_and_release_empty(session, request->command_id, PB_CommandStatus_OK); } diff --git a/applications/snake_game/snake_game.c b/applications/snake_game/snake_game.c index bfd31ced..b7aabb17 100644 --- a/applications/snake_game/snake_game.c +++ b/applications/snake_game/snake_game.c @@ -304,7 +304,7 @@ int32_t snake_game_app(void* p) { furi_timer_start(timer, furi_kernel_get_tick_frequency() / 4); // Open GUI and register view_port - Gui* gui = furi_record_open("gui"); + Gui* gui = furi_record_open(RECORD_GUI); gui_add_view_port(gui, view_port, GuiLayerFullscreen); SnakeEvent event; @@ -354,7 +354,7 @@ int32_t snake_game_app(void* p) { furi_timer_free(timer); view_port_enabled_set(view_port, false); gui_remove_view_port(gui, view_port); - furi_record_close("gui"); + furi_record_close(RECORD_GUI); view_port_free(view_port); furi_message_queue_free(event_queue); delete_mutex(&state_mutex); diff --git a/applications/storage/storage.c b/applications/storage/storage.c index 90a191a2..9079a95e 100644 --- a/applications/storage/storage.c +++ b/applications/storage/storage.c @@ -11,7 +11,7 @@ #define ICON_SD_MOUNTED &I_SDcardMounted_11x8 #define ICON_SD_ERROR &I_SDcardFail_11x8 -#define TAG "Storage" +#define TAG RECORD_STORAGE static void storage_app_sd_icon_draw_callback(Canvas* canvas, void* context) { furi_assert(canvas); @@ -52,9 +52,9 @@ Storage* storage_app_alloc() { view_port_draw_callback_set(app->sd_gui.view_port, storage_app_sd_icon_draw_callback, app); view_port_enabled_set(app->sd_gui.view_port, false); - Gui* gui = furi_record_open("gui"); + Gui* gui = furi_record_open(RECORD_GUI); gui_add_view_port(gui, app->sd_gui.view_port, GuiLayerStatusBarLeft); - furi_record_close("gui"); + furi_record_close(RECORD_GUI); return app; } @@ -102,7 +102,7 @@ void storage_tick(Storage* app) { int32_t storage_srv(void* p) { UNUSED(p); Storage* app = storage_app_alloc(); - furi_record_create("storage", app); + furi_record_create(RECORD_STORAGE, app); StorageMessage message; while(1) { diff --git a/applications/storage/storage.h b/applications/storage/storage.h index dcb8deee..55a951d1 100644 --- a/applications/storage/storage.h +++ b/applications/storage/storage.h @@ -8,6 +8,16 @@ extern "C" { #endif +#define STORAGE_INT_PATH_PREFIX "/int" +#define STORAGE_EXT_PATH_PREFIX "/ext" +#define STORAGE_ANY_PATH_PREFIX "/any" + +#define INT_PATH(path) STORAGE_INT_PATH_PREFIX "/" path +#define EXT_PATH(path) STORAGE_EXT_PATH_PREFIX "/" path +#define ANY_PATH(path) STORAGE_ANY_PATH_PREFIX "/" path + +#define RECORD_STORAGE "storage" + typedef struct Storage Storage; /** Allocates and initializes a file descriptor @@ -273,6 +283,8 @@ FS_Error storage_sd_status(Storage* api); /******************* Internal LFS Functions *******************/ +typedef void (*Storage_name_converter)(string_t); + /** Backs up internal storage to a tar archive * @param api pointer to the api * @param dstmane destination archive path @@ -283,9 +295,10 @@ FS_Error storage_int_backup(Storage* api, const char* dstname); /** Restores internal storage from a tar archive * @param api pointer to the api * @param dstmane archive path + * @param converter pointer to filename conversion function, may be NULL * @return FS_Error operation result */ -FS_Error storage_int_restore(Storage* api, const char* dstname); +FS_Error storage_int_restore(Storage* api, const char* dstname, Storage_name_converter converter); /***************** Simplified Functions ******************/ diff --git a/applications/storage/storage_cli.c b/applications/storage/storage_cli.c index dd423cc6..63b9a54b 100644 --- a/applications/storage/storage_cli.c +++ b/applications/storage/storage_cli.c @@ -40,12 +40,13 @@ static void storage_cli_print_error(FS_Error error) { static void storage_cli_info(Cli* cli, string_t path) { UNUSED(cli); - Storage* api = furi_record_open("storage"); + Storage* api = furi_record_open(RECORD_STORAGE); - if(string_cmp_str(path, "/int") == 0) { + if(string_cmp_str(path, STORAGE_INT_PATH_PREFIX) == 0) { uint64_t total_space; uint64_t free_space; - FS_Error error = storage_common_fs_info(api, "/int", &total_space, &free_space); + FS_Error error = + storage_common_fs_info(api, STORAGE_INT_PATH_PREFIX, &total_space, &free_space); if(error != FSE_OK) { storage_cli_print_error(error); @@ -56,7 +57,7 @@ static void storage_cli_info(Cli* cli, string_t path) { (uint32_t)(total_space / 1024), (uint32_t)(free_space / 1024)); } - } else if(string_cmp_str(path, "/ext") == 0) { + } else if(string_cmp_str(path, STORAGE_EXT_PATH_PREFIX) == 0) { SDInfo sd_info; FS_Error error = storage_sd_info(api, &sd_info); @@ -74,17 +75,17 @@ static void storage_cli_info(Cli* cli, string_t path) { storage_cli_print_usage(); } - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); }; static void storage_cli_format(Cli* cli, string_t path) { - if(string_cmp_str(path, "/int") == 0) { + if(string_cmp_str(path, STORAGE_INT_PATH_PREFIX) == 0) { storage_cli_print_error(FSE_NOT_IMPLEMENTED); - } else if(string_cmp_str(path, "/ext") == 0) { + } else if(string_cmp_str(path, STORAGE_EXT_PATH_PREFIX) == 0) { printf("Formatting SD card, all data will be lost. Are you sure (y/n)?\r\n"); char answer = cli_getc(cli); if(answer == 'y' || answer == 'Y') { - Storage* api = furi_record_open("storage"); + Storage* api = furi_record_open(RECORD_STORAGE); printf("Formatting, please wait...\r\n"); FS_Error error = storage_sd_format(api); @@ -94,7 +95,7 @@ static void storage_cli_format(Cli* cli, string_t path) { } else { printf("SD card was successfully formatted.\r\n"); } - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); } else { printf("Cancelled.\r\n"); } @@ -110,7 +111,7 @@ static void storage_cli_list(Cli* cli, string_t path) { printf("\t[D] ext\r\n"); printf("\t[D] any\r\n"); } else { - Storage* api = furi_record_open("storage"); + Storage* api = furi_record_open(RECORD_STORAGE); File* file = storage_file_alloc(api); if(storage_dir_open(file, string_get_cstr(path))) { @@ -136,18 +137,18 @@ static void storage_cli_list(Cli* cli, string_t path) { storage_dir_close(file); storage_file_free(file); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); } } static void storage_cli_tree(Cli* cli, string_t path) { if(string_cmp_str(path, "/") == 0) { - string_set(path, "/int"); + string_set(path, STORAGE_INT_PATH_PREFIX); storage_cli_tree(cli, path); - string_set(path, "/ext"); + string_set(path, STORAGE_EXT_PATH_PREFIX); storage_cli_tree(cli, path); } else { - Storage* api = furi_record_open("storage"); + Storage* api = furi_record_open(RECORD_STORAGE); DirWalk* dir_walk = dir_walk_alloc(api); string_t name; string_init(name); @@ -174,13 +175,13 @@ static void storage_cli_tree(Cli* cli, string_t path) { string_clear(name); dir_walk_free(dir_walk); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); } } static void storage_cli_read(Cli* cli, string_t path) { UNUSED(cli); - Storage* api = furi_record_open("storage"); + Storage* api = furi_record_open(RECORD_STORAGE); File* file = storage_file_alloc(api); if(storage_file_open(file, string_get_cstr(path), FSAM_READ, FSOM_OPEN_EXISTING)) { @@ -206,11 +207,11 @@ static void storage_cli_read(Cli* cli, string_t path) { storage_file_close(file); storage_file_free(file); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); } static void storage_cli_write(Cli* cli, string_t path) { - Storage* api = furi_record_open("storage"); + Storage* api = furi_record_open(RECORD_STORAGE); File* file = storage_file_alloc(api); const uint16_t buffer_size = 512; @@ -260,11 +261,11 @@ static void storage_cli_write(Cli* cli, string_t path) { free(buffer); storage_file_free(file); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); } static void storage_cli_read_chunks(Cli* cli, string_t path, string_t args) { - Storage* api = furi_record_open("storage"); + Storage* api = furi_record_open(RECORD_STORAGE); File* file = storage_file_alloc(api); uint32_t buffer_size; @@ -298,11 +299,11 @@ static void storage_cli_read_chunks(Cli* cli, string_t path, string_t args) { storage_file_close(file); storage_file_free(file); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); } static void storage_cli_write_chunk(Cli* cli, string_t path, string_t args) { - Storage* api = furi_record_open("storage"); + Storage* api = furi_record_open(RECORD_STORAGE); File* file = storage_file_alloc(api); uint32_t buffer_size; @@ -334,18 +335,19 @@ static void storage_cli_write_chunk(Cli* cli, string_t path, string_t args) { } storage_file_free(file); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); } static void storage_cli_stat(Cli* cli, string_t path) { UNUSED(cli); - Storage* api = furi_record_open("storage"); + Storage* api = furi_record_open(RECORD_STORAGE); if(string_cmp_str(path, "/") == 0) { printf("Storage\r\n"); } else if( - string_cmp_str(path, "/ext") == 0 || string_cmp_str(path, "/int") == 0 || - string_cmp_str(path, "/any") == 0) { + string_cmp_str(path, STORAGE_EXT_PATH_PREFIX) == 0 || + string_cmp_str(path, STORAGE_INT_PATH_PREFIX) == 0 || + string_cmp_str(path, STORAGE_ANY_PATH_PREFIX) == 0) { uint64_t total_space; uint64_t free_space; FS_Error error = @@ -374,12 +376,12 @@ static void storage_cli_stat(Cli* cli, string_t path) { } } - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); } static void storage_cli_copy(Cli* cli, string_t old_path, string_t args) { UNUSED(cli); - Storage* api = furi_record_open("storage"); + Storage* api = furi_record_open(RECORD_STORAGE); string_t new_path; string_init(new_path); @@ -395,24 +397,24 @@ static void storage_cli_copy(Cli* cli, string_t old_path, string_t args) { } string_clear(new_path); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); } static void storage_cli_remove(Cli* cli, string_t path) { UNUSED(cli); - Storage* api = furi_record_open("storage"); + Storage* api = furi_record_open(RECORD_STORAGE); FS_Error error = storage_common_remove(api, string_get_cstr(path)); if(error != FSE_OK) { storage_cli_print_error(error); } - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); } static void storage_cli_rename(Cli* cli, string_t old_path, string_t args) { UNUSED(cli); - Storage* api = furi_record_open("storage"); + Storage* api = furi_record_open(RECORD_STORAGE); string_t new_path; string_init(new_path); @@ -428,24 +430,24 @@ static void storage_cli_rename(Cli* cli, string_t old_path, string_t args) { } string_clear(new_path); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); } static void storage_cli_mkdir(Cli* cli, string_t path) { UNUSED(cli); - Storage* api = furi_record_open("storage"); + Storage* api = furi_record_open(RECORD_STORAGE); FS_Error error = storage_common_mkdir(api, string_get_cstr(path)); if(error != FSE_OK) { storage_cli_print_error(error); } - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); } static void storage_cli_md5(Cli* cli, string_t path) { UNUSED(cli); - Storage* api = furi_record_open("storage"); + Storage* api = furi_record_open(RECORD_STORAGE); File* file = storage_file_alloc(api); if(storage_file_open(file, string_get_cstr(path), FSAM_READ, FSOM_OPEN_EXISTING)) { @@ -478,7 +480,7 @@ static void storage_cli_md5(Cli* cli, string_t path) { storage_file_close(file); storage_file_free(file); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); } void storage_cli(Cli* cli, string_t args, void* context) { @@ -592,11 +594,11 @@ static void storage_cli_factory_reset(Cli* cli, string_t args, void* context) { void storage_on_system_start() { #ifdef SRV_CLI - Cli* cli = furi_record_open("cli"); - cli_add_command(cli, "storage", CliCommandFlagParallelSafe, storage_cli, NULL); + Cli* cli = furi_record_open(RECORD_CLI); + cli_add_command(cli, RECORD_STORAGE, CliCommandFlagParallelSafe, storage_cli, NULL); cli_add_command( cli, "factory_reset", CliCommandFlagParallelSafe, storage_cli_factory_reset, NULL); - furi_record_close("cli"); + furi_record_close(RECORD_CLI); #else UNUSED(storage_cli_factory_reset); #endif diff --git a/applications/storage/storage_external_api.c b/applications/storage/storage_external_api.c index 426fac9a..b32080df 100644 --- a/applications/storage/storage_external_api.c +++ b/applications/storage/storage_external_api.c @@ -447,17 +447,16 @@ static FS_Error storage_merge_recursive(Storage* storage, const char* old_path, const char* new_path) { FS_Error error = storage_common_mkdir(storage, new_path); DirWalk* dir_walk = dir_walk_alloc(storage); - string_t path; - string_t tmp_new_path; - string_t tmp_old_path; + string_t path, file_basename, tmp_new_path; FileInfo fileinfo; string_init(path); + string_init(file_basename); string_init(tmp_new_path); - string_init(tmp_old_path); do { if((error != FSE_OK) && (error != FSE_EXIST)) break; + dir_walk_set_recursive(dir_walk, false); if(!dir_walk_open(dir_walk, old_path)) { error = dir_walk_get_error(dir_walk); break; @@ -472,30 +471,33 @@ static FS_Error } else if(res == DirWalkLast) { break; } else { - string_set(tmp_old_path, path); - string_right(path, strlen(old_path)); - string_printf(tmp_new_path, "%s%s", new_path, string_get_cstr(path)); + path_extract_basename(string_get_cstr(path), file_basename); + path_concat(new_path, string_get_cstr(file_basename), tmp_new_path); if(fileinfo.flags & FSF_DIRECTORY) { if(storage_common_stat(storage, string_get_cstr(tmp_new_path), &fileinfo) == FSE_OK) { if(fileinfo.flags & FSF_DIRECTORY) { error = storage_common_mkdir(storage, string_get_cstr(tmp_new_path)); + if(error != FSE_OK) { + break; + } } } - } else { - error = storage_common_merge( - storage, string_get_cstr(tmp_old_path), string_get_cstr(tmp_new_path)); } + error = storage_common_merge( + storage, string_get_cstr(path), string_get_cstr(tmp_new_path)); - if(error != FSE_OK) break; + if(error != FSE_OK) { + break; + } } } } while(false); string_clear(tmp_new_path); - string_clear(tmp_old_path); + string_clear(file_basename); string_clear(path); dir_walk_free(dir_walk); return error; diff --git a/applications/storage/storage_internal_api.c b/applications/storage/storage_internal_api.c index 09314043..620eae36 100644 --- a/applications/storage/storage_internal_api.c +++ b/applications/storage/storage_internal_api.c @@ -3,20 +3,19 @@ #include "storage.h" #include -#define INT_PATH "/int" - FS_Error storage_int_backup(Storage* api, const char* dstname) { TarArchive* archive = tar_archive_alloc(api); bool success = tar_archive_open(archive, dstname, TAR_OPEN_MODE_WRITE) && - tar_archive_add_dir(archive, INT_PATH, "") && tar_archive_finalize(archive); + tar_archive_add_dir(archive, STORAGE_INT_PATH_PREFIX, "") && + tar_archive_finalize(archive); tar_archive_free(archive); return success ? FSE_OK : FSE_INTERNAL; } -FS_Error storage_int_restore(Storage* api, const char* srcname) { +FS_Error storage_int_restore(Storage* api, const char* srcname, Storage_name_converter converter) { TarArchive* archive = tar_archive_alloc(api); bool success = tar_archive_open(archive, srcname, TAR_OPEN_MODE_READ) && - tar_archive_unpack_to(archive, INT_PATH); + tar_archive_unpack_to(archive, STORAGE_INT_PATH_PREFIX, converter); tar_archive_free(archive); return success ? FSE_OK : FSE_INTERNAL; } diff --git a/applications/storage/storage_processing.c b/applications/storage/storage_processing.c index 0eb8a32c..46ca4e16 100644 --- a/applications/storage/storage_processing.c +++ b/applications/storage/storage_processing.c @@ -43,17 +43,18 @@ static const char* remove_vfs(const char* path) { return path + MIN(4u, strlen(path)); } -static const char* ext_path = "/ext"; -static const char* int_path = "/int"; -static const char* any_path = "/any"; - static StorageType storage_get_type_by_path(Storage* app, const char* path) { StorageType type = ST_ERROR; - if(strlen(path) >= strlen(ext_path) && memcmp(path, ext_path, strlen(ext_path)) == 0) { + if(strlen(path) >= strlen(STORAGE_EXT_PATH_PREFIX) && + memcmp(path, STORAGE_EXT_PATH_PREFIX, strlen(STORAGE_EXT_PATH_PREFIX)) == 0) { type = ST_EXT; - } else if(strlen(path) >= strlen(int_path) && memcmp(path, int_path, strlen(int_path)) == 0) { + } else if( + strlen(path) >= strlen(STORAGE_INT_PATH_PREFIX) && + memcmp(path, STORAGE_INT_PATH_PREFIX, strlen(STORAGE_INT_PATH_PREFIX)) == 0) { type = ST_INT; - } else if(strlen(path) >= strlen(any_path) && memcmp(path, any_path, strlen(any_path)) == 0) { + } else if( + strlen(path) >= strlen(STORAGE_ANY_PATH_PREFIX) && + memcmp(path, STORAGE_ANY_PATH_PREFIX, strlen(STORAGE_ANY_PATH_PREFIX)) == 0) { type = ST_ANY; } @@ -68,19 +69,20 @@ static StorageType storage_get_type_by_path(Storage* app, const char* path) { } static void storage_path_change_to_real_storage(string_t path, StorageType real_storage) { - if(memcmp(string_get_cstr(path), any_path, strlen(any_path)) == 0) { + if(memcmp(string_get_cstr(path), STORAGE_ANY_PATH_PREFIX, strlen(STORAGE_ANY_PATH_PREFIX)) == + 0) { switch(real_storage) { case ST_EXT: - string_set_char(path, 0, ext_path[0]); - string_set_char(path, 1, ext_path[1]); - string_set_char(path, 2, ext_path[2]); - string_set_char(path, 3, ext_path[3]); + string_set_char(path, 0, STORAGE_EXT_PATH_PREFIX[0]); + string_set_char(path, 1, STORAGE_EXT_PATH_PREFIX[1]); + string_set_char(path, 2, STORAGE_EXT_PATH_PREFIX[2]); + string_set_char(path, 3, STORAGE_EXT_PATH_PREFIX[3]); break; case ST_INT: - string_set_char(path, 0, int_path[0]); - string_set_char(path, 1, int_path[1]); - string_set_char(path, 2, int_path[2]); - string_set_char(path, 3, int_path[3]); + string_set_char(path, 0, STORAGE_INT_PATH_PREFIX[0]); + string_set_char(path, 1, STORAGE_INT_PATH_PREFIX[1]); + string_set_char(path, 2, STORAGE_INT_PATH_PREFIX[2]); + string_set_char(path, 3, STORAGE_INT_PATH_PREFIX[3]); break; default: break; diff --git a/applications/storage/storage_test_app.c b/applications/storage/storage_test_app.c index 226024b3..8bfa9826 100644 --- a/applications/storage/storage_test_app.c +++ b/applications/storage/storage_test_app.c @@ -317,22 +317,22 @@ static void do_test_end(Storage* api, const char* path) { int32_t storage_test_app(void* p) { UNUSED(p); - Storage* api = furi_record_open("storage"); - do_test_start(api, "/int"); - do_test_start(api, "/any"); - do_test_start(api, "/ext"); + Storage* api = furi_record_open(RECORD_STORAGE); + do_test_start(api, STORAGE_INT_PATH_PREFIX); + do_test_start(api, STORAGE_ANY_PATH_PREFIX); + do_test_start(api, STORAGE_EXT_PATH_PREFIX); - do_file_test(api, "/int/test.txt"); - do_file_test(api, "/any/test.txt"); - do_file_test(api, "/ext/test.txt"); + do_file_test(api, INT_PATH("test.txt")); + do_file_test(api, ANY_PATH("test.txt")); + do_file_test(api, EXT_PATH("test.txt")); - do_dir_test(api, "/int"); - do_dir_test(api, "/any"); - do_dir_test(api, "/ext"); + do_dir_test(api, STORAGE_INT_PATH_PREFIX); + do_dir_test(api, STORAGE_ANY_PATH_PREFIX); + do_dir_test(api, STORAGE_EXT_PATH_PREFIX); - do_test_end(api, "/int"); - do_test_end(api, "/any"); - do_test_end(api, "/ext"); + do_test_end(api, STORAGE_INT_PATH_PREFIX); + do_test_end(api, STORAGE_ANY_PATH_PREFIX); + do_test_end(api, STORAGE_EXT_PATH_PREFIX); while(true) { furi_delay_ms(1000); diff --git a/applications/storage/storages/storage_ext.c b/applications/storage/storages/storage_ext.c index abfcb0e7..4a9d4218 100644 --- a/applications/storage/storages/storage_ext.c +++ b/applications/storage/storages/storage_ext.c @@ -11,7 +11,7 @@ typedef FILINFO SDFileInfo; typedef FRESULT SDError; #define TAG "StorageExt" -#define STORAGE_PATH "/ext" + /********************* Definitions ********************/ typedef struct { @@ -35,9 +35,9 @@ static bool sd_mount_card(StorageData* storage, bool notify) { while(result == false && counter > 0 && hal_sd_detect()) { if(notify) { - NotificationApp* notification = furi_record_open("notification"); + NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION); sd_notify_wait(notification); - furi_record_close("notification"); + furi_record_close(RECORD_NOTIFICATION); } if((counter % 2) == 0) { @@ -78,9 +78,9 @@ static bool sd_mount_card(StorageData* storage, bool notify) { } if(notify) { - NotificationApp* notification = furi_record_open("notification"); + NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION); sd_notify_wait_off(notification); - furi_record_close("notification"); + furi_record_close(RECORD_NOTIFICATION); } if(!result) { @@ -224,16 +224,16 @@ static void storage_ext_tick_internal(StorageData* storage, bool notify) { if(storage->status != StorageStatusOK) { FURI_LOG_E(TAG, "sd init error: %s", storage_data_status_text(storage)); if(notify) { - NotificationApp* notification = furi_record_open("notification"); + NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION); sd_notify_error(notification); - furi_record_close("notification"); + furi_record_close(RECORD_NOTIFICATION); } } else { FURI_LOG_I(TAG, "card mounted"); if(notify) { - NotificationApp* notification = furi_record_open("notification"); + NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION); sd_notify_success(notification); - furi_record_close("notification"); + furi_record_close(RECORD_NOTIFICATION); } } @@ -252,9 +252,9 @@ static void storage_ext_tick_internal(StorageData* storage, bool notify) { sd_unmount_card(storage); if(notify) { - NotificationApp* notification = furi_record_open("notification"); + NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION); sd_notify_eject(notification); - furi_record_close("notification"); + furi_record_close(RECORD_NOTIFICATION); } } } diff --git a/applications/storage/storages/storage_int.c b/applications/storage/storages/storage_int.c index bdd78172..0765a92d 100644 --- a/applications/storage/storages/storage_int.c +++ b/applications/storage/storages/storage_int.c @@ -1,11 +1,16 @@ #include "storage_int.h" #include #include +#include #define TAG "StorageInt" -#define STORAGE_PATH "/int" +#define STORAGE_PATH STORAGE_INT_PATH_PREFIX #define LFS_CLEAN_FINGERPRINT 0 +/* When less than LFS_RESERVED_PAGES_COUNT are left free, creation & + * modification of non-dot files is restricted */ +#define LFS_RESERVED_PAGES_COUNT 5 + typedef struct { const size_t start_address; const size_t start_page; @@ -297,6 +302,20 @@ static FS_Error storage_int_parse_error(int error) { return result; } +/* Returns false if less than reserved space is left free */ +static bool storage_int_check_for_free_space(StorageData* storage) { + LFSData* lfs_data = lfs_data_get_from_storage(storage); + + lfs_ssize_t result = lfs_fs_size(lfs_get_from_storage(storage)); + if(result >= 0) { + lfs_size_t free_space = + (lfs_data->config.block_count - result) * lfs_data->config.block_size; + + return (free_space > LFS_RESERVED_PAGES_COUNT * furi_hal_flash_get_page_size()); + } + + return false; +} /******************* File Functions *******************/ static bool storage_int_file_open( @@ -308,6 +327,8 @@ static bool storage_int_file_open( StorageData* storage = ctx; lfs_t* lfs = lfs_get_from_storage(storage); + bool enough_free_space = storage_int_check_for_free_space(storage); + int flags = 0; if(access_mode & FSAM_READ) flags |= LFS_O_RDONLY; @@ -321,6 +342,23 @@ static bool storage_int_file_open( LFSHandle* handle = lfs_handle_alloc_file(); storage_set_storage_file_data(file, handle, storage); + + if(!enough_free_space) { + string_t filename; + string_init(filename); + path_extract_basename(path, filename); + bool is_dot_file = (!string_empty_p(filename) && (string_get_char(filename, 0) == '.')); + string_clear(filename); + + /* Restrict write & creation access to all non-dot files */ + if(!is_dot_file && (flags & (LFS_O_CREAT | LFS_O_WRONLY))) { + file->internal_error_id = LFS_ERR_NOSPC; + file->error_id = FSE_DENIED; + FURI_LOG_W(TAG, "Denied access to '%s': no free space", path); + return false; + } + } + file->internal_error_id = lfs_file_open(lfs, lfs_handle_get_file(handle), path, flags); if(file->internal_error_id >= LFS_ERR_OK) { @@ -328,6 +366,7 @@ static bool storage_int_file_open( } file->error_id = storage_int_parse_error(file->internal_error_id); + return (file->error_id == FSE_OK); } diff --git a/applications/storage_move_to_sd/application.fam b/applications/storage_move_to_sd/application.fam index 60a6d987..de47de05 100644 --- a/applications/storage_move_to_sd/application.fam +++ b/applications/storage_move_to_sd/application.fam @@ -3,7 +3,7 @@ App( name="StorageMoveToSd", apptype=FlipperAppType.SYSTEM, entry_point="storage_move_to_sd_app", - requires=["gui","storage"], + requires=["gui", "storage"], provides=["storage_move_to_sd_start"], stack_size=2 * 1024, order=30, @@ -16,4 +16,3 @@ App( requires=["storage"], order=120, ) - diff --git a/applications/storage_move_to_sd/storage_move_to_sd.c b/applications/storage_move_to_sd/storage_move_to_sd.c index fe5807d1..e5b195d5 100644 --- a/applications/storage_move_to_sd/storage_move_to_sd.c +++ b/applications/storage_move_to_sd/storage_move_to_sd.c @@ -4,66 +4,78 @@ #include "loader/loader.h" #include "m-string.h" #include +#include +#include #define TAG "MoveToSd" -#define MOVE_SRC "/int" -#define MOVE_DST "/ext" +#define MOVE_SRC STORAGE_INT_PATH_PREFIX +#define MOVE_DST STORAGE_EXT_PATH_PREFIX -static const char* app_dirs[] = { - "subghz", - "lfrfid", - "nfc", - "infrared", - "ibutton", - "badusb", -}; - -bool storage_move_to_sd_perform(void) { - Storage* storage = furi_record_open("storage"); - string_t path_src; - string_t path_dst; - string_init(path_src); - string_init(path_dst); - - for(uint32_t i = 0; i < COUNT_OF(app_dirs); i++) { - string_printf(path_src, "%s/%s", MOVE_SRC, app_dirs[i]); - string_printf(path_dst, "%s/%s", MOVE_DST, app_dirs[i]); - storage_common_merge(storage, string_get_cstr(path_src), string_get_cstr(path_dst)); - storage_simply_remove_recursive(storage, string_get_cstr(path_src)); +static bool storage_move_to_sd_check_entry(const char* name, FileInfo* fileinfo, void* ctx) { + UNUSED(ctx); + if((fileinfo->flags & FSF_DIRECTORY) != 0) { + return true; } - string_clear(path_src); - string_clear(path_dst); + return (name && (*name != '.')); +} - furi_record_close("storage"); +bool storage_move_to_sd_perform(void) { + Storage* storage = furi_record_open(RECORD_STORAGE); + + DirWalk* dir_walk = dir_walk_alloc(storage); + dir_walk_set_recursive(dir_walk, false); + dir_walk_set_filter_cb(dir_walk, storage_move_to_sd_check_entry, NULL); + + string_t path_src, path_dst; + + string_init(path_dst); + string_init(path_src); + + if(dir_walk_open(dir_walk, STORAGE_INT_PATH_PREFIX)) { + while(dir_walk_read(dir_walk, path_src, NULL) == DirWalkOK) { + string_set(path_dst, path_src); + string_replace_at( + path_dst, 0, strlen(STORAGE_INT_PATH_PREFIX), STORAGE_EXT_PATH_PREFIX); + + storage_common_merge(storage, string_get_cstr(path_src), string_get_cstr(path_dst)); + storage_simply_remove_recursive(storage, string_get_cstr(path_src)); + } + } + + dir_walk_free(dir_walk); + string_clear(path_dst); + string_clear(path_src); + + furi_record_close(RECORD_STORAGE); return false; } static bool storage_move_to_sd_check(void) { - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); - FileInfo file_info; - bool state = false; - string_t path; - string_init(path); + bool should_migrate = false; - for(uint32_t i = 0; i < COUNT_OF(app_dirs); i++) { - string_printf(path, "%s/%s", MOVE_SRC, app_dirs[i]); - if(storage_common_stat(storage, string_get_cstr(path), &file_info) == FSE_OK) { - if((file_info.flags & FSF_DIRECTORY) != 0) { - state = true; - break; - } - } + DirWalk* dir_walk = dir_walk_alloc(storage); + dir_walk_set_recursive(dir_walk, false); + dir_walk_set_filter_cb(dir_walk, storage_move_to_sd_check_entry, NULL); + + string_t name; + string_init(name); + + if(dir_walk_open(dir_walk, STORAGE_INT_PATH_PREFIX)) { + // if at least 1 entry is present, we should migrate + should_migrate = (dir_walk_read(dir_walk, name, NULL) == DirWalkOK); } - string_clear(path); + dir_walk_free(dir_walk); + string_clear(name); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); - return state; + return should_migrate; } static bool storage_move_to_sd_custom_event_callback(void* context, uint32_t event) { @@ -92,8 +104,8 @@ static void storage_move_to_sd_unmount_callback(const void* message, void* conte static StorageMoveToSd* storage_move_to_sd_alloc() { StorageMoveToSd* app = malloc(sizeof(StorageMoveToSd)); - app->gui = furi_record_open("gui"); - app->notifications = furi_record_open("notification"); + app->gui = furi_record_open(RECORD_GUI); + app->notifications = furi_record_open(RECORD_NOTIFICATION); app->view_dispatcher = view_dispatcher_alloc(); app->scene_manager = scene_manager_alloc(&storage_move_to_sd_scene_handlers, app); @@ -114,26 +126,26 @@ static StorageMoveToSd* storage_move_to_sd_alloc() { scene_manager_next_scene(app->scene_manager, StorageMoveToSdConfirm); - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); app->sub = furi_pubsub_subscribe( storage_get_pubsub(storage), storage_move_to_sd_unmount_callback, app); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); return app; } static void storage_move_to_sd_free(StorageMoveToSd* app) { - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); furi_pubsub_unsubscribe(storage_get_pubsub(storage), app->sub); - furi_record_close("storage"); - furi_record_close("notification"); + furi_record_close(RECORD_STORAGE); + furi_record_close(RECORD_NOTIFICATION); view_dispatcher_remove_view(app->view_dispatcher, StorageMoveToSdViewWidget); widget_free(app->widget); view_dispatcher_free(app->view_dispatcher); scene_manager_free(app->scene_manager); - furi_record_close("gui"); + furi_record_close(RECORD_GUI); free(app); } @@ -159,18 +171,18 @@ static void storage_move_to_sd_mount_callback(const void* message, void* context const StorageEvent* storage_event = message; if(storage_event->type == StorageEventTypeCardMount) { - Loader* loader = furi_record_open("loader"); + Loader* loader = furi_record_open(RECORD_LOADER); loader_start(loader, "StorageMoveToSd", NULL); - furi_record_close("loader"); + furi_record_close(RECORD_LOADER); } } int32_t storage_move_to_sd_start(void* p) { UNUSED(p); - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); furi_pubsub_subscribe(storage_get_pubsub(storage), storage_move_to_sd_mount_callback, NULL); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); return 0; } diff --git a/applications/storage_settings/scenes/storage_settings_scene_benchmark.c b/applications/storage_settings/scenes/storage_settings_scene_benchmark.c index 947bb4e5..610696af 100644 --- a/applications/storage_settings/scenes/storage_settings_scene_benchmark.c +++ b/applications/storage_settings/scenes/storage_settings_scene_benchmark.c @@ -4,7 +4,7 @@ #define BENCH_DATA_SIZE 4096 #define BENCH_COUNT 6 #define BENCH_REPEATS 4 -#define BENCH_FILE "/ext/rwfiletest.bin" +#define BENCH_FILE EXT_PATH("rwfiletest.bin") static void storage_settings_scene_benchmark_dialog_callback(DialogExResult result, void* context) { diff --git a/applications/storage_settings/scenes/storage_settings_scene_internal_info.c b/applications/storage_settings/scenes/storage_settings_scene_internal_info.c index 53f791bd..74eecdb9 100644 --- a/applications/storage_settings/scenes/storage_settings_scene_internal_info.c +++ b/applications/storage_settings/scenes/storage_settings_scene_internal_info.c @@ -12,7 +12,8 @@ void storage_settings_scene_internal_info_on_enter(void* context) { StorageSettings* app = context; uint64_t total_space; uint64_t free_space; - FS_Error error = storage_common_fs_info(app->fs_api, "/int", &total_space, &free_space); + FS_Error error = + storage_common_fs_info(app->fs_api, STORAGE_INT_PATH_PREFIX, &total_space, &free_space); DialogEx* dialog_ex = app->dialog_ex; dialog_ex_set_context(dialog_ex, app); diff --git a/applications/storage_settings/storage_settings.c b/applications/storage_settings/storage_settings.c index b89fdf06..f580e636 100644 --- a/applications/storage_settings/storage_settings.c +++ b/applications/storage_settings/storage_settings.c @@ -15,9 +15,9 @@ static bool storage_settings_back_event_callback(void* context) { static StorageSettings* storage_settings_alloc() { StorageSettings* app = malloc(sizeof(StorageSettings)); - app->gui = furi_record_open("gui"); - app->fs_api = furi_record_open("storage"); - app->notification = furi_record_open("notification"); + app->gui = furi_record_open(RECORD_GUI); + app->fs_api = furi_record_open(RECORD_STORAGE); + app->notification = furi_record_open(RECORD_NOTIFICATION); app->view_dispatcher = view_dispatcher_alloc(); app->scene_manager = scene_manager_alloc(&storage_settings_scene_handlers, app); @@ -56,9 +56,9 @@ static void storage_settings_free(StorageSettings* app) { view_dispatcher_free(app->view_dispatcher); scene_manager_free(app->scene_manager); - furi_record_close("gui"); - furi_record_close("storage"); - furi_record_close("notification"); + furi_record_close(RECORD_GUI); + furi_record_close(RECORD_STORAGE); + furi_record_close(RECORD_NOTIFICATION); string_clear(app->text_string); diff --git a/applications/subghz/subghz.c b/applications/subghz/subghz.c index 76998eb0..26f1bbe9 100644 --- a/applications/subghz/subghz.c +++ b/applications/subghz/subghz.c @@ -95,7 +95,7 @@ SubGhz* subghz_alloc() { string_init(subghz->file_path_tmp); // GUI - subghz->gui = furi_record_open("gui"); + subghz->gui = furi_record_open(RECORD_GUI); // View Dispatcher subghz->view_dispatcher = view_dispatcher_alloc(); @@ -111,7 +111,7 @@ SubGhz* subghz_alloc() { subghz->view_dispatcher, subghz_tick_event_callback, 100); // Open Notification record - subghz->notifications = furi_record_open("notification"); + subghz->notifications = furi_record_open(RECORD_NOTIFICATION); // SubMenu subghz->submenu = submenu_alloc(); @@ -141,7 +141,7 @@ SubGhz* subghz_alloc() { subghz->view_dispatcher, SubGhzViewIdWidget, widget_get_view(subghz->widget)); //Dialog - subghz->dialogs = furi_record_open("dialogs"); + subghz->dialogs = furi_record_open(RECORD_DIALOGS); // Transmitter subghz->subghz_transmitter = subghz_view_transmitter_alloc(); @@ -194,7 +194,7 @@ SubGhz* subghz_alloc() { //init setting subghz->setting = subghz_setting_alloc(); - subghz_setting_load(subghz->setting, "/ext/subghz/assets/setting_user"); + subghz_setting_load(subghz->setting, EXT_PATH("subghz/assets/setting_user")); //init Worker & Protocol & History & KeyBoard subghz->lock = SubGhzLockOff; @@ -210,9 +210,9 @@ SubGhz* subghz_alloc() { subghz->txrx->environment = subghz_environment_alloc(); subghz_environment_set_came_atomo_rainbow_table_file_name( - subghz->txrx->environment, "/ext/subghz/assets/came_atomo"); + subghz->txrx->environment, EXT_PATH("subghz/assets/came_atomo")); subghz_environment_set_nice_flor_s_rainbow_table_file_name( - subghz->txrx->environment, "/ext/subghz/assets/nice_flor_s"); + subghz->txrx->environment, EXT_PATH("subghz/assets/nice_flor_s")); subghz->txrx->receiver = subghz_receiver_alloc_init(subghz->txrx->environment); subghz_receiver_set_filter(subghz->txrx->receiver, SubGhzProtocolFlag_Decodable); @@ -263,7 +263,7 @@ void subghz_free(SubGhz* subghz) { widget_free(subghz->widget); //Dialog - furi_record_close("dialogs"); + furi_record_close(RECORD_DIALOGS); // Transmitter view_dispatcher_remove_view(subghz->view_dispatcher, SubGhzViewIdTransmitter); @@ -296,7 +296,7 @@ void subghz_free(SubGhz* subghz) { view_dispatcher_free(subghz->view_dispatcher); // GUI - furi_record_close("gui"); + furi_record_close(RECORD_GUI); subghz->gui = NULL; //setting @@ -314,7 +314,7 @@ void subghz_free(SubGhz* subghz) { string_clear(subghz->error_str); // Notifications - furi_record_close("notification"); + furi_record_close(RECORD_NOTIFICATION); subghz->notifications = NULL; // Path strings @@ -330,9 +330,9 @@ int32_t subghz_app(void* p) { //Load database bool load_database = subghz_environment_load_keystore( - subghz->txrx->environment, "/ext/subghz/assets/keeloq_mfcodes"); + subghz->txrx->environment, EXT_PATH("subghz/assets/keeloq_mfcodes")); subghz_environment_load_keystore( - subghz->txrx->environment, "/ext/subghz/assets/keeloq_mfcodes_user"); + subghz->txrx->environment, EXT_PATH("subghz/assets/keeloq_mfcodes_user")); // Check argument and run corresponding scene if(p) { uint32_t rpc_ctx = 0; diff --git a/applications/subghz/subghz_cli.c b/applications/subghz/subghz_cli.c index eadef9f4..2b6fdd84 100644 --- a/applications/subghz/subghz_cli.c +++ b/applications/subghz/subghz_cli.c @@ -245,12 +245,12 @@ void subghz_cli_command_rx(Cli* cli, string_t args, void* context) { furi_check(instance->stream); SubGhzEnvironment* environment = subghz_environment_alloc(); - subghz_environment_load_keystore(environment, "/ext/subghz/assets/keeloq_mfcodes"); - subghz_environment_load_keystore(environment, "/ext/subghz/assets/keeloq_mfcodes_user"); + subghz_environment_load_keystore(environment, EXT_PATH("subghz/assets/keeloq_mfcodes")); + subghz_environment_load_keystore(environment, EXT_PATH("subghz/assets/keeloq_mfcodes_user")); subghz_environment_set_came_atomo_rainbow_table_file_name( - environment, "/ext/subghz/assets/came_atomo"); + environment, EXT_PATH("subghz/assets/came_atomo")); subghz_environment_set_nice_flor_s_rainbow_table_file_name( - environment, "/ext/subghz/assets/nice_flor_s"); + environment, EXT_PATH("subghz/assets/nice_flor_s")); SubGhzReceiver* receiver = subghz_receiver_alloc_init(environment); subghz_receiver_set_filter(receiver, SubGhzProtocolFlag_Decodable); @@ -304,9 +304,9 @@ void subghz_cli_command_decode_raw(Cli* cli, string_t args, void* context) { UNUSED(context); string_t file_name; string_init(file_name); - string_set_str(file_name, "/any/subghz/test.sub"); + string_set_str(file_name, ANY_PATH("subghz/test.sub")); - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); FlipperFormat* fff_data_file = flipper_format_file_alloc(storage); string_t temp_str; string_init(temp_str); @@ -346,29 +346,30 @@ void subghz_cli_command_decode_raw(Cli* cli, string_t args, void* context) { string_clear(temp_str); flipper_format_free(fff_data_file); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); if(check_file) { // Allocate context SubGhzCliCommandRx* instance = malloc(sizeof(SubGhzCliCommandRx)); SubGhzEnvironment* environment = subghz_environment_alloc(); - if(subghz_environment_load_keystore(environment, "/ext/subghz/assets/keeloq_mfcodes")) { + if(subghz_environment_load_keystore( + environment, EXT_PATH("subghz/assets/keeloq_mfcodes"))) { printf("SubGhz decode_raw: Load_keystore keeloq_mfcodes \033[0;32mOK\033[0m\r\n"); } else { printf("SubGhz decode_raw: Load_keystore keeloq_mfcodes \033[0;31mERROR\033[0m\r\n"); } if(subghz_environment_load_keystore( - environment, "/ext/subghz/assets/keeloq_mfcodes_user")) { + environment, EXT_PATH("subghz/assets/keeloq_mfcodes_user"))) { printf("SubGhz decode_raw: Load_keystore keeloq_mfcodes_user \033[0;32mOK\033[0m\r\n"); } else { printf( "SubGhz decode_raw: Load_keystore keeloq_mfcodes_user \033[0;31mERROR\033[0m\r\n"); } subghz_environment_set_came_atomo_rainbow_table_file_name( - environment, "/ext/subghz/assets/came_atomo"); + environment, EXT_PATH("subghz/assets/came_atomo")); subghz_environment_set_nice_flor_s_rainbow_table_file_name( - environment, "/ext/subghz/assets/nice_flor_s"); + environment, EXT_PATH("subghz/assets/nice_flor_s")); SubGhzReceiver* receiver = subghz_receiver_alloc_init(environment); subghz_receiver_set_filter(receiver, SubGhzProtocolFlag_Decodable); @@ -569,7 +570,7 @@ static void subghz_cli_command_chat(Cli* cli, string_t args) { bool exit = false; SubGhzChatEvent chat_event; - NotificationApp* notification = furi_record_open("notification"); + NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION); string_printf(name, "\033[0;33m%s\033[0m: ", furi_hal_version_get_name_ptr()); string_set(input, name); @@ -688,7 +689,7 @@ static void subghz_cli_command_chat(Cli* cli, string_t args) { string_clear(output); string_clear(sysmsg); furi_hal_power_suppress_charge_exit(); - furi_record_close("notification"); + furi_record_close(RECORD_NOTIFICATION); if(subghz_chat_worker_is_running(subghz_chat)) { subghz_chat_worker_stop(subghz_chat); @@ -757,11 +758,11 @@ static void subghz_cli_command(Cli* cli, string_t args, void* context) { void subghz_on_system_start() { #ifdef SRV_CLI - Cli* cli = furi_record_open("cli"); + Cli* cli = furi_record_open(RECORD_CLI); cli_add_command(cli, "subghz", CliCommandFlagDefault, subghz_cli_command, NULL); - furi_record_close("cli"); + furi_record_close(RECORD_CLI); #else UNUSED(subghz_cli_command); #endif diff --git a/applications/subghz/subghz_i.c b/applications/subghz/subghz_i.c index f6e4d4f5..9c8a3fc4 100644 --- a/applications/subghz/subghz_i.c +++ b/applications/subghz/subghz_i.c @@ -226,7 +226,7 @@ bool subghz_key_load(SubGhz* subghz, const char* file_path, bool show_dialog) { furi_assert(subghz); furi_assert(file_path); - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); FlipperFormat* fff_data_file = flipper_format_file_alloc(storage); Stream* fff_data_stream = flipper_format_get_raw_stream(subghz->txrx->fff_data); @@ -308,7 +308,7 @@ bool subghz_key_load(SubGhz* subghz, const char* file_path, bool show_dialog) { string_clear(temp_str); flipper_format_free(fff_data_file); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); switch(load_key_state) { case SubGhzLoadKeyStateParseErr: @@ -335,7 +335,7 @@ bool subghz_key_load(SubGhz* subghz, const char* file_path, bool show_dialog) { bool subghz_get_next_name_file(SubGhz* subghz, uint8_t max_len) { furi_assert(subghz); - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); string_t temp_str; string_t file_name; string_t file_path; @@ -372,7 +372,7 @@ bool subghz_get_next_name_file(SubGhz* subghz, uint8_t max_len) { string_clear(temp_str); string_clear(file_path); string_clear(file_name); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); return res; } @@ -385,7 +385,7 @@ bool subghz_save_protocol_to_file( furi_assert(flipper_format); furi_assert(dev_file_name); - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); Stream* flipper_format_stream = flipper_format_get_raw_stream(flipper_format); bool saved = false; @@ -414,7 +414,7 @@ bool subghz_save_protocol_to_file( saved = true; } while(0); string_clear(file_dir); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); return saved; } @@ -447,7 +447,7 @@ bool subghz_rename_file(SubGhz* subghz) { furi_assert(subghz); bool ret = true; - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); if(string_cmp(subghz->file_path_tmp, subghz->file_path)) { FS_Error fs_result = storage_common_rename( @@ -458,7 +458,7 @@ bool subghz_rename_file(SubGhz* subghz) { ret = false; } } - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); return ret; } @@ -466,9 +466,9 @@ bool subghz_rename_file(SubGhz* subghz) { bool subghz_delete_file(SubGhz* subghz) { furi_assert(subghz); - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); bool result = storage_simply_remove(storage, string_get_cstr(subghz->file_path_tmp)); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); subghz_file_name_clear(subghz); diff --git a/applications/subghz/subghz_setting.c b/applications/subghz/subghz_setting.c index 9dcfb291..7d688105 100644 --- a/applications/subghz/subghz_setting.c +++ b/applications/subghz/subghz_setting.c @@ -229,7 +229,7 @@ void subghz_setting_load_default(SubGhzSetting* instance) { void subghz_setting_load(SubGhzSetting* instance, const char* file_path) { furi_assert(instance); - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); FlipperFormat* fff_data_file = flipper_format_file_alloc(storage); string_t temp_str; @@ -318,7 +318,7 @@ void subghz_setting_load(SubGhzSetting* instance, const char* file_path) { string_clear(temp_str); flipper_format_free(fff_data_file); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); if(!FrequencyList_size(instance->frequencies) || !FrequencyList_size(instance->hopper_frequencies)) { diff --git a/applications/subghz/views/subghz_test_static.c b/applications/subghz/views/subghz_test_static.c index 41de7262..7af54c3c 100644 --- a/applications/subghz/views/subghz_test_static.c +++ b/applications/subghz/views/subghz_test_static.c @@ -93,7 +93,7 @@ bool subghz_test_static_input(InputEvent* event, void* context) { model->real_frequency = subghz_frequencies_testing[model->frequency]; if(event->key == InputKeyOk) { - NotificationApp* notification = furi_record_open("notification"); + NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION); if(event->type == InputTypePress) { furi_hal_subghz_idle(); furi_hal_subghz_set_frequency_and_path( @@ -126,7 +126,7 @@ bool subghz_test_static_input(InputEvent* event, void* context) { } instance->status_tx = SubGhzTestStaticStatusIDLE; } - furi_record_close("notification"); + furi_record_close(RECORD_NOTIFICATION); } return true; diff --git a/applications/system/system_settings.c b/applications/system/system_settings.c index 7bbcdd7b..7661413d 100644 --- a/applications/system/system_settings.c +++ b/applications/system/system_settings.c @@ -54,7 +54,7 @@ SystemSettings* system_settings_alloc() { SystemSettings* app = malloc(sizeof(SystemSettings)); // Load settings - app->gui = furi_record_open("gui"); + app->gui = furi_record_open(RECORD_GUI); app->view_dispatcher = view_dispatcher_alloc(); view_dispatcher_enable_queue(app->view_dispatcher); @@ -99,7 +99,7 @@ void system_settings_free(SystemSettings* app) { // View dispatcher view_dispatcher_free(app->view_dispatcher); // Records - furi_record_close("gui"); + furi_record_close(RECORD_GUI); free(app); } diff --git a/applications/u2f/u2f_app.c b/applications/u2f/u2f_app.c index 2c3ff562..21648197 100644 --- a/applications/u2f/u2f_app.c +++ b/applications/u2f/u2f_app.c @@ -24,8 +24,8 @@ static void u2f_app_tick_event_callback(void* context) { U2fApp* u2f_app_alloc() { U2fApp* app = malloc(sizeof(U2fApp)); - app->gui = furi_record_open("gui"); - app->notifications = furi_record_open("notification"); + app->gui = furi_record_open(RECORD_GUI); + app->notifications = furi_record_open(RECORD_NOTIFICATION); app->view_dispatcher = view_dispatcher_alloc(); app->scene_manager = scene_manager_alloc(&u2f_scene_handlers, app); @@ -79,8 +79,8 @@ void u2f_app_free(U2fApp* app) { scene_manager_free(app->scene_manager); // Close records - furi_record_close("gui"); - furi_record_close("notification"); + furi_record_close(RECORD_GUI); + furi_record_close(RECORD_NOTIFICATION); free(app); } diff --git a/applications/u2f/u2f_data.c b/applications/u2f/u2f_data.c index 5143b27b..0419fc7e 100644 --- a/applications/u2f/u2f_data.c +++ b/applications/u2f/u2f_data.c @@ -7,7 +7,7 @@ #define TAG "U2F" -#define U2F_DATA_FOLDER "/any/u2f/" +#define U2F_DATA_FOLDER ANY_PATH("u2f/") #define U2F_CERT_FILE U2F_DATA_FOLDER "assets/cert.der" #define U2F_CERT_KEY_FILE U2F_DATA_FOLDER "assets/cert_key.u2f" #define U2F_KEY_FILE U2F_DATA_FOLDER "key.u2f" @@ -40,7 +40,7 @@ typedef struct { bool u2f_data_check(bool cert_only) { bool state = false; - Storage* fs_api = furi_record_open("storage"); + Storage* fs_api = furi_record_open(RECORD_STORAGE); File* file = storage_file_alloc(fs_api); do { @@ -61,14 +61,14 @@ bool u2f_data_check(bool cert_only) { storage_file_close(file); storage_file_free(file); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); return state; } bool u2f_data_cert_check() { bool state = false; - Storage* fs_api = furi_record_open("storage"); + Storage* fs_api = furi_record_open(RECORD_STORAGE); File* file = storage_file_alloc(fs_api); uint8_t file_buf[8]; @@ -96,7 +96,7 @@ bool u2f_data_cert_check() { storage_file_close(file); storage_file_free(file); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); return state; } @@ -104,7 +104,7 @@ bool u2f_data_cert_check() { uint32_t u2f_data_cert_load(uint8_t* cert) { furi_assert(cert); - Storage* fs_api = furi_record_open("storage"); + Storage* fs_api = furi_record_open(RECORD_STORAGE); File* file = storage_file_alloc(fs_api); uint32_t file_size = 0; uint32_t len_cur = 0; @@ -117,7 +117,7 @@ uint32_t u2f_data_cert_load(uint8_t* cert) { storage_file_close(file); storage_file_free(file); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); return len_cur; } @@ -146,7 +146,7 @@ static bool u2f_data_cert_key_encrypt(uint8_t* cert_key) { } furi_hal_crypto_store_unload_key(U2F_DATA_FILE_ENCRYPTION_KEY_SLOT_UNIQUE); - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); FlipperFormat* flipper_format = flipper_format_file_alloc(storage); if(flipper_format_file_open_always(flipper_format, U2F_CERT_KEY_FILE)) { @@ -162,7 +162,7 @@ static bool u2f_data_cert_key_encrypt(uint8_t* cert_key) { } flipper_format_free(flipper_format); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); return state; } @@ -183,7 +183,7 @@ bool u2f_data_cert_key_load(uint8_t* cert_key) { string_t filetype; string_init(filetype); - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); FlipperFormat* flipper_format = flipper_format_file_alloc(storage); if(flipper_format_file_open_existing(flipper_format, U2F_CERT_KEY_FILE)) { @@ -248,7 +248,7 @@ bool u2f_data_cert_key_load(uint8_t* cert_key) { } flipper_format_free(flipper_format); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); string_clear(filetype); if(cert_type == U2F_CERT_USER_UNENCRYPTED) { @@ -269,7 +269,7 @@ bool u2f_data_key_load(uint8_t* device_key) { string_t filetype; string_init(filetype); - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); FlipperFormat* flipper_format = flipper_format_file_alloc(storage); if(flipper_format_file_open_existing(flipper_format, U2F_KEY_FILE)) { @@ -306,7 +306,7 @@ bool u2f_data_key_load(uint8_t* device_key) { } while(0); } flipper_format_free(flipper_format); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); string_clear(filetype); return state; } @@ -334,7 +334,7 @@ bool u2f_data_key_generate(uint8_t* device_key) { } furi_hal_crypto_store_unload_key(U2F_DATA_FILE_ENCRYPTION_KEY_SLOT_UNIQUE); - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); FlipperFormat* flipper_format = flipper_format_file_alloc(storage); if(flipper_format_file_open_always(flipper_format, U2F_KEY_FILE)) { @@ -350,7 +350,7 @@ bool u2f_data_key_generate(uint8_t* device_key) { } flipper_format_free(flipper_format); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); return state; } @@ -367,7 +367,7 @@ bool u2f_data_cnt_read(uint32_t* cnt_val) { string_t filetype; string_init(filetype); - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); FlipperFormat* flipper_format = flipper_format_file_alloc(storage); if(flipper_format_file_open_existing(flipper_format, U2F_CNT_FILE)) { @@ -407,7 +407,7 @@ bool u2f_data_cnt_read(uint32_t* cnt_val) { } while(0); } flipper_format_free(flipper_format); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); string_clear(filetype); return state; } @@ -435,7 +435,7 @@ bool u2f_data_cnt_write(uint32_t cnt_val) { } furi_hal_crypto_store_unload_key(U2F_DATA_FILE_ENCRYPTION_KEY_SLOT_UNIQUE); - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); FlipperFormat* flipper_format = flipper_format_file_alloc(storage); if(flipper_format_file_open_always(flipper_format, U2F_CNT_FILE)) { @@ -450,7 +450,7 @@ bool u2f_data_cnt_write(uint32_t cnt_val) { } flipper_format_free(flipper_format); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); return state; } diff --git a/applications/unit_tests/flipper_format/flipper_format_string_test.c b/applications/unit_tests/flipper_format/flipper_format_string_test.c index 7158ffd8..b22b333a 100644 --- a/applications/unit_tests/flipper_format/flipper_format_string_test.c +++ b/applications/unit_tests/flipper_format/flipper_format_string_test.c @@ -296,9 +296,9 @@ MU_TEST(flipper_format_string_test) { } MU_TEST(flipper_format_file_test) { - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); FlipperFormat* flipper_format = flipper_format_file_alloc(storage); - mu_check(flipper_format_file_open_always(flipper_format, "/ext/flipper.fff")); + mu_check(flipper_format_file_open_always(flipper_format, EXT_PATH("flipper.fff"))); Stream* stream = flipper_format_get_raw_stream(flipper_format); mu_check(flipper_format_write_header_cstr(flipper_format, test_filetype, test_version)); @@ -323,7 +323,7 @@ MU_TEST(flipper_format_file_test) { MU_RUN_TEST_1(flipper_format_read_and_update_test, flipper_format); flipper_format_free(flipper_format); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); } MU_TEST_SUITE(flipper_format_string_suite) { diff --git a/applications/unit_tests/flipper_format/flipper_format_test.c b/applications/unit_tests/flipper_format/flipper_format_test.c index f83360b4..86e2df21 100644 --- a/applications/unit_tests/flipper_format/flipper_format_test.c +++ b/applications/unit_tests/flipper_format/flipper_format_test.c @@ -5,7 +5,7 @@ #include "../minunit.h" #define TEST_DIR TEST_DIR_NAME "/" -#define TEST_DIR_NAME "/ext/unit_tests_tmp" +#define TEST_DIR_NAME EXT_PATH("unit_tests_tmp") static const char* test_filetype = "Flipper File test"; static const uint32_t test_version = 666; @@ -66,7 +66,7 @@ static const char* test_file_windows = TEST_DIR READ_TEST_WIN; static const char* test_file_flipper = TEST_DIR READ_TEST_FLP; static bool storage_write_string(const char* path, const char* data) { - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); File* file = storage_file_alloc(storage); bool result = false; @@ -79,26 +79,26 @@ static bool storage_write_string(const char* path, const char* data) { storage_file_close(file); storage_file_free(file); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); return result; } static void tests_setup() { - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); mu_assert(storage_simply_remove_recursive(storage, TEST_DIR_NAME), "Cannot clean data"); mu_assert(storage_simply_mkdir(storage, TEST_DIR_NAME), "Cannot create dir"); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); } static void tests_teardown() { - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); mu_assert(storage_simply_remove_recursive(storage, TEST_DIR_NAME), "Cannot clean data"); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); } static bool test_read(const char* file_name) { - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); bool result = false; FlipperFormat* file = flipper_format_file_alloc(storage); @@ -154,13 +154,13 @@ static bool test_read(const char* file_name) { flipper_format_free(file); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); return result; } static bool test_read_updated(const char* file_name) { - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); bool result = false; FlipperFormat* file = flipper_format_file_alloc(storage); @@ -232,13 +232,13 @@ static bool test_read_updated(const char* file_name) { flipper_format_free(file); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); return result; } static bool test_write(const char* file_name) { - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); bool result = false; FlipperFormat* file = flipper_format_file_alloc(storage); @@ -264,13 +264,13 @@ static bool test_write(const char* file_name) { } while(false); flipper_format_free(file); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); return result; } static bool test_delete_last_key(const char* file_name) { - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); bool result = false; FlipperFormat* file = flipper_format_file_alloc(storage); @@ -281,13 +281,13 @@ static bool test_delete_last_key(const char* file_name) { } while(false); flipper_format_free(file); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); return result; } static bool test_append_key(const char* file_name) { - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); bool result = false; FlipperFormat* file = flipper_format_file_alloc(storage); @@ -299,13 +299,13 @@ static bool test_append_key(const char* file_name) { } while(false); flipper_format_free(file); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); return result; } static bool test_update(const char* file_name) { - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); bool result = false; FlipperFormat* file = flipper_format_file_alloc(storage); @@ -333,13 +333,13 @@ static bool test_update(const char* file_name) { } while(false); flipper_format_free(file); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); return result; } static bool test_update_backward(const char* file_name) { - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); bool result = false; FlipperFormat* file = flipper_format_file_alloc(storage); @@ -364,13 +364,13 @@ static bool test_update_backward(const char* file_name) { } while(false); flipper_format_free(file); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); return result; } static bool test_write_multikey(const char* file_name) { - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); bool result = false; FlipperFormat* file = flipper_format_file_alloc(storage); @@ -391,13 +391,13 @@ static bool test_write_multikey(const char* file_name) { } while(false); flipper_format_free(file); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); return result; } static bool test_read_multikey(const char* file_name) { - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); bool result = false; FlipperFormat* file = flipper_format_file_alloc(storage); @@ -432,7 +432,7 @@ static bool test_read_multikey(const char* file_name) { string_clear(string_value); flipper_format_free(file); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); return result; } diff --git a/applications/unit_tests/infrared/infrared_test.c b/applications/unit_tests/infrared/infrared_test.c index cdae742f..32266c48 100644 --- a/applications/unit_tests/infrared/infrared_test.c +++ b/applications/unit_tests/infrared/infrared_test.c @@ -4,7 +4,7 @@ #include #include "../minunit.h" -#define IR_TEST_FILES_DIR "/ext/unit_tests/infrared/" +#define IR_TEST_FILES_DIR EXT_PATH("unit_tests/infrared/") #define IR_TEST_FILE_PREFIX "test_" #define IR_TEST_FILE_SUFFIX ".irtest" @@ -18,7 +18,7 @@ typedef struct { static InfraredTest* test; static void infrared_test_alloc() { - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); test = malloc(sizeof(InfraredTest)); test->decoder_handler = infrared_alloc_decoder(); test->encoder_handler = infrared_alloc_encoder(); @@ -32,7 +32,7 @@ static void infrared_test_free() { infrared_free_encoder(test->encoder_handler); flipper_format_free(test->ff); string_clear(test->file_path); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); free(test); test = NULL; } diff --git a/applications/unit_tests/nfc/nfc_test.c b/applications/unit_tests/nfc/nfc_test.c index 4e1b9a64..13060a6d 100644 --- a/applications/unit_tests/nfc/nfc_test.c +++ b/applications/unit_tests/nfc/nfc_test.c @@ -12,7 +12,7 @@ #define TAG "NfcTest" -#define NFC_TEST_RESOURCES_DIR "/ext/unit_tests/nfc/" +#define NFC_TEST_RESOURCES_DIR EXT_PATH("unit_tests/nfc/") #define NFC_TEST_SIGNAL_SHORT_FILE "nfc_nfca_signal_short.nfc" #define NFC_TEST_SIGNAL_LONG_FILE "nfc_nfca_signal_long.nfc" @@ -36,13 +36,13 @@ static NfcTest* nfc_test = NULL; static void nfc_test_alloc() { nfc_test = malloc(sizeof(NfcTest)); nfc_test->signal = nfca_signal_alloc(); - nfc_test->storage = furi_record_open("storage"); + nfc_test->storage = furi_record_open(RECORD_STORAGE); } static void nfc_test_free() { furi_assert(nfc_test); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); nfca_signal_free(nfc_test->signal); free(nfc_test); nfc_test = NULL; diff --git a/applications/unit_tests/rpc/rpc_test.c b/applications/unit_tests/rpc/rpc_test.c index c5336385..1b9c5b0b 100644 --- a/applications/unit_tests/rpc/rpc_test.c +++ b/applications/unit_tests/rpc/rpc_test.c @@ -47,7 +47,7 @@ static RpcSessionContext rpc_session[TEST_RPC_SESSIONS]; #define MAX_NAME_LENGTH 255 #define MAX_DATA_SIZE 512u // have to be exact as in rpc_storage.c #define TEST_DIR TEST_DIR_NAME "/" -#define TEST_DIR_NAME "/ext/unit_tests_tmp" +#define TEST_DIR_NAME EXT_PATH("unit_tests_tmp") #define MD5SUM_SIZE 16 #define PING_REQUEST 0 @@ -83,7 +83,7 @@ static void test_rpc_setup(void) { furi_check(!rpc); furi_check(!(rpc_session[0].session)); - rpc = furi_record_open("rpc"); + rpc = furi_record_open(RECORD_RPC); for(int i = 0; !(rpc_session[0].session) && (i < 10000); ++i) { rpc_session[0].session = rpc_session_open(rpc); furi_delay_tick(1); @@ -125,7 +125,7 @@ static void test_rpc_teardown(void) { xSemaphoreTake(rpc_session[0].terminate_semaphore, 0); rpc_session_close(rpc_session[0].session); furi_check(xSemaphoreTake(rpc_session[0].terminate_semaphore, portMAX_DELAY)); - furi_record_close("rpc"); + furi_record_close(RECORD_RPC); vStreamBufferDelete(rpc_session[0].output_stream); vSemaphoreDelete(rpc_session[0].close_session_semaphore); vSemaphoreDelete(rpc_session[0].terminate_semaphore); @@ -153,17 +153,17 @@ static void test_rpc_teardown_second_session(void) { static void test_rpc_storage_setup(void) { test_rpc_setup(); - Storage* fs_api = furi_record_open("storage"); + Storage* fs_api = furi_record_open(RECORD_STORAGE); clean_directory(fs_api, TEST_DIR_NAME); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); } static void test_rpc_storage_teardown(void) { test_rpc_teardown(); - Storage* fs_api = furi_record_open("storage"); + Storage* fs_api = furi_record_open(RECORD_STORAGE); clean_directory(fs_api, TEST_DIR_NAME); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); } static void test_rpc_session_close_callback(void* context) { @@ -571,7 +571,7 @@ static void test_rpc_storage_list_create_expected_list( MsgList_t msg_list, const char* path, uint32_t command_id) { - Storage* fs_api = furi_record_open("storage"); + Storage* fs_api = furi_record_open(RECORD_STORAGE); File* dir = storage_file_alloc(fs_api); PB_Main response = { @@ -627,7 +627,7 @@ static void test_rpc_storage_list_create_expected_list( storage_dir_close(dir); storage_file_free(dir); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); } static void test_rpc_decode_and_compare(MsgList_t expected_msg_list, uint8_t session) { @@ -693,13 +693,13 @@ static void test_rpc_storage_list_run(const char* path, uint32_t command_id) { MU_TEST(test_storage_list) { test_rpc_storage_list_run("/", ++command_id); - test_rpc_storage_list_run("/ext/nfc", ++command_id); + test_rpc_storage_list_run(EXT_PATH("nfc"), ++command_id); - test_rpc_storage_list_run("/int", ++command_id); - test_rpc_storage_list_run("/ext", ++command_id); - test_rpc_storage_list_run("/ext/infrared", ++command_id); - test_rpc_storage_list_run("/ext/ibutton", ++command_id); - test_rpc_storage_list_run("/ext/lfrfid", ++command_id); + test_rpc_storage_list_run(STORAGE_INT_PATH_PREFIX, ++command_id); + test_rpc_storage_list_run(STORAGE_EXT_PATH_PREFIX, ++command_id); + test_rpc_storage_list_run(EXT_PATH("infrared"), ++command_id); + test_rpc_storage_list_run(EXT_PATH("ibutton"), ++command_id); + test_rpc_storage_list_run(EXT_PATH("lfrfid"), ++command_id); test_rpc_storage_list_run("error_path", ++command_id); } @@ -718,7 +718,7 @@ static void test_rpc_add_read_to_list_by_reading_real_file( const char* path, uint32_t command_id) { furi_check(MsgList_empty_p(msg_list)); - Storage* fs_api = furi_record_open("storage"); + Storage* fs_api = furi_record_open(RECORD_STORAGE); File* file = storage_file_alloc(fs_api); bool result = false; @@ -759,7 +759,7 @@ static void test_rpc_add_read_to_list_by_reading_real_file( storage_file_close(file); storage_file_free(file); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); } static void test_storage_read_run(const char* path, uint32_t command_id) { @@ -777,25 +777,25 @@ static void test_storage_read_run(const char* path, uint32_t command_id) { } static bool test_is_exists(const char* path) { - Storage* fs_api = furi_record_open("storage"); + Storage* fs_api = furi_record_open(RECORD_STORAGE); FileInfo fileinfo; FS_Error result = storage_common_stat(fs_api, path, &fileinfo); furi_check((result == FSE_OK) || (result == FSE_NOT_EXIST)); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); return result == FSE_OK; } static void test_create_dir(const char* path) { - Storage* fs_api = furi_record_open("storage"); + Storage* fs_api = furi_record_open(RECORD_STORAGE); FS_Error error = storage_common_mkdir(fs_api, path); (void)error; furi_check((error == FSE_OK) || (error == FSE_EXIST)); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); furi_check(test_is_exists(path)); } static void test_create_file(const char* path, size_t size) { - Storage* fs_api = furi_record_open("storage"); + Storage* fs_api = furi_record_open(RECORD_STORAGE); File* file = storage_file_alloc(fs_api); if(storage_file_open(file, path, FSAM_WRITE, FSOM_CREATE_ALWAYS)) { @@ -813,7 +813,7 @@ static void test_create_file(const char* path, size_t size) { storage_file_close(file); storage_file_free(file); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); furi_check(test_is_exists(path)); } @@ -827,7 +827,7 @@ static void test_rpc_storage_info_run(const char* path, uint32_t command_id) { PB_Main* response = MsgList_push_new(expected_msg_list); response->command_id = command_id; - Storage* fs_api = furi_record_open("storage"); + Storage* fs_api = furi_record_open(RECORD_STORAGE); FS_Error error = storage_common_fs_info( fs_api, @@ -856,10 +856,10 @@ static void test_rpc_storage_stat_run(const char* path, uint32_t command_id) { test_rpc_create_simple_message(&request, PB_Main_storage_stat_request_tag, path, command_id); - Storage* fs_api = furi_record_open("storage"); + Storage* fs_api = furi_record_open(RECORD_STORAGE); FileInfo fileinfo; FS_Error error = storage_common_stat(fs_api, path, &fileinfo); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); PB_Main* response = MsgList_push_new(expected_msg_list); response->command_id = command_id; @@ -884,9 +884,9 @@ static void test_rpc_storage_stat_run(const char* path, uint32_t command_id) { } MU_TEST(test_storage_info) { - test_rpc_storage_info_run("/any", ++command_id); - test_rpc_storage_info_run("/int", ++command_id); - test_rpc_storage_info_run("/ext", ++command_id); + test_rpc_storage_info_run(STORAGE_ANY_PATH_PREFIX, ++command_id); + test_rpc_storage_info_run(STORAGE_INT_PATH_PREFIX, ++command_id); + test_rpc_storage_info_run(STORAGE_EXT_PATH_PREFIX, ++command_id); } #define TEST_DIR_STAT_NAME TEST_DIR "stat_dir" @@ -897,8 +897,8 @@ MU_TEST(test_storage_stat) { test_create_file(TEST_DIR_STAT "l33t.txt", 1337); test_rpc_storage_stat_run("/", ++command_id); - test_rpc_storage_stat_run("/int", ++command_id); - test_rpc_storage_stat_run("/ext", ++command_id); + test_rpc_storage_stat_run(STORAGE_INT_PATH_PREFIX, ++command_id); + test_rpc_storage_stat_run(STORAGE_EXT_PATH_PREFIX, ++command_id); test_rpc_storage_stat_run(TEST_DIR_STAT "empty.txt", ++command_id); test_rpc_storage_stat_run(TEST_DIR_STAT "l33t.txt", ++command_id); @@ -1225,7 +1225,7 @@ MU_TEST(test_storage_mkdir) { } static void test_storage_calculate_md5sum(const char* path, char* md5sum) { - Storage* api = furi_record_open("storage"); + Storage* api = furi_record_open(RECORD_STORAGE); File* file = storage_file_alloc(api); if(storage_file_open(file, path, FSAM_READ, FSOM_OPEN_EXISTING)) { @@ -1257,7 +1257,7 @@ static void test_storage_calculate_md5sum(const char* path, char* md5sum) { storage_file_close(file); storage_file_free(file); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); } static void test_storage_md5sum_run( @@ -1516,7 +1516,8 @@ static void test_app_get_status_lock_run(bool locked_expected, uint32_t command_ MU_TEST(test_app_start_and_lock_status) { test_app_get_status_lock_run(false, ++command_id); - test_app_start_run(NULL, "/ext/file", PB_CommandStatus_ERROR_INVALID_PARAMETERS, ++command_id); + test_app_start_run( + NULL, EXT_PATH("file"), PB_CommandStatus_ERROR_INVALID_PARAMETERS, ++command_id); test_app_start_run(NULL, NULL, PB_CommandStatus_ERROR_INVALID_PARAMETERS, ++command_id); test_app_get_status_lock_run(false, ++command_id); test_app_start_run( @@ -1765,23 +1766,23 @@ MU_TEST_SUITE(test_rpc_session) { MU_RUN_TEST(test_rpc_feed_rubbish); MU_RUN_TEST(test_rpc_multisession_ping); - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); if(storage_sd_status(storage) != FSE_OK) { FURI_LOG_E(TAG, "SD card not mounted - skip storage tests"); } else { MU_RUN_TEST(test_rpc_multisession_storage); } - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); } int run_minunit_test_rpc() { - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); if(storage_sd_status(storage) != FSE_OK) { FURI_LOG_E(TAG, "SD card not mounted - skip storage tests"); } else { MU_RUN_SUITE(test_rpc_storage); } - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); MU_RUN_SUITE(test_rpc_system); MU_RUN_SUITE(test_rpc_app); MU_RUN_SUITE(test_rpc_session); diff --git a/applications/unit_tests/storage/dirwalk_test.c b/applications/unit_tests/storage/dirwalk_test.c index 25e12259..db3d91a9 100644 --- a/applications/unit_tests/storage/dirwalk_test.c +++ b/applications/unit_tests/storage/dirwalk_test.c @@ -175,10 +175,10 @@ MU_TEST_1(test_dirwalk_full, Storage* storage) { storage_test_paths_alloc(storage_test_dirwalk_full, COUNT_OF(storage_test_dirwalk_full)); DirWalk* dir_walk = dir_walk_alloc(storage); - mu_check(dir_walk_open(dir_walk, "/ext/dirwalk")); + mu_check(dir_walk_open(dir_walk, EXT_PATH("dirwalk"))); while(dir_walk_read(dir_walk, path, &fileinfo) == DirWalkOK) { - string_right(path, strlen("/ext/dirwalk/")); + string_right(path, strlen(EXT_PATH("dirwalk/"))); mu_check(storage_test_paths_mark(paths, path, (fileinfo.flags & FSF_DIRECTORY))); } @@ -200,10 +200,10 @@ MU_TEST_1(test_dirwalk_no_recursive, Storage* storage) { DirWalk* dir_walk = dir_walk_alloc(storage); dir_walk_set_recursive(dir_walk, false); - mu_check(dir_walk_open(dir_walk, "/ext/dirwalk")); + mu_check(dir_walk_open(dir_walk, EXT_PATH("dirwalk"))); while(dir_walk_read(dir_walk, path, &fileinfo) == DirWalkOK) { - string_right(path, strlen("/ext/dirwalk/")); + string_right(path, strlen(EXT_PATH("dirwalk/"))); mu_check(storage_test_paths_mark(paths, path, (fileinfo.flags & FSF_DIRECTORY))); } @@ -239,10 +239,10 @@ MU_TEST_1(test_dirwalk_filter, Storage* storage) { DirWalk* dir_walk = dir_walk_alloc(storage); dir_walk_set_filter_cb(dir_walk, test_dirwalk_filter_no_folder_ext, NULL); - mu_check(dir_walk_open(dir_walk, "/ext/dirwalk")); + mu_check(dir_walk_open(dir_walk, EXT_PATH("dirwalk"))); while(dir_walk_read(dir_walk, path, &fileinfo) == DirWalkOK) { - string_right(path, strlen("/ext/dirwalk/")); + string_right(path, strlen(EXT_PATH("dirwalk/"))); mu_check(storage_test_paths_mark(paths, path, (fileinfo.flags & FSF_DIRECTORY))); } @@ -255,15 +255,15 @@ MU_TEST_1(test_dirwalk_filter, Storage* storage) { } MU_TEST_SUITE(test_dirwalk_suite) { - Storage* storage = furi_record_open("storage"); - storage_dirs_create(storage, "/ext/dirwalk"); + Storage* storage = furi_record_open(RECORD_STORAGE); + storage_dirs_create(storage, EXT_PATH("dirwalk")); MU_RUN_TEST_1(test_dirwalk_full, storage); MU_RUN_TEST_1(test_dirwalk_no_recursive, storage); MU_RUN_TEST_1(test_dirwalk_filter, storage); - storage_simply_remove_recursive(storage, "/ext/dirwalk"); - furi_record_close("storage"); + storage_simply_remove_recursive(storage, EXT_PATH("dirwalk")); + furi_record_close(RECORD_STORAGE); } int run_minunit_test_dirwalk() { diff --git a/applications/unit_tests/storage/storage_test.c b/applications/unit_tests/storage/storage_test.c index c21abecc..c3628a4f 100644 --- a/applications/unit_tests/storage/storage_test.c +++ b/applications/unit_tests/storage/storage_test.c @@ -2,28 +2,28 @@ #include #include -#define STORAGE_LOCKED_FILE "/ext/locked_file.test" -#define STORAGE_LOCKED_DIR "/int" +#define STORAGE_LOCKED_FILE EXT_PATH("locked_file.test") +#define STORAGE_LOCKED_DIR STORAGE_INT_PATH_PREFIX static void storage_file_open_lock_setup() { - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); File* file = storage_file_alloc(storage); storage_simply_remove(storage, STORAGE_LOCKED_FILE); mu_check(storage_file_open(file, STORAGE_LOCKED_FILE, FSAM_WRITE, FSOM_CREATE_NEW)); mu_check(storage_file_write(file, "0123", 4) == 4); mu_check(storage_file_close(file)); storage_file_free(file); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); } static void storage_file_open_lock_teardown() { - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); mu_check(storage_simply_remove(storage, STORAGE_LOCKED_FILE)); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); } static int32_t storage_file_locker(void* ctx) { - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); FuriSemaphore* semaphore = ctx; File* file = storage_file_alloc(storage); furi_check(storage_file_open(file, STORAGE_LOCKED_FILE, FSAM_READ_WRITE, FSOM_OPEN_EXISTING)); @@ -31,13 +31,13 @@ static int32_t storage_file_locker(void* ctx) { furi_delay_ms(1000); furi_check(storage_file_close(file)); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); storage_file_free(file); return 0; } MU_TEST(storage_file_open_lock) { - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); bool result = false; FuriSemaphore* semaphore = furi_semaphore_alloc(1, 0); File* file = storage_file_alloc(storage); @@ -63,13 +63,13 @@ MU_TEST(storage_file_open_lock) { // clean data storage_file_free(file); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); mu_assert(result, "cannot open locked file"); } MU_TEST(storage_file_open_close) { - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); File* file; file = storage_file_alloc(storage); @@ -84,7 +84,7 @@ MU_TEST(storage_file_open_close) { storage_file_free(file); } - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); } MU_TEST_SUITE(storage_file) { @@ -95,7 +95,7 @@ MU_TEST_SUITE(storage_file) { } MU_TEST(storage_dir_open_close) { - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); File* file; file = storage_file_alloc(storage); @@ -109,11 +109,11 @@ MU_TEST(storage_dir_open_close) { storage_file_free(file); } - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); } static int32_t storage_dir_locker(void* ctx) { - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); FuriSemaphore* semaphore = ctx; File* file = storage_file_alloc(storage); furi_check(storage_dir_open(file, STORAGE_LOCKED_DIR)); @@ -121,13 +121,13 @@ static int32_t storage_dir_locker(void* ctx) { furi_delay_ms(1000); furi_check(storage_dir_close(file)); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); storage_file_free(file); return 0; } MU_TEST(storage_dir_open_lock) { - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); bool result = false; FuriSemaphore* semaphore = furi_semaphore_alloc(1, 0); File* file = storage_file_alloc(storage); @@ -153,7 +153,7 @@ MU_TEST(storage_dir_open_lock) { // clean data storage_file_free(file); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); mu_assert(result, "cannot open locked dir"); } @@ -265,46 +265,48 @@ static bool storage_dir_rename_check(Storage* storage, const char* base) { } MU_TEST(storage_file_rename) { - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); File* file = storage_file_alloc(storage); - mu_check(write_file_13DA(storage, "/ext/file.old")); - mu_check(check_file_13DA(storage, "/ext/file.old")); - mu_assert_int_eq(FSE_OK, storage_common_rename(storage, "/ext/file.old", "/ext/file.new")); - mu_assert_int_eq(FSE_NOT_EXIST, storage_common_stat(storage, "/ext/file.old", NULL)); - mu_assert_int_eq(FSE_OK, storage_common_stat(storage, "/ext/file.new", NULL)); - mu_check(check_file_13DA(storage, "/ext/file.new")); - mu_assert_int_eq(FSE_OK, storage_common_remove(storage, "/ext/file.new")); + mu_check(write_file_13DA(storage, EXT_PATH("file.old"))); + mu_check(check_file_13DA(storage, EXT_PATH("file.old"))); + mu_assert_int_eq( + FSE_OK, storage_common_rename(storage, EXT_PATH("file.old"), EXT_PATH("file.new"))); + mu_assert_int_eq(FSE_NOT_EXIST, storage_common_stat(storage, EXT_PATH("file.old"), NULL)); + mu_assert_int_eq(FSE_OK, storage_common_stat(storage, EXT_PATH("file.new"), NULL)); + mu_check(check_file_13DA(storage, EXT_PATH("file.new"))); + mu_assert_int_eq(FSE_OK, storage_common_remove(storage, EXT_PATH("file.new"))); storage_file_free(file); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); } MU_TEST(storage_dir_rename) { - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); - storage_dir_create(storage, "/ext/dir.old"); + storage_dir_create(storage, EXT_PATH("dir.old")); - mu_check(storage_dir_rename_check(storage, "/ext/dir.old")); + mu_check(storage_dir_rename_check(storage, EXT_PATH("dir.old"))); - mu_assert_int_eq(FSE_OK, storage_common_rename(storage, "/ext/dir.old", "/ext/dir.new")); - mu_assert_int_eq(FSE_NOT_EXIST, storage_common_stat(storage, "/ext/dir.old", NULL)); - mu_check(storage_dir_rename_check(storage, "/ext/dir.new")); + mu_assert_int_eq( + FSE_OK, storage_common_rename(storage, EXT_PATH("dir.old"), EXT_PATH("dir.new"))); + mu_assert_int_eq(FSE_NOT_EXIST, storage_common_stat(storage, EXT_PATH("dir.old"), NULL)); + mu_check(storage_dir_rename_check(storage, EXT_PATH("dir.new"))); - storage_dir_remove(storage, "/ext/dir.new"); - mu_assert_int_eq(FSE_NOT_EXIST, storage_common_stat(storage, "/ext/dir.new", NULL)); + storage_dir_remove(storage, EXT_PATH("dir.new")); + mu_assert_int_eq(FSE_NOT_EXIST, storage_common_stat(storage, EXT_PATH("dir.new"), NULL)); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); } MU_TEST_SUITE(storage_rename) { MU_RUN_TEST(storage_file_rename); MU_RUN_TEST(storage_dir_rename); - Storage* storage = furi_record_open("storage"); - storage_dir_remove(storage, "/ext/dir.old"); - storage_dir_remove(storage, "/ext/dir.new"); - furi_record_close("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); + storage_dir_remove(storage, EXT_PATH("dir.old")); + storage_dir_remove(storage, EXT_PATH("dir.new")); + furi_record_close(RECORD_STORAGE); } int run_minunit_test_storage() { diff --git a/applications/unit_tests/stream/stream_test.c b/applications/unit_tests/stream/stream_test.c index 65f1409a..36155e33 100644 --- a/applications/unit_tests/stream/stream_test.c +++ b/applications/unit_tests/stream/stream_test.c @@ -278,19 +278,20 @@ MU_TEST(stream_composite_test) { stream_free(stream); // test file stream - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); stream = file_stream_alloc(storage); - mu_check(file_stream_open(stream, "/ext/filestream.str", FSAM_READ_WRITE, FSOM_CREATE_ALWAYS)); + mu_check( + file_stream_open(stream, EXT_PATH("filestream.str"), FSAM_READ_WRITE, FSOM_CREATE_ALWAYS)); MU_RUN_TEST_1(stream_composite_subtest, stream); stream_free(stream); // test buffered file stream stream = buffered_file_stream_alloc(storage); mu_check(buffered_file_stream_open( - stream, "/ext/filestream.str", FSAM_READ_WRITE, FSOM_CREATE_ALWAYS)); + stream, EXT_PATH("filestream.str"), FSAM_READ_WRITE, FSOM_CREATE_ALWAYS)); MU_RUN_TEST_1(stream_composite_subtest, stream); stream_free(stream); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); } MU_TEST_1(stream_write_subtest, Stream* stream) { @@ -307,7 +308,7 @@ MU_TEST_1(stream_read_subtest, Stream* stream) { MU_TEST(stream_write_read_save_load_test) { Stream* stream_orig = string_stream_alloc(); Stream* stream_copy = string_stream_alloc(); - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); // write, read MU_RUN_TEST_1(stream_write_subtest, stream_orig); @@ -321,7 +322,7 @@ MU_TEST(stream_write_read_save_load_test) { mu_check(stream_seek(stream_orig, 0, StreamOffsetFromStart)); mu_assert_int_eq( strlen(stream_test_data), - stream_save_to_file(stream_orig, storage, "/ext/filestream.str", FSOM_CREATE_ALWAYS)); + stream_save_to_file(stream_orig, storage, EXT_PATH("filestream.str"), FSOM_CREATE_ALWAYS)); stream_free(stream_copy); stream_free(stream_orig); @@ -330,11 +331,11 @@ MU_TEST(stream_write_read_save_load_test) { Stream* stream_new = string_stream_alloc(); mu_assert_int_eq( strlen(stream_test_data), - stream_load_from_file(stream_new, storage, "/ext/filestream.str")); + stream_load_from_file(stream_new, storage, EXT_PATH("filestream.str"))); MU_RUN_TEST_1(stream_read_subtest, stream_new); stream_free(stream_new); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); } MU_TEST_1(stream_split_subtest, Stream* stream) { @@ -369,20 +370,21 @@ MU_TEST(stream_split_test) { stream_free(stream); // test file stream - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); stream = file_stream_alloc(storage); - mu_check(file_stream_open(stream, "/ext/filestream.str", FSAM_READ_WRITE, FSOM_CREATE_ALWAYS)); + mu_check( + file_stream_open(stream, EXT_PATH("filestream.str"), FSAM_READ_WRITE, FSOM_CREATE_ALWAYS)); MU_RUN_TEST_1(stream_split_subtest, stream); stream_free(stream); // test buffered stream stream = buffered_file_stream_alloc(storage); mu_check(buffered_file_stream_open( - stream, "/ext/filestream.str", FSAM_READ_WRITE, FSOM_CREATE_ALWAYS)); + stream, EXT_PATH("filestream.str"), FSAM_READ_WRITE, FSOM_CREATE_ALWAYS)); MU_RUN_TEST_1(stream_split_subtest, stream); stream_free(stream); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); } MU_TEST(stream_buffered_large_file_test) { @@ -391,7 +393,7 @@ MU_TEST(stream_buffered_large_file_test) { string_init(input_data); string_init(output_data); - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); // generate test data consisting of several identical lines const size_t data_size = 4096; @@ -405,7 +407,7 @@ MU_TEST(stream_buffered_large_file_test) { // write test data to file Stream* stream = buffered_file_stream_alloc(storage); mu_check(buffered_file_stream_open( - stream, "/ext/filestream.str", FSAM_READ_WRITE, FSOM_CREATE_ALWAYS)); + stream, EXT_PATH("filestream.str"), FSAM_READ_WRITE, FSOM_CREATE_ALWAYS)); mu_assert_int_eq(0, stream_size(stream)); mu_assert_int_eq(string_size(input_data), stream_write_string(stream, input_data)); mu_assert_int_eq(string_size(input_data), stream_size(stream)); @@ -459,7 +461,7 @@ MU_TEST(stream_buffered_large_file_test) { stream_free(stream); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); string_clear(input_data); string_clear(output_data); } diff --git a/applications/unit_tests/subghz/subghz_test.c b/applications/unit_tests/subghz/subghz_test.c index 23c6117b..4799d235 100644 --- a/applications/unit_tests/subghz/subghz_test.c +++ b/applications/unit_tests/subghz/subghz_test.c @@ -9,10 +9,10 @@ #include #define TAG "SubGhz TEST" -#define KEYSTORE_DIR_NAME "/ext/subghz/assets/keeloq_mfcodes" -#define CAME_ATOMO_DIR_NAME "/ext/subghz/assets/came_atomo" -#define NICE_FLOR_S_DIR_NAME "/ext/subghz/assets/nice_flor_s" -#define TEST_RANDOM_DIR_NAME "/ext/unit_tests/subghz/test_random_raw.sub" +#define KEYSTORE_DIR_NAME EXT_PATH("subghz/assets/keeloq_mfcodes") +#define CAME_ATOMO_DIR_NAME EXT_PATH("subghz/assets/came_atomo") +#define NICE_FLOR_S_DIR_NAME EXT_PATH("subghz/assets/nice_flor_s") +#define TEST_RANDOM_DIR_NAME EXT_PATH("unit_tests/subghz/test_random_raw.sub") #define TEST_RANDOM_COUNT_PARSE 119 #define TEST_TIMEOUT 10000 @@ -145,7 +145,7 @@ static bool subghz_encoder_test(const char* path) { string_init(temp_str); bool file_load = false; - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); FlipperFormat* fff_data_file = flipper_format_file_alloc(storage); do { @@ -210,234 +210,243 @@ MU_TEST(subghz_keystore_test) { MU_TEST(subghz_decoder_came_atomo_test) { mu_assert( subghz_decoder_test( - "/ext/unit_tests/subghz/came_atomo_raw.sub", SUBGHZ_PROTOCOL_CAME_ATOMO_NAME), + EXT_PATH("unit_tests/subghz/came_atomo_raw.sub"), SUBGHZ_PROTOCOL_CAME_ATOMO_NAME), "Test decoder " SUBGHZ_PROTOCOL_CAME_ATOMO_NAME " error\r\n"); } MU_TEST(subghz_decoder_came_test) { mu_assert( - subghz_decoder_test("/ext/unit_tests/subghz/came_raw.sub", SUBGHZ_PROTOCOL_CAME_NAME), + subghz_decoder_test(EXT_PATH("unit_tests/subghz/came_raw.sub"), SUBGHZ_PROTOCOL_CAME_NAME), "Test decoder " SUBGHZ_PROTOCOL_CAME_NAME " error\r\n"); } MU_TEST(subghz_decoder_came_twee_test) { mu_assert( subghz_decoder_test( - "/ext/unit_tests/subghz/came_twee_raw.sub", SUBGHZ_PROTOCOL_CAME_TWEE_NAME), + EXT_PATH("unit_tests/subghz/came_twee_raw.sub"), SUBGHZ_PROTOCOL_CAME_TWEE_NAME), "Test decoder " SUBGHZ_PROTOCOL_CAME_TWEE_NAME " error\r\n"); } MU_TEST(subghz_decoder_faac_slh_test) { mu_assert( subghz_decoder_test( - "/ext/unit_tests/subghz/faac_slh_raw.sub", SUBGHZ_PROTOCOL_FAAC_SLH_NAME), + EXT_PATH("unit_tests/subghz/faac_slh_raw.sub"), SUBGHZ_PROTOCOL_FAAC_SLH_NAME), "Test decoder " SUBGHZ_PROTOCOL_FAAC_SLH_NAME " error\r\n"); } MU_TEST(subghz_decoder_gate_tx_test) { mu_assert( - subghz_decoder_test("/ext/unit_tests/subghz/gate_tx_raw.sub", SUBGHZ_PROTOCOL_GATE_TX_NAME), + subghz_decoder_test( + EXT_PATH("unit_tests/subghz/gate_tx_raw.sub"), SUBGHZ_PROTOCOL_GATE_TX_NAME), "Test decoder " SUBGHZ_PROTOCOL_GATE_TX_NAME " error\r\n"); } MU_TEST(subghz_decoder_hormann_hsm_test) { mu_assert( subghz_decoder_test( - "/ext/unit_tests/subghz/hormann_hsm_raw.sub", SUBGHZ_PROTOCOL_HORMANN_HSM_NAME), + EXT_PATH("unit_tests/subghz/hormann_hsm_raw.sub"), SUBGHZ_PROTOCOL_HORMANN_HSM_NAME), "Test decoder " SUBGHZ_PROTOCOL_HORMANN_HSM_NAME " error\r\n"); } MU_TEST(subghz_decoder_ido_test) { mu_assert( - subghz_decoder_test("/ext/unit_tests/subghz/ido_117_111_raw.sub", SUBGHZ_PROTOCOL_IDO_NAME), + subghz_decoder_test( + EXT_PATH("unit_tests/subghz/ido_117_111_raw.sub"), SUBGHZ_PROTOCOL_IDO_NAME), "Test decoder " SUBGHZ_PROTOCOL_IDO_NAME " error\r\n"); } MU_TEST(subghz_decoder_keelog_test) { mu_assert( - subghz_decoder_test("/ext/unit_tests/subghz/doorhan_raw.sub", SUBGHZ_PROTOCOL_KEELOQ_NAME), + subghz_decoder_test( + EXT_PATH("unit_tests/subghz/doorhan_raw.sub"), SUBGHZ_PROTOCOL_KEELOQ_NAME), "Test decoder " SUBGHZ_PROTOCOL_KEELOQ_NAME " error\r\n"); } MU_TEST(subghz_decoder_kia_seed_test) { mu_assert( - subghz_decoder_test("/ext/unit_tests/subghz/kia_seed_raw.sub", SUBGHZ_PROTOCOL_KIA_NAME), + subghz_decoder_test( + EXT_PATH("unit_tests/subghz/kia_seed_raw.sub"), SUBGHZ_PROTOCOL_KIA_NAME), "Test decoder " SUBGHZ_PROTOCOL_KIA_NAME " error\r\n"); } MU_TEST(subghz_decoder_nero_radio_test) { mu_assert( subghz_decoder_test( - "/ext/unit_tests/subghz/nero_radio_raw.sub", SUBGHZ_PROTOCOL_NERO_RADIO_NAME), + EXT_PATH("unit_tests/subghz/nero_radio_raw.sub"), SUBGHZ_PROTOCOL_NERO_RADIO_NAME), "Test decoder " SUBGHZ_PROTOCOL_NERO_RADIO_NAME " error\r\n"); } MU_TEST(subghz_decoder_nero_sketch_test) { mu_assert( subghz_decoder_test( - "/ext/unit_tests/subghz/nero_sketch_raw.sub", SUBGHZ_PROTOCOL_NERO_SKETCH_NAME), + EXT_PATH("unit_tests/subghz/nero_sketch_raw.sub"), SUBGHZ_PROTOCOL_NERO_SKETCH_NAME), "Test decoder " SUBGHZ_PROTOCOL_NERO_SKETCH_NAME " error\r\n"); } MU_TEST(subghz_decoder_nice_flo_test) { mu_assert( subghz_decoder_test( - "/ext/unit_tests/subghz/nice_flo_raw.sub", SUBGHZ_PROTOCOL_NICE_FLO_NAME), + EXT_PATH("unit_tests/subghz/nice_flo_raw.sub"), SUBGHZ_PROTOCOL_NICE_FLO_NAME), "Test decoder " SUBGHZ_PROTOCOL_NICE_FLO_NAME " error\r\n"); } MU_TEST(subghz_decoder_nice_flor_s_test) { mu_assert( subghz_decoder_test( - "/ext/unit_tests/subghz/nice_flor_s_raw.sub", SUBGHZ_PROTOCOL_NICE_FLOR_S_NAME), + EXT_PATH("unit_tests/subghz/nice_flor_s_raw.sub"), SUBGHZ_PROTOCOL_NICE_FLOR_S_NAME), "Test decoder " SUBGHZ_PROTOCOL_NICE_FLOR_S_NAME " error\r\n"); } MU_TEST(subghz_decoder_princeton_test) { mu_assert( subghz_decoder_test( - "/ext/unit_tests/subghz/Princeton_raw.sub", SUBGHZ_PROTOCOL_PRINCETON_NAME), + EXT_PATH("unit_tests/subghz/Princeton_raw.sub"), SUBGHZ_PROTOCOL_PRINCETON_NAME), "Test decoder " SUBGHZ_PROTOCOL_PRINCETON_NAME " error\r\n"); } MU_TEST(subghz_decoder_scher_khan_magic_code_test) { mu_assert( subghz_decoder_test( - "/ext/unit_tests/subghz/scher_khan_magic_code.sub", SUBGHZ_PROTOCOL_SCHER_KHAN_NAME), + EXT_PATH("unit_tests/subghz/scher_khan_magic_code.sub"), + SUBGHZ_PROTOCOL_SCHER_KHAN_NAME), "Test decoder " SUBGHZ_PROTOCOL_SCHER_KHAN_NAME " error\r\n"); } MU_TEST(subghz_decoder_somfy_keytis_test) { mu_assert( subghz_decoder_test( - "/ext/unit_tests/subghz/Somfy_keytis_raw.sub", SUBGHZ_PROTOCOL_SOMFY_KEYTIS_NAME), + EXT_PATH("unit_tests/subghz/Somfy_keytis_raw.sub"), SUBGHZ_PROTOCOL_SOMFY_KEYTIS_NAME), "Test decoder " SUBGHZ_PROTOCOL_SOMFY_KEYTIS_NAME " error\r\n"); } MU_TEST(subghz_decoder_somfy_telis_test) { mu_assert( subghz_decoder_test( - "/ext/unit_tests/subghz/somfy_telis_raw.sub", SUBGHZ_PROTOCOL_SOMFY_TELIS_NAME), + EXT_PATH("unit_tests/subghz/somfy_telis_raw.sub"), SUBGHZ_PROTOCOL_SOMFY_TELIS_NAME), "Test decoder " SUBGHZ_PROTOCOL_SOMFY_TELIS_NAME " error\r\n"); } MU_TEST(subghz_decoder_star_line_test) { mu_assert( subghz_decoder_test( - "/ext/unit_tests/subghz/cenmax_raw.sub", SUBGHZ_PROTOCOL_STAR_LINE_NAME), + EXT_PATH("unit_tests/subghz/cenmax_raw.sub"), SUBGHZ_PROTOCOL_STAR_LINE_NAME), "Test decoder " SUBGHZ_PROTOCOL_STAR_LINE_NAME " error\r\n"); } MU_TEST(subghz_decoder_linear_test) { mu_assert( - subghz_decoder_test("/ext/unit_tests/subghz/linear_raw.sub", SUBGHZ_PROTOCOL_LINEAR_NAME), + subghz_decoder_test( + EXT_PATH("unit_tests/subghz/linear_raw.sub"), SUBGHZ_PROTOCOL_LINEAR_NAME), "Test decoder " SUBGHZ_PROTOCOL_LINEAR_NAME " error\r\n"); } MU_TEST(subghz_decoder_megacode_test) { mu_assert( subghz_decoder_test( - "/ext/unit_tests/subghz/megacode_raw.sub", SUBGHZ_PROTOCOL_MEGACODE_NAME), + EXT_PATH("unit_tests/subghz/megacode_raw.sub"), SUBGHZ_PROTOCOL_MEGACODE_NAME), "Test decoder " SUBGHZ_PROTOCOL_MEGACODE_NAME " error\r\n"); } MU_TEST(subghz_decoder_secplus_v1_test) { mu_assert( subghz_decoder_test( - "/ext/unit_tests/subghz/security_pls_1_0_raw.sub", SUBGHZ_PROTOCOL_SECPLUS_V1_NAME), + EXT_PATH("unit_tests/subghz/security_pls_1_0_raw.sub"), + SUBGHZ_PROTOCOL_SECPLUS_V1_NAME), "Test decoder " SUBGHZ_PROTOCOL_SECPLUS_V1_NAME " error\r\n"); } MU_TEST(subghz_decoder_secplus_v2_test) { mu_assert( subghz_decoder_test( - "/ext/unit_tests/subghz/security_pls_2_0_raw.sub", SUBGHZ_PROTOCOL_SECPLUS_V2_NAME), + EXT_PATH("unit_tests/subghz/security_pls_2_0_raw.sub"), + SUBGHZ_PROTOCOL_SECPLUS_V2_NAME), "Test decoder " SUBGHZ_PROTOCOL_SECPLUS_V2_NAME " error\r\n"); } MU_TEST(subghz_decoder_holtek_test) { mu_assert( - subghz_decoder_test("/ext/unit_tests/subghz/holtek_raw.sub", SUBGHZ_PROTOCOL_HOLTEK_NAME), + subghz_decoder_test( + EXT_PATH("unit_tests/subghz/holtek_raw.sub"), SUBGHZ_PROTOCOL_HOLTEK_NAME), "Test decoder " SUBGHZ_PROTOCOL_HOLTEK_NAME " error\r\n"); } MU_TEST(subghz_decoder_power_smart_test) { mu_assert( subghz_decoder_test( - "/ext/unit_tests/subghz/power_smart_raw.sub", SUBGHZ_PROTOCOL_POWER_SMART_NAME), + EXT_PATH("unit_tests/subghz/power_smart_raw.sub"), SUBGHZ_PROTOCOL_POWER_SMART_NAME), "Test decoder " SUBGHZ_PROTOCOL_POWER_SMART_NAME " error\r\n"); } //test encoders MU_TEST(subghz_encoder_princeton_test) { mu_assert( - subghz_encoder_test("/ext/unit_tests/subghz/princeton.sub"), + subghz_encoder_test(EXT_PATH("unit_tests/subghz/princeton.sub")), "Test encoder " SUBGHZ_PROTOCOL_PRINCETON_NAME " error\r\n"); } MU_TEST(subghz_encoder_came_test) { mu_assert( - subghz_encoder_test("/ext/unit_tests/subghz/came.sub"), + subghz_encoder_test(EXT_PATH("unit_tests/subghz/came.sub")), "Test encoder " SUBGHZ_PROTOCOL_CAME_NAME " error\r\n"); } MU_TEST(subghz_encoder_came_twee_test) { mu_assert( - subghz_encoder_test("/ext/unit_tests/subghz/came_twee.sub"), + subghz_encoder_test(EXT_PATH("unit_tests/subghz/came_twee.sub")), "Test encoder " SUBGHZ_PROTOCOL_CAME_TWEE_NAME " error\r\n"); } MU_TEST(subghz_encoder_gate_tx_test) { mu_assert( - subghz_encoder_test("/ext/unit_tests/subghz/gate_tx.sub"), + subghz_encoder_test(EXT_PATH("unit_tests/subghz/gate_tx.sub")), "Test encoder " SUBGHZ_PROTOCOL_GATE_TX_NAME " error\r\n"); } MU_TEST(subghz_encoder_nice_flo_test) { mu_assert( - subghz_encoder_test("/ext/unit_tests/subghz/nice_flo.sub"), + subghz_encoder_test(EXT_PATH("unit_tests/subghz/nice_flo.sub")), "Test encoder " SUBGHZ_PROTOCOL_NICE_FLO_NAME " error\r\n"); } MU_TEST(subghz_encoder_keelog_test) { mu_assert( - subghz_encoder_test("/ext/unit_tests/subghz/doorhan.sub"), + subghz_encoder_test(EXT_PATH("unit_tests/subghz/doorhan.sub")), "Test encoder " SUBGHZ_PROTOCOL_KEELOQ_NAME " error\r\n"); } MU_TEST(subghz_encoder_linear_test) { mu_assert( - subghz_encoder_test("/ext/unit_tests/subghz/linear.sub"), + subghz_encoder_test(EXT_PATH("unit_tests/subghz/linear.sub")), "Test encoder " SUBGHZ_PROTOCOL_LINEAR_NAME " error\r\n"); } MU_TEST(subghz_encoder_megacode_test) { mu_assert( - subghz_encoder_test("/ext/unit_tests/subghz/megacode.sub"), + subghz_encoder_test(EXT_PATH("unit_tests/subghz/megacode.sub")), "Test encoder " SUBGHZ_PROTOCOL_MEGACODE_NAME " error\r\n"); } MU_TEST(subghz_encoder_holtek_test) { mu_assert( - subghz_encoder_test("/ext/unit_tests/subghz/holtek.sub"), + subghz_encoder_test(EXT_PATH("unit_tests/subghz/holtek.sub")), "Test encoder " SUBGHZ_PROTOCOL_HOLTEK_NAME " error\r\n"); } MU_TEST(subghz_encoder_secplus_v1_test) { mu_assert( - subghz_encoder_test("/ext/unit_tests/subghz/security_pls_1_0.sub"), + subghz_encoder_test(EXT_PATH("unit_tests/subghz/security_pls_1_0.sub")), "Test encoder " SUBGHZ_PROTOCOL_SECPLUS_V1_NAME " error\r\n"); } MU_TEST(subghz_encoder_secplus_v2_test) { mu_assert( - subghz_encoder_test("/ext/unit_tests/subghz/security_pls_2_0.sub"), + subghz_encoder_test(EXT_PATH("unit_tests/subghz/security_pls_2_0.sub")), "Test encoder " SUBGHZ_PROTOCOL_SECPLUS_V2_NAME " error\r\n"); } MU_TEST(subghz_encoder_power_smart_test) { mu_assert( - subghz_encoder_test("/ext/unit_tests/subghz/power_smart.sub"), + subghz_encoder_test(EXT_PATH("unit_tests/subghz/power_smart.sub")), "Test encoder " SUBGHZ_PROTOCOL_POWER_SMART_NAME " error\r\n"); } diff --git a/applications/unit_tests/test_index.c b/applications/unit_tests/test_index.c index ca7641b1..e5282246 100644 --- a/applications/unit_tests/test_index.c +++ b/applications/unit_tests/test_index.c @@ -67,8 +67,8 @@ void unit_tests_cli(Cli* cli, string_t args, void* context) { minunit_fail = 0; minunit_status = 0; - Loader* loader = furi_record_open("loader"); - NotificationApp* notification = furi_record_open("notification"); + Loader* loader = furi_record_open(RECORD_LOADER); + NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION); // TODO: lock device while test running if(loader_is_locked(loader)) { @@ -116,16 +116,16 @@ void unit_tests_cli(Cli* cli, string_t args, void* context) { } } - furi_record_close("notification"); - furi_record_close("loader"); + furi_record_close(RECORD_NOTIFICATION); + furi_record_close(RECORD_LOADER); } void unit_tests_on_system_start() { #ifdef SRV_CLI - Cli* cli = furi_record_open("cli"); + Cli* cli = furi_record_open(RECORD_CLI); // We need to launch apps from tests, so we cannot lock loader cli_add_command(cli, "unit_tests", CliCommandFlagParallelSafe, unit_tests_cli, NULL); - furi_record_close("cli"); + furi_record_close(RECORD_CLI); #endif } diff --git a/applications/updater/cli/updater_cli.c b/applications/updater/cli/updater_cli.c index 3dfd145c..ec209bd1 100644 --- a/applications/updater/cli/updater_cli.c +++ b/applications/updater/cli/updater_cli.c @@ -35,17 +35,17 @@ static void updater_cli_install(string_t manifest_path) { static void updater_cli_backup(string_t args) { printf("Backup /int to '%s'\r\n", string_get_cstr(args)); - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); bool success = lfs_backup_create(storage, string_get_cstr(args)); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); printf("Result: %s\r\n", success ? "OK" : "FAIL"); } static void updater_cli_restore(string_t args) { printf("Restore /int from '%s'\r\n", string_get_cstr(args)); - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); bool success = lfs_backup_unpack(storage, string_get_cstr(args)); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); printf("Result: %s\r\n", success ? "OK" : "FAIL"); } @@ -88,9 +88,9 @@ static void updater_cli_ep(Cli* cli, string_t args, void* context) { static int32_t updater_spawner_thread_worker(void* arg) { UNUSED(arg); - Loader* loader = furi_record_open("loader"); + Loader* loader = furi_record_open(RECORD_LOADER); loader_start(loader, "UpdaterApp", NULL); - furi_record_close("loader"); + furi_record_close(RECORD_LOADER); return 0; } @@ -123,9 +123,9 @@ static void updater_start_app() { void updater_on_system_start() { #ifdef SRV_CLI - Cli* cli = (Cli*)furi_record_open("cli"); + Cli* cli = (Cli*)furi_record_open(RECORD_CLI); cli_add_command(cli, "update", CliCommandFlagDefault, updater_cli_ep, NULL); - furi_record_close("cli"); + furi_record_close(RECORD_CLI); #else UNUSED(updater_cli_ep); #endif diff --git a/applications/updater/updater.c b/applications/updater/updater.c index 4c9fe41f..daba9eaf 100644 --- a/applications/updater/updater.c +++ b/applications/updater/updater.c @@ -36,15 +36,15 @@ Updater* updater_alloc(const char* arg) { Updater* updater = malloc(sizeof(Updater)); if(arg) { string_init_set_str(updater->startup_arg, arg); - string_replace_str(updater->startup_arg, "/any/", "/ext/"); + string_replace_str(updater->startup_arg, ANY_PATH(""), EXT_PATH("")); } else { string_init(updater->startup_arg); } - updater->storage = furi_record_open("storage"); - updater->notification = furi_record_open("notification"); + updater->storage = furi_record_open(RECORD_STORAGE); + updater->notification = furi_record_open(RECORD_NOTIFICATION); - updater->gui = furi_record_open("gui"); + updater->gui = furi_record_open(RECORD_GUI); updater->view_dispatcher = view_dispatcher_alloc(); updater->scene_manager = scene_manager_alloc(&updater_scene_handlers, updater); @@ -111,9 +111,9 @@ void updater_free(Updater* updater) { view_dispatcher_free(updater->view_dispatcher); scene_manager_free(updater->scene_manager); - furi_record_close("gui"); - furi_record_close("storage"); - furi_record_close("notification"); + furi_record_close(RECORD_GUI); + furi_record_close(RECORD_STORAGE); + furi_record_close(RECORD_NOTIFICATION); free(updater); } diff --git a/applications/updater/util/update_task.c b/applications/updater/util/update_task.c index f7b9f812..6864076d 100644 --- a/applications/updater/util/update_task.c +++ b/applications/updater/util/update_task.c @@ -211,7 +211,7 @@ UpdateTask* update_task_alloc() { string_init(update_task->state.status); update_task->manifest = update_manifest_alloc(); - update_task->storage = furi_record_open("storage"); + update_task->storage = furi_record_open(RECORD_STORAGE); update_task->file = storage_file_alloc(update_task->storage); update_task->status_change_cb = NULL; update_task->boot_mode = furi_hal_rtc_get_boot_mode(); @@ -246,7 +246,7 @@ void update_task_free(UpdateTask* update_task) { storage_file_free(update_task->file); update_manifest_free(update_task->manifest); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); string_clear(update_task->update_path); free(update_task); diff --git a/applications/updater/util/update_task_worker_backup.c b/applications/updater/util/update_task_worker_backup.c index 1e8c2f09..09e45953 100644 --- a/applications/updater/util/update_task_worker_backup.c +++ b/applications/updater/util/update_task_worker_backup.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -18,8 +19,6 @@ break; \ } -#define EXT_PATH "/ext" - static bool update_task_pre_update(UpdateTask* update_task) { bool success = false; string_t backup_file_path; @@ -89,7 +88,7 @@ static bool update_task_post_update(UpdateTask* update_task) { progress.total_files = tar_archive_get_entries_count(archive); if(progress.total_files > 0) { - CHECK_RESULT(tar_archive_unpack_to(archive, EXT_PATH)); + CHECK_RESULT(tar_archive_unpack_to(archive, STORAGE_EXT_PATH_PREFIX, NULL)); } } @@ -99,7 +98,9 @@ static bool update_task_post_update(UpdateTask* update_task) { string_init_set(tmp_path, update_task->update_path); path_append(tmp_path, string_get_cstr(update_task->manifest->splash_file)); if(storage_common_copy( - update_task->storage, string_get_cstr(tmp_path), "/int/slideshow") != FSE_OK) { + update_task->storage, + string_get_cstr(tmp_path), + INT_PATH(SLIDESHOW_FILE_NAME)) != FSE_OK) { // actually, not critical } string_clear(tmp_path); @@ -129,10 +130,6 @@ int32_t update_task_worker_backup_restore(void* context) { break; } - /* Waiting for BT service to 'start', so we don't race for boot mode flag */ - furi_record_open("bt"); - furi_record_close("bt"); - if(boot_mode == FuriHalRtcBootModePreUpdate) { success = update_task_pre_update(update_task); } else if(boot_mode == FuriHalRtcBootModePostUpdate) { diff --git a/firmware/targets/f7/Src/update.c b/firmware/targets/f7/Src/update.c index bab3b9aa..af247195 100644 --- a/firmware/targets/f7/Src/update.c +++ b/firmware/targets/f7/Src/update.c @@ -11,8 +11,7 @@ #include #include -#define FS_ROOT_PATH "/" -#define UPDATE_POINTER_FILE_PATH FS_ROOT_PATH UPDATE_MANIFEST_POINTER_FILE_NAME +#define UPDATE_POINTER_FILE_PATH "/" UPDATE_MANIFEST_POINTER_FILE_NAME static FATFS* pfs = NULL; @@ -40,7 +39,7 @@ static bool flipper_update_init() { } pfs = malloc(sizeof(FATFS)); - CHECK_FRESULT(f_mount(pfs, FS_ROOT_PATH, 1)); + CHECK_FRESULT(f_mount(pfs, "/", 1)); return true; } @@ -119,7 +118,7 @@ static bool flipper_update_get_manifest_path(string_t out_path) { break; } string_set_str(out_path, manifest_name_buf); - string_right(out_path, strlen("/ext")); + string_right(out_path, strlen(STORAGE_EXT_PATH_PREFIX)); } while(0); f_close(&file); return !string_empty_p(out_path); diff --git a/lib/flipper_format/flipper_format.h b/lib/flipper_format/flipper_format.h index 3f7b71af..09928c18 100644 --- a/lib/flipper_format/flipper_format.h +++ b/lib/flipper_format/flipper_format.h @@ -50,7 +50,7 @@ * const uint16_t array_size = 4; * const uint8_t* array[array_size] = {0x00, 0x01, 0xFF, 0xA3}; * - * if(!flipper_format_file_open_new(format, "/ext/flipper_format_test")) break; + * if(!flipper_format_file_open_new(format, EXT_PATH("flipper_format_test"))) break; * if(!flipper_format_write_header_cstr(format, "Flipper Test File", version)) break; * if(!flipper_format_write_comment_cstr(format, "Just test file")) break; * if(!flipper_format_write_string_cstr(format, "String", string_value)) break; @@ -78,7 +78,7 @@ * string_init(file_type); * string_init(string_value); * - * if(!flipper_format_file_open_existing(file, "/ext/flipper_format_test")) break; + * if(!flipper_format_file_open_existing(file, EXT_PATH("flipper_format_test"))) break; * if(!flipper_format_read_header(file, file_type, &version)) break; * if(!flipper_format_read_string(file, "String", string_value)) break; * if(!flipper_format_read_uint32(file, "UINT", &uint32_value, 1)) break; diff --git a/lib/infrared/worker/infrared_worker.c b/lib/infrared/worker/infrared_worker.c index becd8d88..2b4e3cdb 100644 --- a/lib/infrared/worker/infrared_worker.c +++ b/lib/infrared/worker/infrared_worker.c @@ -236,7 +236,7 @@ InfraredWorker* infrared_worker_alloc() { instance->infrared_decoder = infrared_alloc_decoder(); instance->infrared_encoder = infrared_alloc_encoder(); instance->blink_enable = false; - instance->notification = furi_record_open("notification"); + instance->notification = furi_record_open(RECORD_NOTIFICATION); instance->state = InfraredWorkerStateIdle; return instance; @@ -246,7 +246,7 @@ void infrared_worker_free(InfraredWorker* instance) { furi_assert(instance); furi_assert(instance->state == InfraredWorkerStateIdle); - furi_record_close("notification"); + furi_record_close(RECORD_NOTIFICATION); infrared_free_decoder(instance->infrared_decoder); infrared_free_encoder(instance->infrared_encoder); vStreamBufferDelete(instance->stream); diff --git a/lib/subghz/protocols/raw.c b/lib/subghz/protocols/raw.c index ebc84c11..6a75d159 100644 --- a/lib/subghz/protocols/raw.c +++ b/lib/subghz/protocols/raw.c @@ -87,7 +87,7 @@ bool subghz_protocol_raw_save_to_file_init( FuriHalSubGhzPreset preset) { furi_assert(instance); - instance->storage = furi_record_open("storage"); + instance->storage = furi_record_open(RECORD_STORAGE); instance->flipper_file = flipper_format_file_alloc(instance->storage); string_t temp_str; @@ -181,7 +181,7 @@ void subghz_protocol_raw_save_to_file_stop(SubGhzProtocolDecoderRAW* instance) { instance->upload_raw = NULL; flipper_format_file_close(instance->flipper_file); flipper_format_free(instance->flipper_file); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); } instance->file_is_open = RAWFileIsOpenClose; diff --git a/lib/subghz/subghz_file_encoder_worker.c b/lib/subghz/subghz_file_encoder_worker.c index 457c8b02..8f65ea00 100644 --- a/lib/subghz/subghz_file_encoder_worker.c +++ b/lib/subghz/subghz_file_encoder_worker.c @@ -183,7 +183,7 @@ SubGhzFileEncoderWorker* subghz_file_encoder_worker_alloc() { furi_thread_set_callback(instance->thread, subghz_file_encoder_worker_thread); instance->stream = xStreamBufferCreate(sizeof(int32_t) * 2048, sizeof(int32_t)); - instance->storage = furi_record_open("storage"); + instance->storage = furi_record_open(RECORD_STORAGE); instance->flipper_format = flipper_format_file_alloc(instance->storage); string_init(instance->str_data); @@ -204,7 +204,7 @@ void subghz_file_encoder_worker_free(SubGhzFileEncoderWorker* instance) { string_clear(instance->file_path); flipper_format_free(instance->flipper_format); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); free(instance); } diff --git a/lib/subghz/subghz_keystore.c b/lib/subghz/subghz_keystore.c index d3903bc5..0abd2d5e 100644 --- a/lib/subghz/subghz_keystore.c +++ b/lib/subghz/subghz_keystore.c @@ -189,7 +189,7 @@ bool subghz_keystore_load(SubGhzKeystore* instance, const char* file_name) { FURI_LOG_I(TAG, "Loading keystore %s", file_name); - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); FlipperFormat* flipper_format = flipper_format_file_alloc(storage); do { @@ -229,7 +229,7 @@ bool subghz_keystore_load(SubGhzKeystore* instance, const char* file_name) { } while(0); flipper_format_free(flipper_format); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); string_clear(filetype); @@ -240,7 +240,7 @@ bool subghz_keystore_save(SubGhzKeystore* instance, const char* file_name, uint8 furi_assert(instance); bool result = false; - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); char* decrypted_line = malloc(SUBGHZ_KEYSTORE_FILE_DECRYPTED_LINE_SIZE); char* encrypted_line = malloc(SUBGHZ_KEYSTORE_FILE_ENCRYPTED_LINE_SIZE); @@ -326,7 +326,7 @@ bool subghz_keystore_save(SubGhzKeystore* instance, const char* file_name, uint8 free(encrypted_line); free(decrypted_line); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); return result; } @@ -346,7 +346,7 @@ bool subghz_keystore_raw_encrypted_save( string_init(filetype); SubGhzKeystoreEncryption encryption; - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); char* encrypted_line = malloc(SUBGHZ_KEYSTORE_FILE_ENCRYPTED_LINE_SIZE); @@ -470,7 +470,7 @@ bool subghz_keystore_raw_encrypted_save( free(encrypted_line); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); return encrypted; } @@ -484,7 +484,7 @@ bool subghz_keystore_raw_get_data(const char* file_name, size_t offset, uint8_t* string_t str_temp; string_init(str_temp); - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); char* decrypted_line = malloc(SUBGHZ_KEYSTORE_FILE_DECRYPTED_LINE_SIZE); FlipperFormat* flipper_format = flipper_format_file_alloc(storage); @@ -594,7 +594,7 @@ bool subghz_keystore_raw_get_data(const char* file_name, size_t offset, uint8_t* } while(0); flipper_format_free(flipper_format); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); free(decrypted_line); diff --git a/lib/subghz/types.h b/lib/subghz/types.h index 49f971f0..46e5ec24 100644 --- a/lib/subghz/types.h +++ b/lib/subghz/types.h @@ -11,8 +11,8 @@ #include #include -#define SUBGHZ_APP_FOLDER "/any/subghz" -#define SUBGHZ_RAW_FOLDER "/ext/subghz" +#define SUBGHZ_APP_FOLDER ANY_PATH("subghz") +#define SUBGHZ_RAW_FOLDER EXT_PATH("subghz") #define SUBGHZ_APP_EXTENSION ".sub" #define SUBGHZ_KEY_FILE_VERSION 1 diff --git a/lib/toolbox/dir_walk.c b/lib/toolbox/dir_walk.c index 2efbc0f1..348bd544 100644 --- a/lib/toolbox/dir_walk.c +++ b/lib/toolbox/dir_walk.c @@ -55,7 +55,7 @@ static bool dir_walk_filter(DirWalk* dir_walk, const char* name, FileInfo* filei static DirWalkResult dir_walk_iter(DirWalk* dir_walk, string_t return_path, FileInfo* fileinfo) { DirWalkResult result = DirWalkError; - char* name = malloc(256); + char* name = malloc(256); // FIXME: remove magic number FileInfo info; bool end = false; diff --git a/lib/toolbox/path.c b/lib/toolbox/path.c index 767742ac..38af1efe 100644 --- a/lib/toolbox/path.c +++ b/lib/toolbox/path.c @@ -56,7 +56,7 @@ void path_extract_basename(const char* path, string_t basename) { path_cleanup(basename); size_t pos = string_search_rchar(basename, '/'); if(pos != STRING_FAILURE) { - string_right(basename, pos); + string_right(basename, pos + 1); } } diff --git a/lib/toolbox/saved_struct.c b/lib/toolbox/saved_struct.c index ef7dbcf7..65b761f8 100644 --- a/lib/toolbox/saved_struct.c +++ b/lib/toolbox/saved_struct.c @@ -22,7 +22,7 @@ bool saved_struct_save(const char* path, void* data, size_t size, uint8_t magic, FURI_LOG_I(TAG, "Saving \"%s\"", path); // Store - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); File* file = storage_file_alloc(storage); bool result = true; bool saved = storage_file_open(file, path, FSAM_WRITE, FSOM_CREATE_ALWAYS); @@ -58,7 +58,7 @@ bool saved_struct_save(const char* path, void* data, size_t size, uint8_t magic, storage_file_close(file); storage_file_free(file); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); return result; } @@ -68,7 +68,7 @@ bool saved_struct_load(const char* path, void* data, size_t size, uint8_t magic, SavedStructHeader header; uint8_t* data_read = malloc(size); - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); File* file = storage_file_alloc(storage); bool result = true; bool loaded = storage_file_open(file, path, FSAM_READ, FSOM_OPEN_EXISTING); @@ -120,7 +120,7 @@ bool saved_struct_load(const char* path, void* data, size_t size, uint8_t magic, storage_file_close(file); storage_file_free(file); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); free(data_read); return result; diff --git a/lib/toolbox/stream/file_stream.c b/lib/toolbox/stream/file_stream.c index 70db8af9..f7363c6b 100644 --- a/lib/toolbox/stream/file_stream.c +++ b/lib/toolbox/stream/file_stream.c @@ -176,8 +176,9 @@ static bool file_stream_delete_and_insert( string_t scratch_name; string_t tmp_name; string_init(tmp_name); - storage_get_next_filename(_stream->storage, "/any", ".scratch", ".pad", tmp_name, 255); - string_init_printf(scratch_name, "/any/%s.pad", string_get_cstr(tmp_name)); + storage_get_next_filename( + _stream->storage, STORAGE_ANY_PATH_PREFIX, ".scratch", ".pad", tmp_name, 255); + string_init_printf(scratch_name, ANY_PATH("%s.pad"), string_get_cstr(tmp_name)); string_clear(tmp_name); do { diff --git a/lib/toolbox/tar/tar_archive.c b/lib/toolbox/tar/tar_archive.c index cc107530..5ac89a0f 100644 --- a/lib/toolbox/tar/tar_archive.c +++ b/lib/toolbox/tar/tar_archive.c @@ -165,12 +165,12 @@ bool tar_archive_file_finalize(TarArchive* archive) { typedef struct { TarArchive* archive; const char* work_dir; + Storage_name_converter converter; } TarArchiveDirectoryOpParams; static int archive_extract_foreach_cb(mtar_t* tar, const mtar_header_t* header, void* param) { TarArchiveDirectoryOpParams* op_params = param; TarArchive* archive = op_params->archive; - string_t fname; bool skip_entry = false; if(archive->unpack_cb) { @@ -183,12 +183,14 @@ static int archive_extract_foreach_cb(mtar_t* tar, const mtar_header_t* header, return 0; } + string_t full_extracted_fname; if(header->type == MTAR_TDIR) { - string_init(fname); - path_concat(op_params->work_dir, header->name, fname); + string_init(full_extracted_fname); + path_concat(op_params->work_dir, header->name, full_extracted_fname); - bool create_res = storage_simply_mkdir(archive->storage, string_get_cstr(fname)); - string_clear(fname); + bool create_res = + storage_simply_mkdir(archive->storage, string_get_cstr(full_extracted_fname)); + string_clear(full_extracted_fname); return create_res ? 0 : -1; } @@ -197,8 +199,16 @@ static int archive_extract_foreach_cb(mtar_t* tar, const mtar_header_t* header, return 0; } - string_init(fname); - path_concat(op_params->work_dir, header->name, fname); + string_init(full_extracted_fname); + + string_t converted_fname; + string_init_set(converted_fname, header->name); + if(op_params->converter) { + op_params->converter(converted_fname); + } + path_concat(op_params->work_dir, string_get_cstr(converted_fname), full_extracted_fname); + string_clear(converted_fname); + FURI_LOG_I(TAG, "Extracting %d bytes to '%s'", header->size, header->name); File* out_file = storage_file_alloc(archive->storage); uint8_t* readbuf = malloc(FILE_BLOCK_SIZE); @@ -208,10 +218,17 @@ static int archive_extract_foreach_cb(mtar_t* tar, const mtar_header_t* header, do { while(n_tries-- > 0) { if(storage_file_open( - out_file, string_get_cstr(fname), FSAM_WRITE, FSOM_CREATE_ALWAYS)) { + out_file, + string_get_cstr(full_extracted_fname), + FSAM_WRITE, + FSOM_CREATE_ALWAYS)) { break; } - FURI_LOG_W(TAG, "Failed to open '%s', reties: %d", string_get_cstr(fname), n_tries); + FURI_LOG_W( + TAG, + "Failed to open '%s', reties: %d", + string_get_cstr(full_extracted_fname), + n_tries); storage_file_close(out_file); furi_delay_ms(FILE_OPEN_RETRY_DELAY); } @@ -232,15 +249,19 @@ static int archive_extract_foreach_cb(mtar_t* tar, const mtar_header_t* header, storage_file_free(out_file); free(readbuf); - string_clear(fname); + string_clear(full_extracted_fname); return failed ? -1 : 0; } -bool tar_archive_unpack_to(TarArchive* archive, const char* destination) { +bool tar_archive_unpack_to( + TarArchive* archive, + const char* destination, + Storage_name_converter converter) { furi_assert(archive); TarArchiveDirectoryOpParams param = { .archive = archive, .work_dir = destination, + .converter = converter, }; FURI_LOG_I(TAG, "Restoring '%s'", destination); @@ -313,6 +334,7 @@ bool tar_archive_add_dir(TarArchive* archive, const char* fs_full_path, const ch string_t element_name, element_fs_abs_path; string_init(element_name); string_init(element_fs_abs_path); + path_concat(fs_full_path, name, element_fs_abs_path); if(strlen(path_prefix)) { path_concat(path_prefix, name, element_name); diff --git a/lib/toolbox/tar/tar_archive.h b/lib/toolbox/tar/tar_archive.h index d9b0f321..88cb3dd4 100644 --- a/lib/toolbox/tar/tar_archive.h +++ b/lib/toolbox/tar/tar_archive.h @@ -2,6 +2,8 @@ #include #include +#include +#include #ifdef __cplusplus extern "C" { @@ -24,7 +26,10 @@ bool tar_archive_open(TarArchive* archive, const char* path, TarOpenMode mode); void tar_archive_free(TarArchive* archive); /* High-level API - assumes archive is open */ -bool tar_archive_unpack_to(TarArchive* archive, const char* destination); +bool tar_archive_unpack_to( + TarArchive* archive, + const char* destination, + Storage_name_converter converter); bool tar_archive_add_file( TarArchive* archive, diff --git a/lib/update_util/lfs_backup.c b/lib/update_util/lfs_backup.c index fa9141df..b7e7dd89 100644 --- a/lib/update_util/lfs_backup.c +++ b/lib/update_util/lfs_backup.c @@ -2,7 +2,36 @@ #include -#define LFS_BACKUP_DEFAULT_LOCATION "/ext/" LFS_BACKUP_DEFAULT_FILENAME +#include +#include +#include +#include +#include +#include + +#define LFS_BACKUP_DEFAULT_LOCATION EXT_PATH(LFS_BACKUP_DEFAULT_FILENAME) + +static void backup_name_converter(string_t filename) { + if(string_empty_p(filename) || (string_get_char(filename, 0) == '.')) { + return; + } + + /* Filenames are already prefixed with '.' */ + const char* const names[] = { + BT_SETTINGS_FILE_NAME, + BT_KEYS_STORAGE_FILE_NAME, + DESKTOP_SETTINGS_FILE_NAME, + NOTIFICATION_SETTINGS_FILE_NAME, + SLIDESHOW_FILE_NAME, + }; + + for(size_t i = 0; i < COUNT_OF(names); i++) { + if(string_equal_str_p(filename, &names[i][1])) { + string_set_str(filename, names[i]); + return; + } + } +} bool lfs_backup_create(Storage* storage, const char* destination) { const char* final_destination = @@ -18,5 +47,5 @@ bool lfs_backup_exists(Storage* storage, const char* source) { bool lfs_backup_unpack(Storage* storage, const char* source) { const char* final_source = source && strlen(source) ? source : LFS_BACKUP_DEFAULT_LOCATION; - return storage_int_restore(storage, final_source) == FSE_OK; + return storage_int_restore(storage, final_source, backup_name_converter) == FSE_OK; } diff --git a/lib/update_util/update_manifest.c b/lib/update_util/update_manifest.c index d1ac0d7d..1b205d9c 100644 --- a/lib/update_util/update_manifest.c +++ b/lib/update_util/update_manifest.c @@ -157,14 +157,14 @@ bool update_manifest_has_obdata(UpdateManifest* update_manifest) { } bool update_manifest_init(UpdateManifest* update_manifest, const char* manifest_filename) { - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); FlipperFormat* flipper_file = flipper_format_file_alloc(storage); if(flipper_format_file_open_existing(flipper_file, manifest_filename)) { update_manifest_init_from_ff(update_manifest, flipper_file); } flipper_format_free(flipper_file); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); return update_manifest->valid; } diff --git a/lib/update_util/update_manifest.h b/lib/update_util/update_manifest.h index 2b0c9179..8f385947 100644 --- a/lib/update_util/update_manifest.h +++ b/lib/update_util/update_manifest.h @@ -9,8 +9,7 @@ extern "C" { #include #include -/* Paths don't include /ext -- because at startup SD card is mounted as root */ -#define UPDATE_DIR_DEFAULT_REL_PATH "/update" +/* Paths don't include /ext -- because at startup SD card is mounted as FS root */ #define UPDATE_MANIFEST_DEFAULT_NAME "update.fuf" #define UPDATE_MANIFEST_POINTER_FILE_NAME ".fupdate" diff --git a/lib/update_util/update_operation.c b/lib/update_util/update_operation.c index 9082d262..138828ff 100644 --- a/lib/update_util/update_operation.c +++ b/lib/update_util/update_operation.c @@ -9,9 +9,8 @@ #include #include -#define UPDATE_ROOT_DIR "/ext" UPDATE_DIR_DEFAULT_REL_PATH -#define UPDATE_PREFIX "/ext" UPDATE_DIR_DEFAULT_REL_PATH "/" -#define UPDATE_SUFFIX "/" UPDATE_MANIFEST_DEFAULT_NAME +#define UPDATE_ROOT_DIR EXT_PATH("update") + /* Need at least 4 free LFS pages before update */ #define UPDATE_MIN_INT_FREE_SPACE 4 * 4 * 1024 @@ -70,7 +69,7 @@ static bool update_operation_get_current_package_path_rtc(Storage* storage, stri return found; } -#define UPDATE_FILE_POINTER_FN "/ext/" UPDATE_MANIFEST_POINTER_FILE_NAME +#define UPDATE_FILE_POINTER_FN EXT_PATH(UPDATE_MANIFEST_POINTER_FILE_NAME) #define UPDATE_MANIFEST_MAX_PATH_LEN 256u bool update_operation_get_current_package_manifest_path(Storage* storage, string_t out_path) { @@ -137,7 +136,7 @@ static bool update_operation_persist_manifest_path(Storage* storage, const char* UpdatePrepareResult update_operation_prepare(const char* manifest_file_path) { UpdatePrepareResult result = UpdatePrepareResultIntFull; - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); UpdateManifest* manifest = update_manifest_alloc(); File* file = storage_file_alloc(storage); @@ -145,7 +144,8 @@ UpdatePrepareResult update_operation_prepare(const char* manifest_file_path) { string_t stage_path; string_init(stage_path); do { - if((storage_common_fs_info(storage, "/int", NULL, &free_int_space) != FSE_OK) || + if((storage_common_fs_info(storage, STORAGE_INT_PATH_PREFIX, NULL, &free_int_space) != + FSE_OK) || (free_int_space < UPDATE_MIN_INT_FREE_SPACE)) { break; } @@ -197,7 +197,7 @@ UpdatePrepareResult update_operation_prepare(const char* manifest_file_path) { storage_file_free(file); update_manifest_free(manifest); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); return result; } @@ -206,10 +206,10 @@ bool update_operation_is_armed() { FuriHalRtcBootMode boot_mode = furi_hal_rtc_get_boot_mode(); const uint32_t rtc_upd_index = furi_hal_rtc_get_register(FuriHalRtcRegisterUpdateFolderFSIndex); - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); const bool upd_fn_ptr_exists = (storage_common_stat(storage, UPDATE_FILE_POINTER_FN, NULL) == FSE_OK); - furi_record_close("storage"); + furi_record_close(RECORD_STORAGE); return (boot_mode >= FuriHalRtcBootModePreUpdate) && (boot_mode <= FuriHalRtcBootModePostUpdate) && ((rtc_upd_index != INT_MAX) || upd_fn_ptr_exists); @@ -218,7 +218,7 @@ bool update_operation_is_armed() { void update_operation_disarm() { furi_hal_rtc_set_boot_mode(FuriHalRtcBootModeNormal); furi_hal_rtc_set_register(FuriHalRtcRegisterUpdateFolderFSIndex, INT_MAX); - Storage* storage = furi_record_open("storage"); + Storage* storage = furi_record_open(RECORD_STORAGE); storage_simply_remove(storage, UPDATE_FILE_POINTER_FN); - furi_record_close("storage"); -} \ No newline at end of file + furi_record_close(RECORD_STORAGE); +} diff --git a/site_scons/site_tools/fbt_apps.py b/site_scons/site_tools/fbt_apps.py index 1c2e0167..2ffdcae3 100644 --- a/site_scons/site_tools/fbt_apps.py +++ b/site_scons/site_tools/fbt_apps.py @@ -17,7 +17,7 @@ from fbt.appmanifest import ( def LoadApplicationManifests(env): appmgr = env["APPMGR"] = AppManager() - for entry in env.Glob("#/applications/*"): + for entry in env.Glob("#/applications/*", source=True): if isinstance(entry, SCons.Node.FS.Dir) and not str(entry).startswith("."): try: appmgr.load_manifest(entry.File("application.fam").abspath, entry.name) From 3fa5e18c5a2c17fc666c2b767d90187bb5f30c3a Mon Sep 17 00:00:00 2001 From: hedger Date: Tue, 26 Jul 2022 15:44:03 +0300 Subject: [PATCH 34/37] [FL-2692, FL-2604, FL-2632] New first start sequence (#1456) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * desktop: restored automatic power off & manual power off on slideshow view; assets: added frames for new first start sequence; docs: added info on slideshow compilation * desktop: restarting long timer on OK button release Co-authored-by: あく --- .../desktop/scenes/desktop_scene_slideshow.c | 8 +++++ applications/desktop/views/desktop_events.h | 1 + .../desktop/views/desktop_view_slideshow.c | 28 +++++++++++++++++- assets/slideshow/first_start/frame_00.png | Bin 0 -> 602 bytes assets/slideshow/first_start/frame_01.png | Bin 0 -> 558 bytes assets/slideshow/first_start/frame_02.png | Bin 0 -> 562 bytes assets/slideshow/first_start/frame_03.png | Bin 0 -> 595 bytes assets/slideshow/first_start/frame_04.png | Bin 0 -> 548 bytes assets/slideshow/first_start/frame_05.png | Bin 0 -> 579 bytes scripts/ReadMe.md | 13 ++++++++ 10 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 assets/slideshow/first_start/frame_00.png create mode 100644 assets/slideshow/first_start/frame_01.png create mode 100644 assets/slideshow/first_start/frame_02.png create mode 100644 assets/slideshow/first_start/frame_03.png create mode 100644 assets/slideshow/first_start/frame_04.png create mode 100644 assets/slideshow/first_start/frame_05.png diff --git a/applications/desktop/scenes/desktop_scene_slideshow.c b/applications/desktop/scenes/desktop_scene_slideshow.c index 18460a4c..cab7bf62 100644 --- a/applications/desktop/scenes/desktop_scene_slideshow.c +++ b/applications/desktop/scenes/desktop_scene_slideshow.c @@ -3,6 +3,7 @@ #include "../desktop_i.h" #include "../views/desktop_view_slideshow.h" #include "../views/desktop_events.h" +#include void desktop_scene_slideshow_callback(DesktopEvent event, void* context) { Desktop* desktop = (Desktop*)context; @@ -22,6 +23,7 @@ bool desktop_scene_slideshow_on_event(void* context, SceneManagerEvent event) { Desktop* desktop = (Desktop*)context; bool consumed = false; Storage* storage = NULL; + Power* power = NULL; if(event.type == SceneManagerEventTypeCustom) { switch(event.event) { @@ -32,6 +34,12 @@ bool desktop_scene_slideshow_on_event(void* context, SceneManagerEvent event) { scene_manager_previous_scene(desktop->scene_manager); consumed = true; break; + case DesktopSlideshowPoweroff: + power = furi_record_open(RECORD_POWER); + power_off(power); + furi_record_close(RECORD_POWER); + consumed = true; + break; default: break; diff --git a/applications/desktop/views/desktop_events.h b/applications/desktop/views/desktop_events.h index 4ff5f795..5d130be9 100644 --- a/applications/desktop/views/desktop_events.h +++ b/applications/desktop/views/desktop_events.h @@ -35,6 +35,7 @@ typedef enum { DesktopAnimationEventInteractAnimation, DesktopSlideshowCompleted, + DesktopSlideshowPoweroff, // Global events DesktopGlobalBeforeAppStarted, diff --git a/applications/desktop/views/desktop_view_slideshow.c b/applications/desktop/views/desktop_view_slideshow.c index 943206e1..26ae95ea 100644 --- a/applications/desktop/views/desktop_view_slideshow.c +++ b/applications/desktop/views/desktop_view_slideshow.c @@ -2,15 +2,19 @@ #include #include -#include "../desktop_i.h" #include "desktop_view_slideshow.h" +#include "../desktop_i.h" #include "../helpers/slideshow.h" #include "../helpers/slideshow_filename.h" +#define DESKTOP_SLIDESHOW_POWEROFF_SHORT 5000 +#define DESKTOP_SLIDESHOW_POWEROFF_LONG (60 * 60 * 1000) + struct DesktopSlideshowView { View* view; DesktopSlideshowViewCallback callback; void* context; + FuriTimer* timer; }; typedef struct { @@ -51,14 +55,32 @@ static bool desktop_view_slideshow_input(InputEvent* event, void* context) { instance->callback(DesktopSlideshowCompleted, instance->context); } view_commit_model(instance->view, true); + } else if(event->key == InputKeyOk) { + if(event->type == InputTypePress) { + furi_timer_start(instance->timer, DESKTOP_SLIDESHOW_POWEROFF_SHORT); + } else if(event->type == InputTypeRelease) { + furi_timer_stop(instance->timer); + furi_timer_start(instance->timer, DESKTOP_SLIDESHOW_POWEROFF_LONG); + } } return true; } +static void desktop_first_start_timer_callback(void* context) { + DesktopSlideshowView* instance = context; + instance->callback(DesktopSlideshowPoweroff, instance->context); +} + static void desktop_view_slideshow_enter(void* context) { DesktopSlideshowView* instance = context; + furi_assert(instance->timer == NULL); + instance->timer = + furi_timer_alloc(desktop_first_start_timer_callback, FuriTimerTypeOnce, instance); + + furi_timer_start(instance->timer, DESKTOP_SLIDESHOW_POWEROFF_LONG); + DesktopSlideshowViewModel* model = view_get_model(instance->view); model->slideshow = slideshow_alloc(); if(!slideshow_load(model->slideshow, SLIDESHOW_FS_PATH)) { @@ -70,6 +92,10 @@ static void desktop_view_slideshow_enter(void* context) { static void desktop_view_slideshow_exit(void* context) { DesktopSlideshowView* instance = context; + furi_timer_stop(instance->timer); + furi_timer_free(instance->timer); + instance->timer = NULL; + DesktopSlideshowViewModel* model = view_get_model(instance->view); slideshow_free(model->slideshow); view_commit_model(instance->view, false); diff --git a/assets/slideshow/first_start/frame_00.png b/assets/slideshow/first_start/frame_00.png new file mode 100644 index 0000000000000000000000000000000000000000..67f23bd31b596fdf57d3b8bff62b2e6d2a03070a GIT binary patch literal 602 zcmV-g0;TPx#1ZP1_K>z@;j|==^1poj522e~?MgRZ*00010!qa{L000SaNLh0L01FcU01FcV z0GgZ_0005qNklf1jQIb5Ot-FLBM) o8C$9X3)L09%Gjx{=!^ik1;ah0>A+VwJ^%m!07*qoM6N<$f@V(tCIA2c literal 0 HcmV?d00001 diff --git a/assets/slideshow/first_start/frame_01.png b/assets/slideshow/first_start/frame_01.png new file mode 100644 index 0000000000000000000000000000000000000000..5ac995c3976340eeb6607218c872e43363879ba0 GIT binary patch literal 558 zcmV+}0@3}6P)Px#1ZP1_K>z@;j|==^1poj522e~?MgRZ*00010!qa{L000SaNLh0L01FcU01FcV z0GgZ_00058Nkl(1eeS1-S74`v$I40wx#0;{eCP> z<93}+(EH{s4^7IT*9HP26;TpTXT>QbF<_C-XbLGabjDXl4FLyGCc3z-9}YA_7Jy#| za4p~h90LRS1k-t)&iFj+3wW53u;akRe?12dR{a5O0dEzLp;Ek5AafmPNEWQ)yWVl@ zzSqwhsNzLOED8p1>}rb&0yA!#kumNWLMb9+KKE6-GQG`6rwn*`t_Oxmq(P20$Ob=`ev!Mjsj-(RhXPaI zv!aW1UQ;HcqFGJq9ir2wl)wzqpIXXDn$lZQ`Px#1ZP1_K>z@;j|==^1poj522e~?MgRZ*00010!qa{L000SaNLh0L01FcU01FcV z0GgZ_0005CNklDWTK(>sam%ZW+D@kb~X0S@E4iT=oV&Qy% zcmc7yDTKpH#XNu(EBFSMQ(E~93pSQ1E!4gLH#-~GJi|?z>@VMb^XHoh{x4aotd<4h zvLLj=4+hxc2hagBpg=5O(fjT}Swz-D!g9hg*%AI8B|kPF2<_@ceLDKQpRe<4mreQ} zlKuRN&{qkP8nnrfGC@~*jM(FzkTJohH=m=G!e$Z;9aRH+a7(nKMpA}CvIv<#iX`0$ zUFw@0A)0j+;Us?wFeuXaMJjX+&UK!lf8E_r zHau(ty%~40evSm?_!hK64V=&)*Bmm3!P96!3e_pCzB17q+G=LComUua4q)}|&%^QM zS0~^~7ZLU@hSOXsFyPi`0@v~)tU}-H9S$dJHAr;$^Qj>A!FVJ!lppQ~w^@XqhlrUy z#AO`dO9i|SuY|{yZ)58r

(>4?X|CwYLt^;zmGmgJ85iec5G6@WdeT{P5*zV;dlWT<|4Zrq0bj12oc{9Px#1ZP1_K>z@;j|==^1poj522e~?MgRZ*00010!qa{L000SaNLh0L01FcU01FcV z0GgZ_0005jNklljA6bJBkI5dtF66X}rAQhaUkrJ^Orb-~$Y8k8wsa4sL zC*}@FFwv8`q*6B+*$_KB%MFN-g}I}}(juzL1414muK#B{<=n4;6`hmcy}WyVcc%aB za!gu>d-RxZ2d20*(LOa9R5?8)q4`6iiVw)am;k&btQ4aKZHxnk+5W4CF#tcv1@tEI zyKM%9bCl?{Di~tE;aL$0(yk<&BYyed6Cfg?997i83o%gAEDJ+9fDGSm*p(jpMt6+` zhZ}x6@D)SsksFZ8ufyx`^dwZ`*2%@Mw}Wqh(3~F_C3>Ur=97837Ke`3^1*>5{FWm1&Q|i?`{d2)aqXnaz1I4 zfahJsR?4HFWkh}jtuhDBXmlTcX;0@>KNuEP9SqO%I(+$1j}V`?e%GM0efWo{d^-%E huPx#1ZP1_K>z@;j|==^1poj522e~?MgRZ*00010!qa{L000SaNLh0L01FcU01FcV z0GgZ_0004}NklB4*$GWC(}0K=P`9o z@IeQ(Hz5HTfB@pa8_*1hU@<|yC!fL=!Mbq z2y6x#!_&O`?pn%cph^In7uBY##5im+#HL_yFhi9lIanb`a7ZYibd8^o5Hy-v60Ksr z@M_%b4=5kR&_HXqw!3Gv-4)DB#Ge(MGQ1<}Bb`^Uy;p0y0?R$5iw2s7$HME*VPl}+ zGlp}{t$shppyP5@SOD@5;6T$9*oc43z!Atk48=%C^JGw7Eq82z1=`sQoeR6`yLnT< zG->Y`>I4;A_!-)21+{$NwH&-MKK7>~sWtD>w1O;8^L2j6fnjMij&- m3WgS`1HQUa;bryT0NNKHvxH{lzhQO&0000Px#1ZP1_K>z@;j|==^1poj522e~?MgRZ*00010!qa{L000SaNLh0L01FcU01FcV z0GgZ_0005TNklYE7y$6^(psZLjkRC|#Z(ftTe>+2mZA>DLBv@y`2<46 z#ZwR(2(fAxp`e3(2PX-Z79F&&5W&IG(Lspc-6b~l6+B4p_}$%iANL3Td07iZ`HZ0y z)iV2q0RW9a!EczZ0@Nt)RvE0q@E`<0d^nrQd%I63_A`}K%)>4vK%4go21ZyXIs+Ncit=+QaTp)NCT^P7Eq2=XJ}4{uI1#}qR5tRa z4vL*iLI8@-K#l=pP_~1(N6uoglQ%F19l=%X#Oc$~37DV>xXl5-HGMEd;}`0WqH)d- z1EEJmAGH send assets/resources /ext ``` + + +# Slideshow creation + +Put fullscreen slideshow frames in .png format into `assets/slideshow/my_show` folder, named frame_xx.png, where xx is zero-padded frame number, starting with #0. + +Then run + +```bash +python scripts/slideshow.py -i assets/slideshow/my_show/ -o assets/slideshow/my_show/.slideshow +``` + +Upload generated .slideshow file to Flipper's internal storage and restart it. \ No newline at end of file From ed7db336c1ce537ee86af5df6b9512299e323db8 Mon Sep 17 00:00:00 2001 From: Skorpionm <85568270+Skorpionm@users.noreply.github.com> Date: Tue, 26 Jul 2022 16:58:07 +0400 Subject: [PATCH 35/37] [FL-2684, FL-2685] bugfix subghz (#1446) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [FL-2684] SubGhz: fix incorrect CAME TWICE protocol definition * [FL-2685] SubGhz: fix the recorded RAW signal is deleted when trying to transmit on a prohibited frequency Co-authored-by: あく --- applications/subghz/scenes/subghz_scene_read_raw.c | 1 + lib/subghz/protocols/came_twee.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/applications/subghz/scenes/subghz_scene_read_raw.c b/applications/subghz/scenes/subghz_scene_read_raw.c index 598f235e..3552d044 100644 --- a/applications/subghz/scenes/subghz_scene_read_raw.c +++ b/applications/subghz/scenes/subghz_scene_read_raw.c @@ -202,6 +202,7 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) { if((subghz->txrx->txrx_state == SubGhzTxRxStateIDLE) || (subghz->txrx->txrx_state == SubGhzTxRxStateSleep)) { if(!subghz_tx_start(subghz, subghz->txrx->fff_data)) { + subghz->txrx->rx_key_state = SubGhzRxKeyStateBack; scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowOnlyRx); } else { DOLPHIN_DEED(DolphinDeedSubGhzSend); diff --git a/lib/subghz/protocols/came_twee.c b/lib/subghz/protocols/came_twee.c index 1b60e111..fa538c54 100644 --- a/lib/subghz/protocols/came_twee.c +++ b/lib/subghz/protocols/came_twee.c @@ -354,7 +354,7 @@ void subghz_protocol_decoder_came_twee_feed(void* context, bool level, uint32_t } else if( duration >= ((uint32_t)subghz_protocol_came_twee_const.te_long * 2 + subghz_protocol_came_twee_const.te_delta)) { - if(instance->decoder.decode_count_bit >= + if(instance->decoder.decode_count_bit == subghz_protocol_came_twee_const.min_count_bit_for_found) { instance->generic.data = instance->decoder.decode_data; instance->generic.data_count_bit = instance->decoder.decode_count_bit; From ec19c11dbe4a81147947cc3a8dd2d182374ed67a Mon Sep 17 00:00:00 2001 From: Skorpionm <85568270+Skorpionm@users.noreply.github.com> Date: Tue, 26 Jul 2022 18:16:59 +0400 Subject: [PATCH 36/37] [FL-2669] SubGhz: add support for loading custom presets (#1398) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * SubGhz: load custom -preset * SubGhz: fix error prt=0 * SubGhz: load custom preset * SubGhz: code refactoring to support custom preset * SubGhz: add custom presert refactoring * SubGhz: fix alloc history alloc preset * SubGhz: fix error load file * SubGhz: fix start custom preset * SubGhz: fix delete custom preset * SubGhz: add description Custom_preset_data for CC1101 * SubGhz: debug logging and buffer size rounding Co-authored-by: あく Co-authored-by: Aleksandr Kutuzov --- applications/subghz/helpers/subghz_types.h | 13 ++ .../subghz/scenes/subghz_scene_need_saving.c | 8 +- .../subghz/scenes/subghz_scene_read_raw.c | 16 +- .../subghz/scenes/subghz_scene_receiver.c | 22 +- .../scenes/subghz_scene_receiver_config.c | 72 +++---- .../scenes/subghz_scene_receiver_info.c | 21 +- .../subghz/scenes/subghz_scene_set_type.c | 86 +++----- applications/subghz/subghz.c | 9 +- applications/subghz/subghz_history.c | 30 ++- applications/subghz/subghz_history.h | 13 +- applications/subghz/subghz_i.c | 91 +++++--- applications/subghz/subghz_i.h | 15 +- applications/subghz/subghz_setting.c | 202 +++++++++++++++++- applications/subghz/subghz_setting.h | 22 ++ assets/resources/subghz/assets/setting_user | 27 ++- .../targets/f7/furi_hal/furi_hal_subghz.c | 53 ++++- .../furi_hal_include/furi_hal_subghz.h | 11 +- lib/subghz/blocks/generic.c | 57 ++--- lib/subghz/blocks/generic.h | 16 +- lib/subghz/protocols/base.c | 6 +- lib/subghz/protocols/base.h | 6 +- lib/subghz/protocols/came.c | 5 +- lib/subghz/protocols/came.h | 6 +- lib/subghz/protocols/came_atomo.c | 5 +- lib/subghz/protocols/came_atomo.h | 6 +- lib/subghz/protocols/came_twee.c | 5 +- lib/subghz/protocols/came_twee.h | 6 +- lib/subghz/protocols/chamberlain_code.c | 5 +- lib/subghz/protocols/chamberlain_code.h | 6 +- lib/subghz/protocols/faac_slh.c | 5 +- lib/subghz/protocols/faac_slh.h | 6 +- lib/subghz/protocols/gate_tx.c | 5 +- lib/subghz/protocols/gate_tx.h | 6 +- lib/subghz/protocols/holtek.c | 5 +- lib/subghz/protocols/holtek.h | 6 +- lib/subghz/protocols/hormann.c | 5 +- lib/subghz/protocols/hormann.h | 6 +- lib/subghz/protocols/ido.c | 5 +- lib/subghz/protocols/ido.h | 6 +- lib/subghz/protocols/keeloq.c | 12 +- lib/subghz/protocols/keeloq.h | 12 +- lib/subghz/protocols/kia.c | 5 +- lib/subghz/protocols/kia.h | 6 +- lib/subghz/protocols/linear.c | 5 +- lib/subghz/protocols/linear.h | 6 +- lib/subghz/protocols/megacode.c | 5 +- lib/subghz/protocols/megacode.h | 6 +- lib/subghz/protocols/nero_radio.c | 5 +- lib/subghz/protocols/nero_radio.h | 6 +- lib/subghz/protocols/nero_sketch.c | 5 +- lib/subghz/protocols/nero_sketch.h | 6 +- lib/subghz/protocols/nice_flo.c | 5 +- lib/subghz/protocols/nice_flo.h | 6 +- lib/subghz/protocols/nice_flor_s.c | 5 +- lib/subghz/protocols/nice_flor_s.h | 6 +- lib/subghz/protocols/power_smart.c | 5 +- lib/subghz/protocols/power_smart.h | 6 +- lib/subghz/protocols/princeton.c | 6 +- lib/subghz/protocols/princeton.h | 6 +- lib/subghz/protocols/raw.c | 24 ++- lib/subghz/protocols/raw.h | 6 +- lib/subghz/protocols/scher_khan.c | 5 +- lib/subghz/protocols/scher_khan.h | 6 +- lib/subghz/protocols/secplus_v1.c | 5 +- lib/subghz/protocols/secplus_v1.h | 6 +- lib/subghz/protocols/secplus_v2.c | 12 +- lib/subghz/protocols/secplus_v2.h | 12 +- lib/subghz/protocols/somfy_keytis.c | 6 +- lib/subghz/protocols/somfy_keytis.h | 6 +- lib/subghz/protocols/somfy_telis.c | 5 +- lib/subghz/protocols/somfy_telis.h | 6 +- lib/subghz/protocols/star_line.c | 6 +- lib/subghz/protocols/star_line.h | 6 +- lib/subghz/subghz_worker.c | 5 +- lib/subghz/types.h | 8 +- 75 files changed, 685 insertions(+), 458 deletions(-) diff --git a/applications/subghz/helpers/subghz_types.h b/applications/subghz/helpers/subghz_types.h index 8d2dcf17..1b9fe816 100644 --- a/applications/subghz/helpers/subghz_types.h +++ b/applications/subghz/helpers/subghz_types.h @@ -1,5 +1,9 @@ #pragma once +#include "m-string.h" +#include +#include + /** SubGhzNotification state */ typedef enum { SubGhzNotificationStateStarting, @@ -67,3 +71,12 @@ typedef enum { SubGhzViewIdTestCarrier, SubGhzViewIdTestPacket, } SubGhzViewId; + +struct SubGhzPesetDefinition { + string_t name; + uint32_t frequency; + uint8_t* data; + size_t data_size; +}; + +typedef struct SubGhzPesetDefinition SubGhzPesetDefinition; diff --git a/applications/subghz/scenes/subghz_scene_need_saving.c b/applications/subghz/scenes/subghz_scene_need_saving.c index ae76fbb1..eb70223a 100644 --- a/applications/subghz/scenes/subghz_scene_need_saving.c +++ b/applications/subghz/scenes/subghz_scene_need_saving.c @@ -48,8 +48,12 @@ bool subghz_scene_need_saving_on_event(void* context, SceneManagerEvent event) { } else if(event.event == SubGhzCustomEventSceneExit) { if(subghz->txrx->rx_key_state == SubGhzRxKeyStateExit) { subghz->txrx->rx_key_state = SubGhzRxKeyStateIDLE; - subghz->txrx->frequency = subghz_setting_get_default_frequency(subghz->setting); - subghz->txrx->preset = FuriHalSubGhzPresetOok650Async; + subghz_preset_init( + subghz, + "AM650", + subghz_setting_get_default_frequency(subghz->setting), + NULL, + 0); scene_manager_search_and_switch_to_previous_scene( subghz->scene_manager, SubGhzSceneStart); } else { diff --git a/applications/subghz/scenes/subghz_scene_read_raw.c b/applications/subghz/scenes/subghz_scene_read_raw.c index 3552d044..38b73e07 100644 --- a/applications/subghz/scenes/subghz_scene_read_raw.c +++ b/applications/subghz/scenes/subghz_scene_read_raw.c @@ -131,8 +131,12 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) { scene_manager_next_scene(subghz->scene_manager, SubGhzSceneNeedSaving); } else { //Restore default setting - subghz->txrx->frequency = subghz_setting_get_default_frequency(subghz->setting); - subghz->txrx->preset = FuriHalSubGhzPresetOok650Async; + subghz_preset_init( + subghz, + "AM650", + subghz_setting_get_default_frequency(subghz->setting), + NULL, + 0); if(!scene_manager_search_and_switch_to_previous_scene( subghz->scene_manager, SubGhzSceneSaved)) { if(!scene_manager_search_and_switch_to_previous_scene( @@ -268,13 +272,15 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) { if(subghz_protocol_raw_save_to_file_init( (SubGhzProtocolDecoderRAW*)subghz->txrx->decoder_result, RAW_FILE_NAME, - subghz->txrx->frequency, subghz->txrx->preset)) { DOLPHIN_DEED(DolphinDeedSubGhzRawRec); if((subghz->txrx->txrx_state == SubGhzTxRxStateIDLE) || (subghz->txrx->txrx_state == SubGhzTxRxStateSleep)) { - subghz_begin(subghz, subghz->txrx->preset); - subghz_rx(subghz, subghz->txrx->frequency); + subghz_begin( + subghz, + subghz_setting_get_preset_data_by_name( + subghz->setting, string_get_cstr(subghz->txrx->preset->name))); + subghz_rx(subghz, subghz->txrx->preset->frequency); } subghz->state_notifications = SubGhzNotificationStateRx; subghz->txrx->rx_key_state = SubGhzRxKeyStateAddKey; diff --git a/applications/subghz/scenes/subghz_scene_receiver.c b/applications/subghz/scenes/subghz_scene_receiver.c index 55302b01..7c1f016d 100644 --- a/applications/subghz/scenes/subghz_scene_receiver.c +++ b/applications/subghz/scenes/subghz_scene_receiver.c @@ -75,8 +75,7 @@ static void subghz_scene_add_to_history_callback( string_t str_buff; string_init(str_buff); - if(subghz_history_add_to_history( - subghz->txrx->history, decoder_base, subghz->txrx->frequency, subghz->txrx->preset)) { + if(subghz_history_add_to_history(subghz->txrx->history, decoder_base, subghz->txrx->preset)) { string_reset(str_buff); subghz->state_notifications = SubGhzNotificationStateRxDone; @@ -103,8 +102,8 @@ void subghz_scene_receiver_on_enter(void* context) { string_init(str_buff); if(subghz->txrx->rx_key_state == SubGhzRxKeyStateIDLE) { - subghz->txrx->frequency = subghz_setting_get_default_frequency(subghz->setting); - subghz->txrx->preset = FuriHalSubGhzPresetOok650Async; + subghz_preset_init( + subghz, "AM650", subghz_setting_get_default_frequency(subghz->setting), NULL, 0); subghz_history_reset(subghz->txrx->history); subghz->txrx->rx_key_state = SubGhzRxKeyStateStart; } @@ -135,8 +134,11 @@ void subghz_scene_receiver_on_enter(void* context) { }; if((subghz->txrx->txrx_state == SubGhzTxRxStateIDLE) || (subghz->txrx->txrx_state == SubGhzTxRxStateSleep)) { - subghz_begin(subghz, subghz->txrx->preset); - subghz_rx(subghz, subghz->txrx->frequency); + subghz_begin( + subghz, + subghz_setting_get_preset_data_by_name( + subghz->setting, string_get_cstr(subghz->txrx->preset->name))); + subghz_rx(subghz, subghz->txrx->preset->frequency); } subghz_view_receiver_set_idx_menu(subghz->subghz_receiver, subghz->txrx->idx_menu_chosen); @@ -164,8 +166,12 @@ bool subghz_scene_receiver_on_event(void* context, SceneManagerEvent event) { scene_manager_next_scene(subghz->scene_manager, SubGhzSceneNeedSaving); } else { subghz->txrx->rx_key_state = SubGhzRxKeyStateIDLE; - subghz->txrx->frequency = subghz_setting_get_default_frequency(subghz->setting); - subghz->txrx->preset = FuriHalSubGhzPresetOok650Async; + subghz_preset_init( + subghz, + "AM650", + subghz_setting_get_default_frequency(subghz->setting), + NULL, + 0); scene_manager_search_and_switch_to_previous_scene( subghz->scene_manager, SubGhzSceneStart); } diff --git a/applications/subghz/scenes/subghz_scene_receiver_config.c b/applications/subghz/scenes/subghz_scene_receiver_config.c index cf31c1e9..590b51d1 100644 --- a/applications/subghz/scenes/subghz_scene_receiver_config.c +++ b/applications/subghz/scenes/subghz_scene_receiver_config.c @@ -7,20 +7,6 @@ enum SubGhzSettingIndex { SubGhzSettingIndexLock, }; -#define PRESET_COUNT 4 -const char* const preset_text[PRESET_COUNT] = { - "AM270", - "AM650", - "FM238", - "FM476", -}; -const uint32_t preset_value[PRESET_COUNT] = { - FuriHalSubGhzPresetOok270Async, /** OOK, bandwidth 270kHz, asynchronous */ - FuriHalSubGhzPresetOok650Async, /** OOK, bandwidth 650kHz, asynchronous */ - FuriHalSubGhzPreset2FSKDev238Async, /** FM, deviation 2.380371 kHz, asynchronous */ - FuriHalSubGhzPreset2FSKDev476Async, /** FM, deviation 4.760742 kHz, asynchronous */ -}; - #define HOPPING_COUNT 2 const char* const hopping_text[HOPPING_COUNT] = { "OFF", @@ -31,22 +17,6 @@ const uint32_t hopping_value[HOPPING_COUNT] = { SubGhzHopperStateRunnig, }; -uint8_t subghz_scene_receiver_config_uint32_value_index( - const uint32_t value, - const uint32_t values[], - uint8_t values_count) { - int64_t last_value = INT64_MIN; - uint8_t index = 0; - for(uint8_t i = 0; i < values_count; i++) { - if((value >= last_value) && (value <= values[i])) { - index = i; - break; - } - last_value = values[i]; - } - return index; -} - uint8_t subghz_scene_receiver_config_next_frequency(const uint32_t value, void* context) { furi_assert(context); SubGhz* subghz = context; @@ -62,6 +32,21 @@ uint8_t subghz_scene_receiver_config_next_frequency(const uint32_t value, void* return index; } +uint8_t subghz_scene_receiver_config_next_preset(const char* preset_name, void* context) { + furi_assert(context); + SubGhz* subghz = context; + uint8_t index = 0; + for(uint8_t i = 0; i < subghz_setting_get_preset_count(subghz->setting); i++) { + if(!strcmp(subghz_setting_get_preset_name(subghz->setting, i), preset_name)) { + index = i; + break; + } else { + // index = subghz_setting_get_frequency_default_index(subghz->setting); + } + } + return index; +} + uint8_t subghz_scene_receiver_config_hopper_value_index( const uint32_t value, const uint32_t values[], @@ -94,7 +79,7 @@ static void subghz_scene_receiver_config_set_frequency(VariableItem* item) { subghz_setting_get_frequency(subghz->setting, index) / 1000000, (subghz_setting_get_frequency(subghz->setting, index) % 1000000) / 10000); variable_item_set_current_value_text(item, text_buf); - subghz->txrx->frequency = subghz_setting_get_frequency(subghz->setting, index); + subghz->txrx->preset->frequency = subghz_setting_get_frequency(subghz->setting, index); } else { variable_item_set_current_value_index( item, subghz_setting_get_frequency_default_index(subghz->setting)); @@ -104,9 +89,14 @@ static void subghz_scene_receiver_config_set_frequency(VariableItem* item) { static void subghz_scene_receiver_config_set_preset(VariableItem* item) { SubGhz* subghz = variable_item_get_context(item); uint8_t index = variable_item_get_current_value_index(item); - - variable_item_set_current_value_text(item, preset_text[index]); - subghz->txrx->preset = preset_value[index]; + variable_item_set_current_value_text( + item, subghz_setting_get_preset_name(subghz->setting, index)); + subghz_preset_init( + subghz, + subghz_setting_get_preset_name(subghz->setting, index), + subghz->txrx->preset->frequency, + subghz_setting_get_preset_data(subghz->setting, index), + subghz_setting_get_preset_data_size(subghz->setting, index)); } static void subghz_scene_receiver_config_set_hopping_runing(VariableItem* item) { @@ -125,7 +115,7 @@ static void subghz_scene_receiver_config_set_hopping_runing(VariableItem* item) (VariableItem*)scene_manager_get_scene_state( subghz->scene_manager, SubGhzSceneReceiverConfig), text_buf); - subghz->txrx->frequency = subghz_setting_get_default_frequency(subghz->setting); + subghz->txrx->preset->frequency = subghz_setting_get_default_frequency(subghz->setting); variable_item_set_current_value_index( (VariableItem*)scene_manager_get_scene_state( subghz->scene_manager, SubGhzSceneReceiverConfig), @@ -164,7 +154,8 @@ void subghz_scene_receiver_config_on_enter(void* context) { subghz_setting_get_frequency_count(subghz->setting), subghz_scene_receiver_config_set_frequency, subghz); - value_index = subghz_scene_receiver_config_next_frequency(subghz->txrx->frequency, subghz); + value_index = + subghz_scene_receiver_config_next_frequency(subghz->txrx->preset->frequency, subghz); scene_manager_set_scene_state( subghz->scene_manager, SubGhzSceneReceiverConfig, (uint32_t)item); variable_item_set_current_value_index(item, value_index); @@ -193,13 +184,14 @@ void subghz_scene_receiver_config_on_enter(void* context) { item = variable_item_list_add( subghz->variable_item_list, "Modulation:", - PRESET_COUNT, + subghz_setting_get_preset_count(subghz->setting), subghz_scene_receiver_config_set_preset, subghz); - value_index = subghz_scene_receiver_config_uint32_value_index( - subghz->txrx->preset, preset_value, PRESET_COUNT); + value_index = subghz_scene_receiver_config_next_preset( + string_get_cstr(subghz->txrx->preset->name), subghz); variable_item_set_current_value_index(item, value_index); - variable_item_set_current_value_text(item, preset_text[value_index]); + variable_item_set_current_value_text( + item, subghz_setting_get_preset_name(subghz->setting, value_index)); if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneReadRAW) != SubGhzCustomEventManagerSet) { diff --git a/applications/subghz/scenes/subghz_scene_receiver_info.c b/applications/subghz/scenes/subghz_scene_receiver_info.c index 31471184..40051eee 100644 --- a/applications/subghz/scenes/subghz_scene_receiver_info.c +++ b/applications/subghz/scenes/subghz_scene_receiver_info.c @@ -27,10 +27,16 @@ static bool subghz_scene_receiver_info_update_parser(void* context) { subghz_protocol_decoder_base_deserialize( subghz->txrx->decoder_result, subghz_history_get_raw_data(subghz->txrx->history, subghz->txrx->idx_menu_chosen)); - subghz->txrx->frequency = - subghz_history_get_frequency(subghz->txrx->history, subghz->txrx->idx_menu_chosen); - subghz->txrx->preset = - subghz_history_get_preset(subghz->txrx->history, subghz->txrx->idx_menu_chosen); + + SubGhzPesetDefinition* preset = + subghz_history_get_presset(subghz->txrx->history, subghz->txrx->idx_menu_chosen); + subghz_preset_init( + subghz, + string_get_cstr(preset->name), + preset->frequency, + preset->data, + preset->data_size); + return true; } return false; @@ -137,8 +143,11 @@ bool subghz_scene_receiver_info_on_event(void* context, SceneManagerEvent event) subghz_tx_stop(subghz); } if(subghz->txrx->txrx_state == SubGhzTxRxStateIDLE) { - subghz_begin(subghz, subghz->txrx->preset); - subghz_rx(subghz, subghz->txrx->frequency); + subghz_begin( + subghz, + subghz_setting_get_preset_data_by_name( + subghz->setting, string_get_cstr(subghz->txrx->preset->name))); + subghz_rx(subghz, subghz->txrx->preset->frequency); } if(subghz->txrx->hopper_state == SubGhzHopperStatePause) { subghz->txrx->hopper_state = SubGhzHopperStateRunnig; diff --git a/applications/subghz/scenes/subghz_scene_set_type.c b/applications/subghz/scenes/subghz_scene_set_type.c index 55db8011..1a359542 100644 --- a/applications/subghz/scenes/subghz_scene_set_type.c +++ b/applications/subghz/scenes/subghz_scene_set_type.c @@ -16,12 +16,13 @@ bool subghz_scene_set_type_submenu_gen_data_protocol( uint64_t key, uint32_t bit, uint32_t frequency, - FuriHalSubGhzPreset preset) { + const char* preset_name) { furi_assert(context); SubGhz* subghz = context; bool res = false; + subghz_preset_init(subghz, preset_name, frequency, NULL, 0); subghz->txrx->decoder_result = subghz_receiver_search_decoder_base_by_name(subghz->txrx->receiver, protocol_name); @@ -35,7 +36,7 @@ bool subghz_scene_set_type_submenu_gen_data_protocol( Stream* fff_data_stream = flipper_format_get_raw_stream(subghz->txrx->fff_data); stream_clean(fff_data_stream); if(!subghz_protocol_decoder_base_serialize( - subghz->txrx->decoder_result, subghz->txrx->fff_data, frequency, preset)) { + subghz->txrx->decoder_result, subghz->txrx->fff_data, subghz->txrx->preset)) { FURI_LOG_E(TAG, "Unable to serialize"); break; } @@ -177,12 +178,7 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) { case SubmenuIndexPricenton: key = (key & 0x00FFFFF0) | 0x4; //btn 0x1, 0x2, 0x4, 0x8 if(subghz_scene_set_type_submenu_gen_data_protocol( - subghz, - SUBGHZ_PROTOCOL_PRINCETON_NAME, - key, - 24, - 433920000, - FuriHalSubGhzPresetOok650Async)) { + subghz, SUBGHZ_PROTOCOL_PRINCETON_NAME, key, 24, 433920000, "AM650")) { uint32_t te = 400; flipper_format_update_uint32(subghz->txrx->fff_data, "TE", (uint32_t*)&te, 1); generated_protocol = true; @@ -191,60 +187,35 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) { case SubmenuIndexNiceFlo12bit: key = (key & 0x0000FFF0) | 0x1; //btn 0x1, 0x2, 0x4 if(subghz_scene_set_type_submenu_gen_data_protocol( - subghz, - SUBGHZ_PROTOCOL_NICE_FLO_NAME, - key, - 12, - 433920000, - FuriHalSubGhzPresetOok650Async)) { + subghz, SUBGHZ_PROTOCOL_NICE_FLO_NAME, key, 12, 433920000, "AM650")) { generated_protocol = true; } break; case SubmenuIndexNiceFlo24bit: key = (key & 0x00FFFFF0) | 0x4; //btn 0x1, 0x2, 0x4, 0x8 if(subghz_scene_set_type_submenu_gen_data_protocol( - subghz, - SUBGHZ_PROTOCOL_NICE_FLO_NAME, - key, - 24, - 433920000, - FuriHalSubGhzPresetOok650Async)) { + subghz, SUBGHZ_PROTOCOL_NICE_FLO_NAME, key, 24, 433920000, "AM650")) { generated_protocol = true; } break; case SubmenuIndexCAME12bit: key = (key & 0x0000FFF0) | 0x1; //btn 0x1, 0x2, 0x4 if(subghz_scene_set_type_submenu_gen_data_protocol( - subghz, - SUBGHZ_PROTOCOL_CAME_NAME, - key, - 12, - 433920000, - FuriHalSubGhzPresetOok650Async)) { + subghz, SUBGHZ_PROTOCOL_CAME_NAME, key, 12, 433920000, "AM650")) { generated_protocol = true; } break; case SubmenuIndexCAME24bit: key = (key & 0x00FFFFF0) | 0x4; //btn 0x1, 0x2, 0x4, 0x8 if(subghz_scene_set_type_submenu_gen_data_protocol( - subghz, - SUBGHZ_PROTOCOL_CAME_NAME, - key, - 24, - 433920000, - FuriHalSubGhzPresetOok650Async)) { + subghz, SUBGHZ_PROTOCOL_CAME_NAME, key, 24, 433920000, "AM650")) { generated_protocol = true; } break; case SubmenuIndexLinear_300_00: key = (key & 0x3FF); if(subghz_scene_set_type_submenu_gen_data_protocol( - subghz, - SUBGHZ_PROTOCOL_LINEAR_NAME, - key, - 10, - 300000000, - FuriHalSubGhzPresetOok650Async)) { + subghz, SUBGHZ_PROTOCOL_LINEAR_NAME, key, 10, 300000000, "AM650")) { generated_protocol = true; } break; @@ -252,12 +223,7 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) { key = (key & 0x0FFFFFF0); key = 0x003FFF7200000000 | (key ^ 0xE0E0E0EE); if(subghz_scene_set_type_submenu_gen_data_protocol( - subghz, - SUBGHZ_PROTOCOL_CAME_TWEE_NAME, - key, - 54, - 433920000, - FuriHalSubGhzPresetOok650Async)) { + subghz, SUBGHZ_PROTOCOL_CAME_TWEE_NAME, key, 54, 433920000, "AM650")) { generated_protocol = true; } break; @@ -271,18 +237,15 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) { key = (key & 0x00F0FF00) | 0xF << 16 | 0x40; //btn 0xF, 0xC, 0xA, 0x6 (?) uint64_t rev_key = subghz_protocol_blocks_reverse_key(key, 24); if(subghz_scene_set_type_submenu_gen_data_protocol( - subghz, - SUBGHZ_PROTOCOL_GATE_TX_NAME, - rev_key, - 24, - 433920000, - FuriHalSubGhzPresetOok650Async)) { + subghz, SUBGHZ_PROTOCOL_GATE_TX_NAME, rev_key, 24, 433920000, "AM650")) { generated_protocol = true; } break; case SubmenuIndexDoorHan_433_92: subghz->txrx->transmitter = subghz_transmitter_alloc_init( subghz->txrx->environment, SUBGHZ_PROTOCOL_KEELOQ_NAME); + subghz_preset_init( + subghz, "AM650", subghz_setting_get_default_frequency(subghz->setting), NULL, 0); if(subghz->txrx->transmitter) { subghz_protocol_keeloq_create_data( subghz_transmitter_get_protocol_instance(subghz->txrx->transmitter), @@ -291,8 +254,7 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) { 0x2, 0x0003, "DoorHan", - subghz_setting_get_default_frequency(subghz->setting), - FuriHalSubGhzPresetOok650Async); + subghz->txrx->preset); generated_protocol = true; } else { generated_protocol = false; @@ -307,6 +269,7 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) { case SubmenuIndexDoorHan_315_00: subghz->txrx->transmitter = subghz_transmitter_alloc_init( subghz->txrx->environment, SUBGHZ_PROTOCOL_KEELOQ_NAME); + subghz_preset_init(subghz, "AM650", 315000000, NULL, 0); if(subghz->txrx->transmitter) { subghz_protocol_keeloq_create_data( subghz_transmitter_get_protocol_instance(subghz->txrx->transmitter), @@ -315,8 +278,7 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) { 0x2, 0x0003, "DoorHan", - 315000000, - FuriHalSubGhzPresetOok650Async); + subghz->txrx->preset); generated_protocol = true; } else { generated_protocol = false; @@ -338,7 +300,7 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) { (uint64_t)key << 32 | 0xE6000000, 42, 315000000, - FuriHalSubGhzPresetOok650Async)) { + "AM650")) { generated_protocol = true; } break; @@ -352,13 +314,14 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) { (uint64_t)key << 32 | 0xE6000000, 42, 390000000, - FuriHalSubGhzPresetOok650Async)) { + "AM650")) { generated_protocol = true; } break; case SubmenuIndexSecPlus_v2_310_00: subghz->txrx->transmitter = subghz_transmitter_alloc_init( subghz->txrx->environment, SUBGHZ_PROTOCOL_SECPLUS_V2_NAME); + subghz_preset_init(subghz, "AM650", 310000000, NULL, 0); if(subghz->txrx->transmitter) { subghz_protocol_secplus_v2_create_data( subghz_transmitter_get_protocol_instance(subghz->txrx->transmitter), @@ -366,8 +329,7 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) { key, 0x68, 0xE500000, - 310000000, - FuriHalSubGhzPresetOok650Async); + subghz->txrx->preset); generated_protocol = true; } else { generated_protocol = false; @@ -377,6 +339,7 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) { case SubmenuIndexSecPlus_v2_315_00: subghz->txrx->transmitter = subghz_transmitter_alloc_init( subghz->txrx->environment, SUBGHZ_PROTOCOL_SECPLUS_V2_NAME); + subghz_preset_init(subghz, "AM650", 315000000, NULL, 0); if(subghz->txrx->transmitter) { subghz_protocol_secplus_v2_create_data( subghz_transmitter_get_protocol_instance(subghz->txrx->transmitter), @@ -384,8 +347,7 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) { key, 0x68, 0xE500000, - 315000000, - FuriHalSubGhzPresetOok650Async); + subghz->txrx->preset); generated_protocol = true; } else { generated_protocol = false; @@ -395,6 +357,7 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) { case SubmenuIndexSecPlus_v2_390_00: subghz->txrx->transmitter = subghz_transmitter_alloc_init( subghz->txrx->environment, SUBGHZ_PROTOCOL_SECPLUS_V2_NAME); + subghz_preset_init(subghz, "AM650", 390000000, NULL, 0); if(subghz->txrx->transmitter) { subghz_protocol_secplus_v2_create_data( subghz_transmitter_get_protocol_instance(subghz->txrx->transmitter), @@ -402,8 +365,7 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) { key, 0x68, 0xE500000, - 390000000, - FuriHalSubGhzPresetOok650Async); + subghz->txrx->preset); generated_protocol = true; } else { generated_protocol = false; diff --git a/applications/subghz/subghz.c b/applications/subghz/subghz.c index 26f1bbe9..271fe041 100644 --- a/applications/subghz/subghz.c +++ b/applications/subghz/subghz.c @@ -199,8 +199,11 @@ SubGhz* subghz_alloc() { //init Worker & Protocol & History & KeyBoard subghz->lock = SubGhzLockOff; subghz->txrx = malloc(sizeof(SubGhzTxRx)); - subghz->txrx->frequency = subghz_setting_get_default_frequency(subghz->setting); - subghz->txrx->preset = FuriHalSubGhzPresetOok650Async; + subghz->txrx->preset = malloc(sizeof(SubGhzPesetDefinition)); + string_init(subghz->txrx->preset->name); + subghz_preset_init( + subghz, "AM650", subghz_setting_get_default_frequency(subghz->setting), NULL, 0); + subghz->txrx->txrx_state = SubGhzTxRxStateSleep; subghz->txrx->hopper_state = SubGhzHopperStateOFF; subghz->txrx->rx_key_state = SubGhzRxKeyStateIDLE; @@ -308,6 +311,8 @@ void subghz_free(SubGhz* subghz) { subghz_worker_free(subghz->txrx->worker); flipper_format_free(subghz->txrx->fff_data); subghz_history_free(subghz->txrx->history); + string_clear(subghz->txrx->preset->name); + free(subghz->txrx->preset); free(subghz->txrx); //Error string diff --git a/applications/subghz/subghz_history.c b/applications/subghz/subghz_history.c index 85578b99..f234f4c7 100644 --- a/applications/subghz/subghz_history.c +++ b/applications/subghz/subghz_history.c @@ -12,8 +12,7 @@ typedef struct { string_t item_str; FlipperFormat* flipper_string; uint8_t type; - FuriHalSubGhzPreset preset; - uint32_t frequency; + SubGhzPesetDefinition* preset; } SubGhzHistoryItem; ARRAY_DEF(SubGhzHistoryItemArray, SubGhzHistoryItem, M_POD_OPLIST) @@ -46,6 +45,8 @@ void subghz_history_free(SubGhzHistory* instance) { for M_EACH(item, instance->history->data, SubGhzHistoryItemArray_t) { string_clear(item->item_str); + string_clear(item->preset->name); + free(item->preset); flipper_format_free(item->flipper_string); item->type = 0; } @@ -57,21 +58,29 @@ void subghz_history_free(SubGhzHistory* instance) { uint32_t subghz_history_get_frequency(SubGhzHistory* instance, uint16_t idx) { furi_assert(instance); SubGhzHistoryItem* item = SubGhzHistoryItemArray_get(instance->history->data, idx); - return item->frequency; + return item->preset->frequency; } -FuriHalSubGhzPreset subghz_history_get_preset(SubGhzHistory* instance, uint16_t idx) { +SubGhzPesetDefinition* subghz_history_get_presset(SubGhzHistory* instance, uint16_t idx) { furi_assert(instance); SubGhzHistoryItem* item = SubGhzHistoryItemArray_get(instance->history->data, idx); return item->preset; } +const char* subghz_history_get_preset(SubGhzHistory* instance, uint16_t idx) { + furi_assert(instance); + SubGhzHistoryItem* item = SubGhzHistoryItemArray_get(instance->history->data, idx); + return string_get_cstr(item->preset->name); +} + void subghz_history_reset(SubGhzHistory* instance) { furi_assert(instance); string_reset(instance->tmp_string); for M_EACH(item, instance->history->data, SubGhzHistoryItemArray_t) { string_clear(item->item_str); + string_clear(item->preset->name); + free(item->preset); flipper_format_free(item->flipper_string); item->type = 0; } @@ -130,8 +139,7 @@ void subghz_history_get_text_item_menu(SubGhzHistory* instance, string_t output, bool subghz_history_add_to_history( SubGhzHistory* instance, void* context, - uint32_t frequency, - FuriHalSubGhzPreset preset) { + SubGhzPesetDefinition* preset) { furi_assert(instance); furi_assert(context); @@ -151,13 +159,17 @@ bool subghz_history_add_to_history( string_t text; string_init(text); SubGhzHistoryItem* item = SubGhzHistoryItemArray_push_raw(instance->history->data); + item->preset = malloc(sizeof(SubGhzPesetDefinition)); item->type = decoder_base->protocol->type; - item->frequency = frequency; - item->preset = preset; + item->preset->frequency = preset->frequency; + string_init(item->preset->name); + string_set(item->preset->name, preset->name); + item->preset->data = preset->data; + item->preset->data_size = preset->data_size; string_init(item->item_str); item->flipper_string = flipper_format_string_alloc(); - subghz_protocol_decoder_base_serialize(decoder_base, item->flipper_string, frequency, preset); + subghz_protocol_decoder_base_serialize(decoder_base, item->flipper_string, preset); do { if(!flipper_format_rewind(item->flipper_string)) { diff --git a/applications/subghz/subghz_history.h b/applications/subghz/subghz_history.h index f90b01d9..0af56a40 100644 --- a/applications/subghz/subghz_history.h +++ b/applications/subghz/subghz_history.h @@ -5,6 +5,7 @@ #include #include #include +#include "helpers/subghz_types.h" typedef struct SubGhzHistory SubGhzHistory; @@ -34,13 +35,15 @@ void subghz_history_reset(SubGhzHistory* instance); */ uint32_t subghz_history_get_frequency(SubGhzHistory* instance, uint16_t idx); +SubGhzPesetDefinition* subghz_history_get_presset(SubGhzHistory* instance, uint16_t idx); + /** Get preset to history[idx] * * @param instance - SubGhzHistory instance * @param idx - record index - * @return preset - FuriHalSubGhzPreset preset + * @return preset - preset name */ -FuriHalSubGhzPreset subghz_history_get_preset(SubGhzHistory* instance, uint16_t idx); +const char* subghz_history_get_preset(SubGhzHistory* instance, uint16_t idx); /** Get history index write * @@ -85,15 +88,13 @@ bool subghz_history_get_text_space_left(SubGhzHistory* instance, string_t output * * @param instance - SubGhzHistory instance * @param context - SubGhzProtocolCommon context - * @param frequency - frequency Hz - * @param preset - FuriHalSubGhzPreset preset + * @param preset - SubGhzPesetDefinition preset * @return bool; */ bool subghz_history_add_to_history( SubGhzHistory* instance, void* context, - uint32_t frequency, - FuriHalSubGhzPreset preset); + SubGhzPesetDefinition* preset); /** Get SubGhzProtocolCommonLoad to load into the protocol decoder bin data * diff --git a/applications/subghz/subghz_i.c b/applications/subghz/subghz_i.c index 9c8a3fc4..b8232fdb 100644 --- a/applications/subghz/subghz_i.c +++ b/applications/subghz/subghz_i.c @@ -1,7 +1,6 @@ #include "subghz_i.h" #include "assets_icons.h" -#include "m-string.h" #include "subghz/types.h" #include #include @@ -19,15 +18,31 @@ #define TAG "SubGhz" +void subghz_preset_init( + void* context, + const char* preset_name, + uint32_t frequency, + uint8_t* preset_data, + size_t preset_data_size) { + furi_assert(context); + SubGhz* subghz = context; + string_set(subghz->txrx->preset->name, preset_name); + subghz->txrx->preset->frequency = frequency; + subghz->txrx->preset->data = preset_data; + subghz->txrx->preset->data_size = preset_data_size; +} + bool subghz_set_preset(SubGhz* subghz, const char* preset) { if(!strcmp(preset, "FuriHalSubGhzPresetOok270Async")) { - subghz->txrx->preset = FuriHalSubGhzPresetOok270Async; + string_set(subghz->txrx->preset->name, "AM270"); } else if(!strcmp(preset, "FuriHalSubGhzPresetOok650Async")) { - subghz->txrx->preset = FuriHalSubGhzPresetOok650Async; + string_set(subghz->txrx->preset->name, "AM650"); } else if(!strcmp(preset, "FuriHalSubGhzPreset2FSKDev238Async")) { - subghz->txrx->preset = FuriHalSubGhzPreset2FSKDev238Async; + string_set(subghz->txrx->preset->name, "FM238"); } else if(!strcmp(preset, "FuriHalSubGhzPreset2FSKDev476Async")) { - subghz->txrx->preset = FuriHalSubGhzPreset2FSKDev476Async; + string_set(subghz->txrx->preset->name, "FM476"); + } else if(!strcmp(preset, "FuriHalSubGhzPresetCustom")) { + string_set(subghz->txrx->preset->name, "CUSTOM"); } else { FURI_LOG_E(TAG, "Unknown preset"); return false; @@ -41,29 +56,19 @@ void subghz_get_frequency_modulation(SubGhz* subghz, string_t frequency, string_ string_printf( frequency, "%03ld.%02ld", - subghz->txrx->frequency / 1000000 % 1000, - subghz->txrx->frequency / 10000 % 100); + subghz->txrx->preset->frequency / 1000000 % 1000, + subghz->txrx->preset->frequency / 10000 % 100); } - if(modulation != NULL) { - if(subghz->txrx->preset == FuriHalSubGhzPresetOok650Async || - subghz->txrx->preset == FuriHalSubGhzPresetOok270Async) { - string_set_str(modulation, "AM"); - } else if( - subghz->txrx->preset == FuriHalSubGhzPreset2FSKDev238Async || - subghz->txrx->preset == FuriHalSubGhzPreset2FSKDev476Async) { - string_set_str(modulation, "FM"); - } else { - furi_crash("SubGhz: Modulation is incorrect."); - } + string_printf(modulation, "%0.2s", string_get_cstr(subghz->txrx->preset->name)); } } -void subghz_begin(SubGhz* subghz, FuriHalSubGhzPreset preset) { +void subghz_begin(SubGhz* subghz, uint8_t* preset_data) { furi_assert(subghz); furi_hal_subghz_reset(); furi_hal_subghz_idle(); - furi_hal_subghz_load_preset(preset); + furi_hal_subghz_load_custom_preset(preset_data); furi_hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow); subghz->txrx->txrx_state = SubGhzTxRxStateIDLE; } @@ -155,13 +160,21 @@ bool subghz_tx_start(SubGhz* subghz, FlipperFormat* flipper_format) { if(subghz->txrx->transmitter) { if(subghz_transmitter_deserialize(subghz->txrx->transmitter, flipper_format)) { - if(subghz->txrx->preset) { - subghz_begin(subghz, subghz->txrx->preset); + if(strcmp(string_get_cstr(subghz->txrx->preset->name), "")) { + subghz_begin( + subghz, + subghz_setting_get_preset_data_by_name( + subghz->setting, string_get_cstr(subghz->txrx->preset->name))); } else { - subghz_begin(subghz, FuriHalSubGhzPresetOok270Async); + FURI_LOG_E( + TAG, + "Unknown name preset \" %s \"", + string_get_cstr(subghz->txrx->preset->name)); + subghz_begin( + subghz, subghz_setting_get_preset_data_by_name(subghz->setting, "AM650")); } - if(subghz->txrx->frequency) { - ret = subghz_tx(subghz, subghz->txrx->frequency); + if(subghz->txrx->preset->frequency) { + ret = subghz_tx(subghz, subghz->txrx->preset->frequency); } else { ret = subghz_tx(subghz, 433920000); } @@ -270,16 +283,38 @@ bool subghz_key_load(SubGhz* subghz, const char* file_path, bool show_dialog) { load_key_state = SubGhzLoadKeyStateOnlyRx; break; } - subghz->txrx->frequency = temp_data32; + subghz->txrx->preset->frequency = temp_data32; if(!flipper_format_read_string(fff_data_file, "Preset", temp_str)) { FURI_LOG_E(TAG, "Missing Preset"); break; } + if(!subghz_set_preset(subghz, string_get_cstr(temp_str))) { break; } + if(!strcmp(string_get_cstr(temp_str), "FuriHalSubGhzPresetCustom")) { + //Todo add Custom_preset_module + //delete peset if it already exists + subghz_setting_delete_custom_preset( + subghz->setting, string_get_cstr(subghz->txrx->preset->name)); + //load custom preset from file + if(!subghz_setting_load_custom_preset( + subghz->setting, string_get_cstr(subghz->txrx->preset->name), fff_data_file)) { + FURI_LOG_E(TAG, "Missing Custom preset"); + break; + } + } + size_t preset_index = subghz_setting_get_inx_preset_by_name( + subghz->setting, string_get_cstr(subghz->txrx->preset->name)); + subghz_preset_init( + subghz, + string_get_cstr(subghz->txrx->preset->name), + subghz->txrx->preset->frequency, + subghz_setting_get_preset_data(subghz->setting, preset_index), + subghz_setting_get_preset_data_size(subghz->setting, preset_index)); + if(!flipper_format_read_string(fff_data_file, "Protocol", temp_str)) { FURI_LOG_E(TAG, "Missing Protocol"); break; @@ -541,8 +576,8 @@ void subghz_hopper_update(SubGhz* subghz) { }; if(subghz->txrx->txrx_state == SubGhzTxRxStateIDLE) { subghz_receiver_reset(subghz->txrx->receiver); - subghz->txrx->frequency = subghz_setting_get_hopper_frequency( + subghz->txrx->preset->frequency = subghz_setting_get_hopper_frequency( subghz->setting, subghz->txrx->hopper_idx_frequency); - subghz_rx(subghz, subghz->txrx->frequency); + subghz_rx(subghz, subghz->txrx->preset->frequency); } } diff --git a/applications/subghz/subghz_i.h b/applications/subghz/subghz_i.h index 0a4bcf0b..52c3ba59 100644 --- a/applications/subghz/subghz_i.h +++ b/applications/subghz/subghz_i.h @@ -11,8 +11,8 @@ #include "views/subghz_test_carrier.h" #include "views/subghz_test_packet.h" -#include -#include +// #include +// #include #include #include #include @@ -49,8 +49,7 @@ struct SubGhzTxRx { SubGhzProtocolDecoderBase* decoder_result; FlipperFormat* fff_data; - uint32_t frequency; - FuriHalSubGhzPreset preset; + SubGhzPesetDefinition* preset; SubGhzHistory* history; uint16_t idx_menu_chosen; SubGhzTxRxState txrx_state; @@ -97,9 +96,15 @@ struct SubGhz { void* rpc_ctx; }; +void subghz_preset_init( + void* context, + const char* preset_name, + uint32_t frequency, + uint8_t* preset_data, + size_t preset_data_size); bool subghz_set_preset(SubGhz* subghz, const char* preset); void subghz_get_frequency_modulation(SubGhz* subghz, string_t frequency, string_t modulation); -void subghz_begin(SubGhz* subghz, FuriHalSubGhzPreset preset); +void subghz_begin(SubGhz* subghz, uint8_t* preset_data); uint32_t subghz_rx(SubGhz* subghz, uint32_t frequency); void subghz_rx_end(SubGhz* subghz); void subghz_sleep(SubGhz* subghz); diff --git a/applications/subghz/subghz_setting.c b/applications/subghz/subghz_setting.c index 7d688105..0a662f58 100644 --- a/applications/subghz/subghz_setting.c +++ b/applications/subghz/subghz_setting.c @@ -3,7 +3,7 @@ #include #include -#include +#include "furi_hal_subghz_configs.h" #define TAG "SubGhzSetting" @@ -157,29 +157,89 @@ static const uint32_t subghz_hopper_frequency_list_region_jp[] = { 0, }; +typedef struct { + string_t custom_preset_name; + uint8_t* custom_preset_data; + size_t custom_preset_data_size; +} SubGhzSettingCustomPresetItem; + +ARRAY_DEF(SubGhzSettingCustomPresetItemArray, SubGhzSettingCustomPresetItem, M_POD_OPLIST) + +#define M_OPL_SubGhzSettingCustomPresetItemArray_t() \ + ARRAY_OPLIST(SubGhzSettingCustomPresetItemArray, M_POD_OPLIST) + LIST_DEF(FrequencyList, uint32_t) #define M_OPL_FrequencyList_t() LIST_OPLIST(FrequencyList) +typedef struct { + SubGhzSettingCustomPresetItemArray_t data; +} SubGhzSettingCustomPresetStruct; + struct SubGhzSetting { FrequencyList_t frequencies; FrequencyList_t hopper_frequencies; + SubGhzSettingCustomPresetStruct* preset; }; SubGhzSetting* subghz_setting_alloc(void) { SubGhzSetting* instance = malloc(sizeof(SubGhzSetting)); FrequencyList_init(instance->frequencies); FrequencyList_init(instance->hopper_frequencies); + instance->preset = malloc(sizeof(SubGhzSettingCustomPresetStruct)); + SubGhzSettingCustomPresetItemArray_init(instance->preset->data); return instance; } +static void subghz_setting_preset_reset(SubGhzSetting* instance) { + for + M_EACH(item, instance->preset->data, SubGhzSettingCustomPresetItemArray_t) { + string_clear(item->custom_preset_name); + free(item->custom_preset_data); + } + SubGhzSettingCustomPresetItemArray_reset(instance->preset->data); +} + void subghz_setting_free(SubGhzSetting* instance) { furi_assert(instance); FrequencyList_clear(instance->frequencies); FrequencyList_clear(instance->hopper_frequencies); + for + M_EACH(item, instance->preset->data, SubGhzSettingCustomPresetItemArray_t) { + string_clear(item->custom_preset_name); + free(item->custom_preset_data); + } + SubGhzSettingCustomPresetItemArray_clear(instance->preset->data); + free(instance->preset); free(instance); } +static void subghz_setting_load_default_preset( + SubGhzSetting* instance, + const char* preset_name, + const uint8_t* preset_data, + const uint8_t preset_pa_table[8]) { + furi_assert(instance); + furi_assert(preset_data); + uint32_t preset_data_count = 0; + SubGhzSettingCustomPresetItem* item = + SubGhzSettingCustomPresetItemArray_push_raw(instance->preset->data); + + string_init(item->custom_preset_name); + string_set(item->custom_preset_name, preset_name); + + while(preset_data[preset_data_count]) { + preset_data_count += 2; + } + preset_data_count += 2; + item->custom_preset_data_size = sizeof(uint8_t) * preset_data_count + sizeof(uint8_t) * 8; + item->custom_preset_data = malloc(item->custom_preset_data_size); + //load preset register + memcpy(&item->custom_preset_data[0], &preset_data[0], preset_data_count); + //load pa table + memcpy(&item->custom_preset_data[preset_data_count], &preset_pa_table[0], 8); +} + static void subghz_setting_load_default_region( SubGhzSetting* instance, const uint32_t frequencies[], @@ -188,6 +248,7 @@ static void subghz_setting_load_default_region( FrequencyList_reset(instance->frequencies); FrequencyList_reset(instance->hopper_frequencies); + subghz_setting_preset_reset(instance); while(*frequencies) { FrequencyList_push_back(instance->frequencies, *frequencies); @@ -198,6 +259,27 @@ static void subghz_setting_load_default_region( FrequencyList_push_back(instance->hopper_frequencies, *hopper_frequencies); hopper_frequencies++; } + + subghz_setting_load_default_preset( + instance, + "AM270", + (uint8_t*)furi_hal_subghz_preset_ook_270khz_async_regs, + furi_hal_subghz_preset_ook_async_patable); + subghz_setting_load_default_preset( + instance, + "AM650", + (uint8_t*)furi_hal_subghz_preset_ook_650khz_async_regs, + furi_hal_subghz_preset_ook_async_patable); + subghz_setting_load_default_preset( + instance, + "FM238", + (uint8_t*)furi_hal_subghz_preset_2fsk_dev2_38khz_async_regs, + furi_hal_subghz_preset_2fsk_async_patable); + subghz_setting_load_default_preset( + instance, + "FM476", + (uint8_t*)furi_hal_subghz_preset_2fsk_dev47_6khz_async_regs, + furi_hal_subghz_preset_2fsk_async_patable); } void subghz_setting_load_default(SubGhzSetting* instance) { @@ -260,7 +342,7 @@ void subghz_setting_load(SubGhzSetting* instance, const char* file_path) { // Standard frequencies (optional) temp_bool = true; - flipper_format_read_bool(fff_data_file, "add_standard_frequencies", &temp_bool, 1); + flipper_format_read_bool(fff_data_file, "Add_standard_frequencies", &temp_bool, 1); if(!temp_bool) { FURI_LOG_I(TAG, "Removing standard frequencies"); FrequencyList_reset(instance->frequencies); @@ -275,7 +357,7 @@ void subghz_setting_load(SubGhzSetting* instance, const char* file_path) { break; } while(flipper_format_read_uint32( - fff_data_file, "frequency", (uint32_t*)&temp_data32, 1)) { + fff_data_file, "Frequency", (uint32_t*)&temp_data32, 1)) { if(furi_hal_subghz_is_frequency_valid(temp_data32)) { FURI_LOG_I(TAG, "Frequency loaded %lu", temp_data32); FrequencyList_push_back(instance->frequencies, temp_data32); @@ -290,7 +372,7 @@ void subghz_setting_load(SubGhzSetting* instance, const char* file_path) { break; } while(flipper_format_read_uint32( - fff_data_file, "hopper_frequency", (uint32_t*)&temp_data32, 1)) { + fff_data_file, "Hopper_frequency", (uint32_t*)&temp_data32, 1)) { if(furi_hal_subghz_is_frequency_valid(temp_data32)) { FURI_LOG_I(TAG, "Hopper frequency loaded %lu", temp_data32); FrequencyList_push_back(instance->hopper_frequencies, temp_data32); @@ -304,7 +386,7 @@ void subghz_setting_load(SubGhzSetting* instance, const char* file_path) { FURI_LOG_E(TAG, "Rewind error"); break; } - if(flipper_format_read_uint32(fff_data_file, "default_frequency", &temp_data32, 1)) { + if(flipper_format_read_uint32(fff_data_file, "Default_frequency", &temp_data32, 1)) { for M_EACH(frequency, instance->frequencies, FrequencyList_t) { *frequency &= FREQUENCY_MASK; @@ -313,6 +395,18 @@ void subghz_setting_load(SubGhzSetting* instance, const char* file_path) { } } } + + // custom preset (optional) + if(!flipper_format_rewind(fff_data_file)) { + FURI_LOG_E(TAG, "Rewind error"); + break; + } + while(flipper_format_read_string(fff_data_file, "Custom_preset_name", temp_str)) { + FURI_LOG_I(TAG, "Custom preset loaded %s", string_get_cstr(temp_str)); + subghz_setting_load_custom_preset( + instance, string_get_cstr(temp_str), fff_data_file); + } + } while(false); } @@ -337,6 +431,104 @@ size_t subghz_setting_get_hopper_frequency_count(SubGhzSetting* instance) { return FrequencyList_size(instance->hopper_frequencies); } +size_t subghz_setting_get_preset_count(SubGhzSetting* instance) { + furi_assert(instance); + return SubGhzSettingCustomPresetItemArray_size(instance->preset->data); +} + +const char* subghz_setting_get_preset_name(SubGhzSetting* instance, size_t idx) { + furi_assert(instance); + SubGhzSettingCustomPresetItem* item = + SubGhzSettingCustomPresetItemArray_get(instance->preset->data, idx); + return string_get_cstr(item->custom_preset_name); +} + +int subghz_setting_get_inx_preset_by_name(SubGhzSetting* instance, const char* preset_name) { + furi_assert(instance); + size_t idx = 0; + for + M_EACH(item, instance->preset->data, SubGhzSettingCustomPresetItemArray_t) { + if(strcmp(string_get_cstr(item->custom_preset_name), preset_name) == 0) { + return idx; + } + idx++; + } + furi_crash("SubGhz: No name preset."); + return -1; +} + +bool subghz_setting_load_custom_preset( + SubGhzSetting* instance, + const char* preset_name, + FlipperFormat* fff_data_file) { + furi_assert(instance); + furi_assert(preset_name); + uint32_t temp_data32; + SubGhzSettingCustomPresetItem* item = + SubGhzSettingCustomPresetItemArray_push_raw(instance->preset->data); + string_init(item->custom_preset_name); + string_set(item->custom_preset_name, preset_name); + do { + if(!flipper_format_get_value_count(fff_data_file, "Custom_preset_data", &temp_data32)) + break; + if(!temp_data32 || (temp_data32 % 2)) { + FURI_LOG_E(TAG, "Integrity error Custom_preset_data"); + break; + } + item->custom_preset_data_size = sizeof(uint8_t) * temp_data32; + item->custom_preset_data = malloc(item->custom_preset_data_size); + if(!flipper_format_read_hex( + fff_data_file, + "Custom_preset_data", + item->custom_preset_data, + item->custom_preset_data_size)) { + FURI_LOG_E(TAG, "Missing Custom_preset_data"); + break; + } + return true; + } while(true); + return false; +} + +bool subghz_setting_delete_custom_preset(SubGhzSetting* instance, const char* preset_name) { + furi_assert(instance); + furi_assert(preset_name); + SubGhzSettingCustomPresetItemArray_it_t it; + SubGhzSettingCustomPresetItemArray_it_last(it, instance->preset->data); + while(!SubGhzSettingCustomPresetItemArray_end_p(it)) { + SubGhzSettingCustomPresetItem* item = SubGhzSettingCustomPresetItemArray_ref(it); + if(strcmp(string_get_cstr(item->custom_preset_name), preset_name) == 0) { + string_clear(item->custom_preset_name); + free(item->custom_preset_data); + SubGhzSettingCustomPresetItemArray_remove(instance->preset->data, it); + return true; + } + SubGhzSettingCustomPresetItemArray_previous(it); + } + return false; +} + +uint8_t* subghz_setting_get_preset_data(SubGhzSetting* instance, size_t idx) { + furi_assert(instance); + SubGhzSettingCustomPresetItem* item = + SubGhzSettingCustomPresetItemArray_get(instance->preset->data, idx); + return item->custom_preset_data; +} + +size_t subghz_setting_get_preset_data_size(SubGhzSetting* instance, size_t idx) { + furi_assert(instance); + SubGhzSettingCustomPresetItem* item = + SubGhzSettingCustomPresetItemArray_get(instance->preset->data, idx); + return item->custom_preset_data_size; +} + +uint8_t* subghz_setting_get_preset_data_by_name(SubGhzSetting* instance, const char* preset_name) { + furi_assert(instance); + SubGhzSettingCustomPresetItem* item = SubGhzSettingCustomPresetItemArray_get( + instance->preset->data, subghz_setting_get_inx_preset_by_name(instance, preset_name)); + return item->custom_preset_data; +} + uint32_t subghz_setting_get_frequency(SubGhzSetting* instance, size_t idx) { furi_assert(instance); uint32_t* ret = FrequencyList_get(instance->frequencies, idx); diff --git a/applications/subghz/subghz_setting.h b/applications/subghz/subghz_setting.h index 58a898c5..0590cf49 100644 --- a/applications/subghz/subghz_setting.h +++ b/applications/subghz/subghz_setting.h @@ -4,6 +4,9 @@ #include #include #include +#include + +#define SUBGHZ_SETTING_DEFAULT_PRESET_COUNT 4 typedef struct SubGhzSetting SubGhzSetting; @@ -17,6 +20,25 @@ size_t subghz_setting_get_frequency_count(SubGhzSetting* instance); size_t subghz_setting_get_hopper_frequency_count(SubGhzSetting* instance); +size_t subghz_setting_get_preset_count(SubGhzSetting* instance); + +const char* subghz_setting_get_preset_name(SubGhzSetting* instance, size_t idx); + +int subghz_setting_get_inx_preset_by_name(SubGhzSetting* instance, const char* preset_name); + +uint8_t* subghz_setting_get_preset_data(SubGhzSetting* instance, size_t idx); + +size_t subghz_setting_get_preset_data_size(SubGhzSetting* instance, size_t idx); + +uint8_t* subghz_setting_get_preset_data_by_name(SubGhzSetting* instance, const char* preset_name); + +bool subghz_setting_load_custom_preset( + SubGhzSetting* instance, + const char* preset_name, + FlipperFormat* fff_data_file); + +bool subghz_setting_delete_custom_preset(SubGhzSetting* instance, const char* preset_name); + uint32_t subghz_setting_get_frequency(SubGhzSetting* instance, size_t idx); uint32_t subghz_setting_get_hopper_frequency(SubGhzSetting* instance, size_t idx); diff --git a/assets/resources/subghz/assets/setting_user b/assets/resources/subghz/assets/setting_user index 413dbf31..1f37a2eb 100644 --- a/assets/resources/subghz/assets/setting_user +++ b/assets/resources/subghz/assets/setting_user @@ -2,17 +2,28 @@ Filetype: Flipper SubGhz Setting File Version: 1 # Add Standard frequencies for your region -#add_standard_frequencies: true +#Add_standard_frequencies: true # Default Frequency: used as default for "Read" and "Read Raw" -#default_frequency: 433920000 +#Default_frequency: 433920000 # Frequencies used for "Read", "Read Raw" and "Frequency Analyzer" -#frequency: 300000000 -#frequency: 310000000 -#frequency: 320000000 +#Frequency: 300000000 +#Frequency: 310000000 +#Frequency: 320000000 # Frequencies used for hopping mode (keep this list small or flipper will miss signal) -#hopper_frequency: 300000000 -#hopper_frequency: 310000000 -#hopper_frequency: 310000000 +#Hopper_frequency: 300000000 +#Hopper_frequency: 310000000 +#Hopper_frequency: 310000000 + +# Custom preset +# format for CC1101 "Custom_preset_data:" XX YY XX YY .. 00 00 ZZ ZZ ZZ ZZ ZZ ZZ ZZ ZZ, where: XX-register, YY - register data, 00 00 - end load register, ZZ - 8 byte Pa table register + +#Custom_preset_name: AM_1 +#Custom_preset_module: CC1101 +#Custom_preset_data: 02 0D 03 07 08 32 0B 06 14 00 13 00 12 30 11 32 10 17 18 18 19 18 1D 91 1C 00 1B 07 20 FB 22 11 21 B6 00 00 00 C0 00 00 00 00 00 00 + +#Custom_preset_name: AM_2 +#Custom_preset_module: CC1101 +#Custom_preset_data: 02 0D 03 07 08 32 0B 06 14 00 13 00 12 30 11 32 10 17 18 18 19 18 1D 91 1C 00 1B 07 20 FB 22 11 21 B6 00 00 00 C0 00 00 00 00 00 00 diff --git a/firmware/targets/f7/furi_hal/furi_hal_subghz.c b/firmware/targets/f7/furi_hal/furi_hal_subghz.c index 5ad0d578..650f8ac3 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_subghz.c +++ b/firmware/targets/f7/furi_hal/furi_hal_subghz.c @@ -100,22 +100,24 @@ void furi_hal_subghz_dump_state() { void furi_hal_subghz_load_preset(FuriHalSubGhzPreset preset) { if(preset == FuriHalSubGhzPresetOok650Async) { - furi_hal_subghz_load_registers(furi_hal_subghz_preset_ook_650khz_async_regs); + furi_hal_subghz_load_registers((uint8_t*)furi_hal_subghz_preset_ook_650khz_async_regs); furi_hal_subghz_load_patable(furi_hal_subghz_preset_ook_async_patable); } else if(preset == FuriHalSubGhzPresetOok270Async) { - furi_hal_subghz_load_registers(furi_hal_subghz_preset_ook_270khz_async_regs); + furi_hal_subghz_load_registers((uint8_t*)furi_hal_subghz_preset_ook_270khz_async_regs); furi_hal_subghz_load_patable(furi_hal_subghz_preset_ook_async_patable); } else if(preset == FuriHalSubGhzPreset2FSKDev238Async) { - furi_hal_subghz_load_registers(furi_hal_subghz_preset_2fsk_dev2_38khz_async_regs); + furi_hal_subghz_load_registers( + (uint8_t*)furi_hal_subghz_preset_2fsk_dev2_38khz_async_regs); furi_hal_subghz_load_patable(furi_hal_subghz_preset_2fsk_async_patable); } else if(preset == FuriHalSubGhzPreset2FSKDev476Async) { - furi_hal_subghz_load_registers(furi_hal_subghz_preset_2fsk_dev47_6khz_async_regs); + furi_hal_subghz_load_registers( + (uint8_t*)furi_hal_subghz_preset_2fsk_dev47_6khz_async_regs); furi_hal_subghz_load_patable(furi_hal_subghz_preset_2fsk_async_patable); } else if(preset == FuriHalSubGhzPresetMSK99_97KbAsync) { - furi_hal_subghz_load_registers(furi_hal_subghz_preset_msk_99_97kb_async_regs); + furi_hal_subghz_load_registers((uint8_t*)furi_hal_subghz_preset_msk_99_97kb_async_regs); furi_hal_subghz_load_patable(furi_hal_subghz_preset_msk_async_patable); } else if(preset == FuriHalSubGhzPresetGFSK9_99KbAsync) { - furi_hal_subghz_load_registers(furi_hal_subghz_preset_gfsk_9_99kb_async_regs); + furi_hal_subghz_load_registers((uint8_t*)furi_hal_subghz_preset_gfsk_9_99kb_async_regs); furi_hal_subghz_load_patable(furi_hal_subghz_preset_gfsk_async_patable); } else { furi_crash("SubGhz: Missing config."); @@ -123,13 +125,44 @@ void furi_hal_subghz_load_preset(FuriHalSubGhzPreset preset) { furi_hal_subghz.preset = preset; } -void furi_hal_subghz_load_registers(const uint8_t data[][2]) { +void furi_hal_subghz_load_custom_preset(uint8_t* preset_data) { + //load config furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); cc1101_reset(&furi_hal_spi_bus_handle_subghz); uint32_t i = 0; - while(data[i][0]) { - cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, data[i][0], data[i][1]); - i++; + uint8_t pa[8] = {0}; + while(preset_data[i]) { + cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, preset_data[i], preset_data[i + 1]); + i += 2; + } + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); + + //load pa table + memcpy(&pa[0], &preset_data[i + 2], 8); + furi_hal_subghz_load_patable(pa); + furi_hal_subghz.preset = FuriHalSubGhzPresetCustom; + + //show debug + if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) { + i = 0; + FURI_LOG_D(TAG, "Loading custom preset"); + while(preset_data[i]) { + FURI_LOG_D(TAG, "Reg[%lu]: %02X=%02X", i, preset_data[i], preset_data[i + 1]); + i += 2; + } + for(uint8_t y = i; y < i + 10; y++) { + FURI_LOG_D(TAG, "PA[%lu]: %02X", y, preset_data[y]); + } + } +} + +void furi_hal_subghz_load_registers(uint8_t* data) { + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); + cc1101_reset(&furi_hal_spi_bus_handle_subghz); + uint32_t i = 0; + while(data[i]) { + cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, data[i], data[i + 1]); + i += 2; } furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); } diff --git a/firmware/targets/furi_hal_include/furi_hal_subghz.h b/firmware/targets/furi_hal_include/furi_hal_subghz.h index 4c5ad07f..b6d132ac 100644 --- a/firmware/targets/furi_hal_include/furi_hal_subghz.h +++ b/firmware/targets/furi_hal_include/furi_hal_subghz.h @@ -22,7 +22,8 @@ typedef enum { FuriHalSubGhzPreset2FSKDev238Async, /**< FM, deviation 2.380371 kHz, asynchronous */ FuriHalSubGhzPreset2FSKDev476Async, /**< FM, deviation 47.60742 kHz, asynchronous */ FuriHalSubGhzPresetMSK99_97KbAsync, /**< MSK, deviation 47.60742 kHz, 99.97Kb/s, asynchronous */ - FuriHalSubGhzPresetGFSK9_99KbAsync /**< GFSK, deviation 19.042969 kHz, 9.996Kb/s, asynchronous */ + FuriHalSubGhzPresetGFSK9_99KbAsync, /**< GFSK, deviation 19.042969 kHz, 9.996Kb/s, asynchronous */ + FuriHalSubGhzPresetCustom, /**Custom Preset*/ } FuriHalSubGhzPreset; /** Switchable Radio Paths */ @@ -74,11 +75,17 @@ void furi_hal_subghz_dump_state(); */ void furi_hal_subghz_load_preset(FuriHalSubGhzPreset preset); +/** Load custom registers from preset + * + * @param preset_data registers to load + */ +void furi_hal_subghz_load_custom_preset(uint8_t* preset_data); + /** Load registers * * @param data Registers data */ -void furi_hal_subghz_load_registers(const uint8_t data[][2]); +void furi_hal_subghz_load_registers(uint8_t* data); /** Load PATABLE * diff --git a/lib/subghz/blocks/generic.c b/lib/subghz/blocks/generic.c index 811a5fa7..187c30e6 100644 --- a/lib/subghz/blocks/generic.c +++ b/lib/subghz/blocks/generic.c @@ -1,39 +1,29 @@ #include "generic.h" -#include "../types.h" #include #include #define TAG "SubGhzBlockGeneric" -bool subghz_block_generic_get_preset_name(FuriHalSubGhzPreset preset, string_t preset_str) { - const char* preset_name; - switch(preset) { - case FuriHalSubGhzPresetOok270Async: - preset_name = "FuriHalSubGhzPresetOok270Async"; - break; - case FuriHalSubGhzPresetOok650Async: - preset_name = "FuriHalSubGhzPresetOok650Async"; - break; - case FuriHalSubGhzPreset2FSKDev238Async: - preset_name = "FuriHalSubGhzPreset2FSKDev238Async"; - break; - case FuriHalSubGhzPreset2FSKDev476Async: - preset_name = "FuriHalSubGhzPreset2FSKDev476Async"; - break; - default: - FURI_LOG_E(TAG, "Unknown preset"); - return false; - break; +void subghz_block_generic_get_preset_name(const char* preset_name, string_t preset_str) { + const char* preset_name_temp; + if(!strcmp(preset_name, "AM270")) { + preset_name_temp = "FuriHalSubGhzPresetOok270Async"; + } else if(!strcmp(preset_name, "AM650")) { + preset_name_temp = "FuriHalSubGhzPresetOok650Async"; + } else if(!strcmp(preset_name, "FM238")) { + preset_name_temp = "FuriHalSubGhzPreset2FSKDev238Async"; + } else if(!strcmp(preset_name, "FM476")) { + preset_name_temp = "FuriHalSubGhzPreset2FSKDev476Async"; + } else { + preset_name_temp = "FuriHalSubGhzPresetCustom"; } - string_set(preset_str, preset_name); - return true; + string_set(preset_str, preset_name_temp); } bool subghz_block_generic_serialize( SubGhzBlockGeneric* instance, FlipperFormat* flipper_format, - uint32_t frequency, - FuriHalSubGhzPreset preset) { + SubGhzPesetDefinition* preset) { furi_assert(instance); bool res = false; string_t temp_str; @@ -46,17 +36,28 @@ bool subghz_block_generic_serialize( break; } - if(!flipper_format_write_uint32(flipper_format, "Frequency", &frequency, 1)) { + if(!flipper_format_write_uint32(flipper_format, "Frequency", &preset->frequency, 1)) { FURI_LOG_E(TAG, "Unable to add Frequency"); break; } - if(!subghz_block_generic_get_preset_name(preset, temp_str)) { - break; - } + + subghz_block_generic_get_preset_name(string_get_cstr(preset->name), temp_str); if(!flipper_format_write_string_cstr(flipper_format, "Preset", string_get_cstr(temp_str))) { FURI_LOG_E(TAG, "Unable to add Preset"); break; } + if(!strcmp(string_get_cstr(temp_str), "FuriHalSubGhzPresetCustom")) { + if(!flipper_format_write_string_cstr( + flipper_format, "Custom_preset_module", "CC1101")) { + FURI_LOG_E(TAG, "Unable to add Custom_preset_module"); + break; + } + if(!flipper_format_write_hex( + flipper_format, "Custom_preset_data", preset->data, preset->data_size)) { + FURI_LOG_E(TAG, "Unable to add Custom_preset_data"); + break; + } + } if(!flipper_format_write_string_cstr(flipper_format, "Protocol", instance->protocol_name)) { FURI_LOG_E(TAG, "Unable to add Protocol"); break; diff --git a/lib/subghz/blocks/generic.h b/lib/subghz/blocks/generic.h index 1a7bca83..e1256ea4 100644 --- a/lib/subghz/blocks/generic.h +++ b/lib/subghz/blocks/generic.h @@ -7,6 +7,7 @@ #include #include "furi.h" #include "furi_hal.h" +#include "../types.h" typedef struct SubGhzBlockGeneric SubGhzBlockGeneric; @@ -20,26 +21,23 @@ struct SubGhzBlockGeneric { }; /** - * Get modulation name. - * @param preset modulation,FuriHalSubGhzPreset - * @param preset_str Output modulation name - * @return true On success + * Get name preset. + * @param preset_name name preset + * @param preset_str Output name preset */ -bool subghz_block_generic_get_preset_name(FuriHalSubGhzPreset preset, string_t preset_str); +void subghz_block_generic_get_preset_name(const char* preset_name, string_t preset_str); /** * Serialize data SubGhzBlockGeneric. * @param instance Pointer to a SubGhzBlockGeneric instance * @param flipper_format Pointer to a FlipperFormat instance - * @param frequency The frequency at which the signal was received, Hz - * @param preset The modulation on which the signal was received, FuriHalSubGhzPreset + * @param preset The modulation on which the signal was received, SubGhzPesetDefinition * @return true On success */ bool subghz_block_generic_serialize( SubGhzBlockGeneric* instance, FlipperFormat* flipper_format, - uint32_t frequency, - FuriHalSubGhzPreset preset); + SubGhzPesetDefinition* preset); /** * Deserialize data SubGhzBlockGeneric. diff --git a/lib/subghz/protocols/base.c b/lib/subghz/protocols/base.c index 90096c2b..32c64cce 100644 --- a/lib/subghz/protocols/base.c +++ b/lib/subghz/protocols/base.c @@ -26,14 +26,12 @@ bool subghz_protocol_decoder_base_get_string( bool subghz_protocol_decoder_base_serialize( SubGhzProtocolDecoderBase* decoder_base, FlipperFormat* flipper_format, - uint32_t frequency, - FuriHalSubGhzPreset preset) { + SubGhzPesetDefinition* preset) { bool status = false; if(decoder_base->protocol && decoder_base->protocol->decoder && decoder_base->protocol->decoder->serialize) { - status = decoder_base->protocol->decoder->serialize( - decoder_base, flipper_format, frequency, preset); + status = decoder_base->protocol->decoder->serialize(decoder_base, flipper_format, preset); } return status; diff --git a/lib/subghz/protocols/base.h b/lib/subghz/protocols/base.h index 19d9c414..ad237bbe 100644 --- a/lib/subghz/protocols/base.h +++ b/lib/subghz/protocols/base.h @@ -43,15 +43,13 @@ bool subghz_protocol_decoder_base_get_string( * Serialize data SubGhzProtocolDecoderBase. * @param decoder_base Pointer to a SubGhzProtocolDecoderBase instance * @param flipper_format Pointer to a FlipperFormat instance - * @param frequency The frequency at which the signal was received, Hz - * @param preset The modulation on which the signal was received, FuriHalSubGhzPreset + * @param preset The modulation on which the signal was received, SubGhzPesetDefinition * @return true On success */ bool subghz_protocol_decoder_base_serialize( SubGhzProtocolDecoderBase* decoder_base, FlipperFormat* flipper_format, - uint32_t frequency, - FuriHalSubGhzPreset preset); + SubGhzPesetDefinition* preset); /** * Deserialize data SubGhzProtocolDecoderBase. diff --git a/lib/subghz/protocols/came.c b/lib/subghz/protocols/came.c index 8817b380..1d2045ca 100644 --- a/lib/subghz/protocols/came.c +++ b/lib/subghz/protocols/came.c @@ -284,11 +284,10 @@ uint8_t subghz_protocol_decoder_came_get_hash_data(void* context) { bool subghz_protocol_decoder_came_serialize( void* context, FlipperFormat* flipper_format, - uint32_t frequency, - FuriHalSubGhzPreset preset) { + SubGhzPesetDefinition* preset) { furi_assert(context); SubGhzProtocolDecoderCame* instance = context; - return subghz_block_generic_serialize(&instance->generic, flipper_format, frequency, preset); + return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); } bool subghz_protocol_decoder_came_deserialize(void* context, FlipperFormat* flipper_format) { diff --git a/lib/subghz/protocols/came.h b/lib/subghz/protocols/came.h index 2fd1b718..abd3044b 100644 --- a/lib/subghz/protocols/came.h +++ b/lib/subghz/protocols/came.h @@ -83,15 +83,13 @@ uint8_t subghz_protocol_decoder_came_get_hash_data(void* context); * Serialize data SubGhzProtocolDecoderCame. * @param context Pointer to a SubGhzProtocolDecoderCame instance * @param flipper_format Pointer to a FlipperFormat instance - * @param frequency The frequency at which the signal was received, Hz - * @param preset The modulation on which the signal was received, FuriHalSubGhzPreset + * @param preset The modulation on which the signal was received, SubGhzPesetDefinition * @return true On success */ bool subghz_protocol_decoder_came_serialize( void* context, FlipperFormat* flipper_format, - uint32_t frequency, - FuriHalSubGhzPreset preset); + SubGhzPesetDefinition* preset); /** * Deserialize data SubGhzProtocolDecoderCame. diff --git a/lib/subghz/protocols/came_atomo.c b/lib/subghz/protocols/came_atomo.c index ad98f83f..2178b4d1 100644 --- a/lib/subghz/protocols/came_atomo.c +++ b/lib/subghz/protocols/came_atomo.c @@ -301,11 +301,10 @@ uint8_t subghz_protocol_decoder_came_atomo_get_hash_data(void* context) { bool subghz_protocol_decoder_came_atomo_serialize( void* context, FlipperFormat* flipper_format, - uint32_t frequency, - FuriHalSubGhzPreset preset) { + SubGhzPesetDefinition* preset) { furi_assert(context); SubGhzProtocolDecoderCameAtomo* instance = context; - return subghz_block_generic_serialize(&instance->generic, flipper_format, frequency, preset); + return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); } bool subghz_protocol_decoder_came_atomo_deserialize(void* context, FlipperFormat* flipper_format) { diff --git a/lib/subghz/protocols/came_atomo.h b/lib/subghz/protocols/came_atomo.h index d1c856e1..eaba74c8 100644 --- a/lib/subghz/protocols/came_atomo.h +++ b/lib/subghz/protocols/came_atomo.h @@ -48,15 +48,13 @@ uint8_t subghz_protocol_decoder_came_atomo_get_hash_data(void* context); * Serialize data SubGhzProtocolDecoderCameAtomo. * @param context Pointer to a SubGhzProtocolDecoderCameAtomo instance * @param flipper_format Pointer to a FlipperFormat instance - * @param frequency The frequency at which the signal was received, Hz - * @param preset The modulation on which the signal was received, FuriHalSubGhzPreset + * @param preset The modulation on which the signal was received, SubGhzPesetDefinition * @return true On success */ bool subghz_protocol_decoder_came_atomo_serialize( void* context, FlipperFormat* flipper_format, - uint32_t frequency, - FuriHalSubGhzPreset preset); + SubGhzPesetDefinition* preset); /** * Deserialize data SubGhzProtocolDecoderCameAtomo. diff --git a/lib/subghz/protocols/came_twee.c b/lib/subghz/protocols/came_twee.c index fa538c54..7310d6f9 100644 --- a/lib/subghz/protocols/came_twee.c +++ b/lib/subghz/protocols/came_twee.c @@ -418,11 +418,10 @@ uint8_t subghz_protocol_decoder_came_twee_get_hash_data(void* context) { bool subghz_protocol_decoder_came_twee_serialize( void* context, FlipperFormat* flipper_format, - uint32_t frequency, - FuriHalSubGhzPreset preset) { + SubGhzPesetDefinition* preset) { furi_assert(context); SubGhzProtocolDecoderCameTwee* instance = context; - return subghz_block_generic_serialize(&instance->generic, flipper_format, frequency, preset); + return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); } bool subghz_protocol_decoder_came_twee_deserialize(void* context, FlipperFormat* flipper_format) { diff --git a/lib/subghz/protocols/came_twee.h b/lib/subghz/protocols/came_twee.h index 225f3c04..66a89423 100644 --- a/lib/subghz/protocols/came_twee.h +++ b/lib/subghz/protocols/came_twee.h @@ -83,15 +83,13 @@ uint8_t subghz_protocol_decoder_came_twee_get_hash_data(void* context); * Serialize data SubGhzProtocolDecoderCameTwee. * @param context Pointer to a SubGhzProtocolDecoderCameTwee instance * @param flipper_format Pointer to a FlipperFormat instance - * @param frequency The frequency at which the signal was received, Hz - * @param preset The modulation on which the signal was received, FuriHalSubGhzPreset + * @param preset The modulation on which the signal was received, SubGhzPesetDefinition * @return true On success */ bool subghz_protocol_decoder_came_twee_serialize( void* context, FlipperFormat* flipper_format, - uint32_t frequency, - FuriHalSubGhzPreset preset); + SubGhzPesetDefinition* preset); /** * Deserialize data SubGhzProtocolDecoderCameTwee. diff --git a/lib/subghz/protocols/chamberlain_code.c b/lib/subghz/protocols/chamberlain_code.c index 23ac8cc8..40958421 100644 --- a/lib/subghz/protocols/chamberlain_code.c +++ b/lib/subghz/protocols/chamberlain_code.c @@ -423,11 +423,10 @@ uint8_t subghz_protocol_decoder_chamb_code_get_hash_data(void* context) { bool subghz_protocol_decoder_chamb_code_serialize( void* context, FlipperFormat* flipper_format, - uint32_t frequency, - FuriHalSubGhzPreset preset) { + SubGhzPesetDefinition* preset) { furi_assert(context); SubGhzProtocolDecoderChamb_Code* instance = context; - return subghz_block_generic_serialize(&instance->generic, flipper_format, frequency, preset); + return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); } bool subghz_protocol_decoder_chamb_code_deserialize(void* context, FlipperFormat* flipper_format) { diff --git a/lib/subghz/protocols/chamberlain_code.h b/lib/subghz/protocols/chamberlain_code.h index f6ef48fd..e25e54c2 100644 --- a/lib/subghz/protocols/chamberlain_code.h +++ b/lib/subghz/protocols/chamberlain_code.h @@ -83,15 +83,13 @@ uint8_t subghz_protocol_decoder_chamb_code_get_hash_data(void* context); * Serialize data SubGhzProtocolDecoderChamb_Code. * @param context Pointer to a SubGhzProtocolDecoderChamb_Code instance * @param flipper_format Pointer to a FlipperFormat instance - * @param frequency The frequency at which the signal was received, Hz - * @param preset The modulation on which the signal was received, FuriHalSubGhzPreset + * @param preset The modulation on which the signal was received, SubGhzPesetDefinition * @return true On success */ bool subghz_protocol_decoder_chamb_code_serialize( void* context, FlipperFormat* flipper_format, - uint32_t frequency, - FuriHalSubGhzPreset preset); + SubGhzPesetDefinition* preset); /** * Deserialize data SubGhzProtocolDecoderChamb_Code. diff --git a/lib/subghz/protocols/faac_slh.c b/lib/subghz/protocols/faac_slh.c index d5761831..caa8e5eb 100644 --- a/lib/subghz/protocols/faac_slh.c +++ b/lib/subghz/protocols/faac_slh.c @@ -183,11 +183,10 @@ uint8_t subghz_protocol_decoder_faac_slh_get_hash_data(void* context) { bool subghz_protocol_decoder_faac_slh_serialize( void* context, FlipperFormat* flipper_format, - uint32_t frequency, - FuriHalSubGhzPreset preset) { + SubGhzPesetDefinition* preset) { furi_assert(context); SubGhzProtocolDecoderFaacSLH* instance = context; - return subghz_block_generic_serialize(&instance->generic, flipper_format, frequency, preset); + return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); } bool subghz_protocol_decoder_faac_slh_deserialize(void* context, FlipperFormat* flipper_format) { diff --git a/lib/subghz/protocols/faac_slh.h b/lib/subghz/protocols/faac_slh.h index 2575a5ff..f1ad1452 100644 --- a/lib/subghz/protocols/faac_slh.h +++ b/lib/subghz/protocols/faac_slh.h @@ -49,15 +49,13 @@ uint8_t subghz_protocol_decoder_faac_slh_get_hash_data(void* context); * Serialize data SubGhzProtocolDecoderFaacSLH. * @param context Pointer to a SubGhzProtocolDecoderFaacSLH instance * @param flipper_format Pointer to a FlipperFormat instance - * @param frequency The frequency at which the signal was received, Hz - * @param preset The modulation on which the signal was received, FuriHalSubGhzPreset + * @param preset The modulation on which the signal was received, SubGhzPesetDefinition * @return true On success */ bool subghz_protocol_decoder_faac_slh_serialize( void* context, FlipperFormat* flipper_format, - uint32_t frequency, - FuriHalSubGhzPreset preset); + SubGhzPesetDefinition* preset); /** * Deserialize data SubGhzProtocolDecoderFaacSLH. diff --git a/lib/subghz/protocols/gate_tx.c b/lib/subghz/protocols/gate_tx.c index 5f124c37..a172eb3c 100644 --- a/lib/subghz/protocols/gate_tx.c +++ b/lib/subghz/protocols/gate_tx.c @@ -289,11 +289,10 @@ uint8_t subghz_protocol_decoder_gate_tx_get_hash_data(void* context) { bool subghz_protocol_decoder_gate_tx_serialize( void* context, FlipperFormat* flipper_format, - uint32_t frequency, - FuriHalSubGhzPreset preset) { + SubGhzPesetDefinition* preset) { furi_assert(context); SubGhzProtocolDecoderGateTx* instance = context; - return subghz_block_generic_serialize(&instance->generic, flipper_format, frequency, preset); + return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); } bool subghz_protocol_decoder_gate_tx_deserialize(void* context, FlipperFormat* flipper_format) { diff --git a/lib/subghz/protocols/gate_tx.h b/lib/subghz/protocols/gate_tx.h index 4b5f4d00..f296a27e 100644 --- a/lib/subghz/protocols/gate_tx.h +++ b/lib/subghz/protocols/gate_tx.h @@ -83,15 +83,13 @@ uint8_t subghz_protocol_decoder_gate_tx_get_hash_data(void* context); * Serialize data SubGhzProtocolDecoderGateTx. * @param context Pointer to a SubGhzProtocolDecoderGateTx instance * @param flipper_format Pointer to a FlipperFormat instance - * @param frequency The frequency at which the signal was received, Hz - * @param preset The modulation on which the signal was received, FuriHalSubGhzPreset + * @param preset The modulation on which the signal was received, SubGhzPesetDefinition * @return true On success */ bool subghz_protocol_decoder_gate_tx_serialize( void* context, FlipperFormat* flipper_format, - uint32_t frequency, - FuriHalSubGhzPreset preset); + SubGhzPesetDefinition* preset); /** * Deserialize data SubGhzProtocolDecoderGateTx. diff --git a/lib/subghz/protocols/holtek.c b/lib/subghz/protocols/holtek.c index 174d023e..c24bdf6f 100644 --- a/lib/subghz/protocols/holtek.c +++ b/lib/subghz/protocols/holtek.c @@ -322,11 +322,10 @@ uint8_t subghz_protocol_decoder_holtek_get_hash_data(void* context) { bool subghz_protocol_decoder_holtek_serialize( void* context, FlipperFormat* flipper_format, - uint32_t frequency, - FuriHalSubGhzPreset preset) { + SubGhzPesetDefinition* preset) { furi_assert(context); SubGhzProtocolDecoderHoltek* instance = context; - return subghz_block_generic_serialize(&instance->generic, flipper_format, frequency, preset); + return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); } bool subghz_protocol_decoder_holtek_deserialize(void* context, FlipperFormat* flipper_format) { diff --git a/lib/subghz/protocols/holtek.h b/lib/subghz/protocols/holtek.h index 0110fdd3..cc962dcc 100644 --- a/lib/subghz/protocols/holtek.h +++ b/lib/subghz/protocols/holtek.h @@ -83,15 +83,13 @@ uint8_t subghz_protocol_decoder_holtek_get_hash_data(void* context); * Serialize data SubGhzProtocolDecoderHoltek. * @param context Pointer to a SubGhzProtocolDecoderHoltek instance * @param flipper_format Pointer to a FlipperFormat instance - * @param frequency The frequency at which the signal was received, Hz - * @param preset The modulation on which the signal was received, FuriHalSubGhzPreset + * @param preset The modulation on which the signal was received, SubGhzPesetDefinition * @return true On success */ bool subghz_protocol_decoder_holtek_serialize( void* context, FlipperFormat* flipper_format, - uint32_t frequency, - FuriHalSubGhzPreset preset); + SubGhzPesetDefinition* preset); /** * Deserialize data SubGhzProtocolDecoderHoltek. diff --git a/lib/subghz/protocols/hormann.c b/lib/subghz/protocols/hormann.c index 20ff50fc..696aaf61 100644 --- a/lib/subghz/protocols/hormann.c +++ b/lib/subghz/protocols/hormann.c @@ -310,11 +310,10 @@ uint8_t subghz_protocol_decoder_hormann_get_hash_data(void* context) { bool subghz_protocol_decoder_hormann_serialize( void* context, FlipperFormat* flipper_format, - uint32_t frequency, - FuriHalSubGhzPreset preset) { + SubGhzPesetDefinition* preset) { furi_assert(context); SubGhzProtocolDecoderHormann* instance = context; - return subghz_block_generic_serialize(&instance->generic, flipper_format, frequency, preset); + return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); } bool subghz_protocol_decoder_hormann_deserialize(void* context, FlipperFormat* flipper_format) { diff --git a/lib/subghz/protocols/hormann.h b/lib/subghz/protocols/hormann.h index 2b09a065..04634ff0 100644 --- a/lib/subghz/protocols/hormann.h +++ b/lib/subghz/protocols/hormann.h @@ -83,15 +83,13 @@ uint8_t subghz_protocol_decoder_hormann_get_hash_data(void* context); * Serialize data SubGhzProtocolDecoderHormann. * @param context Pointer to a SubGhzProtocolDecoderHormann instance * @param flipper_format Pointer to a FlipperFormat instance - * @param frequency The frequency at which the signal was received, Hz - * @param preset The modulation on which the signal was received, FuriHalSubGhzPreset + * @param preset The modulation on which the signal was received, SubGhzPesetDefinition * @return true On success */ bool subghz_protocol_decoder_hormann_serialize( void* context, FlipperFormat* flipper_format, - uint32_t frequency, - FuriHalSubGhzPreset preset); + SubGhzPesetDefinition* preset); /** * Deserialize data SubGhzProtocolDecoderHormann. diff --git a/lib/subghz/protocols/ido.c b/lib/subghz/protocols/ido.c index 93693b68..2f5a9195 100644 --- a/lib/subghz/protocols/ido.c +++ b/lib/subghz/protocols/ido.c @@ -182,11 +182,10 @@ uint8_t subghz_protocol_decoder_ido_get_hash_data(void* context) { bool subghz_protocol_decoder_ido_serialize( void* context, FlipperFormat* flipper_format, - uint32_t frequency, - FuriHalSubGhzPreset preset) { + SubGhzPesetDefinition* preset) { furi_assert(context); SubGhzProtocolDecoderIDo* instance = context; - return subghz_block_generic_serialize(&instance->generic, flipper_format, frequency, preset); + return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); } bool subghz_protocol_decoder_ido_deserialize(void* context, FlipperFormat* flipper_format) { diff --git a/lib/subghz/protocols/ido.h b/lib/subghz/protocols/ido.h index 266529e1..d2328218 100644 --- a/lib/subghz/protocols/ido.h +++ b/lib/subghz/protocols/ido.h @@ -49,15 +49,13 @@ uint8_t subghz_protocol_decoder_ido_get_hash_data(void* context); * Serialize data SubGhzProtocolDecoderIDo. * @param context Pointer to a SubGhzProtocolDecoderIDo instance * @param flipper_format Pointer to a FlipperFormat instance - * @param frequency The frequency at which the signal was received, Hz - * @param preset The modulation on which the signal was received, FuriHalSubGhzPreset + * @param preset The modulation on which the signal was received, SubGhzPesetDefinition * @return true On success */ bool subghz_protocol_decoder_ido_serialize( void* context, FlipperFormat* flipper_format, - uint32_t frequency, - FuriHalSubGhzPreset preset); + SubGhzPesetDefinition* preset); /** * Deserialize data SubGhzProtocolDecoderIDo. diff --git a/lib/subghz/protocols/keeloq.c b/lib/subghz/protocols/keeloq.c index 566ae576..de18e294 100644 --- a/lib/subghz/protocols/keeloq.c +++ b/lib/subghz/protocols/keeloq.c @@ -174,8 +174,7 @@ bool subghz_protocol_keeloq_create_data( uint8_t btn, uint16_t cnt, const char* manufacture_name, - uint32_t frequency, - FuriHalSubGhzPreset preset) { + SubGhzPesetDefinition* preset) { furi_assert(context); SubGhzProtocolEncoderKeeloq* instance = context; instance->generic.serial = serial; @@ -184,8 +183,7 @@ bool subghz_protocol_keeloq_create_data( instance->generic.data_count_bit = 64; bool res = subghz_protocol_keeloq_gen_data(instance, btn); if(res) { - res = - subghz_block_generic_serialize(&instance->generic, flipper_format, frequency, preset); + res = subghz_block_generic_serialize(&instance->generic, flipper_format, preset); } return res; } @@ -633,15 +631,13 @@ uint8_t subghz_protocol_decoder_keeloq_get_hash_data(void* context) { bool subghz_protocol_decoder_keeloq_serialize( void* context, FlipperFormat* flipper_format, - uint32_t frequency, - FuriHalSubGhzPreset preset) { + SubGhzPesetDefinition* preset) { furi_assert(context); SubGhzProtocolDecoderKeeloq* instance = context; subghz_protocol_keeloq_check_remote_controller( &instance->generic, instance->keystore, &instance->manufacture_name); - bool res = - subghz_block_generic_serialize(&instance->generic, flipper_format, frequency, preset); + bool res = subghz_block_generic_serialize(&instance->generic, flipper_format, preset); if(res && !flipper_format_write_string_cstr( flipper_format, "Manufacture", instance->manufacture_name)) { diff --git a/lib/subghz/protocols/keeloq.h b/lib/subghz/protocols/keeloq.h index 72961ceb..2a590b0d 100644 --- a/lib/subghz/protocols/keeloq.h +++ b/lib/subghz/protocols/keeloq.h @@ -32,8 +32,7 @@ void subghz_protocol_encoder_keeloq_free(void* context); * @param btn Button number, 4 bit * @param cnt Container value, 16 bit * @param manufacture_name Name of manufacturer's key - * @param frequency Transmission frequency, Hz - * @param preset Modulation, FuriHalSubGhzPreset + * @param preset Modulation, SubGhzPesetDefinition * @return true On success */ bool subghz_protocol_keeloq_create_data( @@ -43,8 +42,7 @@ bool subghz_protocol_keeloq_create_data( uint8_t btn, uint16_t cnt, const char* manufacture_name, - uint32_t frequency, - FuriHalSubGhzPreset preset); + SubGhzPesetDefinition* preset); /** * Deserialize and generating an upload to send. @@ -105,15 +103,13 @@ uint8_t subghz_protocol_decoder_keeloq_get_hash_data(void* context); * Serialize data SubGhzProtocolDecoderKeeloq. * @param context Pointer to a SubGhzProtocolDecoderKeeloq instance * @param flipper_format Pointer to a FlipperFormat instance - * @param frequency The frequency at which the signal was received, Hz - * @param preset The modulation on which the signal was received, FuriHalSubGhzPreset + * @param preset The modulation on which the signal was received, SubGhzPesetDefinition * @return true On success */ bool subghz_protocol_decoder_keeloq_serialize( void* context, FlipperFormat* flipper_format, - uint32_t frequency, - FuriHalSubGhzPreset preset); + SubGhzPesetDefinition* preset); /** * Deserialize data SubGhzProtocolDecoderKeeloq. diff --git a/lib/subghz/protocols/kia.c b/lib/subghz/protocols/kia.c index 5a89934b..069eb8f1 100644 --- a/lib/subghz/protocols/kia.c +++ b/lib/subghz/protocols/kia.c @@ -233,11 +233,10 @@ uint8_t subghz_protocol_decoder_kia_get_hash_data(void* context) { bool subghz_protocol_decoder_kia_serialize( void* context, FlipperFormat* flipper_format, - uint32_t frequency, - FuriHalSubGhzPreset preset) { + SubGhzPesetDefinition* preset) { furi_assert(context); SubGhzProtocolDecoderKIA* instance = context; - return subghz_block_generic_serialize(&instance->generic, flipper_format, frequency, preset); + return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); } bool subghz_protocol_decoder_kia_deserialize(void* context, FlipperFormat* flipper_format) { diff --git a/lib/subghz/protocols/kia.h b/lib/subghz/protocols/kia.h index 40e49683..a3294046 100644 --- a/lib/subghz/protocols/kia.h +++ b/lib/subghz/protocols/kia.h @@ -49,15 +49,13 @@ uint8_t subghz_protocol_decoder_kia_get_hash_data(void* context); * Serialize data SubGhzProtocolDecoderKIA. * @param context Pointer to a SubGhzProtocolDecoderKIA instance * @param flipper_format Pointer to a FlipperFormat instance - * @param frequency The frequency at which the signal was received, Hz - * @param preset The modulation on which the signal was received, FuriHalSubGhzPreset + * @param preset The modulation on which the signal was received, SubGhzPesetDefinition * @return true On success */ bool subghz_protocol_decoder_kia_serialize( void* context, FlipperFormat* flipper_format, - uint32_t frequency, - FuriHalSubGhzPreset preset); + SubGhzPesetDefinition* preset); /** * Deserialize data SubGhzProtocolDecoderKIA. diff --git a/lib/subghz/protocols/linear.c b/lib/subghz/protocols/linear.c index 6b013278..a8c9dad6 100644 --- a/lib/subghz/protocols/linear.c +++ b/lib/subghz/protocols/linear.c @@ -299,11 +299,10 @@ uint8_t subghz_protocol_decoder_linear_get_hash_data(void* context) { bool subghz_protocol_decoder_linear_serialize( void* context, FlipperFormat* flipper_format, - uint32_t frequency, - FuriHalSubGhzPreset preset) { + SubGhzPesetDefinition* preset) { furi_assert(context); SubGhzProtocolDecoderLinear* instance = context; - return subghz_block_generic_serialize(&instance->generic, flipper_format, frequency, preset); + return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); } bool subghz_protocol_decoder_linear_deserialize(void* context, FlipperFormat* flipper_format) { diff --git a/lib/subghz/protocols/linear.h b/lib/subghz/protocols/linear.h index 44f4e7dd..5060d444 100644 --- a/lib/subghz/protocols/linear.h +++ b/lib/subghz/protocols/linear.h @@ -83,15 +83,13 @@ uint8_t subghz_protocol_decoder_linear_get_hash_data(void* context); * Serialize data SubGhzProtocolDecoderLinear. * @param context Pointer to a SubGhzProtocolDecoderLinear instance * @param flipper_format Pointer to a FlipperFormat instance - * @param frequency The frequency at which the signal was received, Hz - * @param preset The modulation on which the signal was received, FuriHalSubGhzPreset + * @param preset The modulation on which the signal was received, SubGhzPesetDefinition * @return true On success */ bool subghz_protocol_decoder_linear_serialize( void* context, FlipperFormat* flipper_format, - uint32_t frequency, - FuriHalSubGhzPreset preset); + SubGhzPesetDefinition* preset); /** * Deserialize data SubGhzProtocolDecoderLinear. diff --git a/lib/subghz/protocols/megacode.c b/lib/subghz/protocols/megacode.c index f8d42b29..8a1f67b5 100644 --- a/lib/subghz/protocols/megacode.c +++ b/lib/subghz/protocols/megacode.c @@ -380,11 +380,10 @@ uint8_t subghz_protocol_decoder_megacode_get_hash_data(void* context) { bool subghz_protocol_decoder_megacode_serialize( void* context, FlipperFormat* flipper_format, - uint32_t frequency, - FuriHalSubGhzPreset preset) { + SubGhzPesetDefinition* preset) { furi_assert(context); SubGhzProtocolDecoderMegaCode* instance = context; - return subghz_block_generic_serialize(&instance->generic, flipper_format, frequency, preset); + return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); } bool subghz_protocol_decoder_megacode_deserialize(void* context, FlipperFormat* flipper_format) { diff --git a/lib/subghz/protocols/megacode.h b/lib/subghz/protocols/megacode.h index 1a3cfd5d..f25011d7 100644 --- a/lib/subghz/protocols/megacode.h +++ b/lib/subghz/protocols/megacode.h @@ -83,15 +83,13 @@ uint8_t subghz_protocol_decoder_megacode_get_hash_data(void* context); * Serialize data SubGhzProtocolDecoderMegaCode. * @param context Pointer to a SubGhzProtocolDecoderMegaCode instance * @param flipper_format Pointer to a FlipperFormat instance - * @param frequency The frequency at which the signal was received, Hz - * @param preset The modulation on which the signal was received, FuriHalSubGhzPreset + * @param preset The modulation on which the signal was received, SubGhzPesetDefinition * @return true On success */ bool subghz_protocol_decoder_megacode_serialize( void* context, FlipperFormat* flipper_format, - uint32_t frequency, - FuriHalSubGhzPreset preset); + SubGhzPesetDefinition* preset); /** * Deserialize data SubGhzProtocolDecoderMegaCode. diff --git a/lib/subghz/protocols/nero_radio.c b/lib/subghz/protocols/nero_radio.c index 6797843f..7dcb5975 100644 --- a/lib/subghz/protocols/nero_radio.c +++ b/lib/subghz/protocols/nero_radio.c @@ -342,11 +342,10 @@ uint8_t subghz_protocol_decoder_nero_radio_get_hash_data(void* context) { bool subghz_protocol_decoder_nero_radio_serialize( void* context, FlipperFormat* flipper_format, - uint32_t frequency, - FuriHalSubGhzPreset preset) { + SubGhzPesetDefinition* preset) { furi_assert(context); SubGhzProtocolDecoderNeroRadio* instance = context; - return subghz_block_generic_serialize(&instance->generic, flipper_format, frequency, preset); + return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); } bool subghz_protocol_decoder_nero_radio_deserialize(void* context, FlipperFormat* flipper_format) { diff --git a/lib/subghz/protocols/nero_radio.h b/lib/subghz/protocols/nero_radio.h index 46c80738..f1c540d5 100644 --- a/lib/subghz/protocols/nero_radio.h +++ b/lib/subghz/protocols/nero_radio.h @@ -83,15 +83,13 @@ uint8_t subghz_protocol_decoder_nero_radio_get_hash_data(void* context); * Serialize data SubGhzProtocolDecoderNeroRadio. * @param context Pointer to a SubGhzProtocolDecoderNeroRadio instance * @param flipper_format Pointer to a FlipperFormat instance - * @param frequency The frequency at which the signal was received, Hz - * @param preset The modulation on which the signal was received, FuriHalSubGhzPreset + * @param preset The modulation on which the signal was received, SubGhzPesetDefinition * @return true On success */ bool subghz_protocol_decoder_nero_radio_serialize( void* context, FlipperFormat* flipper_format, - uint32_t frequency, - FuriHalSubGhzPreset preset); + SubGhzPesetDefinition* preset); /** * Deserialize data SubGhzProtocolDecoderNeroRadio. diff --git a/lib/subghz/protocols/nero_sketch.c b/lib/subghz/protocols/nero_sketch.c index 1ba0cf86..a4e9f2cf 100644 --- a/lib/subghz/protocols/nero_sketch.c +++ b/lib/subghz/protocols/nero_sketch.c @@ -327,11 +327,10 @@ uint8_t subghz_protocol_decoder_nero_sketch_get_hash_data(void* context) { bool subghz_protocol_decoder_nero_sketch_serialize( void* context, FlipperFormat* flipper_format, - uint32_t frequency, - FuriHalSubGhzPreset preset) { + SubGhzPesetDefinition* preset) { furi_assert(context); SubGhzProtocolDecoderNeroSketch* instance = context; - return subghz_block_generic_serialize(&instance->generic, flipper_format, frequency, preset); + return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); } bool subghz_protocol_decoder_nero_sketch_deserialize(void* context, FlipperFormat* flipper_format) { diff --git a/lib/subghz/protocols/nero_sketch.h b/lib/subghz/protocols/nero_sketch.h index e2b12f64..af93a9d9 100644 --- a/lib/subghz/protocols/nero_sketch.h +++ b/lib/subghz/protocols/nero_sketch.h @@ -83,15 +83,13 @@ uint8_t subghz_protocol_decoder_nero_sketch_get_hash_data(void* context); * Serialize data SubGhzProtocolDecoderNeroSketch. * @param context Pointer to a SubGhzProtocolDecoderNeroSketch instance * @param flipper_format Pointer to a FlipperFormat instance - * @param frequency The frequency at which the signal was received, Hz - * @param preset The modulation on which the signal was received, FuriHalSubGhzPreset + * @param preset The modulation on which the signal was received, SubGhzPesetDefinition * @return true On success */ bool subghz_protocol_decoder_nero_sketch_serialize( void* context, FlipperFormat* flipper_format, - uint32_t frequency, - FuriHalSubGhzPreset preset); + SubGhzPesetDefinition* preset); /** * Deserialize data SubGhzProtocolDecoderNeroSketch. diff --git a/lib/subghz/protocols/nice_flo.c b/lib/subghz/protocols/nice_flo.c index d2844dcd..1b8e0308 100644 --- a/lib/subghz/protocols/nice_flo.c +++ b/lib/subghz/protocols/nice_flo.c @@ -277,11 +277,10 @@ uint8_t subghz_protocol_decoder_nice_flo_get_hash_data(void* context) { bool subghz_protocol_decoder_nice_flo_serialize( void* context, FlipperFormat* flipper_format, - uint32_t frequency, - FuriHalSubGhzPreset preset) { + SubGhzPesetDefinition* preset) { furi_assert(context); SubGhzProtocolDecoderNiceFlo* instance = context; - return subghz_block_generic_serialize(&instance->generic, flipper_format, frequency, preset); + return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); } bool subghz_protocol_decoder_nice_flo_deserialize(void* context, FlipperFormat* flipper_format) { diff --git a/lib/subghz/protocols/nice_flo.h b/lib/subghz/protocols/nice_flo.h index 430b111d..f7d48dfa 100644 --- a/lib/subghz/protocols/nice_flo.h +++ b/lib/subghz/protocols/nice_flo.h @@ -83,15 +83,13 @@ uint8_t subghz_protocol_decoder_nice_flo_get_hash_data(void* context); * Serialize data SubGhzProtocolDecoderNiceFlo. * @param context Pointer to a SubGhzProtocolDecoderNiceFlo instance * @param flipper_format Pointer to a FlipperFormat instance - * @param frequency The frequency at which the signal was received, Hz - * @param preset The modulation on which the signal was received, FuriHalSubGhzPreset + * @param preset The modulation on which the signal was received, SubGhzPesetDefinition * @return true On success */ bool subghz_protocol_decoder_nice_flo_serialize( void* context, FlipperFormat* flipper_format, - uint32_t frequency, - FuriHalSubGhzPreset preset); + SubGhzPesetDefinition* preset); /** * Deserialize data SubGhzProtocolDecoderNiceFlo. diff --git a/lib/subghz/protocols/nice_flor_s.c b/lib/subghz/protocols/nice_flor_s.c index 1fe5876d..381e7bd1 100644 --- a/lib/subghz/protocols/nice_flor_s.c +++ b/lib/subghz/protocols/nice_flor_s.c @@ -330,11 +330,10 @@ uint8_t subghz_protocol_decoder_nice_flor_s_get_hash_data(void* context) { bool subghz_protocol_decoder_nice_flor_s_serialize( void* context, FlipperFormat* flipper_format, - uint32_t frequency, - FuriHalSubGhzPreset preset) { + SubGhzPesetDefinition* preset) { furi_assert(context); SubGhzProtocolDecoderNiceFlorS* instance = context; - return subghz_block_generic_serialize(&instance->generic, flipper_format, frequency, preset); + return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); } bool subghz_protocol_decoder_nice_flor_s_deserialize(void* context, FlipperFormat* flipper_format) { diff --git a/lib/subghz/protocols/nice_flor_s.h b/lib/subghz/protocols/nice_flor_s.h index d11264bc..fc27da38 100644 --- a/lib/subghz/protocols/nice_flor_s.h +++ b/lib/subghz/protocols/nice_flor_s.h @@ -49,15 +49,13 @@ uint8_t subghz_protocol_decoder_nice_flor_s_get_hash_data(void* context); * Serialize data SubGhzProtocolDecoderNiceFlorS. * @param context Pointer to a SubGhzProtocolDecoderNiceFlorS instance * @param flipper_format Pointer to a FlipperFormat instance - * @param frequency The frequency at which the signal was received, Hz - * @param preset The modulation on which the signal was received, FuriHalSubGhzPreset + * @param preset The modulation on which the signal was received, SubGhzPesetDefinition * @return true On success */ bool subghz_protocol_decoder_nice_flor_s_serialize( void* context, FlipperFormat* flipper_format, - uint32_t frequency, - FuriHalSubGhzPreset preset); + SubGhzPesetDefinition* preset); /** * Deserialize data SubGhzProtocolDecoderNiceFlorS. diff --git a/lib/subghz/protocols/power_smart.c b/lib/subghz/protocols/power_smart.c index 0dc81f2a..3c356ff8 100644 --- a/lib/subghz/protocols/power_smart.c +++ b/lib/subghz/protocols/power_smart.c @@ -345,11 +345,10 @@ uint8_t subghz_protocol_decoder_power_smart_get_hash_data(void* context) { bool subghz_protocol_decoder_power_smart_serialize( void* context, FlipperFormat* flipper_format, - uint32_t frequency, - FuriHalSubGhzPreset preset) { + SubGhzPesetDefinition* preset) { furi_assert(context); SubGhzProtocolDecoderPowerSmart* instance = context; - return subghz_block_generic_serialize(&instance->generic, flipper_format, frequency, preset); + return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); } bool subghz_protocol_decoder_power_smart_deserialize(void* context, FlipperFormat* flipper_format) { diff --git a/lib/subghz/protocols/power_smart.h b/lib/subghz/protocols/power_smart.h index 346fe537..e6445ca4 100644 --- a/lib/subghz/protocols/power_smart.h +++ b/lib/subghz/protocols/power_smart.h @@ -83,15 +83,13 @@ uint8_t subghz_protocol_decoder_power_smart_get_hash_data(void* context); * Serialize data SubGhzProtocolDecoderPowerSmart. * @param context Pointer to a SubGhzProtocolDecoderPowerSmart instance * @param flipper_format Pointer to a FlipperFormat instance - * @param frequency The frequency at which the signal was received, Hz - * @param preset The modulation on which the signal was received, FuriHalSubGhzPreset + * @param preset The modulation on which the signal was received, SubGhzPesetDefinition * @return true On success */ bool subghz_protocol_decoder_power_smart_serialize( void* context, FlipperFormat* flipper_format, - uint32_t frequency, - FuriHalSubGhzPreset preset); + SubGhzPesetDefinition* preset); /** * Deserialize data SubGhzProtocolDecoderPowerSmart. diff --git a/lib/subghz/protocols/princeton.c b/lib/subghz/protocols/princeton.c index 046484c7..ce34d32c 100644 --- a/lib/subghz/protocols/princeton.c +++ b/lib/subghz/protocols/princeton.c @@ -300,12 +300,10 @@ uint8_t subghz_protocol_decoder_princeton_get_hash_data(void* context) { bool subghz_protocol_decoder_princeton_serialize( void* context, FlipperFormat* flipper_format, - uint32_t frequency, - FuriHalSubGhzPreset preset) { + SubGhzPesetDefinition* preset) { furi_assert(context); SubGhzProtocolDecoderPrinceton* instance = context; - bool res = - subghz_block_generic_serialize(&instance->generic, flipper_format, frequency, preset); + bool res = subghz_block_generic_serialize(&instance->generic, flipper_format, preset); if(res && !flipper_format_write_uint32(flipper_format, "TE", &instance->te, 1)) { FURI_LOG_E(TAG, "Unable to add TE"); res = false; diff --git a/lib/subghz/protocols/princeton.h b/lib/subghz/protocols/princeton.h index 129819c6..fb126f2d 100644 --- a/lib/subghz/protocols/princeton.h +++ b/lib/subghz/protocols/princeton.h @@ -83,15 +83,13 @@ uint8_t subghz_protocol_decoder_princeton_get_hash_data(void* context); * Serialize data SubGhzProtocolDecoderPrinceton. * @param context Pointer to a SubGhzProtocolDecoderPrinceton instance * @param flipper_format Pointer to a FlipperFormat instance - * @param frequency The frequency at which the signal was received, Hz - * @param preset The modulation on which the signal was received, FuriHalSubGhzPreset + * @param preset The modulation on which the signal was received, SubGhzPesetDefinition * @return true On success */ bool subghz_protocol_decoder_princeton_serialize( void* context, FlipperFormat* flipper_format, - uint32_t frequency, - FuriHalSubGhzPreset preset); + SubGhzPesetDefinition* preset); /** * Deserialize data SubGhzProtocolDecoderPrinceton. diff --git a/lib/subghz/protocols/raw.c b/lib/subghz/protocols/raw.c index 6a75d159..92f20438 100644 --- a/lib/subghz/protocols/raw.c +++ b/lib/subghz/protocols/raw.c @@ -83,8 +83,7 @@ const SubGhzProtocol subghz_protocol_raw = { bool subghz_protocol_raw_save_to_file_init( SubGhzProtocolDecoderRAW* instance, const char* dev_name, - uint32_t frequency, - FuriHalSubGhzPreset preset) { + SubGhzPesetDefinition* preset) { furi_assert(instance); instance->storage = furi_record_open(RECORD_STORAGE); @@ -124,19 +123,30 @@ bool subghz_protocol_raw_save_to_file_init( break; } - if(!flipper_format_write_uint32(instance->flipper_file, "Frequency", &frequency, 1)) { + if(!flipper_format_write_uint32( + instance->flipper_file, "Frequency", &preset->frequency, 1)) { FURI_LOG_E(TAG, "Unable to add Frequency"); break; } - if(!subghz_block_generic_get_preset_name(preset, temp_str)) { - break; - } + + subghz_block_generic_get_preset_name(string_get_cstr(preset->name), temp_str); if(!flipper_format_write_string_cstr( instance->flipper_file, "Preset", string_get_cstr(temp_str))) { FURI_LOG_E(TAG, "Unable to add Preset"); break; } - + if(!strcmp(string_get_cstr(temp_str), "FuriHalSubGhzPresetCustom")) { + if(!flipper_format_write_string_cstr( + instance->flipper_file, "Custom_preset_module", "CC1101")) { + FURI_LOG_E(TAG, "Unable to add Custom_preset_module"); + break; + } + if(!flipper_format_write_hex( + instance->flipper_file, "Custom_preset_data", preset->data, preset->data_size)) { + FURI_LOG_E(TAG, "Unable to add Custom_preset_data"); + break; + } + } if(!flipper_format_write_string_cstr( instance->flipper_file, "Protocol", instance->base.protocol->name)) { FURI_LOG_E(TAG, "Unable to add Protocol"); diff --git a/lib/subghz/protocols/raw.h b/lib/subghz/protocols/raw.h index 9e4931f9..a6435d33 100644 --- a/lib/subghz/protocols/raw.h +++ b/lib/subghz/protocols/raw.h @@ -17,15 +17,13 @@ extern const SubGhzProtocol subghz_protocol_raw; * Open file for writing * @param instance Pointer to a SubGhzProtocolDecoderRAW instance * @param dev_name File name - * @param frequency The frequency at which the signal was received, Hz - * @param preset The modulation on which the signal was received, FuriHalSubGhzPreset + * @param preset The modulation on which the signal was received, SubGhzPesetDefinition * @return true On success */ bool subghz_protocol_raw_save_to_file_init( SubGhzProtocolDecoderRAW* instance, const char* dev_name, - uint32_t frequency, - FuriHalSubGhzPreset preset); + SubGhzPesetDefinition* preset); /** * Stop writing file to flash diff --git a/lib/subghz/protocols/scher_khan.c b/lib/subghz/protocols/scher_khan.c index 233b9564..7c9aa6a7 100644 --- a/lib/subghz/protocols/scher_khan.c +++ b/lib/subghz/protocols/scher_khan.c @@ -251,11 +251,10 @@ uint8_t subghz_protocol_decoder_scher_khan_get_hash_data(void* context) { bool subghz_protocol_decoder_scher_khan_serialize( void* context, FlipperFormat* flipper_format, - uint32_t frequency, - FuriHalSubGhzPreset preset) { + SubGhzPesetDefinition* preset) { furi_assert(context); SubGhzProtocolDecoderScherKhan* instance = context; - return subghz_block_generic_serialize(&instance->generic, flipper_format, frequency, preset); + return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); } bool subghz_protocol_decoder_scher_khan_deserialize(void* context, FlipperFormat* flipper_format) { diff --git a/lib/subghz/protocols/scher_khan.h b/lib/subghz/protocols/scher_khan.h index fa3f5147..b22e8934 100644 --- a/lib/subghz/protocols/scher_khan.h +++ b/lib/subghz/protocols/scher_khan.h @@ -49,15 +49,13 @@ uint8_t subghz_protocol_decoder_scher_khan_get_hash_data(void* context); * Serialize data SubGhzProtocolDecoderScherKhan. * @param context Pointer to a SubGhzProtocolDecoderScherKhan instance * @param flipper_format Pointer to a FlipperFormat instance - * @param frequency The frequency at which the signal was received, Hz - * @param preset The modulation on which the signal was received, FuriHalSubGhzPreset + * @param preset The modulation on which the signal was received, SubGhzPesetDefinition * @return true On success */ bool subghz_protocol_decoder_scher_khan_serialize( void* context, FlipperFormat* flipper_format, - uint32_t frequency, - FuriHalSubGhzPreset preset); + SubGhzPesetDefinition* preset); /** * Deserialize data SubGhzProtocolDecoderScherKhan. diff --git a/lib/subghz/protocols/secplus_v1.c b/lib/subghz/protocols/secplus_v1.c index b51179f4..119c0307 100644 --- a/lib/subghz/protocols/secplus_v1.c +++ b/lib/subghz/protocols/secplus_v1.c @@ -515,11 +515,10 @@ uint8_t subghz_protocol_decoder_secplus_v1_get_hash_data(void* context) { bool subghz_protocol_decoder_secplus_v1_serialize( void* context, FlipperFormat* flipper_format, - uint32_t frequency, - FuriHalSubGhzPreset preset) { + SubGhzPesetDefinition* preset) { furi_assert(context); SubGhzProtocolDecoderSecPlus_v1* instance = context; - return subghz_block_generic_serialize(&instance->generic, flipper_format, frequency, preset); + return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); } bool subghz_protocol_decoder_secplus_v1_deserialize(void* context, FlipperFormat* flipper_format) { diff --git a/lib/subghz/protocols/secplus_v1.h b/lib/subghz/protocols/secplus_v1.h index 1c752df7..5447e3f8 100644 --- a/lib/subghz/protocols/secplus_v1.h +++ b/lib/subghz/protocols/secplus_v1.h @@ -82,15 +82,13 @@ uint8_t subghz_protocol_decoder_secplus_v1_get_hash_data(void* context); * Serialize data SubGhzProtocolDecoderSecPlus_v1. * @param context Pointer to a SubGhzProtocolDecoderSecPlus_v1 instance * @param flipper_format Pointer to a FlipperFormat instance - * @param frequency The frequency at which the signal was received, Hz - * @param preset The modulation on which the signal was received, FuriHalSubGhzPreset + * @param preset The modulation on which the signal was received, SubGhzPesetDefinition * @return true On success */ bool subghz_protocol_decoder_secplus_v1_serialize( void* context, FlipperFormat* flipper_format, - uint32_t frequency, - FuriHalSubGhzPreset preset); + SubGhzPesetDefinition* preset); /** * Deserialize data SubGhzProtocolDecoderSecPlus_v1. diff --git a/lib/subghz/protocols/secplus_v2.c b/lib/subghz/protocols/secplus_v2.c index 70ff19e4..837b2638 100644 --- a/lib/subghz/protocols/secplus_v2.c +++ b/lib/subghz/protocols/secplus_v2.c @@ -588,8 +588,7 @@ bool subghz_protocol_secplus_v2_create_data( uint32_t serial, uint8_t btn, uint32_t cnt, - uint32_t frequency, - FuriHalSubGhzPreset preset) { + SubGhzPesetDefinition* preset) { furi_assert(context); SubGhzProtocolEncoderSecPlus_v2* instance = context; instance->generic.serial = serial; @@ -598,8 +597,7 @@ bool subghz_protocol_secplus_v2_create_data( instance->generic.data_count_bit = (uint8_t)subghz_protocol_secplus_v2_const.min_count_bit_for_found; subghz_protocol_secplus_v2_encode(instance); - bool res = - subghz_block_generic_serialize(&instance->generic, flipper_format, frequency, preset); + bool res = subghz_block_generic_serialize(&instance->generic, flipper_format, preset); uint8_t key_data[sizeof(uint64_t)] = {0}; for(size_t i = 0; i < sizeof(uint64_t); i++) { @@ -757,12 +755,10 @@ uint8_t subghz_protocol_decoder_secplus_v2_get_hash_data(void* context) { bool subghz_protocol_decoder_secplus_v2_serialize( void* context, FlipperFormat* flipper_format, - uint32_t frequency, - FuriHalSubGhzPreset preset) { + SubGhzPesetDefinition* preset) { furi_assert(context); SubGhzProtocolDecoderSecPlus_v2* instance = context; - bool res = - subghz_block_generic_serialize(&instance->generic, flipper_format, frequency, preset); + bool res = subghz_block_generic_serialize(&instance->generic, flipper_format, preset); uint8_t key_data[sizeof(uint64_t)] = {0}; for(size_t i = 0; i < sizeof(uint64_t); i++) { diff --git a/lib/subghz/protocols/secplus_v2.h b/lib/subghz/protocols/secplus_v2.h index 3d695148..43bce629 100644 --- a/lib/subghz/protocols/secplus_v2.h +++ b/lib/subghz/protocols/secplus_v2.h @@ -52,8 +52,7 @@ LevelDuration subghz_protocol_encoder_secplus_v2_yield(void* context); * @param btn Button number, 8 bit * @param cnt Container value, 28 bit * @param manufacture_name Name of manufacturer's key - * @param frequency Transmission frequency, Hz - * @param preset Modulation, FuriHalSubGhzPreset + * @param preset Modulation, SubGhzPesetDefinition * @return true On success */ bool subghz_protocol_secplus_v2_create_data( @@ -62,8 +61,7 @@ bool subghz_protocol_secplus_v2_create_data( uint32_t serial, uint8_t btn, uint32_t cnt, - uint32_t frequency, - FuriHalSubGhzPreset preset); + SubGhzPesetDefinition* preset); /** * Allocate SubGhzProtocolDecoderSecPlus_v2. @@ -103,15 +101,13 @@ uint8_t subghz_protocol_decoder_secplus_v2_get_hash_data(void* context); * Serialize data SubGhzProtocolDecoderSecPlus_v2. * @param context Pointer to a SubGhzProtocolDecoderSecPlus_v2 instance * @param flipper_format Pointer to a FlipperFormat instance - * @param frequency The frequency at which the signal was received, Hz - * @param preset The modulation on which the signal was received, FuriHalSubGhzPreset + * @param preset The modulation on which the signal was received, SubGhzPesetDefinition * @return true On success */ bool subghz_protocol_decoder_secplus_v2_serialize( void* context, FlipperFormat* flipper_format, - uint32_t frequency, - FuriHalSubGhzPreset preset); + SubGhzPesetDefinition* preset); /** * Deserialize data SubGhzProtocolDecoderSecPlus_v2. diff --git a/lib/subghz/protocols/somfy_keytis.c b/lib/subghz/protocols/somfy_keytis.c index 764e8147..d2df9eff 100644 --- a/lib/subghz/protocols/somfy_keytis.c +++ b/lib/subghz/protocols/somfy_keytis.c @@ -382,12 +382,10 @@ uint8_t subghz_protocol_decoder_somfy_keytis_get_hash_data(void* context) { bool subghz_protocol_decoder_somfy_keytis_serialize( void* context, FlipperFormat* flipper_format, - uint32_t frequency, - FuriHalSubGhzPreset preset) { + SubGhzPesetDefinition* preset) { furi_assert(context); SubGhzProtocolDecoderSomfyKeytis* instance = context; - bool res = - subghz_block_generic_serialize(&instance->generic, flipper_format, frequency, preset); + bool res = subghz_block_generic_serialize(&instance->generic, flipper_format, preset); if(res && !flipper_format_write_uint32( flipper_format, "Duration_Counter", &instance->press_duration_counter, 1)) { FURI_LOG_E(TAG, "Unable to add Duration_Counter"); diff --git a/lib/subghz/protocols/somfy_keytis.h b/lib/subghz/protocols/somfy_keytis.h index eea12f36..46193994 100644 --- a/lib/subghz/protocols/somfy_keytis.h +++ b/lib/subghz/protocols/somfy_keytis.h @@ -49,15 +49,13 @@ uint8_t subghz_protocol_decoder_somfy_keytis_get_hash_data(void* context); * Serialize data SubGhzProtocolDecoderSomfyKeytis. * @param context Pointer to a SubGhzProtocolDecoderSomfyKeytis instance * @param flipper_format Pointer to a FlipperFormat instance - * @param frequency The frequency at which the signal was received, Hz - * @param preset The modulation on which the signal was received, FuriHalSubGhzPreset + * @param preset The modulation on which the signal was received, SubGhzPesetDefinition * @return true On success */ bool subghz_protocol_decoder_somfy_keytis_serialize( void* context, FlipperFormat* flipper_format, - uint32_t frequency, - FuriHalSubGhzPreset preset); + SubGhzPesetDefinition* preset); /** * Deserialize data SubGhzProtocolDecoderSomfyKeytis. diff --git a/lib/subghz/protocols/somfy_telis.c b/lib/subghz/protocols/somfy_telis.c index 63407427..039cb8ee 100644 --- a/lib/subghz/protocols/somfy_telis.c +++ b/lib/subghz/protocols/somfy_telis.c @@ -339,11 +339,10 @@ uint8_t subghz_protocol_decoder_somfy_telis_get_hash_data(void* context) { bool subghz_protocol_decoder_somfy_telis_serialize( void* context, FlipperFormat* flipper_format, - uint32_t frequency, - FuriHalSubGhzPreset preset) { + SubGhzPesetDefinition* preset) { furi_assert(context); SubGhzProtocolDecoderSomfyTelis* instance = context; - return subghz_block_generic_serialize(&instance->generic, flipper_format, frequency, preset); + return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); } bool subghz_protocol_decoder_somfy_telis_deserialize(void* context, FlipperFormat* flipper_format) { diff --git a/lib/subghz/protocols/somfy_telis.h b/lib/subghz/protocols/somfy_telis.h index 3414de6f..ce474769 100644 --- a/lib/subghz/protocols/somfy_telis.h +++ b/lib/subghz/protocols/somfy_telis.h @@ -49,15 +49,13 @@ uint8_t subghz_protocol_decoder_somfy_telis_get_hash_data(void* context); * Serialize data SubGhzProtocolDecoderSomfyTelis. * @param context Pointer to a SubGhzProtocolDecoderSomfyTelis instance * @param flipper_format Pointer to a FlipperFormat instance - * @param frequency The frequency at which the signal was received, Hz - * @param preset The modulation on which the signal was received, FuriHalSubGhzPreset + * @param preset The modulation on which the signal was received, SubGhzPesetDefinition * @return true On success */ bool subghz_protocol_decoder_somfy_telis_serialize( void* context, FlipperFormat* flipper_format, - uint32_t frequency, - FuriHalSubGhzPreset preset); + SubGhzPesetDefinition* preset); /** * Deserialize data SubGhzProtocolDecoderSomfyTelis. diff --git a/lib/subghz/protocols/star_line.c b/lib/subghz/protocols/star_line.c index 7db33570..4492338a 100644 --- a/lib/subghz/protocols/star_line.c +++ b/lib/subghz/protocols/star_line.c @@ -320,14 +320,12 @@ uint8_t subghz_protocol_decoder_star_line_get_hash_data(void* context) { bool subghz_protocol_decoder_star_line_serialize( void* context, FlipperFormat* flipper_format, - uint32_t frequency, - FuriHalSubGhzPreset preset) { + SubGhzPesetDefinition* preset) { furi_assert(context); SubGhzProtocolDecoderStarLine* instance = context; subghz_protocol_star_line_check_remote_controller( &instance->generic, instance->keystore, &instance->manufacture_name); - bool res = - subghz_block_generic_serialize(&instance->generic, flipper_format, frequency, preset); + bool res = subghz_block_generic_serialize(&instance->generic, flipper_format, preset); if(res && !flipper_format_write_string_cstr( flipper_format, "Manufacture", instance->manufacture_name)) { diff --git a/lib/subghz/protocols/star_line.h b/lib/subghz/protocols/star_line.h index 9253ff52..b48f1c21 100644 --- a/lib/subghz/protocols/star_line.h +++ b/lib/subghz/protocols/star_line.h @@ -49,15 +49,13 @@ uint8_t subghz_protocol_decoder_star_line_get_hash_data(void* context); * Serialize data SubGhzProtocolDecoderStarLine. * @param context Pointer to a SubGhzProtocolDecoderStarLine instance * @param flipper_format Pointer to a FlipperFormat instance - * @param frequency The frequency at which the signal was received, Hz - * @param preset The modulation on which the signal was received, FuriHalSubGhzPreset + * @param preset The modulation on which the signal was received, SubGhzPesetDefinition * @return true On success */ bool subghz_protocol_decoder_star_line_serialize( void* context, FlipperFormat* flipper_format, - uint32_t frequency, - FuriHalSubGhzPreset preset); + SubGhzPesetDefinition* preset); /** * Deserialize data SubGhzProtocolDecoderStarLine. diff --git a/lib/subghz/subghz_worker.c b/lib/subghz/subghz_worker.c index dcebdfff..58db8ea5 100644 --- a/lib/subghz/subghz_worker.c +++ b/lib/subghz/subghz_worker.c @@ -57,7 +57,6 @@ static int32_t subghz_worker_thread_callback(void* context) { if(ret == sizeof(LevelDuration)) { if(level_duration_is_reset(level_duration)) { FURI_LOG_E(TAG, "Overrun buffer"); - ; if(instance->overrun_callback) instance->overrun_callback(instance->context); } else { bool level = level_duration_get_level(level_duration); @@ -98,11 +97,11 @@ SubGhzWorker* subghz_worker_alloc() { furi_thread_set_context(instance->thread, instance); furi_thread_set_callback(instance->thread, subghz_worker_thread_callback); - instance->stream = xStreamBufferCreate(sizeof(LevelDuration) * 2048, sizeof(LevelDuration)); + instance->stream = xStreamBufferCreate(sizeof(LevelDuration) * 4096, sizeof(LevelDuration)); //setting filter instance->filter_running = true; - instance->filter_duration = 20; + instance->filter_duration = 30; return instance; } diff --git a/lib/subghz/types.h b/lib/subghz/types.h index 46e5ec24..41a04cb1 100644 --- a/lib/subghz/types.h +++ b/lib/subghz/types.h @@ -10,6 +10,7 @@ #include "environment.h" #include #include +#include #define SUBGHZ_APP_FOLDER ANY_PATH("subghz") #define SUBGHZ_RAW_FOLDER EXT_PATH("subghz") @@ -30,11 +31,8 @@ typedef void* (*SubGhzAlloc)(SubGhzEnvironment* environment); typedef void (*SubGhzFree)(void* context); // Serialize and Deserialize -typedef bool (*SubGhzSerialize)( - void* context, - FlipperFormat* flipper_format, - uint32_t frequency, - FuriHalSubGhzPreset preset); +typedef bool ( + *SubGhzSerialize)(void* context, FlipperFormat* flipper_format, SubGhzPesetDefinition* preset); typedef bool (*SubGhzDeserialize)(void* context, FlipperFormat* flipper_format); // Decoder specific From 9c59bcd7763cbe9b0132b0f2698543e2dfb11623 Mon Sep 17 00:00:00 2001 From: gornekich Date: Tue, 26 Jul 2022 18:30:49 +0300 Subject: [PATCH 37/37] [FL-2605] NFC new design (#1364) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * nfc: add new read scene * lib: refactore nfc library * mifare desfire: add read card fuction * lib nfc: add auto read worker * nfc: add supported cards * nfc: add mifare classic read success scene * nfc: add troyka support * submodule: update protobuf * nfc: mifare classic keys cache * nfc: rework mifare classic key cache * Correct spelling * nfc: add user dictionary * nfc: introduce block read map in fff * nfc: rework dict attack * nfc: improve dict attack * nfc: rework mifare classic format * nfc: rework MFC read with Reader * nfc: add gui for MFC read success scene * nfc: fix dict attack view gui * nfc: add retry and exit confirm scenes * nfc: add retry and exit scenes navigation * nfc: check user dictionary * nfc: remove unused scenes * nfc: rename functions in nfc worker * nfc: rename mf_classic_dict_attack -> dict_attack * nfc: change scenes names * nfc: remove scene tick events * nfc: rework dict calls with buffer streams * nfc: fix notifications * nfc: fix mf desfire navigation * nfc: remove notification from mf classic read success * nfc: fix read sectors calculation * nfc: add fallback for unknown card * nfc: show file name while emulating * nfc: fix build * nfc: fix memory leak * nfc: fix desfire read * nfc: add no dict found navigation * nfc: add read views * nfc: update card fix * nfc: fix access bytes save * nfc: add exit and retry confirm to mf ultralight read success * nfc: introduce detect reader * nfc: change record open arg to macros * nfc: fix start from archive Co-authored-by: Astra Co-authored-by: あく --- .github/CODEOWNERS | 2 +- applications/nfc/helpers/nfc_custom_event.h | 1 + applications/nfc/helpers/nfc_generators.c | 26 +- .../nfc/helpers/nfc_mf_classic_dict.c | 53 -- .../nfc/helpers/nfc_mf_classic_dict.h | 15 - applications/nfc/nfc.c | 24 +- applications/nfc/nfc_cli.c | 5 +- applications/nfc/nfc_i.h | 11 +- applications/nfc/nfc_worker.c | 708 ------------------ applications/nfc/nfc_worker_i.h | 57 -- applications/nfc/scenes/nfc_scene_card_menu.c | 90 --- applications/nfc/scenes/nfc_scene_config.h | 53 +- .../nfc/scenes/nfc_scene_detect_reader.c | 143 ++++ .../nfc/scenes/nfc_scene_device_info.c | 2 +- .../nfc/scenes/nfc_scene_dict_not_found.c | 7 +- .../nfc/scenes/nfc_scene_emulate_uid.c | 9 +- ...success.c => nfc_scene_emv_read_success.c} | 36 +- .../nfc/scenes/nfc_scene_exit_confirm.c | 47 ++ .../nfc/scenes/nfc_scene_extra_actions.c | 48 ++ .../scenes/nfc_scene_mf_classic_dict_attack.c | 137 ++++ ...assic.c => nfc_scene_mf_classic_emulate.c} | 29 +- .../nfc/scenes/nfc_scene_mf_classic_keys.c | 59 ++ .../scenes/nfc_scene_mf_classic_keys_add.c | 57 ++ ..._ul_menu.c => nfc_scene_mf_classic_menu.c} | 22 +- .../nfc_scene_mf_classic_read_success.c | 104 +++ ...sfire_app.c => nfc_scene_mf_desfire_app.c} | 36 +- ...ire_data.c => nfc_scene_mf_desfire_data.c} | 32 +- ...ire_menu.c => nfc_scene_mf_desfire_menu.c} | 15 +- ....c => nfc_scene_mf_desfire_read_success.c} | 45 +- ...ul.c => nfc_scene_mf_ultralight_emulate.c} | 29 +- ..._menu.c => nfc_scene_mf_ultralight_menu.c} | 22 +- ...=> nfc_scene_mf_ultralight_read_success.c} | 28 +- applications/nfc/scenes/nfc_scene_read.c | 108 +++ applications/nfc/scenes/nfc_scene_read_card.c | 51 -- .../nfc/scenes/nfc_scene_read_card_success.c | 20 +- .../nfc/scenes/nfc_scene_read_emv_app.c | 58 -- .../scenes/nfc_scene_read_emv_app_success.c | 83 -- .../nfc/scenes/nfc_scene_read_emv_data.c | 59 -- .../scenes/nfc_scene_read_mifare_classic.c | 96 --- .../scenes/nfc_scene_read_mifare_desfire.c | 56 -- .../nfc/scenes/nfc_scene_read_mifare_ul.c | 54 -- .../nfc/scenes/nfc_scene_retry_confirm.c | 47 ++ .../scenes/nfc_scene_run_emv_app_confirm.c | 49 -- .../nfc/scenes/nfc_scene_save_success.c | 8 +- .../nfc/scenes/nfc_scene_saved_menu.c | 4 +- .../nfc/scenes/nfc_scene_scripts_menu.c | 82 -- applications/nfc/scenes/nfc_scene_start.c | 23 +- applications/nfc/views/dict_attack.c | 220 +++--- applications/nfc/views/dict_attack.h | 25 +- applications/unit_tests/nfc/nfc_test.c | 2 +- assets/icons/NFC/NFC_manual.png | Bin 0 -> 3785 bytes assets/icons/NFC/Reader_detect.png | Bin 0 -> 3771 bytes firmware.scons | 1 + .../targets/furi_hal_include/furi_hal_nfc.h | 2 +- furi/core/common_defines.h | 4 + lib/SConscript | 1 + lib/misc.scons | 2 - lib/nfc/SConscript | 16 + lib/nfc/helpers/mf_classic_dict.c | 148 ++++ lib/nfc/helpers/mf_classic_dict.h | 28 + .../nfc/helpers/nfc_debug_pcap.c | 0 .../nfc/helpers/nfc_debug_pcap.h | 0 {applications => lib}/nfc/nfc_device.c | 273 ++++++- {applications => lib}/nfc/nfc_device.h | 11 +- {applications => lib}/nfc/nfc_types.c | 0 {applications => lib}/nfc/nfc_types.h | 0 lib/nfc/nfc_worker.c | 510 +++++++++++++ {applications => lib}/nfc/nfc_worker.h | 36 +- lib/nfc/nfc_worker_i.h | 48 ++ lib/nfc/parsers/nfc_supported_card.c | 12 + lib/nfc/parsers/nfc_supported_card.h | 27 + lib/nfc/parsers/troyka_parser.c | 70 ++ lib/nfc/parsers/troyka_parser.h | 9 + .../protocols}/crypto1.c | 0 .../protocols}/crypto1.h | 0 lib/{nfc_protocols => nfc/protocols}/emv.c | 0 lib/{nfc_protocols => nfc/protocols}/emv.h | 0 .../protocols}/mifare_classic.c | 325 ++++++-- .../protocols}/mifare_classic.h | 71 +- .../protocols}/mifare_common.c | 0 .../protocols}/mifare_common.h | 0 .../protocols}/mifare_desfire.c | 172 +++++ .../protocols}/mifare_desfire.h | 4 + .../protocols}/mifare_ultralight.c | 0 .../protocols}/mifare_ultralight.h | 0 .../protocols}/nfc_util.c | 0 .../protocols}/nfc_util.h | 0 lib/{nfc_protocols => nfc/protocols}/nfca.c | 0 lib/{nfc_protocols => nfc/protocols}/nfca.h | 0 89 files changed, 2755 insertions(+), 2012 deletions(-) delete mode 100644 applications/nfc/helpers/nfc_mf_classic_dict.c delete mode 100644 applications/nfc/helpers/nfc_mf_classic_dict.h delete mode 100644 applications/nfc/nfc_worker.c delete mode 100644 applications/nfc/nfc_worker_i.h delete mode 100755 applications/nfc/scenes/nfc_scene_card_menu.c create mode 100644 applications/nfc/scenes/nfc_scene_detect_reader.c rename applications/nfc/scenes/{nfc_scene_read_emv_data_success.c => nfc_scene_emv_read_success.c} (78%) mode change 100755 => 100644 create mode 100644 applications/nfc/scenes/nfc_scene_exit_confirm.c create mode 100644 applications/nfc/scenes/nfc_scene_extra_actions.c create mode 100644 applications/nfc/scenes/nfc_scene_mf_classic_dict_attack.c rename applications/nfc/scenes/{nfc_scene_emulate_mifare_classic.c => nfc_scene_mf_classic_emulate.c} (57%) create mode 100644 applications/nfc/scenes/nfc_scene_mf_classic_keys.c create mode 100644 applications/nfc/scenes/nfc_scene_mf_classic_keys_add.c rename applications/nfc/scenes/{nfc_scene_mifare_ul_menu.c => nfc_scene_mf_classic_menu.c} (64%) mode change 100755 => 100644 create mode 100644 applications/nfc/scenes/nfc_scene_mf_classic_read_success.c rename applications/nfc/scenes/{nfc_scene_mifare_desfire_app.c => nfc_scene_mf_desfire_app.c} (73%) rename applications/nfc/scenes/{nfc_scene_mifare_desfire_data.c => nfc_scene_mf_desfire_data.c} (74%) rename applications/nfc/scenes/{nfc_scene_mifare_desfire_menu.c => nfc_scene_mf_desfire_menu.c} (61%) rename applications/nfc/scenes/{nfc_scene_read_mifare_desfire_success.c => nfc_scene_mf_desfire_read_success.c} (64%) rename applications/nfc/scenes/{nfc_scene_emulate_mifare_ul.c => nfc_scene_mf_ultralight_emulate.c} (56%) rename applications/nfc/scenes/{nfc_scene_mifare_classic_menu.c => nfc_scene_mf_ultralight_menu.c} (66%) rename applications/nfc/scenes/{nfc_scene_read_mifare_ul_success.c => nfc_scene_mf_ultralight_read_success.c} (77%) create mode 100644 applications/nfc/scenes/nfc_scene_read.c delete mode 100755 applications/nfc/scenes/nfc_scene_read_card.c delete mode 100755 applications/nfc/scenes/nfc_scene_read_emv_app.c delete mode 100755 applications/nfc/scenes/nfc_scene_read_emv_app_success.c delete mode 100755 applications/nfc/scenes/nfc_scene_read_emv_data.c delete mode 100644 applications/nfc/scenes/nfc_scene_read_mifare_classic.c delete mode 100644 applications/nfc/scenes/nfc_scene_read_mifare_desfire.c delete mode 100755 applications/nfc/scenes/nfc_scene_read_mifare_ul.c create mode 100644 applications/nfc/scenes/nfc_scene_retry_confirm.c delete mode 100755 applications/nfc/scenes/nfc_scene_run_emv_app_confirm.c delete mode 100755 applications/nfc/scenes/nfc_scene_scripts_menu.c create mode 100644 assets/icons/NFC/NFC_manual.png create mode 100644 assets/icons/NFC/Reader_detect.png create mode 100644 lib/nfc/SConscript create mode 100644 lib/nfc/helpers/mf_classic_dict.c create mode 100644 lib/nfc/helpers/mf_classic_dict.h rename {applications => lib}/nfc/helpers/nfc_debug_pcap.c (100%) rename {applications => lib}/nfc/helpers/nfc_debug_pcap.h (100%) rename {applications => lib}/nfc/nfc_device.c (79%) rename {applications => lib}/nfc/nfc_device.h (89%) rename {applications => lib}/nfc/nfc_types.c (100%) rename {applications => lib}/nfc/nfc_types.h (100%) create mode 100644 lib/nfc/nfc_worker.c rename {applications => lib}/nfc/nfc_worker.h (59%) create mode 100644 lib/nfc/nfc_worker_i.h create mode 100644 lib/nfc/parsers/nfc_supported_card.c create mode 100644 lib/nfc/parsers/nfc_supported_card.h create mode 100644 lib/nfc/parsers/troyka_parser.c create mode 100644 lib/nfc/parsers/troyka_parser.h rename lib/{nfc_protocols => nfc/protocols}/crypto1.c (100%) rename lib/{nfc_protocols => nfc/protocols}/crypto1.h (100%) rename lib/{nfc_protocols => nfc/protocols}/emv.c (100%) rename lib/{nfc_protocols => nfc/protocols}/emv.h (100%) rename lib/{nfc_protocols => nfc/protocols}/mifare_classic.c (71%) rename lib/{nfc_protocols => nfc/protocols}/mifare_classic.h (54%) rename lib/{nfc_protocols => nfc/protocols}/mifare_common.c (100%) rename lib/{nfc_protocols => nfc/protocols}/mifare_common.h (100%) rename lib/{nfc_protocols => nfc/protocols}/mifare_desfire.c (62%) rename lib/{nfc_protocols => nfc/protocols}/mifare_desfire.h (98%) rename lib/{nfc_protocols => nfc/protocols}/mifare_ultralight.c (100%) rename lib/{nfc_protocols => nfc/protocols}/mifare_ultralight.h (100%) rename lib/{nfc_protocols => nfc/protocols}/nfc_util.c (100%) rename lib/{nfc_protocols => nfc/protocols}/nfc_util.h (100%) rename lib/{nfc_protocols => nfc/protocols}/nfca.c (100%) rename lib/{nfc_protocols => nfc/protocols}/nfca.h (100%) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index da0cfd2c..71acb5f1 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -76,7 +76,7 @@ /lib/microtar/ @skotopes @DrZlo13 @hedger /lib/mlib/ @skotopes @DrZlo13 @hedger /lib/nanopb/ @skotopes @DrZlo13 @hedger -/lib/nfc_protocols/ @skotopes @DrZlo13 @hedger @gornekich +/lib/nfc/ @skotopes @DrZlo13 @hedger @gornekich /lib/one_wire/ @skotopes @DrZlo13 @hedger /lib/qrcode/ @skotopes @DrZlo13 @hedger /lib/subghz/ @skotopes @DrZlo13 @hedger @Skorpionm diff --git a/applications/nfc/helpers/nfc_custom_event.h b/applications/nfc/helpers/nfc_custom_event.h index b877732a..fbd54b27 100644 --- a/applications/nfc/helpers/nfc_custom_event.h +++ b/applications/nfc/helpers/nfc_custom_event.h @@ -9,5 +9,6 @@ enum NfcCustomEvent { NfcCustomEventByteInputDone, NfcCustomEventTextInputDone, NfcCustomEventDictAttackDone, + NfcCustomEventDictAttackSkip, NfcCustomEventRpcLoad, }; diff --git a/applications/nfc/helpers/nfc_generators.c b/applications/nfc/helpers/nfc_generators.c index 4121daf4..066ac9d1 100644 --- a/applications/nfc/helpers/nfc_generators.c +++ b/applications/nfc/helpers/nfc_generators.c @@ -267,67 +267,67 @@ static void nfc_generate_ntag_i2c_plus_2k(NfcDeviceData* data) { static const NfcGenerator mf_ul_generator = { .name = "Mifare Ultralight", .generator_func = nfc_generate_mf_ul_orig, - .next_scene = NfcSceneMifareUlMenu}; + .next_scene = NfcSceneMfUltralightMenu}; static const NfcGenerator mf_ul_11_generator = { .name = "Mifare Ultralight EV1 11", .generator_func = nfc_generate_mf_ul_11, - .next_scene = NfcSceneMifareUlMenu}; + .next_scene = NfcSceneMfUltralightMenu}; static const NfcGenerator mf_ul_h11_generator = { .name = "Mifare Ultralight EV1 H11", .generator_func = nfc_generate_mf_ul_h11, - .next_scene = NfcSceneMifareUlMenu}; + .next_scene = NfcSceneMfUltralightMenu}; static const NfcGenerator mf_ul_21_generator = { .name = "Mifare Ultralight EV1 21", .generator_func = nfc_generate_mf_ul_21, - .next_scene = NfcSceneMifareUlMenu}; + .next_scene = NfcSceneMfUltralightMenu}; static const NfcGenerator mf_ul_h21_generator = { .name = "Mifare Ultralight EV1 H21", .generator_func = nfc_generate_mf_ul_h21, - .next_scene = NfcSceneMifareUlMenu}; + .next_scene = NfcSceneMfUltralightMenu}; static const NfcGenerator ntag203_generator = { .name = "NTAG203", .generator_func = nfc_generate_mf_ul_ntag203, - .next_scene = NfcSceneMifareUlMenu}; + .next_scene = NfcSceneMfUltralightMenu}; static const NfcGenerator ntag213_generator = { .name = "NTAG213", .generator_func = nfc_generate_ntag213, - .next_scene = NfcSceneMifareUlMenu}; + .next_scene = NfcSceneMfUltralightMenu}; static const NfcGenerator ntag215_generator = { .name = "NTAG215", .generator_func = nfc_generate_ntag215, - .next_scene = NfcSceneMifareUlMenu}; + .next_scene = NfcSceneMfUltralightMenu}; static const NfcGenerator ntag216_generator = { .name = "NTAG216", .generator_func = nfc_generate_ntag216, - .next_scene = NfcSceneMifareUlMenu}; + .next_scene = NfcSceneMfUltralightMenu}; static const NfcGenerator ntag_i2c_1k_generator = { .name = "NTAG I2C 1k", .generator_func = nfc_generate_ntag_i2c_1k, - .next_scene = NfcSceneMifareUlMenu}; + .next_scene = NfcSceneMfUltralightMenu}; static const NfcGenerator ntag_i2c_2k_generator = { .name = "NTAG I2C 2k", .generator_func = nfc_generate_ntag_i2c_2k, - .next_scene = NfcSceneMifareUlMenu}; + .next_scene = NfcSceneMfUltralightMenu}; static const NfcGenerator ntag_i2c_plus_1k_generator = { .name = "NTAG I2C Plus 1k", .generator_func = nfc_generate_ntag_i2c_plus_1k, - .next_scene = NfcSceneMifareUlMenu}; + .next_scene = NfcSceneMfUltralightMenu}; static const NfcGenerator ntag_i2c_plus_2k_generator = { .name = "NTAG I2C Plus 2k", .generator_func = nfc_generate_ntag_i2c_plus_2k, - .next_scene = NfcSceneMifareUlMenu}; + .next_scene = NfcSceneMfUltralightMenu}; const NfcGenerator* const nfc_generators[] = { &mf_ul_generator, diff --git a/applications/nfc/helpers/nfc_mf_classic_dict.c b/applications/nfc/helpers/nfc_mf_classic_dict.c deleted file mode 100644 index be77dede..00000000 --- a/applications/nfc/helpers/nfc_mf_classic_dict.c +++ /dev/null @@ -1,53 +0,0 @@ -#include "nfc_mf_classic_dict.h" - -#include -#include - -#define NFC_MF_CLASSIC_DICT_PATH EXT_PATH("nfc/assets/mf_classic_dict.nfc") - -#define NFC_MF_CLASSIC_KEY_LEN (13) - -bool nfc_mf_classic_dict_check_presence(Storage* storage) { - furi_assert(storage); - return storage_common_stat(storage, NFC_MF_CLASSIC_DICT_PATH, NULL) == FSE_OK; -} - -bool nfc_mf_classic_dict_open_file(Stream* stream) { - furi_assert(stream); - return file_stream_open(stream, NFC_MF_CLASSIC_DICT_PATH, FSAM_READ, FSOM_OPEN_EXISTING); -} - -void nfc_mf_classic_dict_close_file(Stream* stream) { - furi_assert(stream); - file_stream_close(stream); -} - -bool nfc_mf_classic_dict_get_next_key(Stream* stream, uint64_t* key) { - furi_assert(stream); - furi_assert(key); - uint8_t key_byte_tmp = 0; - string_t next_line; - string_init(next_line); - *key = 0; - - bool next_key_read = false; - while(!next_key_read) { - if(!stream_read_line(stream, next_line)) break; - if(string_get_char(next_line, 0) == '#') continue; - if(string_size(next_line) != NFC_MF_CLASSIC_KEY_LEN) continue; - for(uint8_t i = 0; i < 12; i += 2) { - args_char_to_hex( - string_get_char(next_line, i), string_get_char(next_line, i + 1), &key_byte_tmp); - *key |= (uint64_t)key_byte_tmp << 8 * (5 - i / 2); - } - next_key_read = true; - } - - string_clear(next_line); - return next_key_read; -} - -void nfc_mf_classic_dict_reset(Stream* stream) { - furi_assert(stream); - stream_rewind(stream); -} diff --git a/applications/nfc/helpers/nfc_mf_classic_dict.h b/applications/nfc/helpers/nfc_mf_classic_dict.h deleted file mode 100644 index 8d3a7372..00000000 --- a/applications/nfc/helpers/nfc_mf_classic_dict.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include -#include -#include - -bool nfc_mf_classic_dict_check_presence(Storage* storage); - -bool nfc_mf_classic_dict_open_file(Stream* stream); - -void nfc_mf_classic_dict_close_file(Stream* stream); - -bool nfc_mf_classic_dict_get_next_key(Stream* stream, uint64_t* key); - -void nfc_mf_classic_dict_reset(Stream* stream); diff --git a/applications/nfc/nfc.c b/applications/nfc/nfc.c index f6af3573..b19f92f2 100644 --- a/applications/nfc/nfc.c +++ b/applications/nfc/nfc.c @@ -13,12 +13,6 @@ bool nfc_back_event_callback(void* context) { return scene_manager_handle_back_event(nfc->scene_manager); } -void nfc_tick_event_callback(void* context) { - furi_assert(context); - Nfc* nfc = context; - scene_manager_handle_tick_event(nfc->scene_manager); -} - void nfc_rpc_exit_callback(Nfc* nfc) { if(nfc->rpc_state == NfcRpcStateEmulating) { // Stop worker @@ -36,11 +30,12 @@ void nfc_rpc_exit_callback(Nfc* nfc) { } } -static void nfc_rpc_emulate_callback(NfcWorkerEvent event, void* context) { +static bool nfc_rpc_emulate_callback(NfcWorkerEvent event, void* context) { UNUSED(event); Nfc* nfc = context; nfc->rpc_state = NfcRpcStateEmulated; + return true; } static bool nfc_rpc_command_callback(RpcAppSystemEvent event, const char* arg, void* context) { @@ -67,20 +62,20 @@ static bool nfc_rpc_command_callback(RpcAppSystemEvent event, const char* arg, v if(nfc->dev->format == NfcDeviceSaveFormatMifareUl) { nfc_worker_start( nfc->worker, - NfcWorkerStateEmulateMifareUltralight, + NfcWorkerStateMfUltralightEmulate, &nfc->dev->dev_data, nfc_rpc_emulate_callback, nfc); } else if(nfc->dev->format == NfcDeviceSaveFormatMifareClassic) { nfc_worker_start( nfc->worker, - NfcWorkerStateEmulateMifareClassic, + NfcWorkerStateMfClassicEmulate, &nfc->dev->dev_data, nfc_rpc_emulate_callback, nfc); } else { nfc_worker_start( - nfc->worker, NfcWorkerStateEmulate, &nfc->dev->dev_data, NULL, nfc); + nfc->worker, NfcWorkerStateUidEmulate, &nfc->dev->dev_data, NULL, nfc); } nfc->rpc_state = NfcRpcStateEmulating; view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventRpcLoad); @@ -102,7 +97,6 @@ Nfc* nfc_alloc() { view_dispatcher_set_event_callback_context(nfc->view_dispatcher, nfc); view_dispatcher_set_custom_event_callback(nfc->view_dispatcher, nfc_custom_event_callback); view_dispatcher_set_navigation_event_callback(nfc->view_dispatcher, nfc_back_event_callback); - view_dispatcher_set_tick_event_callback(nfc->view_dispatcher, nfc_tick_event_callback, 100); // Nfc device nfc->dev = nfc_device_alloc(); @@ -155,7 +149,7 @@ Nfc* nfc_alloc() { view_dispatcher_add_view( nfc->view_dispatcher, NfcViewBankCard, bank_card_get_view(nfc->bank_card)); - // Dict Attack + // Mifare Classic Dict Attack nfc->dict_attack = dict_attack_alloc(); view_dispatcher_add_view( nfc->view_dispatcher, NfcViewDictAttack, dict_attack_get_view(nfc->dict_attack)); @@ -209,7 +203,7 @@ void nfc_free(Nfc* nfc) { view_dispatcher_remove_view(nfc->view_dispatcher, NfcViewBankCard); bank_card_free(nfc->bank_card); - // Dict Attack + // Mifare Classic Dict Attack view_dispatcher_remove_view(nfc->view_dispatcher, NfcViewDictAttack); dict_attack_free(nfc->dict_attack); @@ -301,9 +295,9 @@ int32_t nfc_app(void* p) { nfc->view_dispatcher, nfc->gui, ViewDispatcherTypeFullscreen); if(nfc_device_load(nfc->dev, p, true)) { if(nfc->dev->format == NfcDeviceSaveFormatMifareUl) { - scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateMifareUl); + scene_manager_next_scene(nfc->scene_manager, NfcSceneMfUltralightEmulate); } else if(nfc->dev->format == NfcDeviceSaveFormatMifareClassic) { - scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateMifareClassic); + scene_manager_next_scene(nfc->scene_manager, NfcSceneMfClassicEmulate); } else { scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateUid); } diff --git a/applications/nfc/nfc_cli.c b/applications/nfc/nfc_cli.c index 133bd558..4ac95f04 100755 --- a/applications/nfc/nfc_cli.c +++ b/applications/nfc/nfc_cli.c @@ -1,9 +1,10 @@ #include #include #include -#include +#include -#include "nfc_types.h" +#include +#include static void nfc_cli_print_usage() { printf("Usage:\r\n"); diff --git a/applications/nfc/nfc_i.h b/applications/nfc/nfc_i.h index 4b806d40..84c0e7f0 100755 --- a/applications/nfc/nfc_i.h +++ b/applications/nfc/nfc_i.h @@ -1,9 +1,6 @@ #pragma once #include "nfc.h" -#include "nfc_types.h" -#include "nfc_worker.h" -#include "nfc_device.h" #include #include @@ -24,6 +21,11 @@ #include #include +#include +#include +#include +#include + #include "views/bank_card.h" #include "views/dict_attack.h" @@ -32,8 +34,6 @@ #include "rpc/rpc_app.h" -#define NFC_SEND_NOTIFICATION_FALSE (0UL) -#define NFC_SEND_NOTIFICATION_TRUE (1UL) #define NFC_TEXT_STORE_SIZE 128 typedef enum { @@ -56,6 +56,7 @@ struct Nfc { char text_store[NFC_TEXT_STORE_SIZE + 1]; string_t text_box_store; + uint8_t byte_input_store[6]; void* rpc_ctx; NfcRpcState rpc_state; diff --git a/applications/nfc/nfc_worker.c b/applications/nfc/nfc_worker.c deleted file mode 100644 index df1b5faf..00000000 --- a/applications/nfc/nfc_worker.c +++ /dev/null @@ -1,708 +0,0 @@ -#include "nfc_worker_i.h" -#include - -#include - -#define TAG "NfcWorker" - -/***************************** NFC Worker API *******************************/ - -NfcWorker* nfc_worker_alloc() { - NfcWorker* nfc_worker = malloc(sizeof(NfcWorker)); - - // Worker thread attributes - nfc_worker->thread = furi_thread_alloc(); - furi_thread_set_name(nfc_worker->thread, "NfcWorker"); - furi_thread_set_stack_size(nfc_worker->thread, 8192); - furi_thread_set_callback(nfc_worker->thread, nfc_worker_task); - furi_thread_set_context(nfc_worker->thread, nfc_worker); - - nfc_worker->callback = NULL; - nfc_worker->context = NULL; - nfc_worker->storage = furi_record_open(RECORD_STORAGE); - - // Initialize rfal - while(furi_hal_nfc_is_busy()) { - furi_delay_ms(10); - } - nfc_worker_change_state(nfc_worker, NfcWorkerStateReady); - - if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) { - nfc_worker->debug_pcap_worker = nfc_debug_pcap_alloc(nfc_worker->storage); - } - - return nfc_worker; -} - -void nfc_worker_free(NfcWorker* nfc_worker) { - furi_assert(nfc_worker); - - furi_thread_free(nfc_worker->thread); - - furi_record_close(RECORD_STORAGE); - - if(nfc_worker->debug_pcap_worker) nfc_debug_pcap_free(nfc_worker->debug_pcap_worker); - - free(nfc_worker); -} - -NfcWorkerState nfc_worker_get_state(NfcWorker* nfc_worker) { - return nfc_worker->state; -} - -void nfc_worker_start( - NfcWorker* nfc_worker, - NfcWorkerState state, - NfcDeviceData* dev_data, - NfcWorkerCallback callback, - void* context) { - furi_assert(nfc_worker); - furi_assert(dev_data); - while(furi_hal_nfc_is_busy()) { - furi_delay_ms(10); - } - - nfc_worker->callback = callback; - nfc_worker->context = context; - nfc_worker->dev_data = dev_data; - nfc_worker_change_state(nfc_worker, state); - furi_thread_start(nfc_worker->thread); -} - -void nfc_worker_stop(NfcWorker* nfc_worker) { - furi_assert(nfc_worker); - if(nfc_worker->state == NfcWorkerStateBroken || nfc_worker->state == NfcWorkerStateReady) { - return; - } - furi_hal_nfc_stop(); - nfc_worker_change_state(nfc_worker, NfcWorkerStateStop); - furi_thread_join(nfc_worker->thread); -} - -void nfc_worker_change_state(NfcWorker* nfc_worker, NfcWorkerState state) { - nfc_worker->state = state; -} - -/***************************** NFC Worker Thread *******************************/ - -int32_t nfc_worker_task(void* context) { - NfcWorker* nfc_worker = context; - - furi_hal_nfc_exit_sleep(); - - if(nfc_worker->state == NfcWorkerStateDetect) { - nfc_worker_detect(nfc_worker); - } else if(nfc_worker->state == NfcWorkerStateEmulate) { - nfc_worker_emulate(nfc_worker); - } else if(nfc_worker->state == NfcWorkerStateReadEMVApp) { - nfc_worker_read_emv_app(nfc_worker); - } else if(nfc_worker->state == NfcWorkerStateReadEMVData) { - nfc_worker_read_emv(nfc_worker); - } else if(nfc_worker->state == NfcWorkerStateEmulateApdu) { - nfc_worker_emulate_apdu(nfc_worker); - } else if(nfc_worker->state == NfcWorkerStateReadMifareUltralight) { - nfc_worker_read_mifare_ultralight(nfc_worker); - } else if(nfc_worker->state == NfcWorkerStateEmulateMifareUltralight) { - nfc_worker_emulate_mifare_ul(nfc_worker); - } else if(nfc_worker->state == NfcWorkerStateReadMifareClassic) { - nfc_worker_mifare_classic_dict_attack(nfc_worker); - } else if(nfc_worker->state == NfcWorkerStateEmulateMifareClassic) { - nfc_worker_emulate_mifare_classic(nfc_worker); - } else if(nfc_worker->state == NfcWorkerStateReadMifareDesfire) { - nfc_worker_read_mifare_desfire(nfc_worker); - } - furi_hal_nfc_sleep(); - nfc_worker_change_state(nfc_worker, NfcWorkerStateReady); - - return 0; -} - -void nfc_worker_detect(NfcWorker* nfc_worker) { - nfc_device_data_clear(nfc_worker->dev_data); - NfcDeviceData* dev_data = nfc_worker->dev_data; - FuriHalNfcDevData* nfc_data = &nfc_worker->dev_data->nfc_data; - - while(nfc_worker->state == NfcWorkerStateDetect) { - if(furi_hal_nfc_detect(nfc_data, 1000)) { - // Process first found device - if(nfc_data->type == FuriHalNfcTypeA) { - if(mf_ul_check_card_type(nfc_data->atqa[0], nfc_data->atqa[1], nfc_data->sak)) { - dev_data->protocol = NfcDeviceProtocolMifareUl; - } else if(mf_classic_check_card_type( - nfc_data->atqa[0], nfc_data->atqa[1], nfc_data->sak)) { - dev_data->protocol = NfcDeviceProtocolMifareClassic; - } else if(mf_df_check_card_type( - nfc_data->atqa[0], nfc_data->atqa[1], nfc_data->sak)) { - dev_data->protocol = NfcDeviceProtocolMifareDesfire; - } else if(nfc_data->interface == FuriHalNfcInterfaceIsoDep) { - dev_data->protocol = NfcDeviceProtocolEMV; - } else { - dev_data->protocol = NfcDeviceProtocolUnknown; - } - } - - // Notify caller and exit - if(nfc_worker->callback) { - nfc_worker->callback(NfcWorkerEventSuccess, nfc_worker->context); - } - break; - } - furi_hal_nfc_sleep(); - furi_delay_ms(100); - } -} - -void nfc_worker_emulate(NfcWorker* nfc_worker) { - FuriHalNfcTxRxContext tx_rx = {}; - nfc_debug_pcap_prepare_tx_rx(nfc_worker->debug_pcap_worker, &tx_rx, true); - FuriHalNfcDevData* data = &nfc_worker->dev_data->nfc_data; - NfcReaderRequestData* reader_data = &nfc_worker->dev_data->reader_data; - - while(nfc_worker->state == NfcWorkerStateEmulate) { - if(furi_hal_nfc_listen(data->uid, data->uid_len, data->atqa, data->sak, true, 100)) { - if(furi_hal_nfc_tx_rx(&tx_rx, 100)) { - reader_data->size = tx_rx.rx_bits / 8; - if(reader_data->size > 0) { - memcpy(reader_data->data, tx_rx.rx_data, reader_data->size); - if(nfc_worker->callback) { - nfc_worker->callback(NfcWorkerEventSuccess, nfc_worker->context); - } - } - } else { - FURI_LOG_E(TAG, "Failed to get reader commands"); - } - } - } -} - -void nfc_worker_read_emv_app(NfcWorker* nfc_worker) { - FuriHalNfcTxRxContext tx_rx = {}; - nfc_debug_pcap_prepare_tx_rx(nfc_worker->debug_pcap_worker, &tx_rx, false); - EmvApplication emv_app = {}; - NfcDeviceData* result = nfc_worker->dev_data; - FuriHalNfcDevData* nfc_data = &nfc_worker->dev_data->nfc_data; - nfc_device_data_clear(result); - - while(nfc_worker->state == NfcWorkerStateReadEMVApp) { - if(furi_hal_nfc_detect(nfc_data, 1000)) { - // Card was found. Check that it supports EMV - if(nfc_data->interface == FuriHalNfcInterfaceIsoDep) { - result->protocol = NfcDeviceProtocolEMV; - if(emv_search_application(&tx_rx, &emv_app)) { - // Notify caller and exit - result->emv_data.aid_len = emv_app.aid_len; - memcpy(result->emv_data.aid, emv_app.aid, emv_app.aid_len); - if(nfc_worker->callback) { - nfc_worker->callback(NfcWorkerEventSuccess, nfc_worker->context); - } - } - } else { - FURI_LOG_W(TAG, "Card doesn't support EMV"); - } - } else { - FURI_LOG_D(TAG, "Can't find any cards"); - } - furi_hal_nfc_sleep(); - furi_delay_ms(20); - } -} - -void nfc_worker_read_emv(NfcWorker* nfc_worker) { - FuriHalNfcTxRxContext tx_rx = {}; - nfc_debug_pcap_prepare_tx_rx(nfc_worker->debug_pcap_worker, &tx_rx, false); - EmvApplication emv_app = {}; - NfcDeviceData* result = nfc_worker->dev_data; - FuriHalNfcDevData* nfc_data = &nfc_worker->dev_data->nfc_data; - nfc_device_data_clear(result); - - while(nfc_worker->state == NfcWorkerStateReadEMVData) { - if(furi_hal_nfc_detect(nfc_data, 1000)) { - // Card was found. Check that it supports EMV - if(nfc_data->interface == FuriHalNfcInterfaceIsoDep) { - result->protocol = NfcDeviceProtocolEMV; - if(emv_read_bank_card(&tx_rx, &emv_app)) { - result->emv_data.number_len = emv_app.card_number_len; - memcpy( - result->emv_data.number, emv_app.card_number, result->emv_data.number_len); - result->emv_data.aid_len = emv_app.aid_len; - memcpy(result->emv_data.aid, emv_app.aid, emv_app.aid_len); - if(emv_app.name_found) { - memcpy(result->emv_data.name, emv_app.name, sizeof(emv_app.name)); - } - if(emv_app.exp_month) { - result->emv_data.exp_mon = emv_app.exp_month; - result->emv_data.exp_year = emv_app.exp_year; - } - if(emv_app.country_code) { - result->emv_data.country_code = emv_app.country_code; - } - if(emv_app.currency_code) { - result->emv_data.currency_code = emv_app.currency_code; - } - // Notify caller and exit - if(nfc_worker->callback) { - nfc_worker->callback(NfcWorkerEventSuccess, nfc_worker->context); - } - break; - } - } else { - FURI_LOG_W(TAG, "Card doesn't support EMV"); - } - } else { - FURI_LOG_D(TAG, "Can't find any cards"); - } - furi_hal_nfc_sleep(); - furi_delay_ms(20); - } -} - -void nfc_worker_emulate_apdu(NfcWorker* nfc_worker) { - FuriHalNfcTxRxContext tx_rx = {}; - nfc_debug_pcap_prepare_tx_rx(nfc_worker->debug_pcap_worker, &tx_rx, true); - FuriHalNfcDevData params = { - .uid = {0xCF, 0x72, 0xd4, 0x40}, - .uid_len = 4, - .atqa = {0x00, 0x04}, - .sak = 0x20, - .type = FuriHalNfcTypeA, - }; - - while(nfc_worker->state == NfcWorkerStateEmulateApdu) { - if(furi_hal_nfc_listen(params.uid, params.uid_len, params.atqa, params.sak, false, 300)) { - FURI_LOG_D(TAG, "POS terminal detected"); - if(emv_card_emulation(&tx_rx)) { - FURI_LOG_D(TAG, "EMV card emulated"); - } - } else { - FURI_LOG_D(TAG, "Can't find reader"); - } - furi_hal_nfc_sleep(); - furi_delay_ms(20); - } -} - -void nfc_worker_read_mifare_ultralight(NfcWorker* nfc_worker) { - FuriHalNfcTxRxContext tx_rx = {}; - nfc_debug_pcap_prepare_tx_rx(nfc_worker->debug_pcap_worker, &tx_rx, false); - MfUltralightReader reader = {}; - MfUltralightData data = {}; - NfcDeviceData* result = nfc_worker->dev_data; - FuriHalNfcDevData* nfc_data = &nfc_worker->dev_data->nfc_data; - - while(nfc_worker->state == NfcWorkerStateReadMifareUltralight) { - if(furi_hal_nfc_detect(nfc_data, 300)) { - if(nfc_data->type == FuriHalNfcTypeA && - mf_ul_check_card_type(nfc_data->atqa[0], nfc_data->atqa[1], nfc_data->sak)) { - FURI_LOG_D(TAG, "Found Mifare Ultralight tag. Start reading"); - if(mf_ul_read_card(&tx_rx, &reader, &data)) { - result->protocol = NfcDeviceProtocolMifareUl; - result->mf_ul_data = data; - // Notify caller and exit - if(nfc_worker->callback) { - nfc_worker->callback(NfcWorkerEventSuccess, nfc_worker->context); - } - break; - } else { - FURI_LOG_D(TAG, "Failed reading Mifare Ultralight"); - } - } else { - FURI_LOG_W(TAG, "Tag is not Mifare Ultralight"); - } - } else { - FURI_LOG_D(TAG, "Can't find any tags"); - } - furi_hal_nfc_sleep(); - furi_delay_ms(100); - } -} - -void nfc_worker_emulate_mifare_ul(NfcWorker* nfc_worker) { - FuriHalNfcDevData* nfc_data = &nfc_worker->dev_data->nfc_data; - MfUltralightEmulator emulator = {}; - mf_ul_prepare_emulation(&emulator, &nfc_worker->dev_data->mf_ul_data); - while(nfc_worker->state == NfcWorkerStateEmulateMifareUltralight) { - mf_ul_reset_emulation(&emulator, true); - furi_hal_nfc_emulate_nfca( - nfc_data->uid, - nfc_data->uid_len, - nfc_data->atqa, - nfc_data->sak, - mf_ul_prepare_emulation_response, - &emulator, - 5000); - // Check if data was modified - if(emulator.data_changed) { - nfc_worker->dev_data->mf_ul_data = emulator.data; - if(nfc_worker->callback) { - nfc_worker->callback(NfcWorkerEventSuccess, nfc_worker->context); - } - emulator.data_changed = false; - } - } -} - -void nfc_worker_mifare_classic_dict_attack(NfcWorker* nfc_worker) { - furi_assert(nfc_worker->callback); - FuriHalNfcTxRxContext tx_rx_ctx = {}; - nfc_debug_pcap_prepare_tx_rx(nfc_worker->debug_pcap_worker, &tx_rx_ctx, false); - MfClassicAuthContext auth_ctx = {}; - MfClassicReader reader = {}; - uint64_t curr_key = 0; - uint16_t curr_sector = 0; - uint8_t total_sectors = 0; - NfcWorkerEvent event; - FuriHalNfcDevData* nfc_data = &nfc_worker->dev_data->nfc_data; - - // Open dictionary - nfc_worker->dict_stream = file_stream_alloc(nfc_worker->storage); - if(!nfc_mf_classic_dict_open_file(nfc_worker->dict_stream)) { - event = NfcWorkerEventNoDictFound; - nfc_worker->callback(event, nfc_worker->context); - nfc_mf_classic_dict_close_file(nfc_worker->dict_stream); - stream_free(nfc_worker->dict_stream); - return; - } - - // Detect Mifare Classic card - while(nfc_worker->state == NfcWorkerStateReadMifareClassic) { - if(furi_hal_nfc_detect(nfc_data, 300)) { - if(mf_classic_get_type( - nfc_data->uid, - nfc_data->uid_len, - nfc_data->atqa[0], - nfc_data->atqa[1], - nfc_data->sak, - &reader)) { - total_sectors = mf_classic_get_total_sectors_num(&reader); - if(reader.type == MfClassicType1k) { - event = NfcWorkerEventDetectedClassic1k; - } else { - event = NfcWorkerEventDetectedClassic4k; - } - nfc_worker->callback(event, nfc_worker->context); - break; - } - } else { - event = NfcWorkerEventNoCardDetected; - nfc_worker->callback(event, nfc_worker->context); - } - } - - if(nfc_worker->state == NfcWorkerStateReadMifareClassic) { - bool card_removed_notified = false; - bool card_found_notified = false; - // Seek for mifare classic keys - for(curr_sector = 0; curr_sector < total_sectors; curr_sector++) { - FURI_LOG_I(TAG, "Sector: %d ...", curr_sector); - event = NfcWorkerEventNewSector; - nfc_worker->callback(event, nfc_worker->context); - mf_classic_auth_init_context(&auth_ctx, reader.cuid, curr_sector); - bool sector_key_found = false; - while(nfc_mf_classic_dict_get_next_key(nfc_worker->dict_stream, &curr_key)) { - furi_hal_nfc_sleep(); - if(furi_hal_nfc_activate_nfca(300, &reader.cuid)) { - if(!card_found_notified) { - if(reader.type == MfClassicType1k) { - event = NfcWorkerEventDetectedClassic1k; - } else { - event = NfcWorkerEventDetectedClassic4k; - } - nfc_worker->callback(event, nfc_worker->context); - card_found_notified = true; - card_removed_notified = false; - } - FURI_LOG_D( - TAG, - "Try to auth to sector %d with key %04lx%08lx", - curr_sector, - (uint32_t)(curr_key >> 32), - (uint32_t)curr_key); - if(mf_classic_auth_attempt(&tx_rx_ctx, &auth_ctx, curr_key)) { - sector_key_found = true; - if((auth_ctx.key_a != MF_CLASSIC_NO_KEY) && - (auth_ctx.key_b != MF_CLASSIC_NO_KEY)) - break; - } - } else { - // Notify that no tag is availalble - FURI_LOG_D(TAG, "Can't find tags"); - if(!card_removed_notified) { - event = NfcWorkerEventNoCardDetected; - nfc_worker->callback(event, nfc_worker->context); - card_removed_notified = true; - card_found_notified = false; - } - } - if(nfc_worker->state != NfcWorkerStateReadMifareClassic) break; - furi_delay_tick(1); - } - if(nfc_worker->state != NfcWorkerStateReadMifareClassic) break; - if(sector_key_found) { - // Notify that keys were found - if(auth_ctx.key_a != MF_CLASSIC_NO_KEY) { - FURI_LOG_I( - TAG, - "Sector %d key A: %04lx%08lx", - curr_sector, - (uint32_t)(auth_ctx.key_a >> 32), - (uint32_t)auth_ctx.key_a); - event = NfcWorkerEventFoundKeyA; - nfc_worker->callback(event, nfc_worker->context); - } - if(auth_ctx.key_b != MF_CLASSIC_NO_KEY) { - FURI_LOG_I( - TAG, - "Sector %d key B: %04lx%08lx", - curr_sector, - (uint32_t)(auth_ctx.key_b >> 32), - (uint32_t)auth_ctx.key_b); - event = NfcWorkerEventFoundKeyB; - nfc_worker->callback(event, nfc_worker->context); - } - // Add sectors to read sequence - mf_classic_reader_add_sector(&reader, curr_sector, auth_ctx.key_a, auth_ctx.key_b); - } - nfc_mf_classic_dict_reset(nfc_worker->dict_stream); - } - } - - if(nfc_worker->state == NfcWorkerStateReadMifareClassic) { - FURI_LOG_I(TAG, "Found keys to %d sectors. Start reading sectors", reader.sectors_to_read); - uint8_t sectors_read = - mf_classic_read_card(&tx_rx_ctx, &reader, &nfc_worker->dev_data->mf_classic_data); - if(sectors_read) { - event = NfcWorkerEventSuccess; - nfc_worker->dev_data->protocol = NfcDeviceProtocolMifareClassic; - FURI_LOG_I(TAG, "Successfully read %d sectors", sectors_read); - } else { - event = NfcWorkerEventFail; - FURI_LOG_W(TAG, "Failed to read any sector"); - } - nfc_worker->callback(event, nfc_worker->context); - } - - nfc_mf_classic_dict_close_file(nfc_worker->dict_stream); - stream_free(nfc_worker->dict_stream); -} - -void nfc_worker_emulate_mifare_classic(NfcWorker* nfc_worker) { - FuriHalNfcTxRxContext tx_rx = {}; - nfc_debug_pcap_prepare_tx_rx(nfc_worker->debug_pcap_worker, &tx_rx, true); - FuriHalNfcDevData* nfc_data = &nfc_worker->dev_data->nfc_data; - MfClassicEmulator emulator = { - .cuid = nfc_util_bytes2num(&nfc_data->uid[nfc_data->uid_len - 4], 4), - .data = nfc_worker->dev_data->mf_classic_data, - .data_changed = false, - }; - NfcaSignal* nfca_signal = nfca_signal_alloc(); - tx_rx.nfca_signal = nfca_signal; - - rfal_platform_spi_acquire(); - - furi_hal_nfc_listen_start(nfc_data); - while(nfc_worker->state == NfcWorkerStateEmulateMifareClassic) { - if(furi_hal_nfc_listen_rx(&tx_rx, 300)) { - mf_classic_emulator(&emulator, &tx_rx); - } - } - if(emulator.data_changed) { - nfc_worker->dev_data->mf_classic_data = emulator.data; - if(nfc_worker->callback) { - nfc_worker->callback(NfcWorkerEventSuccess, nfc_worker->context); - } - emulator.data_changed = false; - } - - nfca_signal_free(nfca_signal); - - rfal_platform_spi_release(); -} - -void nfc_worker_read_mifare_desfire(NfcWorker* nfc_worker) { - FuriHalNfcTxRxContext tx_rx = {}; - nfc_debug_pcap_prepare_tx_rx(nfc_worker->debug_pcap_worker, &tx_rx, false); - NfcDeviceData* result = nfc_worker->dev_data; - nfc_device_data_clear(result); - MifareDesfireData* data = &result->mf_df_data; - FuriHalNfcDevData* nfc_data = &nfc_worker->dev_data->nfc_data; - - while(nfc_worker->state == NfcWorkerStateReadMifareDesfire) { - furi_hal_nfc_sleep(); - if(!furi_hal_nfc_detect(nfc_data, 300)) { - furi_delay_ms(100); - continue; - } - memset(data, 0, sizeof(MifareDesfireData)); - if(nfc_data->type != FuriHalNfcTypeA || - !mf_df_check_card_type(nfc_data->atqa[0], nfc_data->atqa[1], nfc_data->sak)) { - FURI_LOG_D(TAG, "Tag is not DESFire"); - furi_delay_ms(100); - continue; - } - - FURI_LOG_D(TAG, "Found DESFire tag"); - - result->protocol = NfcDeviceProtocolMifareDesfire; - - // Get DESFire version - tx_rx.tx_bits = 8 * mf_df_prepare_get_version(tx_rx.tx_data); - if(!furi_hal_nfc_tx_rx_full(&tx_rx)) { - FURI_LOG_W(TAG, "Bad exchange getting version"); - continue; - } - if(!mf_df_parse_get_version_response(tx_rx.rx_data, tx_rx.rx_bits / 8, &data->version)) { - FURI_LOG_W(TAG, "Bad DESFire GET_VERSION response"); - continue; - } - - tx_rx.tx_bits = 8 * mf_df_prepare_get_free_memory(tx_rx.tx_data); - if(furi_hal_nfc_tx_rx_full(&tx_rx)) { - data->free_memory = malloc(sizeof(MifareDesfireFreeMemory)); - memset(data->free_memory, 0, sizeof(MifareDesfireFreeMemory)); - if(!mf_df_parse_get_free_memory_response( - tx_rx.rx_data, tx_rx.rx_bits / 8, data->free_memory)) { - FURI_LOG_D(TAG, "Bad DESFire GET_FREE_MEMORY response (normal for pre-EV1 cards)"); - free(data->free_memory); - data->free_memory = NULL; - } - } - - tx_rx.tx_bits = 8 * mf_df_prepare_get_key_settings(tx_rx.tx_data); - if(!furi_hal_nfc_tx_rx_full(&tx_rx)) { - FURI_LOG_D(TAG, "Bad exchange getting key settings"); - } else { - data->master_key_settings = malloc(sizeof(MifareDesfireKeySettings)); - memset(data->master_key_settings, 0, sizeof(MifareDesfireKeySettings)); - if(!mf_df_parse_get_key_settings_response( - tx_rx.rx_data, tx_rx.rx_bits / 8, data->master_key_settings)) { - FURI_LOG_W(TAG, "Bad DESFire GET_KEY_SETTINGS response"); - free(data->master_key_settings); - data->master_key_settings = NULL; - } else { - MifareDesfireKeyVersion** key_version_head = - &data->master_key_settings->key_version_head; - for(uint8_t key_id = 0; key_id < data->master_key_settings->max_keys; key_id++) { - tx_rx.tx_bits = 8 * mf_df_prepare_get_key_version(tx_rx.tx_data, key_id); - if(!furi_hal_nfc_tx_rx_full(&tx_rx)) { - FURI_LOG_W(TAG, "Bad exchange getting key version"); - continue; - } - MifareDesfireKeyVersion* key_version = malloc(sizeof(MifareDesfireKeyVersion)); - memset(key_version, 0, sizeof(MifareDesfireKeyVersion)); - key_version->id = key_id; - if(!mf_df_parse_get_key_version_response( - tx_rx.rx_data, tx_rx.rx_bits / 8, key_version)) { - FURI_LOG_W(TAG, "Bad DESFire GET_KEY_VERSION response"); - free(key_version); - continue; - } - *key_version_head = key_version; - key_version_head = &key_version->next; - } - } - } - - tx_rx.tx_bits = 8 * mf_df_prepare_get_application_ids(tx_rx.tx_data); - if(!furi_hal_nfc_tx_rx_full(&tx_rx)) { - FURI_LOG_W(TAG, "Bad exchange getting application IDs"); - } else { - if(!mf_df_parse_get_application_ids_response( - tx_rx.rx_data, tx_rx.rx_bits / 8, &data->app_head)) { - FURI_LOG_W(TAG, "Bad DESFire GET_APPLICATION_IDS response"); - } - } - - for(MifareDesfireApplication* app = data->app_head; app; app = app->next) { - tx_rx.tx_bits = 8 * mf_df_prepare_select_application(tx_rx.tx_data, app->id); - if(!furi_hal_nfc_tx_rx_full(&tx_rx) || - !mf_df_parse_select_application_response(tx_rx.rx_data, tx_rx.rx_bits / 8)) { - FURI_LOG_W(TAG, "Bad exchange selecting application"); - continue; - } - tx_rx.tx_bits = 8 * mf_df_prepare_get_key_settings(tx_rx.tx_data); - if(!furi_hal_nfc_tx_rx_full(&tx_rx)) { - FURI_LOG_W(TAG, "Bad exchange getting key settings"); - } else { - app->key_settings = malloc(sizeof(MifareDesfireKeySettings)); - memset(app->key_settings, 0, sizeof(MifareDesfireKeySettings)); - if(!mf_df_parse_get_key_settings_response( - tx_rx.rx_data, tx_rx.rx_bits / 8, app->key_settings)) { - FURI_LOG_W(TAG, "Bad DESFire GET_KEY_SETTINGS response"); - free(app->key_settings); - app->key_settings = NULL; - continue; - } - - MifareDesfireKeyVersion** key_version_head = &app->key_settings->key_version_head; - for(uint8_t key_id = 0; key_id < app->key_settings->max_keys; key_id++) { - tx_rx.tx_bits = 8 * mf_df_prepare_get_key_version(tx_rx.tx_data, key_id); - if(!furi_hal_nfc_tx_rx_full(&tx_rx)) { - FURI_LOG_W(TAG, "Bad exchange getting key version"); - continue; - } - MifareDesfireKeyVersion* key_version = malloc(sizeof(MifareDesfireKeyVersion)); - memset(key_version, 0, sizeof(MifareDesfireKeyVersion)); - key_version->id = key_id; - if(!mf_df_parse_get_key_version_response( - tx_rx.rx_data, tx_rx.rx_bits / 8, key_version)) { - FURI_LOG_W(TAG, "Bad DESFire GET_KEY_VERSION response"); - free(key_version); - continue; - } - *key_version_head = key_version; - key_version_head = &key_version->next; - } - } - - tx_rx.tx_bits = 8 * mf_df_prepare_get_file_ids(tx_rx.tx_data); - if(!furi_hal_nfc_tx_rx_full(&tx_rx)) { - FURI_LOG_W(TAG, "Bad exchange getting file IDs"); - } else { - if(!mf_df_parse_get_file_ids_response( - tx_rx.rx_data, tx_rx.rx_bits / 8, &app->file_head)) { - FURI_LOG_W(TAG, "Bad DESFire GET_FILE_IDS response"); - } - } - - for(MifareDesfireFile* file = app->file_head; file; file = file->next) { - tx_rx.tx_bits = 8 * mf_df_prepare_get_file_settings(tx_rx.tx_data, file->id); - if(!furi_hal_nfc_tx_rx_full(&tx_rx)) { - FURI_LOG_W(TAG, "Bad exchange getting file settings"); - continue; - } - if(!mf_df_parse_get_file_settings_response( - tx_rx.rx_data, tx_rx.rx_bits / 8, file)) { - FURI_LOG_W(TAG, "Bad DESFire GET_FILE_SETTINGS response"); - continue; - } - switch(file->type) { - case MifareDesfireFileTypeStandard: - case MifareDesfireFileTypeBackup: - tx_rx.tx_bits = 8 * mf_df_prepare_read_data(tx_rx.tx_data, file->id, 0, 0); - break; - case MifareDesfireFileTypeValue: - tx_rx.tx_bits = 8 * mf_df_prepare_get_value(tx_rx.tx_data, file->id); - break; - case MifareDesfireFileTypeLinearRecord: - case MifareDesfireFileTypeCyclicRecord: - tx_rx.tx_bits = 8 * mf_df_prepare_read_records(tx_rx.tx_data, file->id, 0, 0); - break; - } - if(!furi_hal_nfc_tx_rx_full(&tx_rx)) { - FURI_LOG_W(TAG, "Bad exchange reading file %d", file->id); - continue; - } - if(!mf_df_parse_read_data_response(tx_rx.rx_data, tx_rx.rx_bits / 8, file)) { - FURI_LOG_W(TAG, "Bad response reading file %d", file->id); - continue; - } - } - } - - // Notify caller and exit - if(nfc_worker->callback) { - nfc_worker->callback(NfcWorkerEventSuccess, nfc_worker->context); - } - break; - } -} diff --git a/applications/nfc/nfc_worker_i.h b/applications/nfc/nfc_worker_i.h deleted file mode 100644 index 18c495a4..00000000 --- a/applications/nfc/nfc_worker_i.h +++ /dev/null @@ -1,57 +0,0 @@ -#pragma once - -#include "nfc_worker.h" -#include "nfc_i.h" - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "helpers/nfc_mf_classic_dict.h" -#include "helpers/nfc_debug_pcap.h" - -struct NfcWorker { - FuriThread* thread; - Storage* storage; - Stream* dict_stream; - - NfcDeviceData* dev_data; - - NfcWorkerCallback callback; - void* context; - - NfcWorkerState state; - - NfcDebugPcapWorker* debug_pcap_worker; -}; - -void nfc_worker_change_state(NfcWorker* nfc_worker, NfcWorkerState state); - -int32_t nfc_worker_task(void* context); - -void nfc_worker_read_emv_app(NfcWorker* nfc_worker); - -void nfc_worker_read_emv(NfcWorker* nfc_worker); - -void nfc_worker_emulate_apdu(NfcWorker* nfc_worker); - -void nfc_worker_detect(NfcWorker* nfc_worker); - -void nfc_worker_emulate(NfcWorker* nfc_worker); - -void nfc_worker_read_mifare_ultralight(NfcWorker* nfc_worker); - -void nfc_worker_mifare_classic_dict_attack(NfcWorker* nfc_worker); - -void nfc_worker_read_mifare_desfire(NfcWorker* nfc_worker); - -void nfc_worker_emulate_mifare_ul(NfcWorker* nfc_worker); - -void nfc_worker_emulate_mifare_classic(NfcWorker* nfc_worker); diff --git a/applications/nfc/scenes/nfc_scene_card_menu.c b/applications/nfc/scenes/nfc_scene_card_menu.c deleted file mode 100755 index b7862409..00000000 --- a/applications/nfc/scenes/nfc_scene_card_menu.c +++ /dev/null @@ -1,90 +0,0 @@ -#include "../nfc_i.h" - -enum SubmenuIndex { - SubmenuIndexRunApp, - SubmenuIndexChooseScript, - SubmenuIndexEmulate, - SubmenuIndexSave, -}; - -void nfc_scene_card_menu_submenu_callback(void* context, uint32_t index) { - Nfc* nfc = context; - - view_dispatcher_send_custom_event(nfc->view_dispatcher, index); -} - -void nfc_scene_card_menu_on_enter(void* context) { - Nfc* nfc = context; - Submenu* submenu = nfc->submenu; - - if(nfc->dev->dev_data.protocol > NfcDeviceProtocolUnknown) { - submenu_add_item( - submenu, - "Run Compatible App", - SubmenuIndexRunApp, - nfc_scene_card_menu_submenu_callback, - nfc); - } - submenu_add_item( - submenu, - "Additional reading scripts", - SubmenuIndexChooseScript, - nfc_scene_card_menu_submenu_callback, - nfc); - submenu_add_item( - submenu, "Emulate UID", SubmenuIndexEmulate, nfc_scene_card_menu_submenu_callback, nfc); - submenu_add_item( - submenu, "Save UID", SubmenuIndexSave, nfc_scene_card_menu_submenu_callback, nfc); - submenu_set_selected_item( - nfc->submenu, scene_manager_get_scene_state(nfc->scene_manager, NfcSceneCardMenu)); - - view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewMenu); -} - -bool nfc_scene_card_menu_on_event(void* context, SceneManagerEvent event) { - Nfc* nfc = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == SubmenuIndexRunApp) { - scene_manager_set_scene_state( - nfc->scene_manager, NfcSceneCardMenu, SubmenuIndexRunApp); - if(nfc->dev->dev_data.protocol == NfcDeviceProtocolMifareUl) { - scene_manager_next_scene(nfc->scene_manager, NfcSceneReadMifareUl); - } else if(nfc->dev->dev_data.protocol == NfcDeviceProtocolMifareDesfire) { - scene_manager_next_scene(nfc->scene_manager, NfcSceneReadMifareDesfire); - } else if(nfc->dev->dev_data.protocol == NfcDeviceProtocolEMV) { - scene_manager_next_scene(nfc->scene_manager, NfcSceneReadEmvApp); - } else if(nfc->dev->dev_data.protocol == NfcDeviceProtocolMifareClassic) { - scene_manager_next_scene(nfc->scene_manager, NfcSceneReadMifareClassic); - } - consumed = true; - } else if(event.event == SubmenuIndexChooseScript) { - scene_manager_set_scene_state( - nfc->scene_manager, NfcSceneCardMenu, SubmenuIndexChooseScript); - scene_manager_next_scene(nfc->scene_manager, NfcSceneScriptsMenu); - consumed = true; - } else if(event.event == SubmenuIndexEmulate) { - scene_manager_set_scene_state( - nfc->scene_manager, NfcSceneCardMenu, SubmenuIndexEmulate); - scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateUid); - consumed = true; - } else if(event.event == SubmenuIndexSave) { - scene_manager_set_scene_state(nfc->scene_manager, NfcSceneCardMenu, SubmenuIndexSave); - nfc->dev->format = NfcDeviceSaveFormatUid; - scene_manager_next_scene(nfc->scene_manager, NfcSceneSaveName); - consumed = true; - } - } else if(event.type == SceneManagerEventTypeBack) { - consumed = - scene_manager_search_and_switch_to_previous_scene(nfc->scene_manager, NfcSceneStart); - } - - return consumed; -} - -void nfc_scene_card_menu_on_exit(void* context) { - Nfc* nfc = context; - - submenu_reset(nfc->submenu); -} diff --git a/applications/nfc/scenes/nfc_scene_config.h b/applications/nfc/scenes/nfc_scene_config.h index ffd757de..6e2369fd 100755 --- a/applications/nfc/scenes/nfc_scene_config.h +++ b/applications/nfc/scenes/nfc_scene_config.h @@ -1,41 +1,40 @@ ADD_SCENE(nfc, start, Start) -ADD_SCENE(nfc, read_card, ReadCard) -ADD_SCENE(nfc, read_card_success, ReadCardSuccess) -ADD_SCENE(nfc, card_menu, CardMenu) -ADD_SCENE(nfc, emulate_uid, EmulateUid) -ADD_SCENE(nfc, save_name, SaveName) -ADD_SCENE(nfc, save_success, SaveSuccess) -ADD_SCENE(nfc, file_select, FileSelect) +ADD_SCENE(nfc, read, Read) ADD_SCENE(nfc, saved_menu, SavedMenu) +ADD_SCENE(nfc, extra_actions, ExtraActions) ADD_SCENE(nfc, set_type, SetType) ADD_SCENE(nfc, set_sak, SetSak) ADD_SCENE(nfc, set_atqa, SetAtqua) ADD_SCENE(nfc, set_uid, SetUid) -ADD_SCENE(nfc, scripts_menu, ScriptsMenu) -ADD_SCENE(nfc, read_mifare_ul, ReadMifareUl) -ADD_SCENE(nfc, read_mifare_ul_success, ReadMifareUlSuccess) -ADD_SCENE(nfc, mifare_ul_menu, MifareUlMenu) -ADD_SCENE(nfc, emulate_mifare_ul, EmulateMifareUl) -ADD_SCENE(nfc, read_emv_app, ReadEmvApp) -ADD_SCENE(nfc, read_emv_app_success, ReadEmvAppSuccess) -ADD_SCENE(nfc, read_mifare_desfire, ReadMifareDesfire) -ADD_SCENE(nfc, read_mifare_desfire_success, ReadMifareDesfireSuccess) -ADD_SCENE(nfc, mifare_desfire_menu, MifareDesfireMenu) -ADD_SCENE(nfc, mifare_desfire_data, MifareDesfireData) -ADD_SCENE(nfc, mifare_desfire_app, MifareDesfireApp) +ADD_SCENE(nfc, generate_info, GenerateInfo) +ADD_SCENE(nfc, read_card_success, ReadCardSuccess) +ADD_SCENE(nfc, save_name, SaveName) +ADD_SCENE(nfc, save_success, SaveSuccess) +ADD_SCENE(nfc, file_select, FileSelect) +ADD_SCENE(nfc, emulate_uid, EmulateUid) +ADD_SCENE(nfc, mf_ultralight_read_success, MfUltralightReadSuccess) +ADD_SCENE(nfc, mf_ultralight_menu, MfUltralightMenu) +ADD_SCENE(nfc, mf_ultralight_emulate, MfUltralightEmulate) +ADD_SCENE(nfc, mf_desfire_read_success, MfDesfireReadSuccess) +ADD_SCENE(nfc, mf_desfire_menu, MfDesfireMenu) +ADD_SCENE(nfc, mf_desfire_data, MfDesfireData) +ADD_SCENE(nfc, mf_desfire_app, MfDesfireApp) +ADD_SCENE(nfc, mf_classic_read_success, MfClassicReadSuccess) +ADD_SCENE(nfc, mf_classic_menu, MfClassicMenu) +ADD_SCENE(nfc, mf_classic_emulate, MfClassicEmulate) +ADD_SCENE(nfc, mf_classic_keys, MfClassicKeys) +ADD_SCENE(nfc, mf_classic_keys_add, MfClassicKeysAdd) +ADD_SCENE(nfc, mf_classic_dict_attack, MfClassicDictAttack) +ADD_SCENE(nfc, emv_read_success, EmvReadSuccess) +ADD_SCENE(nfc, emulate_apdu_sequence, EmulateApduSequence) ADD_SCENE(nfc, device_info, DeviceInfo) ADD_SCENE(nfc, delete, Delete) ADD_SCENE(nfc, delete_success, DeleteSuccess) -ADD_SCENE(nfc, run_emv_app_confirm, RunEmvAppConfirm) -ADD_SCENE(nfc, read_emv_data, ReadEmvData) -ADD_SCENE(nfc, read_emv_data_success, ReadEmvDataSuccess) -ADD_SCENE(nfc, emulate_apdu_sequence, EmulateApduSequence) ADD_SCENE(nfc, restore_original, RestoreOriginal) ADD_SCENE(nfc, debug, Debug) ADD_SCENE(nfc, field, Field) -ADD_SCENE(nfc, read_mifare_classic, ReadMifareClassic) -ADD_SCENE(nfc, emulate_mifare_classic, EmulateMifareClassic) -ADD_SCENE(nfc, mifare_classic_menu, MifareClassicMenu) ADD_SCENE(nfc, dict_not_found, DictNotFound) ADD_SCENE(nfc, rpc, Rpc) -ADD_SCENE(nfc, generate_info, GenerateInfo) +ADD_SCENE(nfc, exit_confirm, ExitConfirm) +ADD_SCENE(nfc, retry_confirm, RetryConfirm) +ADD_SCENE(nfc, detect_reader, DetectReader) diff --git a/applications/nfc/scenes/nfc_scene_detect_reader.c b/applications/nfc/scenes/nfc_scene_detect_reader.c new file mode 100644 index 00000000..4639735d --- /dev/null +++ b/applications/nfc/scenes/nfc_scene_detect_reader.c @@ -0,0 +1,143 @@ +#include "../nfc_i.h" +#include + +#define NFC_SCENE_DETECT_READER_LOG_SIZE_MAX (200) + +enum { + NfcSceneDetectReaderStateWidget, + NfcSceneDetectReaderStateTextBox, +}; + +bool nfc_detect_reader_worker_callback(NfcWorkerEvent event, void* context) { + UNUSED(event); + furi_assert(context); + Nfc* nfc = context; + view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventWorkerExit); + return true; +} + +void nfc_scene_detect_reader_widget_callback(GuiButtonType result, InputType type, void* context) { + furi_assert(context); + Nfc* nfc = context; + if(type == InputTypeShort) { + view_dispatcher_send_custom_event(nfc->view_dispatcher, result); + } +} + +void nfc_detect_reader_textbox_callback(void* context) { + furi_assert(context); + Nfc* nfc = context; + view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventViewExit); +} + +// Add widget with device name or inform that data received +static void nfc_scene_detect_reader_widget_config(Nfc* nfc, bool data_received) { + Widget* widget = nfc->widget; + widget_reset(widget); + + widget_add_icon_element(widget, 0, 14, &I_Reader_detect); + widget_add_string_element( + widget, 64, 3, AlignCenter, AlignTop, FontSecondary, "Hold near reader"); + widget_add_string_element(widget, 55, 22, AlignLeft, AlignTop, FontPrimary, "Emulating..."); + + if(data_received) { + widget_add_button_element( + widget, GuiButtonTypeCenter, "Log", nfc_scene_detect_reader_widget_callback, nfc); + } +} + +void nfc_scene_detect_reader_on_enter(void* context) { + Nfc* nfc = context; + DOLPHIN_DEED(DolphinDeedNfcEmulate); + FuriHalNfcDevData nfc_params = { + .uid = {0x36, 0x9C, 0xe7, 0xb1, 0x0A, 0xC1, 0x34}, + .uid_len = 7, + .atqa = {0x44, 0x00}, + .sak = 0x08, + .type = FuriHalNfcTypeA, + }; + nfc->dev->dev_data.nfc_data = nfc_params; + + // Setup Widget + nfc_scene_detect_reader_widget_config(nfc, false); + // Setup TextBox + TextBox* text_box = nfc->text_box; + text_box_set_font(text_box, TextBoxFontHex); + text_box_set_focus(text_box, TextBoxFocusEnd); + string_reset(nfc->text_box_store); + + // Set Widget state and view + scene_manager_set_scene_state( + nfc->scene_manager, NfcSceneDetectReader, NfcSceneDetectReaderStateWidget); + view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewWidget); + // Start worker + memset(&nfc->dev->dev_data.reader_data, 0, sizeof(NfcReaderRequestData)); + nfc_worker_start( + nfc->worker, + NfcWorkerStateUidEmulate, + &nfc->dev->dev_data, + nfc_detect_reader_worker_callback, + nfc); + + nfc_blink_start(nfc); +} + +bool nfc_scene_detect_reader_on_event(void* context, SceneManagerEvent event) { + Nfc* nfc = context; + NfcReaderRequestData* reader_data = &nfc->dev->dev_data.reader_data; + uint32_t state = scene_manager_get_scene_state(nfc->scene_manager, NfcSceneDetectReader); + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == NfcCustomEventWorkerExit) { + // Add data button to widget if data is received for the first time + if(!string_size(nfc->text_box_store)) { + nfc_scene_detect_reader_widget_config(nfc, true); + } + // Update TextBox data + if(string_size(nfc->text_box_store) < NFC_SCENE_DETECT_READER_LOG_SIZE_MAX) { + string_cat_printf(nfc->text_box_store, "R:"); + for(uint16_t i = 0; i < reader_data->size; i++) { + string_cat_printf(nfc->text_box_store, " %02X", reader_data->data[i]); + } + string_push_back(nfc->text_box_store, '\n'); + text_box_set_text(nfc->text_box, string_get_cstr(nfc->text_box_store)); + } + memset(reader_data, 0, sizeof(NfcReaderRequestData)); + consumed = true; + } else if(event.event == GuiButtonTypeCenter && state == NfcSceneDetectReaderStateWidget) { + view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewTextBox); + scene_manager_set_scene_state( + nfc->scene_manager, NfcSceneDetectReader, NfcSceneDetectReaderStateTextBox); + consumed = true; + } else if(event.event == NfcCustomEventViewExit && state == NfcSceneDetectReaderStateTextBox) { + view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewWidget); + scene_manager_set_scene_state( + nfc->scene_manager, NfcSceneDetectReader, NfcSceneDetectReaderStateWidget); + consumed = true; + } + } else if(event.type == SceneManagerEventTypeBack) { + if(state == NfcSceneDetectReaderStateTextBox) { + view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewWidget); + scene_manager_set_scene_state( + nfc->scene_manager, NfcSceneDetectReader, NfcSceneDetectReaderStateWidget); + consumed = true; + } + } + + return consumed; +} + +void nfc_scene_detect_reader_on_exit(void* context) { + Nfc* nfc = context; + + // Stop worker + nfc_worker_stop(nfc->worker); + + // Clear view + widget_reset(nfc->widget); + text_box_reset(nfc->text_box); + string_reset(nfc->text_box_store); + + nfc_blink_stop(nfc); +} diff --git a/applications/nfc/scenes/nfc_scene_device_info.c b/applications/nfc/scenes/nfc_scene_device_info.c index 03464c66..b79c5104 100644 --- a/applications/nfc/scenes/nfc_scene_device_info.c +++ b/applications/nfc/scenes/nfc_scene_device_info.c @@ -190,7 +190,7 @@ bool nfc_scene_device_info_on_event(void* context, SceneManagerEvent event) { view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewBankCard); consumed = true; } else if(nfc->dev->format == NfcDeviceSaveFormatMifareDesfire) { - scene_manager_next_scene(nfc->scene_manager, NfcSceneMifareDesfireData); + scene_manager_next_scene(nfc->scene_manager, NfcSceneMfDesfireData); consumed = true; } } else if(state == NfcSceneDeviceInfoData && event.event == NfcCustomEventViewExit) { diff --git a/applications/nfc/scenes/nfc_scene_dict_not_found.c b/applications/nfc/scenes/nfc_scene_dict_not_found.c index 19db68d8..dc21b08b 100644 --- a/applications/nfc/scenes/nfc_scene_dict_not_found.c +++ b/applications/nfc/scenes/nfc_scene_dict_not_found.c @@ -31,12 +31,9 @@ bool nfc_scene_dict_not_found_on_event(void* context, SceneManagerEvent event) { if(event.type == SceneManagerEventTypeCustom) { if(event.event == NfcCustomEventViewExit) { - if(scene_manager_has_previous_scene(nfc->scene_manager, NfcSceneScriptsMenu)) { + if(scene_manager_has_previous_scene(nfc->scene_manager, NfcSceneExtraActions)) { consumed = scene_manager_search_and_switch_to_previous_scene( - nfc->scene_manager, NfcSceneScriptsMenu); - } else if(scene_manager_has_previous_scene(nfc->scene_manager, NfcSceneCardMenu)) { - consumed = scene_manager_search_and_switch_to_previous_scene( - nfc->scene_manager, NfcSceneCardMenu); + nfc->scene_manager, NfcSceneExtraActions); } else { consumed = scene_manager_search_and_switch_to_previous_scene( nfc->scene_manager, NfcSceneStart); diff --git a/applications/nfc/scenes/nfc_scene_emulate_uid.c b/applications/nfc/scenes/nfc_scene_emulate_uid.c index 3fabf495..0d92c9f0 100755 --- a/applications/nfc/scenes/nfc_scene_emulate_uid.c +++ b/applications/nfc/scenes/nfc_scene_emulate_uid.c @@ -8,11 +8,12 @@ enum { NfcSceneEmulateUidStateTextBox, }; -void nfc_emulate_uid_worker_callback(NfcWorkerEvent event, void* context) { +bool nfc_emulate_uid_worker_callback(NfcWorkerEvent event, void* context) { UNUSED(event); furi_assert(context); Nfc* nfc = context; view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventWorkerExit); + return true; } void nfc_scene_emulate_uid_widget_callback(GuiButtonType result, InputType type, void* context) { @@ -76,7 +77,7 @@ void nfc_scene_emulate_uid_on_enter(void* context) { memset(&nfc->dev->dev_data.reader_data, 0, sizeof(NfcReaderRequestData)); nfc_worker_start( nfc->worker, - NfcWorkerStateEmulate, + NfcWorkerStateUidEmulate, &nfc->dev->dev_data, nfc_emulate_uid_worker_callback, nfc); @@ -90,9 +91,7 @@ bool nfc_scene_emulate_uid_on_event(void* context, SceneManagerEvent event) { uint32_t state = scene_manager_get_scene_state(nfc->scene_manager, NfcSceneEmulateUid); bool consumed = false; - if(event.type == SceneManagerEventTypeTick) { - consumed = true; - } else if(event.type == SceneManagerEventTypeCustom) { + if(event.type == SceneManagerEventTypeCustom) { if(event.event == NfcCustomEventWorkerExit) { // Add data button to widget if data is received for the first time if(!string_size(nfc->text_box_store)) { diff --git a/applications/nfc/scenes/nfc_scene_read_emv_data_success.c b/applications/nfc/scenes/nfc_scene_emv_read_success.c old mode 100755 new mode 100644 similarity index 78% rename from applications/nfc/scenes/nfc_scene_read_emv_data_success.c rename to applications/nfc/scenes/nfc_scene_emv_read_success.c index 4b3be9e1..eefe560e --- a/applications/nfc/scenes/nfc_scene_read_emv_data_success.c +++ b/applications/nfc/scenes/nfc_scene_emv_read_success.c @@ -2,7 +2,7 @@ #include "../helpers/nfc_emv_parser.h" #include -void nfc_scene_read_emv_data_success_widget_callback( +void nfc_scene_emv_read_success_widget_callback( GuiButtonType result, InputType type, void* context) { @@ -12,7 +12,7 @@ void nfc_scene_read_emv_data_success_widget_callback( } } -void nfc_scene_read_emv_data_success_on_enter(void* context) { +void nfc_scene_emv_read_success_on_enter(void* context) { Nfc* nfc = context; EmvData* emv_data = &nfc->dev->dev_data.emv_data; FuriHalNfcDevData* nfc_data = &nfc->dev->dev_data.nfc_data; @@ -23,17 +23,9 @@ void nfc_scene_read_emv_data_success_on_enter(void* context) { widget_add_frame_element(nfc->widget, 0, 0, 128, 64, 6); // Add buttons widget_add_button_element( - nfc->widget, - GuiButtonTypeLeft, - "Back", - nfc_scene_read_emv_data_success_widget_callback, - nfc); + nfc->widget, GuiButtonTypeLeft, "Retry", nfc_scene_emv_read_success_widget_callback, nfc); widget_add_button_element( - nfc->widget, - GuiButtonTypeRight, - "Save", - nfc_scene_read_emv_data_success_widget_callback, - nfc); + nfc->widget, GuiButtonTypeRight, "Save", nfc_scene_emv_read_success_widget_callback, nfc); // Add card name widget_add_string_element( nfc->widget, 64, 3, AlignCenter, AlignTop, FontSecondary, nfc->dev->dev_data.emv_data.name); @@ -103,25 +95,17 @@ void nfc_scene_read_emv_data_success_on_enter(void* context) { widget_add_string_element(nfc->widget, 7, 32, AlignLeft, AlignTop, FontSecondary, exp_str); } - // Send notification - if(scene_manager_get_scene_state(nfc->scene_manager, NfcSceneReadEmvDataSuccess) == - NFC_SEND_NOTIFICATION_TRUE) { - notification_message(nfc->notifications, &sequence_success); - scene_manager_set_scene_state( - nfc->scene_manager, NfcSceneReadEmvDataSuccess, NFC_SEND_NOTIFICATION_FALSE); - } - view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewWidget); } -bool nfc_scene_read_emv_data_success_on_event(void* context, SceneManagerEvent event) { +bool nfc_scene_emv_read_success_on_event(void* context, SceneManagerEvent event) { Nfc* nfc = context; bool consumed = false; if(event.type == SceneManagerEventTypeCustom) { if(event.event == GuiButtonTypeLeft) { - consumed = scene_manager_search_and_switch_to_previous_scene( - nfc->scene_manager, NfcSceneReadEmvAppSuccess); + scene_manager_next_scene(nfc->scene_manager, NfcSceneRetryConfirm); + consumed = true; } else if(event.event == GuiButtonTypeRight) { // Clear device name nfc_device_set_name(nfc->dev, ""); @@ -130,13 +114,13 @@ bool nfc_scene_read_emv_data_success_on_event(void* context, SceneManagerEvent e consumed = true; } } else if(event.type == SceneManagerEventTypeBack) { - consumed = scene_manager_search_and_switch_to_previous_scene( - nfc->scene_manager, NfcSceneReadEmvAppSuccess); + scene_manager_next_scene(nfc->scene_manager, NfcSceneExitConfirm); + consumed = true; } return consumed; } -void nfc_scene_read_emv_data_success_on_exit(void* context) { +void nfc_scene_emv_read_success_on_exit(void* context) { Nfc* nfc = context; // Clear view diff --git a/applications/nfc/scenes/nfc_scene_exit_confirm.c b/applications/nfc/scenes/nfc_scene_exit_confirm.c new file mode 100644 index 00000000..24942bcd --- /dev/null +++ b/applications/nfc/scenes/nfc_scene_exit_confirm.c @@ -0,0 +1,47 @@ +#include "../nfc_i.h" + +void nfc_scene_exit_confirm_dialog_callback(DialogExResult result, void* context) { + Nfc* nfc = context; + + view_dispatcher_send_custom_event(nfc->view_dispatcher, result); +} + +void nfc_scene_exit_confirm_on_enter(void* context) { + Nfc* nfc = context; + DialogEx* dialog_ex = nfc->dialog_ex; + + dialog_ex_set_left_button_text(dialog_ex, "Exit"); + dialog_ex_set_right_button_text(dialog_ex, "Stay"); + dialog_ex_set_header(dialog_ex, "Exit to NFC menu?", 64, 11, AlignCenter, AlignTop); + dialog_ex_set_text( + dialog_ex, "All unsaved data\nwill be lost.", 64, 25, AlignCenter, AlignTop); + dialog_ex_set_context(dialog_ex, nfc); + dialog_ex_set_result_callback(dialog_ex, nfc_scene_exit_confirm_dialog_callback); + + view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewDialogEx); +} + +bool nfc_scene_exit_confirm_on_event(void* context, SceneManagerEvent event) { + Nfc* nfc = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == DialogExResultRight) { + consumed = scene_manager_previous_scene(nfc->scene_manager); + } else if(event.event == DialogExResultLeft) { + consumed = scene_manager_search_and_switch_to_previous_scene( + nfc->scene_manager, NfcSceneStart); + } + } else if(event.type == SceneManagerEventTypeBack) { + consumed = true; + } + + return consumed; +} + +void nfc_scene_exit_confirm_on_exit(void* context) { + Nfc* nfc = context; + + // Clean view + dialog_ex_reset(nfc->dialog_ex); +} diff --git a/applications/nfc/scenes/nfc_scene_extra_actions.c b/applications/nfc/scenes/nfc_scene_extra_actions.c new file mode 100644 index 00000000..823a4ace --- /dev/null +++ b/applications/nfc/scenes/nfc_scene_extra_actions.c @@ -0,0 +1,48 @@ +#include "../nfc_i.h" + +enum SubmenuIndex { + SubmenuIndexMfClassicKeys, +}; + +void nfc_scene_extra_actions_submenu_callback(void* context, uint32_t index) { + Nfc* nfc = context; + + view_dispatcher_send_custom_event(nfc->view_dispatcher, index); +} + +void nfc_scene_extra_actions_on_enter(void* context) { + Nfc* nfc = context; + Submenu* submenu = nfc->submenu; + + submenu_add_item( + submenu, + "Mf Classic Keys", + SubmenuIndexMfClassicKeys, + nfc_scene_extra_actions_submenu_callback, + nfc); + view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewMenu); +} + +bool nfc_scene_extra_actions_on_event(void* context, SceneManagerEvent event) { + Nfc* nfc = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == SubmenuIndexMfClassicKeys) { + if(mf_classic_dict_check_presence(MfClassicDictTypeFlipper)) { + scene_manager_next_scene(nfc->scene_manager, NfcSceneMfClassicKeys); + } else { + scene_manager_next_scene(nfc->scene_manager, NfcSceneDictNotFound); + } + consumed = true; + } + scene_manager_set_scene_state(nfc->scene_manager, NfcSceneExtraActions, event.event); + } + return consumed; +} + +void nfc_scene_extra_actions_on_exit(void* context) { + Nfc* nfc = context; + + submenu_reset(nfc->submenu); +} diff --git a/applications/nfc/scenes/nfc_scene_mf_classic_dict_attack.c b/applications/nfc/scenes/nfc_scene_mf_classic_dict_attack.c new file mode 100644 index 00000000..0736f0f1 --- /dev/null +++ b/applications/nfc/scenes/nfc_scene_mf_classic_dict_attack.c @@ -0,0 +1,137 @@ +#include "../nfc_i.h" + +typedef enum { + DictAttackStateIdle, + DictAttackStateUserDictInProgress, + DictAttackStateFlipperDictInProgress, +} DictAttackState; + +bool nfc_dict_attack_worker_callback(NfcWorkerEvent event, void* context) { + furi_assert(context); + Nfc* nfc = context; + view_dispatcher_send_custom_event(nfc->view_dispatcher, event); + return true; +} + +void nfc_dict_attack_dict_attack_result_callback(void* context) { + furi_assert(context); + Nfc* nfc = context; + view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventDictAttackSkip); +} + +static void nfc_scene_mf_classic_dict_attack_update_view(Nfc* nfc) { + MfClassicData* data = &nfc->dev->dev_data.mf_classic_data; + uint8_t sectors_read = 0; + uint8_t keys_found = 0; + + // Calculate found keys and read sectors + mf_classic_get_read_sectors_and_keys(data, §ors_read, &keys_found); + dict_attack_set_keys_found(nfc->dict_attack, keys_found); + dict_attack_set_sector_read(nfc->dict_attack, sectors_read); +} + +static void nfc_scene_mf_classic_dict_attack_prepare_view(Nfc* nfc, DictAttackState state) { + MfClassicData* data = &nfc->dev->dev_data.mf_classic_data; + NfcWorkerState worker_state = NfcWorkerStateReady; + + // Identify scene state + if(state == DictAttackStateIdle) { + if(mf_classic_dict_check_presence(MfClassicDictTypeUser)) { + state = DictAttackStateUserDictInProgress; + } else { + state = DictAttackStateFlipperDictInProgress; + } + } else if(state == DictAttackStateUserDictInProgress) { + state = DictAttackStateFlipperDictInProgress; + } + + // Setup view + if(state == DictAttackStateUserDictInProgress) { + worker_state = NfcWorkerStateMfClassicUserDictAttack; + dict_attack_set_header(nfc->dict_attack, "Mf Classic User Dict."); + } else if(state == DictAttackStateFlipperDictInProgress) { + worker_state = NfcWorkerStateMfClassicFlipperDictAttack; + dict_attack_set_header(nfc->dict_attack, "Mf Classic Flipper Dict."); + } + scene_manager_set_scene_state(nfc->scene_manager, NfcSceneMfClassicDictAttack, state); + dict_attack_set_callback(nfc->dict_attack, nfc_dict_attack_dict_attack_result_callback, nfc); + dict_attack_set_current_sector(nfc->dict_attack, 0); + dict_attack_set_card_detected(nfc->dict_attack, data->type); + nfc_scene_mf_classic_dict_attack_update_view(nfc); + nfc_worker_start( + nfc->worker, worker_state, &nfc->dev->dev_data, nfc_dict_attack_worker_callback, nfc); +} + +void nfc_scene_mf_classic_dict_attack_on_enter(void* context) { + Nfc* nfc = context; + nfc_scene_mf_classic_dict_attack_prepare_view(nfc, DictAttackStateIdle); + view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewDictAttack); + nfc_blink_start(nfc); +} + +bool nfc_scene_mf_classic_dict_attack_on_event(void* context, SceneManagerEvent event) { + Nfc* nfc = context; + MfClassicData* data = &nfc->dev->dev_data.mf_classic_data; + bool consumed = false; + + uint32_t state = + scene_manager_get_scene_state(nfc->scene_manager, NfcSceneMfClassicDictAttack); + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == NfcWorkerEventSuccess) { + if(state == DictAttackStateUserDictInProgress) { + nfc_worker_stop(nfc->worker); + nfc_scene_mf_classic_dict_attack_prepare_view(nfc, state); + consumed = true; + } else { + notification_message(nfc->notifications, &sequence_success); + scene_manager_next_scene(nfc->scene_manager, NfcSceneMfClassicReadSuccess); + consumed = true; + } + } else if(event.event == NfcWorkerEventAborted) { + if(state == DictAttackStateUserDictInProgress) { + nfc_scene_mf_classic_dict_attack_prepare_view(nfc, state); + consumed = true; + } else { + notification_message(nfc->notifications, &sequence_success); + scene_manager_next_scene(nfc->scene_manager, NfcSceneMfClassicReadSuccess); + consumed = true; + } + } else if(event.event == NfcWorkerEventCardDetected) { + dict_attack_set_card_detected(nfc->dict_attack, data->type); + consumed = true; + } else if(event.event == NfcWorkerEventNoCardDetected) { + dict_attack_set_card_removed(nfc->dict_attack); + consumed = true; + } else if(event.event == NfcWorkerEventFoundKeyA) { + dict_attack_inc_keys_found(nfc->dict_attack); + consumed = true; + } else if(event.event == NfcWorkerEventFoundKeyB) { + dict_attack_inc_keys_found(nfc->dict_attack); + consumed = true; + } else if(event.event == NfcWorkerEventNewSector) { + nfc_scene_mf_classic_dict_attack_update_view(nfc); + dict_attack_inc_current_sector(nfc->dict_attack); + consumed = true; + } else if(event.event == NfcCustomEventDictAttackSkip) { + if(state == DictAttackStateUserDictInProgress) { + nfc_worker_stop(nfc->worker); + consumed = true; + } else if(state == DictAttackStateFlipperDictInProgress) { + nfc_worker_stop(nfc->worker); + consumed = true; + } + } + } else if(event.type == SceneManagerEventTypeBack) { + scene_manager_next_scene(nfc->scene_manager, NfcSceneExitConfirm); + consumed = true; + } + return consumed; +} + +void nfc_scene_mf_classic_dict_attack_on_exit(void* context) { + Nfc* nfc = context; + // Stop worker + nfc_worker_stop(nfc->worker); + dict_attack_reset(nfc->dict_attack); + nfc_blink_stop(nfc); +} diff --git a/applications/nfc/scenes/nfc_scene_emulate_mifare_classic.c b/applications/nfc/scenes/nfc_scene_mf_classic_emulate.c similarity index 57% rename from applications/nfc/scenes/nfc_scene_emulate_mifare_classic.c rename to applications/nfc/scenes/nfc_scene_mf_classic_emulate.c index 97e86545..044388b8 100644 --- a/applications/nfc/scenes/nfc_scene_emulate_mifare_classic.c +++ b/applications/nfc/scenes/nfc_scene_mf_classic_emulate.c @@ -4,51 +4,52 @@ #define NFC_MF_CLASSIC_DATA_NOT_CHANGED (0UL) #define NFC_MF_CLASSIC_DATA_CHANGED (1UL) -void nfc_emulate_mifare_classic_worker_callback(NfcWorkerEvent event, void* context) { +bool nfc_mf_classic_emulate_worker_callback(NfcWorkerEvent event, void* context) { UNUSED(event); Nfc* nfc = context; scene_manager_set_scene_state( - nfc->scene_manager, NfcSceneEmulateMifareClassic, NFC_MF_CLASSIC_DATA_CHANGED); + nfc->scene_manager, NfcSceneMfClassicEmulate, NFC_MF_CLASSIC_DATA_CHANGED); + return true; } -void nfc_scene_emulate_mifare_classic_on_enter(void* context) { +void nfc_scene_mf_classic_emulate_on_enter(void* context) { Nfc* nfc = context; DOLPHIN_DEED(DolphinDeedNfcEmulate); // Setup view Popup* popup = nfc->popup; if(strcmp(nfc->dev->dev_name, "")) { - nfc_text_store_set(nfc, "%s", nfc->dev->dev_name); + nfc_text_store_set(nfc, "Emulating\n%s", nfc->dev->dev_name); + } else { + nfc_text_store_set(nfc, "Emulating\nMf Classic", nfc->dev->dev_name); } popup_set_icon(popup, 0, 3, &I_RFIDDolphinSend_97x61); - popup_set_header(popup, "Emulating\nMf Classic", 56, 31, AlignLeft, AlignTop); + popup_set_header(popup, nfc->text_store, 56, 31, AlignLeft, AlignTop); // Setup and start worker view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup); nfc_worker_start( nfc->worker, - NfcWorkerStateEmulateMifareClassic, + NfcWorkerStateMfClassicEmulate, &nfc->dev->dev_data, - nfc_emulate_mifare_classic_worker_callback, + nfc_mf_classic_emulate_worker_callback, nfc); nfc_blink_start(nfc); } -bool nfc_scene_emulate_mifare_classic_on_event(void* context, SceneManagerEvent event) { +bool nfc_scene_mf_classic_emulate_on_event(void* context, SceneManagerEvent event) { Nfc* nfc = context; bool consumed = false; - if(event.type == SceneManagerEventTypeTick) { - consumed = true; - } else if(event.type == SceneManagerEventTypeBack) { + if(event.type == SceneManagerEventTypeBack) { // Stop worker nfc_worker_stop(nfc->worker); // Check if data changed and save in shadow file - if(scene_manager_get_scene_state(nfc->scene_manager, NfcSceneEmulateMifareClassic) == + if(scene_manager_get_scene_state(nfc->scene_manager, NfcSceneMfClassicEmulate) == NFC_MF_CLASSIC_DATA_CHANGED) { scene_manager_set_scene_state( - nfc->scene_manager, NfcSceneEmulateMifareClassic, NFC_MF_CLASSIC_DATA_NOT_CHANGED); + nfc->scene_manager, NfcSceneMfClassicEmulate, NFC_MF_CLASSIC_DATA_NOT_CHANGED); nfc_device_save_shadow(nfc->dev, nfc->dev->dev_name); } consumed = false; @@ -56,7 +57,7 @@ bool nfc_scene_emulate_mifare_classic_on_event(void* context, SceneManagerEvent return consumed; } -void nfc_scene_emulate_mifare_classic_on_exit(void* context) { +void nfc_scene_mf_classic_emulate_on_exit(void* context) { Nfc* nfc = context; // Clear view diff --git a/applications/nfc/scenes/nfc_scene_mf_classic_keys.c b/applications/nfc/scenes/nfc_scene_mf_classic_keys.c new file mode 100644 index 00000000..0faa7367 --- /dev/null +++ b/applications/nfc/scenes/nfc_scene_mf_classic_keys.c @@ -0,0 +1,59 @@ +#include "../nfc_i.h" + +void nfc_scene_mf_classic_keys_widget_callback(GuiButtonType result, InputType type, void* context) { + Nfc* nfc = context; + if(type == InputTypeShort) { + view_dispatcher_send_custom_event(nfc->view_dispatcher, result); + } +} + +void nfc_scene_mf_classic_keys_on_enter(void* context) { + Nfc* nfc = context; + + // Load flipper dict keys total + uint32_t flipper_dict_keys_total = 0; + MfClassicDict* dict = mf_classic_dict_alloc(MfClassicDictTypeFlipper); + if(dict) { + flipper_dict_keys_total = mf_classic_dict_get_total_keys(dict); + mf_classic_dict_free(dict); + } + // Load user dict keys total + uint32_t user_dict_keys_total = 0; + dict = mf_classic_dict_alloc(MfClassicDictTypeUser); + if(dict) { + user_dict_keys_total = mf_classic_dict_get_total_keys(dict); + mf_classic_dict_free(dict); + } + + widget_add_string_element( + nfc->widget, 0, 0, AlignLeft, AlignTop, FontPrimary, "MF Classic Keys"); + char temp_str[32]; + snprintf(temp_str, sizeof(temp_str), "Flipper dict: %ld", flipper_dict_keys_total); + widget_add_string_element(nfc->widget, 0, 20, AlignLeft, AlignTop, FontSecondary, temp_str); + snprintf(temp_str, sizeof(temp_str), "User dict: %ld", user_dict_keys_total); + widget_add_string_element(nfc->widget, 0, 32, AlignLeft, AlignTop, FontSecondary, temp_str); + widget_add_button_element( + nfc->widget, GuiButtonTypeCenter, "Add", nfc_scene_mf_classic_keys_widget_callback, nfc); + + view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewWidget); +} + +bool nfc_scene_mf_classic_keys_on_event(void* context, SceneManagerEvent event) { + Nfc* nfc = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == GuiButtonTypeCenter) { + scene_manager_next_scene(nfc->scene_manager, NfcSceneMfClassicKeysAdd); + consumed = true; + } + } + + return consumed; +} + +void nfc_scene_mf_classic_keys_on_exit(void* context) { + Nfc* nfc = context; + + widget_reset(nfc->widget); +} diff --git a/applications/nfc/scenes/nfc_scene_mf_classic_keys_add.c b/applications/nfc/scenes/nfc_scene_mf_classic_keys_add.c new file mode 100644 index 00000000..9f56b0f4 --- /dev/null +++ b/applications/nfc/scenes/nfc_scene_mf_classic_keys_add.c @@ -0,0 +1,57 @@ +#include "../nfc_i.h" + +void nfc_scene_mf_classic_keys_add_byte_input_callback(void* context) { + Nfc* nfc = context; + + view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventByteInputDone); +} + +void nfc_scene_mf_classic_keys_add_on_enter(void* context) { + Nfc* nfc = context; + + // Setup view + ByteInput* byte_input = nfc->byte_input; + byte_input_set_header_text(byte_input, "Enter the key in hex"); + byte_input_set_result_callback( + byte_input, + nfc_scene_mf_classic_keys_add_byte_input_callback, + NULL, + nfc, + nfc->byte_input_store, + 6); + view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewByteInput); +} + +bool nfc_scene_mf_classic_keys_add_on_event(void* context, SceneManagerEvent event) { + Nfc* nfc = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == NfcCustomEventByteInputDone) { + // Add key to dict + bool key_added = false; + MfClassicDict* dict = mf_classic_dict_alloc(MfClassicDictTypeUser); + if(dict) { + if(mf_classic_dict_add_key(dict, nfc->byte_input_store)) { + key_added = true; + } + } + if(key_added) { + scene_manager_next_scene(nfc->scene_manager, NfcSceneSaveSuccess); + } else { + scene_manager_next_scene(nfc->scene_manager, NfcSceneDictNotFound); + } + mf_classic_dict_free(dict); + consumed = true; + } + } + return consumed; +} + +void nfc_scene_mf_classic_keys_add_on_exit(void* context) { + Nfc* nfc = context; + + // Clear view + byte_input_set_result_callback(nfc->byte_input, NULL, NULL, NULL, NULL, 0); + byte_input_set_header_text(nfc->byte_input, ""); +} diff --git a/applications/nfc/scenes/nfc_scene_mifare_ul_menu.c b/applications/nfc/scenes/nfc_scene_mf_classic_menu.c old mode 100755 new mode 100644 similarity index 64% rename from applications/nfc/scenes/nfc_scene_mifare_ul_menu.c rename to applications/nfc/scenes/nfc_scene_mf_classic_menu.c index 0099f1a0..4942292c --- a/applications/nfc/scenes/nfc_scene_mifare_ul_menu.c +++ b/applications/nfc/scenes/nfc_scene_mf_classic_menu.c @@ -5,43 +5,43 @@ enum SubmenuIndex { SubmenuIndexEmulate, }; -void nfc_scene_mifare_ul_menu_submenu_callback(void* context, uint32_t index) { +void nfc_scene_mf_classic_menu_submenu_callback(void* context, uint32_t index) { Nfc* nfc = context; view_dispatcher_send_custom_event(nfc->view_dispatcher, index); } -void nfc_scene_mifare_ul_menu_on_enter(void* context) { +void nfc_scene_mf_classic_menu_on_enter(void* context) { Nfc* nfc = context; Submenu* submenu = nfc->submenu; submenu_add_item( - submenu, "Save", SubmenuIndexSave, nfc_scene_mifare_ul_menu_submenu_callback, nfc); + submenu, "Save", SubmenuIndexSave, nfc_scene_mf_classic_menu_submenu_callback, nfc); submenu_add_item( - submenu, "Emulate", SubmenuIndexEmulate, nfc_scene_mifare_ul_menu_submenu_callback, nfc); + submenu, "Emulate", SubmenuIndexEmulate, nfc_scene_mf_classic_menu_submenu_callback, nfc); submenu_set_selected_item( - nfc->submenu, scene_manager_get_scene_state(nfc->scene_manager, NfcSceneMifareUlMenu)); + nfc->submenu, scene_manager_get_scene_state(nfc->scene_manager, NfcSceneMfClassicMenu)); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewMenu); } -bool nfc_scene_mifare_ul_menu_on_event(void* context, SceneManagerEvent event) { +bool nfc_scene_mf_classic_menu_on_event(void* context, SceneManagerEvent event) { Nfc* nfc = context; bool consumed = false; if(event.type == SceneManagerEventTypeCustom) { if(event.event == SubmenuIndexSave) { scene_manager_set_scene_state( - nfc->scene_manager, NfcSceneMifareUlMenu, SubmenuIndexSave); - nfc->dev->format = NfcDeviceSaveFormatMifareUl; + nfc->scene_manager, NfcSceneMfClassicMenu, SubmenuIndexSave); + nfc->dev->format = NfcDeviceSaveFormatMifareClassic; // Clear device name nfc_device_set_name(nfc->dev, ""); scene_manager_next_scene(nfc->scene_manager, NfcSceneSaveName); consumed = true; } else if(event.event == SubmenuIndexEmulate) { scene_manager_set_scene_state( - nfc->scene_manager, NfcSceneMifareUlMenu, SubmenuIndexEmulate); - scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateMifareUl); + nfc->scene_manager, NfcSceneMfClassicMenu, SubmenuIndexEmulate); + scene_manager_next_scene(nfc->scene_manager, NfcSceneMfClassicEmulate); consumed = true; } } else if(event.type == SceneManagerEventTypeBack) { @@ -52,7 +52,7 @@ bool nfc_scene_mifare_ul_menu_on_event(void* context, SceneManagerEvent event) { return consumed; } -void nfc_scene_mifare_ul_menu_on_exit(void* context) { +void nfc_scene_mf_classic_menu_on_exit(void* context) { Nfc* nfc = context; // Clear view diff --git a/applications/nfc/scenes/nfc_scene_mf_classic_read_success.c b/applications/nfc/scenes/nfc_scene_mf_classic_read_success.c new file mode 100644 index 00000000..bd782305 --- /dev/null +++ b/applications/nfc/scenes/nfc_scene_mf_classic_read_success.c @@ -0,0 +1,104 @@ +#include "../nfc_i.h" +#include + +void nfc_scene_mf_classic_read_success_widget_callback( + GuiButtonType result, + InputType type, + void* context) { + furi_assert(context); + Nfc* nfc = context; + + if(type == InputTypeShort) { + view_dispatcher_send_custom_event(nfc->view_dispatcher, result); + } +} + +void nfc_scene_mf_classic_read_success_on_enter(void* context) { + Nfc* nfc = context; + NfcDeviceData* dev_data = &nfc->dev->dev_data; + MfClassicData* mf_data = &dev_data->mf_classic_data; + string_t str_tmp; + string_init(str_tmp); + + DOLPHIN_DEED(DolphinDeedNfcReadSuccess); + + // Setup view + Widget* widget = nfc->widget; + widget_add_button_element( + widget, GuiButtonTypeLeft, "Retry", nfc_scene_mf_classic_read_success_widget_callback, nfc); + widget_add_button_element( + widget, GuiButtonTypeRight, "More", nfc_scene_mf_classic_read_success_widget_callback, nfc); + + if(string_size(nfc->dev->dev_data.parsed_data)) { + widget_add_text_box_element( + nfc->widget, + 0, + 0, + 128, + 32, + AlignLeft, + AlignTop, + string_get_cstr(nfc->dev->dev_data.parsed_data), + true); + } else { + widget_add_string_element( + widget, + 0, + 0, + AlignLeft, + AlignTop, + FontSecondary, + mf_classic_get_type_str(mf_data->type)); + widget_add_string_element( + widget, 0, 11, AlignLeft, AlignTop, FontSecondary, "ISO 14443-3 (Type A)"); + string_printf(str_tmp, "UID:"); + for(size_t i = 0; i < dev_data->nfc_data.uid_len; i++) { + string_cat_printf(str_tmp, " %02X", dev_data->nfc_data.uid[i]); + } + widget_add_string_element( + widget, 0, 22, AlignLeft, AlignTop, FontSecondary, string_get_cstr(str_tmp)); + uint8_t sectors_total = mf_classic_get_total_sectors_num(mf_data->type); + uint8_t keys_total = sectors_total * 2; + uint8_t keys_found = 0; + uint8_t sectors_read = 0; + mf_classic_get_read_sectors_and_keys(mf_data, §ors_read, &keys_found); + string_printf(str_tmp, "Keys Found: %d/%d", keys_found, keys_total); + widget_add_string_element( + widget, 0, 33, AlignLeft, AlignTop, FontSecondary, string_get_cstr(str_tmp)); + string_printf(str_tmp, "Sectors Read: %d/%d", sectors_read, sectors_total); + widget_add_string_element( + widget, 0, 44, AlignLeft, AlignTop, FontSecondary, string_get_cstr(str_tmp)); + } + + string_clear(str_tmp); + view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewWidget); +} + +bool nfc_scene_mf_classic_read_success_on_event(void* context, SceneManagerEvent event) { + Nfc* nfc = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == GuiButtonTypeLeft) { + scene_manager_next_scene(nfc->scene_manager, NfcSceneRetryConfirm); + consumed = true; + } else if(event.event == GuiButtonTypeRight) { + // Clear device name + nfc_device_set_name(nfc->dev, ""); + scene_manager_next_scene(nfc->scene_manager, NfcSceneMfClassicMenu); + consumed = true; + } + } else if(event.type == SceneManagerEventTypeBack) { + scene_manager_next_scene(nfc->scene_manager, NfcSceneExitConfirm); + consumed = true; + } + + return consumed; +} + +void nfc_scene_mf_classic_read_success_on_exit(void* context) { + Nfc* nfc = context; + + // Clear view + widget_reset(nfc->widget); +} diff --git a/applications/nfc/scenes/nfc_scene_mifare_desfire_app.c b/applications/nfc/scenes/nfc_scene_mf_desfire_app.c similarity index 73% rename from applications/nfc/scenes/nfc_scene_mifare_desfire_app.c rename to applications/nfc/scenes/nfc_scene_mf_desfire_app.c index fdfbd2ec..7faafdcf 100644 --- a/applications/nfc/scenes/nfc_scene_mifare_desfire_app.c +++ b/applications/nfc/scenes/nfc_scene_mf_desfire_app.c @@ -1,15 +1,15 @@ #include "../nfc_i.h" -#define TAG "NfcSceneMifareDesfireApp" +#define TAG "NfcSceneMfDesfireApp" enum SubmenuIndex { SubmenuIndexAppInfo, SubmenuIndexDynamic, // dynamic indexes start here }; -MifareDesfireApplication* nfc_scene_mifare_desfire_app_get_app(Nfc* nfc) { - uint32_t app_idx = - scene_manager_get_scene_state(nfc->scene_manager, NfcSceneMifareDesfireApp) >> 1; +MifareDesfireApplication* nfc_scene_mf_desfire_app_get_app(Nfc* nfc) { + uint32_t app_idx = scene_manager_get_scene_state(nfc->scene_manager, NfcSceneMfDesfireApp) >> + 1; MifareDesfireApplication* app = nfc->dev->dev_data.mf_df_data.app_head; for(uint32_t i = 0; i < app_idx && app; i++) { app = app->next; @@ -17,16 +17,16 @@ MifareDesfireApplication* nfc_scene_mifare_desfire_app_get_app(Nfc* nfc) { return app; } -void nfc_scene_mifare_desfire_app_submenu_callback(void* context, uint32_t index) { +void nfc_scene_mf_desfire_app_submenu_callback(void* context, uint32_t index) { Nfc* nfc = context; view_dispatcher_send_custom_event(nfc->view_dispatcher, index); } -void nfc_scene_mifare_desfire_app_on_enter(void* context) { +void nfc_scene_mf_desfire_app_on_enter(void* context) { Nfc* nfc = context; Submenu* submenu = nfc->submenu; - MifareDesfireApplication* app = nfc_scene_mifare_desfire_app_get_app(nfc); + MifareDesfireApplication* app = nfc_scene_mf_desfire_app_get_app(nfc); if(!app) { popup_set_icon(nfc->popup, 5, 5, &I_WarningDolphin_45x42); popup_set_header(nfc->popup, "Internal Error!", 55, 12, AlignLeft, AlignBottom); @@ -45,11 +45,7 @@ void nfc_scene_mifare_desfire_app_on_enter(void* context) { text_box_set_font(nfc->text_box, TextBoxFontHex); submenu_add_item( - submenu, - "App info", - SubmenuIndexAppInfo, - nfc_scene_mifare_desfire_app_submenu_callback, - nfc); + submenu, "App info", SubmenuIndexAppInfo, nfc_scene_mf_desfire_app_submenu_callback, nfc); uint16_t cap = NFC_TEXT_STORE_SIZE; char* buf = nfc->text_store; @@ -65,20 +61,19 @@ void nfc_scene_mifare_desfire_app_on_enter(void* context) { char* label = buf; cap -= size + 1; buf += size + 1; - submenu_add_item( - submenu, label, idx++, nfc_scene_mifare_desfire_app_submenu_callback, nfc); + submenu_add_item(submenu, label, idx++, nfc_scene_mf_desfire_app_submenu_callback, nfc); } view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewMenu); } -bool nfc_scene_mifare_desfire_app_on_event(void* context, SceneManagerEvent event) { +bool nfc_scene_mf_desfire_app_on_event(void* context, SceneManagerEvent event) { Nfc* nfc = context; bool consumed = false; - uint32_t state = scene_manager_get_scene_state(nfc->scene_manager, NfcSceneMifareDesfireApp); + uint32_t state = scene_manager_get_scene_state(nfc->scene_manager, NfcSceneMfDesfireApp); if(event.type == SceneManagerEventTypeCustom) { - MifareDesfireApplication* app = nfc_scene_mifare_desfire_app_get_app(nfc); + MifareDesfireApplication* app = nfc_scene_mf_desfire_app_get_app(nfc); TextBox* text_box = nfc->text_box; string_reset(nfc->text_box_store); if(event.event == SubmenuIndexAppInfo) { @@ -95,14 +90,13 @@ bool nfc_scene_mifare_desfire_app_on_event(void* context, SceneManagerEvent even mf_df_cat_file(file, nfc->text_box_store); } text_box_set_text(text_box, string_get_cstr(nfc->text_box_store)); - scene_manager_set_scene_state(nfc->scene_manager, NfcSceneMifareDesfireApp, state | 1); + scene_manager_set_scene_state(nfc->scene_manager, NfcSceneMfDesfireApp, state | 1); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewTextBox); consumed = true; } else if(event.type == SceneManagerEventTypeBack) { if(state & 1) { view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewMenu); - scene_manager_set_scene_state( - nfc->scene_manager, NfcSceneMifareDesfireApp, state & ~1); + scene_manager_set_scene_state(nfc->scene_manager, NfcSceneMfDesfireApp, state & ~1); consumed = true; } } @@ -110,7 +104,7 @@ bool nfc_scene_mifare_desfire_app_on_event(void* context, SceneManagerEvent even return consumed; } -void nfc_scene_mifare_desfire_app_on_exit(void* context) { +void nfc_scene_mf_desfire_app_on_exit(void* context) { Nfc* nfc = context; // Clear views diff --git a/applications/nfc/scenes/nfc_scene_mifare_desfire_data.c b/applications/nfc/scenes/nfc_scene_mf_desfire_data.c similarity index 74% rename from applications/nfc/scenes/nfc_scene_mifare_desfire_data.c rename to applications/nfc/scenes/nfc_scene_mf_desfire_data.c index 3eb23fc2..0019a084 100644 --- a/applications/nfc/scenes/nfc_scene_mifare_desfire_data.c +++ b/applications/nfc/scenes/nfc_scene_mf_desfire_data.c @@ -1,6 +1,6 @@ #include "../nfc_i.h" -#define TAG "NfcSceneMifareDesfireData" +#define TAG "NfcSceneMfDesfireData" enum { MifareDesfireDataStateMenu, @@ -12,16 +12,16 @@ enum SubmenuIndex { SubmenuIndexDynamic, // dynamic indexes start here }; -void nfc_scene_mifare_desfire_data_submenu_callback(void* context, uint32_t index) { +void nfc_scene_mf_desfire_data_submenu_callback(void* context, uint32_t index) { Nfc* nfc = (Nfc*)context; view_dispatcher_send_custom_event(nfc->view_dispatcher, index); } -void nfc_scene_mifare_desfire_data_on_enter(void* context) { +void nfc_scene_mf_desfire_data_on_enter(void* context) { Nfc* nfc = context; Submenu* submenu = nfc->submenu; - uint32_t state = scene_manager_get_scene_state(nfc->scene_manager, NfcSceneMifareDesfireData); + uint32_t state = scene_manager_get_scene_state(nfc->scene_manager, NfcSceneMfDesfireData); MifareDesfireData* data = &nfc->dev->dev_data.mf_df_data; text_box_set_font(nfc->text_box, TextBoxFontHex); @@ -30,7 +30,7 @@ void nfc_scene_mifare_desfire_data_on_enter(void* context) { submenu, "Card info", SubmenuIndexCardInfo, - nfc_scene_mifare_desfire_data_submenu_callback, + nfc_scene_mf_desfire_data_submenu_callback, nfc); uint16_t cap = NFC_TEXT_STORE_SIZE; @@ -46,24 +46,23 @@ void nfc_scene_mifare_desfire_data_on_enter(void* context) { char* label = buf; cap -= size + 1; buf += size + 1; - submenu_add_item( - submenu, label, idx++, nfc_scene_mifare_desfire_data_submenu_callback, nfc); + submenu_add_item(submenu, label, idx++, nfc_scene_mf_desfire_data_submenu_callback, nfc); } if(state >= MifareDesfireDataStateItem) { submenu_set_selected_item( nfc->submenu, state - MifareDesfireDataStateItem + SubmenuIndexDynamic); scene_manager_set_scene_state( - nfc->scene_manager, NfcSceneMifareDesfireData, MifareDesfireDataStateMenu); + nfc->scene_manager, NfcSceneMfDesfireData, MifareDesfireDataStateMenu); } view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewMenu); } -bool nfc_scene_mifare_desfire_data_on_event(void* context, SceneManagerEvent event) { +bool nfc_scene_mf_desfire_data_on_event(void* context, SceneManagerEvent event) { Nfc* nfc = context; bool consumed = false; - uint32_t state = scene_manager_get_scene_state(nfc->scene_manager, NfcSceneMifareDesfireData); + uint32_t state = scene_manager_get_scene_state(nfc->scene_manager, NfcSceneMfDesfireData); MifareDesfireData* data = &nfc->dev->dev_data.mf_df_data; if(event.type == SceneManagerEventTypeCustom) { @@ -75,23 +74,22 @@ bool nfc_scene_mifare_desfire_data_on_event(void* context, SceneManagerEvent eve view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewTextBox); scene_manager_set_scene_state( nfc->scene_manager, - NfcSceneMifareDesfireData, + NfcSceneMfDesfireData, MifareDesfireDataStateItem + SubmenuIndexCardInfo); consumed = true; } else { uint16_t index = event.event - SubmenuIndexDynamic; scene_manager_set_scene_state( - nfc->scene_manager, NfcSceneMifareDesfireData, MifareDesfireDataStateItem + index); - scene_manager_set_scene_state( - nfc->scene_manager, NfcSceneMifareDesfireApp, index << 1); - scene_manager_next_scene(nfc->scene_manager, NfcSceneMifareDesfireApp); + nfc->scene_manager, NfcSceneMfDesfireData, MifareDesfireDataStateItem + index); + scene_manager_set_scene_state(nfc->scene_manager, NfcSceneMfDesfireApp, index << 1); + scene_manager_next_scene(nfc->scene_manager, NfcSceneMfDesfireApp); consumed = true; } } else if(event.type == SceneManagerEventTypeBack) { if(state >= MifareDesfireDataStateItem) { view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewMenu); scene_manager_set_scene_state( - nfc->scene_manager, NfcSceneMifareDesfireData, MifareDesfireDataStateMenu); + nfc->scene_manager, NfcSceneMfDesfireData, MifareDesfireDataStateMenu); consumed = true; } } @@ -99,7 +97,7 @@ bool nfc_scene_mifare_desfire_data_on_event(void* context, SceneManagerEvent eve return consumed; } -void nfc_scene_mifare_desfire_data_on_exit(void* context) { +void nfc_scene_mf_desfire_data_on_exit(void* context) { Nfc* nfc = context; // Clear views diff --git a/applications/nfc/scenes/nfc_scene_mifare_desfire_menu.c b/applications/nfc/scenes/nfc_scene_mf_desfire_menu.c similarity index 61% rename from applications/nfc/scenes/nfc_scene_mifare_desfire_menu.c rename to applications/nfc/scenes/nfc_scene_mf_desfire_menu.c index f6171c8b..f1525114 100644 --- a/applications/nfc/scenes/nfc_scene_mifare_desfire_menu.c +++ b/applications/nfc/scenes/nfc_scene_mf_desfire_menu.c @@ -4,33 +4,32 @@ enum SubmenuIndex { SubmenuIndexSave, }; -void nfc_scene_mifare_desfire_menu_submenu_callback(void* context, uint32_t index) { +void nfc_scene_mf_desfire_menu_submenu_callback(void* context, uint32_t index) { Nfc* nfc = context; view_dispatcher_send_custom_event(nfc->view_dispatcher, index); } -void nfc_scene_mifare_desfire_menu_on_enter(void* context) { +void nfc_scene_mf_desfire_menu_on_enter(void* context) { Nfc* nfc = context; Submenu* submenu = nfc->submenu; submenu_add_item( - submenu, "Save", SubmenuIndexSave, nfc_scene_mifare_desfire_menu_submenu_callback, nfc); + submenu, "Save", SubmenuIndexSave, nfc_scene_mf_desfire_menu_submenu_callback, nfc); submenu_set_selected_item( - nfc->submenu, - scene_manager_get_scene_state(nfc->scene_manager, NfcSceneMifareDesfireMenu)); + nfc->submenu, scene_manager_get_scene_state(nfc->scene_manager, NfcSceneMfDesfireMenu)); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewMenu); } -bool nfc_scene_mifare_desfire_menu_on_event(void* context, SceneManagerEvent event) { +bool nfc_scene_mf_desfire_menu_on_event(void* context, SceneManagerEvent event) { Nfc* nfc = context; bool consumed = false; if(event.type == SceneManagerEventTypeCustom) { if(event.event == SubmenuIndexSave) { scene_manager_set_scene_state( - nfc->scene_manager, NfcSceneMifareDesfireMenu, SubmenuIndexSave); + nfc->scene_manager, NfcSceneMfDesfireMenu, SubmenuIndexSave); nfc->dev->format = NfcDeviceSaveFormatMifareDesfire; // Clear device name nfc_device_set_name(nfc->dev, ""); @@ -42,7 +41,7 @@ bool nfc_scene_mifare_desfire_menu_on_event(void* context, SceneManagerEvent eve return consumed; } -void nfc_scene_mifare_desfire_menu_on_exit(void* context) { +void nfc_scene_mf_desfire_menu_on_exit(void* context) { Nfc* nfc = context; // Clear view diff --git a/applications/nfc/scenes/nfc_scene_read_mifare_desfire_success.c b/applications/nfc/scenes/nfc_scene_mf_desfire_read_success.c similarity index 64% rename from applications/nfc/scenes/nfc_scene_read_mifare_desfire_success.c rename to applications/nfc/scenes/nfc_scene_mf_desfire_read_success.c index 17f62e41..673b316b 100644 --- a/applications/nfc/scenes/nfc_scene_read_mifare_desfire_success.c +++ b/applications/nfc/scenes/nfc_scene_mf_desfire_read_success.c @@ -4,22 +4,22 @@ #define NFC_SCENE_READ_SUCCESS_SHIFT " " enum { - ReadMifareDesfireSuccessStateShowUID, - ReadMifareDesfireSuccessStateShowData, + MfDesfireReadSuccessStateShowUID, + MfDesfireReadSuccessStateShowData, }; -void nfc_scene_read_mifare_desfire_success_dialog_callback(DialogExResult result, void* context) { +void nfc_scene_mf_desfire_read_success_dialog_callback(DialogExResult result, void* context) { Nfc* nfc = context; view_dispatcher_send_custom_event(nfc->view_dispatcher, result); } -void nfc_scene_read_mifare_desfire_success_on_enter(void* context) { +void nfc_scene_mf_desfire_read_success_on_enter(void* context) { Nfc* nfc = context; MifareDesfireData* data = &nfc->dev->dev_data.mf_df_data; DialogEx* dialog_ex = nfc->dialog_ex; - dialog_ex_set_left_button_text(dialog_ex, "Back"); + dialog_ex_set_left_button_text(dialog_ex, "Retry"); dialog_ex_set_center_button_text(dialog_ex, "Data"); dialog_ex_set_right_button_text(dialog_ex, "More"); dialog_ex_set_icon(dialog_ex, 8, 16, &I_Medium_chip_22x21); @@ -55,41 +55,40 @@ void nfc_scene_read_mifare_desfire_success_on_enter(void* context) { n_files == 1 ? "" : "s"); dialog_ex_set_text(dialog_ex, nfc->text_store, 8, 6, AlignLeft, AlignTop); dialog_ex_set_context(dialog_ex, nfc); - dialog_ex_set_result_callback( - dialog_ex, nfc_scene_read_mifare_desfire_success_dialog_callback); + dialog_ex_set_result_callback(dialog_ex, nfc_scene_mf_desfire_read_success_dialog_callback); scene_manager_set_scene_state( - nfc->scene_manager, - NfcSceneReadMifareDesfireSuccess, - ReadMifareDesfireSuccessStateShowUID); + nfc->scene_manager, NfcSceneMfDesfireReadSuccess, MfDesfireReadSuccessStateShowUID); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewDialogEx); } -bool nfc_scene_read_mifare_desfire_success_on_event(void* context, SceneManagerEvent event) { +bool nfc_scene_mf_desfire_read_success_on_event(void* context, SceneManagerEvent event) { Nfc* nfc = context; bool consumed = false; uint32_t state = - scene_manager_get_scene_state(nfc->scene_manager, NfcSceneReadMifareDesfireSuccess); + scene_manager_get_scene_state(nfc->scene_manager, NfcSceneMfDesfireReadSuccess); if(event.type == SceneManagerEventTypeCustom) { - if(state == ReadMifareDesfireSuccessStateShowUID && event.event == DialogExResultLeft) { - scene_manager_previous_scene(nfc->scene_manager); + if(state == MfDesfireReadSuccessStateShowUID && event.event == DialogExResultLeft) { + scene_manager_next_scene(nfc->scene_manager, NfcSceneRetryConfirm); consumed = true; - } else if( - state == ReadMifareDesfireSuccessStateShowUID && event.event == DialogExResultCenter) { - scene_manager_next_scene(nfc->scene_manager, NfcSceneMifareDesfireData); + } else if(state == MfDesfireReadSuccessStateShowUID && event.event == DialogExResultCenter) { + scene_manager_next_scene(nfc->scene_manager, NfcSceneMfDesfireData); consumed = true; - } else if(state == ReadMifareDesfireSuccessStateShowUID && event.event == DialogExResultRight) { - scene_manager_next_scene(nfc->scene_manager, NfcSceneMifareDesfireMenu); + } else if(state == MfDesfireReadSuccessStateShowUID && event.event == DialogExResultRight) { + scene_manager_next_scene(nfc->scene_manager, NfcSceneMfDesfireMenu); consumed = true; } } else if(event.type == SceneManagerEventTypeBack) { - if(state == ReadMifareDesfireSuccessStateShowData) { + if(state == MfDesfireReadSuccessStateShowData) { view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewDialogEx); scene_manager_set_scene_state( nfc->scene_manager, - NfcSceneReadMifareDesfireSuccess, - ReadMifareDesfireSuccessStateShowUID); + NfcSceneMfDesfireReadSuccess, + MfDesfireReadSuccessStateShowUID); + consumed = true; + } else { + scene_manager_next_scene(nfc->scene_manager, NfcSceneExitConfirm); consumed = true; } } @@ -97,7 +96,7 @@ bool nfc_scene_read_mifare_desfire_success_on_event(void* context, SceneManagerE return consumed; } -void nfc_scene_read_mifare_desfire_success_on_exit(void* context) { +void nfc_scene_mf_desfire_read_success_on_exit(void* context) { Nfc* nfc = context; // Clean dialog diff --git a/applications/nfc/scenes/nfc_scene_emulate_mifare_ul.c b/applications/nfc/scenes/nfc_scene_mf_ultralight_emulate.c similarity index 56% rename from applications/nfc/scenes/nfc_scene_emulate_mifare_ul.c rename to applications/nfc/scenes/nfc_scene_mf_ultralight_emulate.c index f23f554e..ce375554 100755 --- a/applications/nfc/scenes/nfc_scene_emulate_mifare_ul.c +++ b/applications/nfc/scenes/nfc_scene_mf_ultralight_emulate.c @@ -4,51 +4,52 @@ #define NFC_MF_UL_DATA_NOT_CHANGED (0UL) #define NFC_MF_UL_DATA_CHANGED (1UL) -void nfc_emulate_mifare_ul_worker_callback(NfcWorkerEvent event, void* context) { +bool nfc_mf_ultralight_emulate_worker_callback(NfcWorkerEvent event, void* context) { UNUSED(event); Nfc* nfc = context; scene_manager_set_scene_state( - nfc->scene_manager, NfcSceneEmulateMifareUl, NFC_MF_UL_DATA_CHANGED); + nfc->scene_manager, NfcSceneMfUltralightEmulate, NFC_MF_UL_DATA_CHANGED); + return true; } -void nfc_scene_emulate_mifare_ul_on_enter(void* context) { +void nfc_scene_mf_ultralight_emulate_on_enter(void* context) { Nfc* nfc = context; DOLPHIN_DEED(DolphinDeedNfcEmulate); // Setup view Popup* popup = nfc->popup; if(strcmp(nfc->dev->dev_name, "")) { - nfc_text_store_set(nfc, "%s", nfc->dev->dev_name); + nfc_text_store_set(nfc, "Emulating\n%s", nfc->dev->dev_name); + } else { + nfc_text_store_set(nfc, "Emulating\nMf Ultralight", nfc->dev->dev_name); } popup_set_icon(popup, 0, 3, &I_RFIDDolphinSend_97x61); - popup_set_header(popup, "Emulating\nMf Ultralight", 56, 31, AlignLeft, AlignTop); + popup_set_header(popup, nfc->text_store, 56, 31, AlignLeft, AlignTop); // Setup and start worker view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup); nfc_worker_start( nfc->worker, - NfcWorkerStateEmulateMifareUltralight, + NfcWorkerStateMfUltralightEmulate, &nfc->dev->dev_data, - nfc_emulate_mifare_ul_worker_callback, + nfc_mf_ultralight_emulate_worker_callback, nfc); nfc_blink_start(nfc); } -bool nfc_scene_emulate_mifare_ul_on_event(void* context, SceneManagerEvent event) { +bool nfc_scene_mf_ultralight_emulate_on_event(void* context, SceneManagerEvent event) { Nfc* nfc = context; bool consumed = false; - if(event.type == SceneManagerEventTypeTick) { - consumed = true; - } else if(event.type == SceneManagerEventTypeBack) { + if(event.type == SceneManagerEventTypeBack) { // Stop worker nfc_worker_stop(nfc->worker); // Check if data changed and save in shadow file - if(scene_manager_get_scene_state(nfc->scene_manager, NfcSceneEmulateMifareUl) == + if(scene_manager_get_scene_state(nfc->scene_manager, NfcSceneMfUltralightEmulate) == NFC_MF_UL_DATA_CHANGED) { scene_manager_set_scene_state( - nfc->scene_manager, NfcSceneEmulateMifareUl, NFC_MF_UL_DATA_NOT_CHANGED); + nfc->scene_manager, NfcSceneMfUltralightEmulate, NFC_MF_UL_DATA_NOT_CHANGED); nfc_device_save_shadow(nfc->dev, nfc->dev->dev_name); } consumed = false; @@ -56,7 +57,7 @@ bool nfc_scene_emulate_mifare_ul_on_event(void* context, SceneManagerEvent event return consumed; } -void nfc_scene_emulate_mifare_ul_on_exit(void* context) { +void nfc_scene_mf_ultralight_emulate_on_exit(void* context) { Nfc* nfc = context; // Clear view diff --git a/applications/nfc/scenes/nfc_scene_mifare_classic_menu.c b/applications/nfc/scenes/nfc_scene_mf_ultralight_menu.c similarity index 66% rename from applications/nfc/scenes/nfc_scene_mifare_classic_menu.c rename to applications/nfc/scenes/nfc_scene_mf_ultralight_menu.c index 4611d16b..615c516d 100644 --- a/applications/nfc/scenes/nfc_scene_mifare_classic_menu.c +++ b/applications/nfc/scenes/nfc_scene_mf_ultralight_menu.c @@ -5,47 +5,47 @@ enum SubmenuIndex { SubmenuIndexEmulate, }; -void nfc_scene_mifare_classic_menu_submenu_callback(void* context, uint32_t index) { +void nfc_scene_mf_ultralight_menu_submenu_callback(void* context, uint32_t index) { Nfc* nfc = context; view_dispatcher_send_custom_event(nfc->view_dispatcher, index); } -void nfc_scene_mifare_classic_menu_on_enter(void* context) { +void nfc_scene_mf_ultralight_menu_on_enter(void* context) { Nfc* nfc = context; Submenu* submenu = nfc->submenu; submenu_add_item( - submenu, "Save", SubmenuIndexSave, nfc_scene_mifare_classic_menu_submenu_callback, nfc); + submenu, "Save", SubmenuIndexSave, nfc_scene_mf_ultralight_menu_submenu_callback, nfc); submenu_add_item( submenu, "Emulate", SubmenuIndexEmulate, - nfc_scene_mifare_classic_menu_submenu_callback, + nfc_scene_mf_ultralight_menu_submenu_callback, nfc); submenu_set_selected_item( - nfc->submenu, scene_manager_get_scene_state(nfc->scene_manager, NfcSceneMifareUlMenu)); + nfc->submenu, scene_manager_get_scene_state(nfc->scene_manager, NfcSceneMfUltralightMenu)); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewMenu); } -bool nfc_scene_mifare_classic_menu_on_event(void* context, SceneManagerEvent event) { +bool nfc_scene_mf_ultralight_menu_on_event(void* context, SceneManagerEvent event) { Nfc* nfc = context; bool consumed = false; if(event.type == SceneManagerEventTypeCustom) { if(event.event == SubmenuIndexSave) { scene_manager_set_scene_state( - nfc->scene_manager, NfcSceneMifareUlMenu, SubmenuIndexSave); - nfc->dev->format = NfcDeviceSaveFormatMifareClassic; + nfc->scene_manager, NfcSceneMfUltralightMenu, SubmenuIndexSave); + nfc->dev->format = NfcDeviceSaveFormatMifareUl; // Clear device name nfc_device_set_name(nfc->dev, ""); scene_manager_next_scene(nfc->scene_manager, NfcSceneSaveName); consumed = true; } else if(event.event == SubmenuIndexEmulate) { scene_manager_set_scene_state( - nfc->scene_manager, NfcSceneMifareUlMenu, SubmenuIndexEmulate); - scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateMifareClassic); + nfc->scene_manager, NfcSceneMfUltralightMenu, SubmenuIndexEmulate); + scene_manager_next_scene(nfc->scene_manager, NfcSceneMfUltralightEmulate); consumed = true; } } else if(event.type == SceneManagerEventTypeBack) { @@ -56,7 +56,7 @@ bool nfc_scene_mifare_classic_menu_on_event(void* context, SceneManagerEvent eve return consumed; } -void nfc_scene_mifare_classic_menu_on_exit(void* context) { +void nfc_scene_mf_ultralight_menu_on_exit(void* context) { Nfc* nfc = context; // Clear view diff --git a/applications/nfc/scenes/nfc_scene_read_mifare_ul_success.c b/applications/nfc/scenes/nfc_scene_mf_ultralight_read_success.c similarity index 77% rename from applications/nfc/scenes/nfc_scene_read_mifare_ul_success.c rename to applications/nfc/scenes/nfc_scene_mf_ultralight_read_success.c index 5bcf1589..8b1b6c00 100755 --- a/applications/nfc/scenes/nfc_scene_read_mifare_ul_success.c +++ b/applications/nfc/scenes/nfc_scene_mf_ultralight_read_success.c @@ -8,19 +8,16 @@ enum { ReadMifareUlStateShowData, }; -void nfc_scene_read_mifare_ul_success_dialog_callback(DialogExResult result, void* context) { +void nfc_scene_mf_ultralight_read_success_dialog_callback(DialogExResult result, void* context) { Nfc* nfc = context; view_dispatcher_send_custom_event(nfc->view_dispatcher, result); } -void nfc_scene_read_mifare_ul_success_on_enter(void* context) { +void nfc_scene_mf_ultralight_read_success_on_enter(void* context) { Nfc* nfc = context; DOLPHIN_DEED(DolphinDeedNfcReadSuccess); - // Send notification - notification_message(nfc->notifications, &sequence_success); - // Setup dialog view FuriHalNfcDevData* data = &nfc->dev->dev_data.nfc_data; MfUltralightData* mf_ul_data = &nfc->dev->dev_data.mf_ul_data; @@ -48,7 +45,7 @@ void nfc_scene_read_mifare_ul_success_on_enter(void* context) { data->uid[6]); dialog_ex_set_text(dialog_ex, nfc->text_store, 8, 16, AlignLeft, AlignTop); dialog_ex_set_context(dialog_ex, nfc); - dialog_ex_set_result_callback(dialog_ex, nfc_scene_read_mifare_ul_success_dialog_callback); + dialog_ex_set_result_callback(dialog_ex, nfc_scene_mf_ultralight_read_success_dialog_callback); // Setup TextBox view TextBox* text_box = nfc->text_box; @@ -63,34 +60,37 @@ void nfc_scene_read_mifare_ul_success_on_enter(void* context) { text_box_set_text(text_box, string_get_cstr(nfc->text_box_store)); scene_manager_set_scene_state( - nfc->scene_manager, NfcSceneReadMifareUlSuccess, ReadMifareUlStateShowUID); + nfc->scene_manager, NfcSceneMfUltralightReadSuccess, ReadMifareUlStateShowUID); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewDialogEx); } -bool nfc_scene_read_mifare_ul_success_on_event(void* context, SceneManagerEvent event) { +bool nfc_scene_mf_ultralight_read_success_on_event(void* context, SceneManagerEvent event) { Nfc* nfc = context; bool consumed = false; uint32_t state = - scene_manager_get_scene_state(nfc->scene_manager, NfcSceneReadMifareUlSuccess); + scene_manager_get_scene_state(nfc->scene_manager, NfcSceneMfUltralightReadSuccess); if(event.type == SceneManagerEventTypeCustom) { if(state == ReadMifareUlStateShowUID && event.event == DialogExResultLeft) { - scene_manager_previous_scene(nfc->scene_manager); + scene_manager_next_scene(nfc->scene_manager, NfcSceneRetryConfirm); consumed = true; } else if(state == ReadMifareUlStateShowUID && event.event == DialogExResultRight) { - scene_manager_next_scene(nfc->scene_manager, NfcSceneMifareUlMenu); + scene_manager_next_scene(nfc->scene_manager, NfcSceneMfUltralightMenu); consumed = true; } else if(state == ReadMifareUlStateShowUID && event.event == DialogExResultCenter) { view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewTextBox); scene_manager_set_scene_state( - nfc->scene_manager, NfcSceneReadMifareUlSuccess, ReadMifareUlStateShowData); + nfc->scene_manager, NfcSceneMfUltralightReadSuccess, ReadMifareUlStateShowData); consumed = true; } } else if(event.type == SceneManagerEventTypeBack) { if(state == ReadMifareUlStateShowData) { view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewDialogEx); scene_manager_set_scene_state( - nfc->scene_manager, NfcSceneReadMifareUlSuccess, ReadMifareUlStateShowUID); + nfc->scene_manager, NfcSceneMfUltralightReadSuccess, ReadMifareUlStateShowUID); + consumed = true; + } else { + scene_manager_next_scene(nfc->scene_manager, NfcSceneExitConfirm); consumed = true; } } @@ -98,7 +98,7 @@ bool nfc_scene_read_mifare_ul_success_on_event(void* context, SceneManagerEvent return consumed; } -void nfc_scene_read_mifare_ul_success_on_exit(void* context) { +void nfc_scene_mf_ultralight_read_success_on_exit(void* context) { Nfc* nfc = context; // Clean views diff --git a/applications/nfc/scenes/nfc_scene_read.c b/applications/nfc/scenes/nfc_scene_read.c new file mode 100644 index 00000000..9e1c0109 --- /dev/null +++ b/applications/nfc/scenes/nfc_scene_read.c @@ -0,0 +1,108 @@ +#include "../nfc_i.h" +#include + +typedef enum { + NfcSceneReadStateIdle, + NfcSceneReadStateDetecting, + NfcSceneReadStateReading, +} NfcSceneReadState; + +bool nfc_scene_read_worker_callback(NfcWorkerEvent event, void* context) { + Nfc* nfc = context; + bool consumed = false; + if(event == NfcWorkerEventReadMfClassicLoadKeyCache) { + consumed = nfc_device_load_key_cache(nfc->dev); + } else { + view_dispatcher_send_custom_event(nfc->view_dispatcher, event); + consumed = true; + } + return consumed; +} + +void nfc_scene_read_set_state(Nfc* nfc, NfcSceneReadState state) { + uint32_t curr_state = scene_manager_get_scene_state(nfc->scene_manager, NfcSceneRead); + if(curr_state != state) { + if(state == NfcSceneReadStateDetecting) { + popup_set_header(nfc->popup, "Detecting\nNFC card", 90, 24, AlignCenter, AlignTop); + popup_set_icon(nfc->popup, 5, 7, &I_NFC_manual); + } else if(state == NfcSceneReadStateReading) { + popup_set_header( + nfc->popup, "Reading card\nDon't move...", 85, 24, AlignCenter, AlignTop); + popup_set_icon(nfc->popup, 19, 23, &A_Loading_24); + } + scene_manager_set_scene_state(nfc->scene_manager, NfcSceneRead, state); + } +} + +void nfc_scene_read_on_enter(void* context) { + Nfc* nfc = context; + DOLPHIN_DEED(DolphinDeedNfcRead); + + nfc_device_clear(nfc->dev); + // Setup view + nfc_scene_read_set_state(nfc, NfcSceneReadStateDetecting); + view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup); + // Start worker + nfc_worker_start( + nfc->worker, NfcWorkerStateRead, &nfc->dev->dev_data, nfc_scene_read_worker_callback, nfc); + + nfc_blink_start(nfc); +} + +bool nfc_scene_read_on_event(void* context, SceneManagerEvent event) { + Nfc* nfc = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if((event.event == NfcWorkerEventReadUidNfcB) || + (event.event == NfcWorkerEventReadUidNfcF) || + (event.event == NfcWorkerEventReadUidNfcV) || + (event.event == NfcWorkerEventReadUidNfcA)) { + notification_message(nfc->notifications, &sequence_success); + scene_manager_next_scene(nfc->scene_manager, NfcSceneReadCardSuccess); + consumed = true; + } else if(event.event == NfcWorkerEventReadMfUltralight) { + notification_message(nfc->notifications, &sequence_success); + scene_manager_next_scene(nfc->scene_manager, NfcSceneMfUltralightReadSuccess); + consumed = true; + } else if(event.event == NfcWorkerEventReadMfClassicDone) { + notification_message(nfc->notifications, &sequence_success); + scene_manager_next_scene(nfc->scene_manager, NfcSceneMfClassicReadSuccess); + consumed = true; + } else if(event.event == NfcWorkerEventReadMfDesfire) { + notification_message(nfc->notifications, &sequence_success); + scene_manager_next_scene(nfc->scene_manager, NfcSceneMfDesfireReadSuccess); + consumed = true; + } else if(event.event == NfcWorkerEventReadBankCard) { + notification_message(nfc->notifications, &sequence_success); + scene_manager_next_scene(nfc->scene_manager, NfcSceneEmvReadSuccess); + consumed = true; + } else if(event.event == NfcWorkerEventReadMfClassicDictAttackRequired) { + if(mf_classic_dict_check_presence(MfClassicDictTypeFlipper)) { + scene_manager_next_scene(nfc->scene_manager, NfcSceneMfClassicDictAttack); + } else { + scene_manager_next_scene(nfc->scene_manager, NfcSceneDictNotFound); + } + consumed = true; + } else if(event.event == NfcWorkerEventCardDetected) { + nfc_scene_read_set_state(nfc, NfcSceneReadStateReading); + consumed = true; + } else if(event.event == NfcWorkerEventNoCardDetected) { + nfc_scene_read_set_state(nfc, NfcSceneReadStateDetecting); + consumed = true; + } + } + return consumed; +} + +void nfc_scene_read_on_exit(void* context) { + Nfc* nfc = context; + + // Stop worker + nfc_worker_stop(nfc->worker); + // Clear view + popup_reset(nfc->popup); + scene_manager_set_scene_state(nfc->scene_manager, NfcSceneRead, NfcSceneReadStateIdle); + + nfc_blink_stop(nfc); +} diff --git a/applications/nfc/scenes/nfc_scene_read_card.c b/applications/nfc/scenes/nfc_scene_read_card.c deleted file mode 100755 index 0cd0fc89..00000000 --- a/applications/nfc/scenes/nfc_scene_read_card.c +++ /dev/null @@ -1,51 +0,0 @@ -#include "../nfc_i.h" -#include - -void nfc_read_card_worker_callback(NfcWorkerEvent event, void* context) { - UNUSED(event); - Nfc* nfc = context; - view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventWorkerExit); -} - -void nfc_scene_read_card_on_enter(void* context) { - Nfc* nfc = context; - DOLPHIN_DEED(DolphinDeedNfcRead); - - // Setup view - Popup* popup = nfc->popup; - popup_set_header(popup, "Detecting\nNFC card", 70, 34, AlignLeft, AlignTop); - popup_set_icon(popup, 0, 3, &I_RFIDDolphinReceive_97x61); - - // Start worker - view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup); - nfc_worker_start( - nfc->worker, NfcWorkerStateDetect, &nfc->dev->dev_data, nfc_read_card_worker_callback, nfc); - - nfc_blink_start(nfc); -} - -bool nfc_scene_read_card_on_event(void* context, SceneManagerEvent event) { - Nfc* nfc = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == NfcCustomEventWorkerExit) { - scene_manager_next_scene(nfc->scene_manager, NfcSceneReadCardSuccess); - consumed = true; - } - } else if(event.type == SceneManagerEventTypeTick) { - consumed = true; - } - return consumed; -} - -void nfc_scene_read_card_on_exit(void* context) { - Nfc* nfc = context; - - // Stop worker - nfc_worker_stop(nfc->worker); - // Clear view - popup_reset(nfc->popup); - - nfc_blink_stop(nfc); -} diff --git a/applications/nfc/scenes/nfc_scene_read_card_success.c b/applications/nfc/scenes/nfc_scene_read_card_success.c index c0a865bc..b889ce08 100755 --- a/applications/nfc/scenes/nfc_scene_read_card_success.c +++ b/applications/nfc/scenes/nfc_scene_read_card_success.c @@ -22,9 +22,6 @@ void nfc_scene_read_card_success_on_enter(void* context) { string_init(uid_str); DOLPHIN_DEED(DolphinDeedNfcReadSuccess); - // Send notification - notification_message(nfc->notifications, &sequence_success); - // Setup view FuriHalNfcDevData* data = &nfc->dev->dev_data.nfc_data; Widget* widget = nfc->widget; @@ -38,18 +35,12 @@ void nfc_scene_read_card_success_on_enter(void* context) { widget, GuiButtonTypeLeft, "Retry", nfc_scene_read_card_success_widget_callback, nfc); if(data->type == FuriHalNfcTypeA) { widget_add_button_element( - widget, GuiButtonTypeRight, "More", nfc_scene_read_card_success_widget_callback, nfc); + widget, GuiButtonTypeRight, "Save", nfc_scene_read_card_success_widget_callback, nfc); widget_add_icon_element(widget, 8, 13, &I_Medium_chip_22x21); - string_cat_printf(data_str, " may be:"); widget_add_string_element( widget, 37, 12, AlignLeft, AlignBottom, FontPrimary, string_get_cstr(data_str)); string_printf( - data_str, - "%s\nATQA: %02X%02X SAK: %02X", - nfc_guess_protocol(nfc->dev->dev_data.protocol), - data->atqa[0], - data->atqa[1], - data->sak); + data_str, "ATQA: %02X%02X\nSAK: %02X", data->atqa[0], data->atqa[1], data->sak); widget_add_string_multiline_element( widget, 37, 16, AlignLeft, AlignTop, FontSecondary, string_get_cstr(data_str)); widget_add_string_element( @@ -69,16 +60,15 @@ void nfc_scene_read_card_success_on_enter(void* context) { bool nfc_scene_read_card_success_on_event(void* context, SceneManagerEvent event) { Nfc* nfc = context; - FuriHalNfcDevData* data = &nfc->dev->dev_data.nfc_data; bool consumed = false; if(event.type == SceneManagerEventTypeCustom) { if(event.event == GuiButtonTypeLeft) { consumed = scene_manager_previous_scene(nfc->scene_manager); - } else if(data->type == FuriHalNfcTypeA && event.event == GuiButtonTypeRight) { - // Clear device name + } else if(event.event == GuiButtonTypeRight) { + nfc->dev->format = NfcDeviceSaveFormatUid; nfc_device_set_name(nfc->dev, ""); - scene_manager_next_scene(nfc->scene_manager, NfcSceneCardMenu); + scene_manager_next_scene(nfc->scene_manager, NfcSceneSaveName); consumed = true; } } diff --git a/applications/nfc/scenes/nfc_scene_read_emv_app.c b/applications/nfc/scenes/nfc_scene_read_emv_app.c deleted file mode 100755 index 5bb8ac5f..00000000 --- a/applications/nfc/scenes/nfc_scene_read_emv_app.c +++ /dev/null @@ -1,58 +0,0 @@ -#include "../nfc_i.h" -#include - -void nfc_read_emv_app_worker_callback(NfcWorkerEvent event, void* context) { - UNUSED(event); - Nfc* nfc = context; - view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventWorkerExit); -} - -void nfc_scene_read_emv_app_on_enter(void* context) { - Nfc* nfc = context; - DOLPHIN_DEED(DolphinDeedNfcRead); - - // Setup view - Popup* popup = nfc->popup; - popup_set_header(popup, "Reading\nbank card", 70, 34, AlignLeft, AlignTop); - popup_set_icon(popup, 0, 3, &I_RFIDDolphinReceive_97x61); - - view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup); - // Start worker - nfc_worker_start( - nfc->worker, - NfcWorkerStateReadEMVApp, - &nfc->dev->dev_data, - nfc_read_emv_app_worker_callback, - nfc); - nfc_blink_start(nfc); -} - -bool nfc_scene_read_emv_app_on_event(void* context, SceneManagerEvent event) { - Nfc* nfc = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == NfcCustomEventWorkerExit) { - scene_manager_set_scene_state( - nfc->scene_manager, NfcSceneReadEmvAppSuccess, NFC_SEND_NOTIFICATION_TRUE); - scene_manager_next_scene(nfc->scene_manager, NfcSceneReadEmvAppSuccess); - consumed = true; - } - } else if(event.type == SceneManagerEventTypeTick) { - consumed = true; - } - - return consumed; -} - -void nfc_scene_read_emv_app_on_exit(void* context) { - Nfc* nfc = context; - - // Stop worker - nfc_worker_stop(nfc->worker); - - // Clear view - popup_reset(nfc->popup); - - nfc_blink_stop(nfc); -} diff --git a/applications/nfc/scenes/nfc_scene_read_emv_app_success.c b/applications/nfc/scenes/nfc_scene_read_emv_app_success.c deleted file mode 100755 index b9bc5ba4..00000000 --- a/applications/nfc/scenes/nfc_scene_read_emv_app_success.c +++ /dev/null @@ -1,83 +0,0 @@ -#include "../nfc_i.h" -#include "../helpers/nfc_emv_parser.h" -#include - -void nfc_scene_read_emv_app_widget_callback(GuiButtonType result, InputType type, void* context) { - Nfc* nfc = context; - if(type == InputTypeShort) { - view_dispatcher_send_custom_event(nfc->view_dispatcher, result); - } -} - -void nfc_scene_read_emv_app_success_on_enter(void* context) { - Nfc* nfc = context; - DOLPHIN_DEED(DolphinDeedNfcReadSuccess); - - // Setup view - FuriHalNfcDevData* nfc_data = &nfc->dev->dev_data.nfc_data; - EmvData* emv_data = &nfc->dev->dev_data.emv_data; - Widget* widget = nfc->widget; - widget_add_button_element( - widget, GuiButtonTypeLeft, "Retry", nfc_scene_read_emv_app_widget_callback, nfc); - widget_add_button_element( - widget, GuiButtonTypeRight, "Run app", nfc_scene_read_emv_app_widget_callback, nfc); - widget_add_string_element(widget, 36, 5, AlignLeft, AlignTop, FontPrimary, "Found EMV App"); - widget_add_icon_element(widget, 8, 5, &I_Medium_chip_22x21); - // Display UID - string_t temp_str; - string_init_printf(temp_str, "UID:"); - for(size_t i = 0; i < nfc_data->uid_len; i++) { - string_cat_printf(temp_str, " %02X", nfc_data->uid[i]); - } - widget_add_string_element( - widget, 36, 18, AlignLeft, AlignTop, FontSecondary, string_get_cstr(temp_str)); - string_reset(temp_str); - // Display application - string_printf(temp_str, "App: "); - string_t aid; - string_init(aid); - bool aid_found = - nfc_emv_parser_get_aid_name(nfc->dev->storage, emv_data->aid, emv_data->aid_len, aid); - if(!aid_found) { - for(uint8_t i = 0; i < emv_data->aid_len; i++) { - string_cat_printf(aid, "%02X", emv_data->aid[i]); - } - } - string_cat(temp_str, aid); - widget_add_string_element( - widget, 7, 29, AlignLeft, AlignTop, FontSecondary, string_get_cstr(temp_str)); - string_clear(temp_str); - string_clear(aid); - - // Send notification - if(scene_manager_get_scene_state(nfc->scene_manager, NfcSceneReadEmvAppSuccess) == - NFC_SEND_NOTIFICATION_TRUE) { - notification_message(nfc->notifications, &sequence_success); - scene_manager_set_scene_state( - nfc->scene_manager, NfcSceneReadEmvAppSuccess, NFC_SEND_NOTIFICATION_FALSE); - } - - view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewWidget); -} - -bool nfc_scene_read_emv_app_success_on_event(void* context, SceneManagerEvent event) { - Nfc* nfc = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == GuiButtonTypeLeft) { - consumed = scene_manager_previous_scene(nfc->scene_manager); - } else if(event.event == GuiButtonTypeRight) { - scene_manager_next_scene(nfc->scene_manager, NfcSceneRunEmvAppConfirm); - consumed = true; - } - } - return consumed; -} - -void nfc_scene_read_emv_app_success_on_exit(void* context) { - Nfc* nfc = context; - - // Clear views - widget_reset(nfc->widget); -} diff --git a/applications/nfc/scenes/nfc_scene_read_emv_data.c b/applications/nfc/scenes/nfc_scene_read_emv_data.c deleted file mode 100755 index e1881cef..00000000 --- a/applications/nfc/scenes/nfc_scene_read_emv_data.c +++ /dev/null @@ -1,59 +0,0 @@ -#include "../nfc_i.h" -#include - -void nfc_read_emv_data_worker_callback(NfcWorkerEvent event, void* context) { - UNUSED(event); - Nfc* nfc = context; - view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventWorkerExit); -} - -void nfc_scene_read_emv_data_on_enter(void* context) { - Nfc* nfc = context; - DOLPHIN_DEED(DolphinDeedNfcRead); - - // Setup view - Popup* popup = nfc->popup; - popup_set_header(popup, "Reading\nbank card", 70, 34, AlignLeft, AlignTop); - popup_set_icon(popup, 0, 3, &I_RFIDDolphinReceive_97x61); - - view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup); - // Clear emv data - memset(&nfc->dev->dev_data.emv_data, 0, sizeof(nfc->dev->dev_data.emv_data)); - // Start worker - nfc_worker_start( - nfc->worker, - NfcWorkerStateReadEMVData, - &nfc->dev->dev_data, - nfc_read_emv_data_worker_callback, - nfc); - - nfc_blink_start(nfc); -} - -bool nfc_scene_read_emv_data_on_event(void* context, SceneManagerEvent event) { - Nfc* nfc = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == NfcCustomEventWorkerExit) { - scene_manager_set_scene_state( - nfc->scene_manager, NfcSceneReadEmvDataSuccess, NFC_SEND_NOTIFICATION_TRUE); - scene_manager_next_scene(nfc->scene_manager, NfcSceneReadEmvDataSuccess); - consumed = true; - } - } else if(event.type == SceneManagerEventTypeTick) { - consumed = true; - } - return consumed; -} - -void nfc_scene_read_emv_data_on_exit(void* context) { - Nfc* nfc = context; - - // Stop worker - nfc_worker_stop(nfc->worker); - // Clear view - popup_reset(nfc->popup); - - nfc_blink_stop(nfc); -} diff --git a/applications/nfc/scenes/nfc_scene_read_mifare_classic.c b/applications/nfc/scenes/nfc_scene_read_mifare_classic.c deleted file mode 100644 index a901ecd4..00000000 --- a/applications/nfc/scenes/nfc_scene_read_mifare_classic.c +++ /dev/null @@ -1,96 +0,0 @@ -#include "../nfc_i.h" - -enum { - NfcSceneReadMifareClassicStateInProgress, - NfcSceneReadMifareClassicStateDone, -}; - -void nfc_read_mifare_classic_worker_callback(NfcWorkerEvent event, void* context) { - furi_assert(context); - Nfc* nfc = context; - view_dispatcher_send_custom_event(nfc->view_dispatcher, event); -} - -void nfc_read_mifare_classic_dict_attack_result_callback(void* context) { - furi_assert(context); - Nfc* nfc = context; - view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventDictAttackDone); -} - -void nfc_scene_read_mifare_classic_on_enter(void* context) { - Nfc* nfc = context; - - // Setup and start worker - memset(&nfc->dev->dev_data.mf_classic_data, 0, sizeof(MfClassicData)); - dict_attack_set_result_callback( - nfc->dict_attack, nfc_read_mifare_classic_dict_attack_result_callback, nfc); - scene_manager_set_scene_state( - nfc->scene_manager, NfcSceneReadMifareClassic, NfcSceneReadMifareClassicStateInProgress); - view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewDictAttack); - nfc_worker_start( - nfc->worker, - NfcWorkerStateReadMifareClassic, - &nfc->dev->dev_data, - nfc_read_mifare_classic_worker_callback, - nfc); - - nfc_blink_start(nfc); -} - -bool nfc_scene_read_mifare_classic_on_event(void* context, SceneManagerEvent event) { - Nfc* nfc = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeTick) { - consumed = true; - } else if(event.type == SceneManagerEventTypeCustom) { - if(event.event == NfcCustomEventDictAttackDone) { - scene_manager_next_scene(nfc->scene_manager, NfcSceneMifareClassicMenu); - consumed = true; - } else if(event.event == NfcWorkerEventDetectedClassic1k) { - dict_attack_card_detected(nfc->dict_attack, MfClassicType1k); - consumed = true; - } else if(event.event == NfcWorkerEventDetectedClassic4k) { - dict_attack_card_detected(nfc->dict_attack, MfClassicType4k); - consumed = true; - } else if(event.event == NfcWorkerEventNewSector) { - dict_attack_inc_curr_sector(nfc->dict_attack); - consumed = true; - } else if(event.event == NfcWorkerEventFoundKeyA) { - dict_attack_inc_found_key(nfc->dict_attack, MfClassicKeyA); - consumed = true; - } else if(event.event == NfcWorkerEventFoundKeyB) { - dict_attack_inc_found_key(nfc->dict_attack, MfClassicKeyB); - consumed = true; - } else if(event.event == NfcWorkerEventNoCardDetected) { - dict_attack_card_removed(nfc->dict_attack); - consumed = true; - } else if(event.event == NfcWorkerEventSuccess) { - scene_manager_set_scene_state( - nfc->scene_manager, NfcSceneReadMifareClassic, NfcSceneReadMifareClassicStateDone); - nfc_blink_stop(nfc); - notification_message(nfc->notifications, &sequence_success); - dict_attack_set_result(nfc->dict_attack, true); - consumed = true; - } else if(event.event == NfcWorkerEventFail) { - scene_manager_set_scene_state( - nfc->scene_manager, NfcSceneReadMifareClassic, NfcSceneReadMifareClassicStateDone); - nfc_blink_stop(nfc); - dict_attack_set_result(nfc->dict_attack, false); - consumed = true; - } else if(event.event == NfcWorkerEventNoDictFound) { - scene_manager_next_scene(nfc->scene_manager, NfcSceneDictNotFound); - consumed = true; - } - } - return consumed; -} - -void nfc_scene_read_mifare_classic_on_exit(void* context) { - Nfc* nfc = context; - // Stop worker - nfc_worker_stop(nfc->worker); - dict_attack_reset(nfc->dict_attack); - - nfc_blink_stop(nfc); -} diff --git a/applications/nfc/scenes/nfc_scene_read_mifare_desfire.c b/applications/nfc/scenes/nfc_scene_read_mifare_desfire.c deleted file mode 100644 index fc99b64c..00000000 --- a/applications/nfc/scenes/nfc_scene_read_mifare_desfire.c +++ /dev/null @@ -1,56 +0,0 @@ -#include "../nfc_i.h" -#include - -void nfc_read_mifare_desfire_worker_callback(NfcWorkerEvent event, void* context) { - UNUSED(event); - Nfc* nfc = context; - view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventWorkerExit); -} - -void nfc_scene_read_mifare_desfire_on_enter(void* context) { - Nfc* nfc = context; - DOLPHIN_DEED(DolphinDeedNfcRead); - - // Setup view - Popup* popup = nfc->popup; - popup_set_header(popup, "Reading\nDESFire", 70, 34, AlignLeft, AlignTop); - popup_set_icon(popup, 0, 3, &I_RFIDDolphinReceive_97x61); - - view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup); - // Start worker - nfc_worker_start( - nfc->worker, - NfcWorkerStateReadMifareDesfire, - &nfc->dev->dev_data, - nfc_read_mifare_desfire_worker_callback, - nfc); - nfc_blink_start(nfc); -} - -bool nfc_scene_read_mifare_desfire_on_event(void* context, SceneManagerEvent event) { - Nfc* nfc = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == NfcCustomEventWorkerExit) { - notification_message(nfc->notifications, &sequence_success); - DOLPHIN_DEED(DolphinDeedNfcReadSuccess); - scene_manager_next_scene(nfc->scene_manager, NfcSceneReadMifareDesfireSuccess); - consumed = true; - } - } else if(event.type == SceneManagerEventTypeTick) { - consumed = true; - } - return consumed; -} - -void nfc_scene_read_mifare_desfire_on_exit(void* context) { - Nfc* nfc = context; - - // Stop worker - nfc_worker_stop(nfc->worker); - // Clear view - popup_reset(nfc->popup); - - nfc_blink_stop(nfc); -} diff --git a/applications/nfc/scenes/nfc_scene_read_mifare_ul.c b/applications/nfc/scenes/nfc_scene_read_mifare_ul.c deleted file mode 100755 index 444f6253..00000000 --- a/applications/nfc/scenes/nfc_scene_read_mifare_ul.c +++ /dev/null @@ -1,54 +0,0 @@ -#include "../nfc_i.h" -#include - -void nfc_read_mifare_ul_worker_callback(NfcWorkerEvent event, void* context) { - UNUSED(event); - Nfc* nfc = context; - view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventWorkerExit); -} - -void nfc_scene_read_mifare_ul_on_enter(void* context) { - Nfc* nfc = context; - DOLPHIN_DEED(DolphinDeedNfcRead); - - // Setup view - Popup* popup = nfc->popup; - popup_set_header(popup, "Detecting\nultralight", 70, 34, AlignLeft, AlignTop); - popup_set_icon(popup, 0, 3, &I_RFIDDolphinReceive_97x61); - - view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup); - // Start worker - nfc_worker_start( - nfc->worker, - NfcWorkerStateReadMifareUltralight, - &nfc->dev->dev_data, - nfc_read_mifare_ul_worker_callback, - nfc); - nfc_blink_start(nfc); -} - -bool nfc_scene_read_mifare_ul_on_event(void* context, SceneManagerEvent event) { - Nfc* nfc = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == NfcCustomEventWorkerExit) { - scene_manager_next_scene(nfc->scene_manager, NfcSceneReadMifareUlSuccess); - consumed = true; - } - } else if(event.type == SceneManagerEventTypeTick) { - consumed = true; - } - return consumed; -} - -void nfc_scene_read_mifare_ul_on_exit(void* context) { - Nfc* nfc = context; - - // Stop worker - nfc_worker_stop(nfc->worker); - // Clear view - popup_reset(nfc->popup); - - nfc_blink_stop(nfc); -} diff --git a/applications/nfc/scenes/nfc_scene_retry_confirm.c b/applications/nfc/scenes/nfc_scene_retry_confirm.c new file mode 100644 index 00000000..f7b3991e --- /dev/null +++ b/applications/nfc/scenes/nfc_scene_retry_confirm.c @@ -0,0 +1,47 @@ +#include "../nfc_i.h" + +void nfc_scene_retry_confirm_dialog_callback(DialogExResult result, void* context) { + Nfc* nfc = context; + + view_dispatcher_send_custom_event(nfc->view_dispatcher, result); +} + +void nfc_scene_retry_confirm_on_enter(void* context) { + Nfc* nfc = context; + DialogEx* dialog_ex = nfc->dialog_ex; + + dialog_ex_set_left_button_text(dialog_ex, "Retry"); + dialog_ex_set_right_button_text(dialog_ex, "Stay"); + dialog_ex_set_header(dialog_ex, "Retry reading?", 64, 11, AlignCenter, AlignTop); + dialog_ex_set_text( + dialog_ex, "All unsaved data will be\nlost.", 64, 25, AlignCenter, AlignTop); + dialog_ex_set_context(dialog_ex, nfc); + dialog_ex_set_result_callback(dialog_ex, nfc_scene_retry_confirm_dialog_callback); + + view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewDialogEx); +} + +bool nfc_scene_retry_confirm_on_event(void* context, SceneManagerEvent event) { + Nfc* nfc = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == DialogExResultRight) { + consumed = scene_manager_previous_scene(nfc->scene_manager); + } else if(event.event == DialogExResultLeft) { + consumed = scene_manager_search_and_switch_to_previous_scene( + nfc->scene_manager, NfcSceneRead); + } + } else if(event.type == SceneManagerEventTypeBack) { + consumed = true; + } + + return consumed; +} + +void nfc_scene_retry_confirm_on_exit(void* context) { + Nfc* nfc = context; + + // Clean view + dialog_ex_reset(nfc->dialog_ex); +} diff --git a/applications/nfc/scenes/nfc_scene_run_emv_app_confirm.c b/applications/nfc/scenes/nfc_scene_run_emv_app_confirm.c deleted file mode 100755 index 5ee9f442..00000000 --- a/applications/nfc/scenes/nfc_scene_run_emv_app_confirm.c +++ /dev/null @@ -1,49 +0,0 @@ -#include "../nfc_i.h" - -void nfc_scene_run_emv_app_confirm_dialog_callback(DialogExResult result, void* context) { - Nfc* nfc = context; - - view_dispatcher_send_custom_event(nfc->view_dispatcher, result); -} - -void nfc_scene_run_emv_app_confirm_on_enter(void* context) { - Nfc* nfc = context; - - DialogEx* dialog_ex = nfc->dialog_ex; - dialog_ex_set_left_button_text(dialog_ex, "Back"); - dialog_ex_set_right_button_text(dialog_ex, "Run"); - dialog_ex_set_header(dialog_ex, "Run EMV app?", 64, 8, AlignCenter, AlignCenter); - dialog_ex_set_text( - dialog_ex, - "It will try to run card's app\nand detect unencrypted\ndata", - 64, - 18, - AlignCenter, - AlignTop); - dialog_ex_set_context(dialog_ex, nfc); - dialog_ex_set_result_callback(dialog_ex, nfc_scene_run_emv_app_confirm_dialog_callback); - - view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewDialogEx); -} - -bool nfc_scene_run_emv_app_confirm_on_event(void* context, SceneManagerEvent event) { - Nfc* nfc = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == DialogExResultLeft) { - consumed = scene_manager_previous_scene(nfc->scene_manager); - } else if(event.event == DialogExResultRight) { - scene_manager_next_scene(nfc->scene_manager, NfcSceneReadEmvData); - consumed = true; - } - } - return consumed; -} - -void nfc_scene_run_emv_app_confirm_on_exit(void* context) { - Nfc* nfc = context; - - // Clean view - dialog_ex_reset(nfc->dialog_ex); -} diff --git a/applications/nfc/scenes/nfc_scene_save_success.c b/applications/nfc/scenes/nfc_scene_save_success.c index 5c15a509..355f4a80 100644 --- a/applications/nfc/scenes/nfc_scene_save_success.c +++ b/applications/nfc/scenes/nfc_scene_save_success.c @@ -27,13 +27,9 @@ bool nfc_scene_save_success_on_event(void* context, SceneManagerEvent event) { if(event.type == SceneManagerEventTypeCustom) { if(event.event == NfcCustomEventViewExit) { - if(scene_manager_has_previous_scene(nfc->scene_manager, NfcSceneCardMenu)) { + if(scene_manager_has_previous_scene(nfc->scene_manager, NfcSceneMfDesfireMenu)) { consumed = scene_manager_search_and_switch_to_previous_scene( - nfc->scene_manager, NfcSceneCardMenu); - } else if(scene_manager_has_previous_scene( - nfc->scene_manager, NfcSceneMifareDesfireMenu)) { - consumed = scene_manager_search_and_switch_to_previous_scene( - nfc->scene_manager, NfcSceneMifareDesfireMenu); + nfc->scene_manager, NfcSceneMfDesfireMenu); } else { consumed = scene_manager_search_and_switch_to_previous_scene( nfc->scene_manager, NfcSceneStart); diff --git a/applications/nfc/scenes/nfc_scene_saved_menu.c b/applications/nfc/scenes/nfc_scene_saved_menu.c index f2b2dea3..269864ca 100644 --- a/applications/nfc/scenes/nfc_scene_saved_menu.c +++ b/applications/nfc/scenes/nfc_scene_saved_menu.c @@ -61,9 +61,9 @@ bool nfc_scene_saved_menu_on_event(void* context, SceneManagerEvent event) { scene_manager_set_scene_state(nfc->scene_manager, NfcSceneSavedMenu, event.event); if(event.event == SubmenuIndexEmulate) { if(nfc->dev->format == NfcDeviceSaveFormatMifareUl) { - scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateMifareUl); + scene_manager_next_scene(nfc->scene_manager, NfcSceneMfUltralightEmulate); } else if(nfc->dev->format == NfcDeviceSaveFormatMifareClassic) { - scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateMifareClassic); + scene_manager_next_scene(nfc->scene_manager, NfcSceneMfClassicEmulate); } else { scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateUid); } diff --git a/applications/nfc/scenes/nfc_scene_scripts_menu.c b/applications/nfc/scenes/nfc_scene_scripts_menu.c deleted file mode 100755 index 446b9d82..00000000 --- a/applications/nfc/scenes/nfc_scene_scripts_menu.c +++ /dev/null @@ -1,82 +0,0 @@ -#include "../nfc_i.h" - -enum SubmenuIndex { - SubmenuIndexBankCard, - SubmenuIndexMifareUltralight, - SubmenuIdexReadMfClassic, - SubmenuIndexMifareDesfire, -}; - -void nfc_scene_scripts_menu_submenu_callback(void* context, uint32_t index) { - Nfc* nfc = context; - view_dispatcher_send_custom_event(nfc->view_dispatcher, index); -} - -void nfc_scene_scripts_menu_on_enter(void* context) { - Nfc* nfc = context; - Submenu* submenu = nfc->submenu; - - submenu_add_item( - submenu, - "Read Bank Card", - SubmenuIndexBankCard, - nfc_scene_scripts_menu_submenu_callback, - nfc); - submenu_add_item( - submenu, - "Read Mifare Ultral/Ntag", - SubmenuIndexMifareUltralight, - nfc_scene_scripts_menu_submenu_callback, - nfc); - submenu_add_item( - submenu, - "Read Mifare Classic", - SubmenuIdexReadMfClassic, - nfc_scene_scripts_menu_submenu_callback, - nfc); - submenu_add_item( - submenu, - "Read Mifare DESFire", - SubmenuIndexMifareDesfire, - nfc_scene_scripts_menu_submenu_callback, - nfc); - submenu_set_selected_item( - nfc->submenu, scene_manager_get_scene_state(nfc->scene_manager, NfcSceneScriptsMenu)); - view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewMenu); -} - -bool nfc_scene_scripts_menu_on_event(void* context, SceneManagerEvent event) { - Nfc* nfc = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == SubmenuIndexBankCard) { - scene_manager_set_scene_state( - nfc->scene_manager, NfcSceneScriptsMenu, SubmenuIndexBankCard); - scene_manager_next_scene(nfc->scene_manager, NfcSceneReadEmvApp); - consumed = true; - } else if(event.event == SubmenuIndexMifareUltralight) { - scene_manager_set_scene_state( - nfc->scene_manager, NfcSceneScriptsMenu, SubmenuIndexMifareUltralight); - scene_manager_next_scene(nfc->scene_manager, NfcSceneReadMifareUl); - consumed = true; - } else if(event.event == SubmenuIdexReadMfClassic) { - scene_manager_set_scene_state( - nfc->scene_manager, NfcSceneScriptsMenu, SubmenuIdexReadMfClassic); - scene_manager_next_scene(nfc->scene_manager, NfcSceneReadMifareClassic); - consumed = true; - } else if(event.event == SubmenuIndexMifareDesfire) { - scene_manager_set_scene_state( - nfc->scene_manager, NfcSceneScriptsMenu, SubmenuIndexMifareDesfire); - scene_manager_next_scene(nfc->scene_manager, NfcSceneReadMifareDesfire); - consumed = true; - } - } - - return consumed; -} - -void nfc_scene_scripts_menu_on_exit(void* context) { - Nfc* nfc = context; - submenu_reset(nfc->submenu); -} diff --git a/applications/nfc/scenes/nfc_scene_start.c b/applications/nfc/scenes/nfc_scene_start.c index d64aa76e..01ffb46b 100644 --- a/applications/nfc/scenes/nfc_scene_start.c +++ b/applications/nfc/scenes/nfc_scene_start.c @@ -2,8 +2,9 @@ enum SubmenuIndex { SubmenuIndexRead, - SubmenuIndexRunScript, + SubmenuIndexDetectReader, SubmenuIndexSaved, + SubmenuIndexExtraAction, SubmenuIndexAddManualy, SubmenuIndexDebug, }; @@ -18,15 +19,12 @@ void nfc_scene_start_on_enter(void* context) { Nfc* nfc = context; Submenu* submenu = nfc->submenu; + submenu_add_item(submenu, "Read", SubmenuIndexRead, nfc_scene_start_submenu_callback, nfc); submenu_add_item( - submenu, "Read Card", SubmenuIndexRead, nfc_scene_start_submenu_callback, nfc); - submenu_add_item( - submenu, - "Run Special Action", - SubmenuIndexRunScript, - nfc_scene_start_submenu_callback, - nfc); + submenu, "Detect Reader", SubmenuIndexDetectReader, nfc_scene_start_submenu_callback, nfc); submenu_add_item(submenu, "Saved", SubmenuIndexSaved, nfc_scene_start_submenu_callback, nfc); + submenu_add_item( + submenu, "Extra Actions", SubmenuIndexExtraAction, nfc_scene_start_submenu_callback, nfc); submenu_add_item( submenu, "Add Manually", SubmenuIndexAddManualy, nfc_scene_start_submenu_callback, nfc); @@ -48,14 +46,17 @@ bool nfc_scene_start_on_event(void* context, SceneManagerEvent event) { if(event.type == SceneManagerEventTypeCustom) { if(event.event == SubmenuIndexRead) { - scene_manager_next_scene(nfc->scene_manager, NfcSceneReadCard); + scene_manager_next_scene(nfc->scene_manager, NfcSceneRead); consumed = true; - } else if(event.event == SubmenuIndexRunScript) { - scene_manager_next_scene(nfc->scene_manager, NfcSceneScriptsMenu); + } else if(event.event == SubmenuIndexDetectReader) { + scene_manager_next_scene(nfc->scene_manager, NfcSceneDetectReader); consumed = true; } else if(event.event == SubmenuIndexSaved) { scene_manager_next_scene(nfc->scene_manager, NfcSceneFileSelect); consumed = true; + } else if(event.event == SubmenuIndexExtraAction) { + scene_manager_next_scene(nfc->scene_manager, NfcSceneExtraActions); + consumed = true; } else if(event.event == SubmenuIndexAddManualy) { scene_manager_next_scene(nfc->scene_manager, NfcSceneSetType); consumed = true; diff --git a/applications/nfc/views/dict_attack.c b/applications/nfc/views/dict_attack.c index 0f9da494..25690005 100644 --- a/applications/nfc/views/dict_attack.c +++ b/applications/nfc/views/dict_attack.c @@ -1,83 +1,60 @@ #include "dict_attack.h" -#include +#include #include typedef enum { - DictAttackStateSearchCard, - DictAttackStateSearchKeys, + DictAttackStateRead, DictAttackStateCardRemoved, - DictAttackStateSuccess, - DictAttackStateFail, } DictAttackState; struct DictAttack { View* view; - DictAttackResultCallback callback; + DictAttackCallback callback; void* context; }; typedef struct { DictAttackState state; MfClassicType type; - uint8_t current_sector; - uint8_t total_sectors; - uint8_t keys_a_found; - uint8_t keys_a_total; - uint8_t keys_b_found; - uint8_t keys_b_total; + string_t header; + uint8_t sectors_total; + uint8_t sectors_read; + uint8_t sector_current; + uint8_t keys_total; + uint8_t keys_found; } DictAttackViewModel; static void dict_attack_draw_callback(Canvas* canvas, void* model) { DictAttackViewModel* m = model; - if(m->state == DictAttackStateSearchCard) { + if(m->state == DictAttackStateCardRemoved) { canvas_set_font(canvas, FontPrimary); - canvas_draw_str_aligned( - canvas, 64, 32, AlignCenter, AlignCenter, "Detecting Mifare Classic"); - } else if(m->state == DictAttackStateCardRemoved) { - canvas_set_font(canvas, FontPrimary); - canvas_draw_str_aligned( - canvas, 64, 32, AlignCenter, AlignTop, "Place card back to flipper"); - } else { - char draw_str[32]; - if(m->state == DictAttackStateSearchKeys) { - snprintf( - draw_str, sizeof(draw_str), "Searching keys for sector %d", m->current_sector); - canvas_draw_str_aligned(canvas, 64, 2, AlignCenter, AlignTop, draw_str); - } else if(m->state == DictAttackStateSuccess) { - canvas_draw_str_aligned(canvas, 64, 2, AlignCenter, AlignTop, "Complete!"); - elements_button_right(canvas, "More"); - } else if(m->state == DictAttackStateFail) { - canvas_draw_str_aligned( - canvas, 64, 2, AlignCenter, AlignTop, "Failed to read any sector"); - } - uint16_t keys_found = m->keys_a_found + m->keys_b_found; - uint16_t keys_total = m->keys_a_total + m->keys_b_total; - float progress = (float)(m->current_sector) / (float)(m->total_sectors); - elements_progress_bar(canvas, 5, 12, 120, progress); + canvas_draw_str_aligned(canvas, 64, 4, AlignCenter, AlignTop, "Lost the tag!"); canvas_set_font(canvas, FontSecondary); - snprintf(draw_str, sizeof(draw_str), "Total keys found: %d/%d", keys_found, keys_total); - canvas_draw_str_aligned(canvas, 1, 23, AlignLeft, AlignTop, draw_str); + elements_multiline_text_aligned( + canvas, 64, 23, AlignCenter, AlignTop, "Make sure the tag is\npositioned correctly."); + } else if(m->state == DictAttackStateRead) { + char draw_str[32] = {}; + canvas_set_font(canvas, FontPrimary); + canvas_draw_str_aligned(canvas, 64, 2, AlignCenter, AlignTop, string_get_cstr(m->header)); + canvas_set_font(canvas, FontSecondary); + float progress = + m->sectors_total == 0 ? 0 : (float)(m->sector_current) / (float)(m->sectors_total); + elements_progress_bar(canvas, 5, 15, 120, progress); + canvas_set_font(canvas, FontSecondary); + snprintf(draw_str, sizeof(draw_str), "Keys found: %d/%d", m->keys_found, m->keys_total); + canvas_draw_str_aligned(canvas, 1, 28, AlignLeft, AlignTop, draw_str); snprintf( - draw_str, sizeof(draw_str), "A keys found: %d/%d", m->keys_a_found, m->keys_a_total); - canvas_draw_str_aligned(canvas, 1, 34, AlignLeft, AlignTop, draw_str); - snprintf( - draw_str, sizeof(draw_str), "B keys found: %d/%d", m->keys_b_found, m->keys_b_total); - canvas_draw_str_aligned(canvas, 1, 45, AlignLeft, AlignTop, draw_str); + draw_str, sizeof(draw_str), "Sectors Read: %d/%d", m->sectors_read, m->sectors_total); + canvas_draw_str_aligned(canvas, 1, 40, AlignLeft, AlignTop, draw_str); } + elements_button_center(canvas, "Skip"); } static bool dict_attack_input_callback(InputEvent* event, void* context) { DictAttack* dict_attack = context; bool consumed = false; - DictAttackState state; - with_view_model( - dict_attack->view, (DictAttackViewModel * model) { - state = model->state; - return false; - }); - if(state == DictAttackStateSuccess && event->type == InputTypeShort && - event->key == InputKeyRight) { + if(event->type == InputTypeShort && event->key == InputKeyOk) { if(dict_attack->callback) { dict_attack->callback(dict_attack->context); } @@ -93,11 +70,21 @@ DictAttack* dict_attack_alloc() { view_set_draw_callback(dict_attack->view, dict_attack_draw_callback); view_set_input_callback(dict_attack->view, dict_attack_input_callback); view_set_context(dict_attack->view, dict_attack); + with_view_model( + dict_attack->view, (DictAttackViewModel * model) { + string_init(model->header); + return false; + }); return dict_attack; } void dict_attack_free(DictAttack* dict_attack) { furi_assert(dict_attack); + with_view_model( + dict_attack->view, (DictAttackViewModel * model) { + string_clear(model->header); + return false; + }); view_free(dict_attack->view); free(dict_attack); } @@ -106,8 +93,15 @@ void dict_attack_reset(DictAttack* dict_attack) { furi_assert(dict_attack); with_view_model( dict_attack->view, (DictAttackViewModel * model) { - memset(model, 0, sizeof(DictAttackViewModel)); - return true; + model->state = DictAttackStateRead; + model->type = MfClassicType1k; + model->sectors_total = 0; + model->sectors_read = 0; + model->sector_current = 0; + model->keys_total = 0; + model->keys_found = 0; + string_reset(model->header); + return false; }); } @@ -116,78 +110,88 @@ View* dict_attack_get_view(DictAttack* dict_attack) { return dict_attack->view; } -void dict_attack_set_result_callback( - DictAttack* dict_attack, - DictAttackResultCallback callback, - void* context) { +void dict_attack_set_callback(DictAttack* dict_attack, DictAttackCallback callback, void* context) { furi_assert(dict_attack); furi_assert(callback); dict_attack->callback = callback; dict_attack->context = context; } -void dict_attack_card_detected(DictAttack* dict_attack, MfClassicType type) { +void dict_attack_set_header(DictAttack* dict_attack, const char* header) { + furi_assert(dict_attack); + furi_assert(header); + + with_view_model( + dict_attack->view, (DictAttackViewModel * model) { + string_set_str(model->header, header); + return true; + }); +} + +void dict_attack_set_card_detected(DictAttack* dict_attack, MfClassicType type) { furi_assert(dict_attack); with_view_model( dict_attack->view, (DictAttackViewModel * model) { - model->state = DictAttackStateSearchKeys; - if(type == MfClassicType1k) { - model->total_sectors = 16; - model->keys_a_total = 16; - model->keys_b_total = 16; - } else if(type == MfClassicType4k) { - model->total_sectors = 40; - model->keys_a_total = 40; - model->keys_b_total = 40; + model->state = DictAttackStateRead; + model->sectors_total = mf_classic_get_total_sectors_num(type); + model->keys_total = model->sectors_total * 2; + return true; + }); +} + +void dict_attack_set_card_removed(DictAttack* dict_attack) { + furi_assert(dict_attack); + with_view_model( + dict_attack->view, (DictAttackViewModel * model) { + model->state = DictAttackStateCardRemoved; + return true; + }); +} + +void dict_attack_set_sector_read(DictAttack* dict_attack, uint8_t sec_read) { + furi_assert(dict_attack); + with_view_model( + dict_attack->view, (DictAttackViewModel * model) { + model->sectors_read = sec_read; + return true; + }); +} + +void dict_attack_set_keys_found(DictAttack* dict_attack, uint8_t keys_found) { + furi_assert(dict_attack); + with_view_model( + dict_attack->view, (DictAttackViewModel * model) { + model->keys_found = keys_found; + return true; + }); +} + +void dict_attack_set_current_sector(DictAttack* dict_attack, uint8_t curr_sec) { + furi_assert(dict_attack); + with_view_model( + dict_attack->view, (DictAttackViewModel * model) { + model->sector_current = curr_sec; + return true; + }); +} + +void dict_attack_inc_current_sector(DictAttack* dict_attack) { + furi_assert(dict_attack); + with_view_model( + dict_attack->view, (DictAttackViewModel * model) { + if(model->sector_current < model->sectors_total) { + model->sector_current++; } return true; }); } -void dict_attack_card_removed(DictAttack* dict_attack) { +void dict_attack_inc_keys_found(DictAttack* dict_attack) { furi_assert(dict_attack); with_view_model( dict_attack->view, (DictAttackViewModel * model) { - if(model->state == DictAttackStateSearchKeys) { - model->state = DictAttackStateCardRemoved; - } else { - model->state = DictAttackStateSearchCard; - } - return true; - }); -} - -void dict_attack_inc_curr_sector(DictAttack* dict_attack) { - furi_assert(dict_attack); - with_view_model( - dict_attack->view, (DictAttackViewModel * model) { - model->current_sector++; - return true; - }); -} - -void dict_attack_inc_found_key(DictAttack* dict_attack, MfClassicKey key) { - furi_assert(dict_attack); - with_view_model( - dict_attack->view, (DictAttackViewModel * model) { - model->state = DictAttackStateSearchKeys; - if(key == MfClassicKeyA) { - model->keys_a_found++; - } else if(key == MfClassicKeyB) { - model->keys_b_found++; - } - return true; - }); -} - -void dict_attack_set_result(DictAttack* dict_attack, bool success) { - furi_assert(dict_attack); - with_view_model( - dict_attack->view, (DictAttackViewModel * model) { - if(success) { - model->state = DictAttackStateSuccess; - } else { - model->state = DictAttackStateFail; + if(model->keys_found < model->keys_total) { + model->keys_found++; } return true; }); diff --git a/applications/nfc/views/dict_attack.h b/applications/nfc/views/dict_attack.h index f8d5afca..3f557b19 100644 --- a/applications/nfc/views/dict_attack.h +++ b/applications/nfc/views/dict_attack.h @@ -3,11 +3,11 @@ #include #include -#include +#include typedef struct DictAttack DictAttack; -typedef void (*DictAttackResultCallback)(void* context); +typedef void (*DictAttackCallback)(void* context); DictAttack* dict_attack_alloc(); @@ -17,17 +17,20 @@ void dict_attack_reset(DictAttack* dict_attack); View* dict_attack_get_view(DictAttack* dict_attack); -void dict_attack_set_result_callback( - DictAttack* dict_attack, - DictAttackResultCallback callback, - void* context); +void dict_attack_set_callback(DictAttack* dict_attack, DictAttackCallback callback, void* context); -void dict_attack_card_detected(DictAttack* dict_attack, MfClassicType type); +void dict_attack_set_header(DictAttack* dict_attack, const char* header); -void dict_attack_card_removed(DictAttack* dict_attack); +void dict_attack_set_card_detected(DictAttack* dict_attack, MfClassicType type); -void dict_attack_inc_curr_sector(DictAttack* dict_attack); +void dict_attack_set_card_removed(DictAttack* dict_attack); -void dict_attack_inc_found_key(DictAttack* dict_attack, MfClassicKey key); +void dict_attack_set_sector_read(DictAttack* dict_attack, uint8_t sec_read); -void dict_attack_set_result(DictAttack* dict_attack, bool success); +void dict_attack_set_keys_found(DictAttack* dict_attack, uint8_t keys_found); + +void dict_attack_set_current_sector(DictAttack* dict_attack, uint8_t curr_sec); + +void dict_attack_inc_current_sector(DictAttack* dict_attack); + +void dict_attack_inc_keys_found(DictAttack* dict_attack); diff --git a/applications/unit_tests/nfc/nfc_test.c b/applications/unit_tests/nfc/nfc_test.c index 13060a6d..dcd162d1 100644 --- a/applications/unit_tests/nfc/nfc_test.c +++ b/applications/unit_tests/nfc/nfc_test.c @@ -2,7 +2,7 @@ #include #include #include -#include +#include #include #include diff --git a/assets/icons/NFC/NFC_manual.png b/assets/icons/NFC/NFC_manual.png new file mode 100644 index 0000000000000000000000000000000000000000..d142f0fcf6c043f990efad9cfa7eca1417499b2f GIT binary patch literal 3785 zcmaJ^c|26@+dq~HWl5Hhj1f-@W(*@HV_!y%Ft$;NF=iNMYm8-xl%$d^Th@d~4W$&x zmdH*N31!KW&{#sUz0>o1dVcR8Z}0hh&bhDqzOV21TF>X)=bFt)3t=HyApih`Em5Wz z?x@YZ;R1ZzCsOo_5da98kW5T$EKN*6bOwz`A`<{0us_o-0GqHPr9ZSn5Op-}n=45n zUj)EPY=I^*=Nz${0PeDwxM4%YRUtKMdLPK=FA5GTo;?+rPdK65m%zT*7QX5|fDen9MGC#TL_ISvTCDb;qVjPkx`!&YiQ$?sux7pQH4*G)HK|QK8G+ z-OYiZIpAEHVQNurZurJI9M!)V6EoS$Z>&LGnN-?rjJU87bEs=ntK^KTH=(DA$dbEAwU>lU$L$|`E1A2R&s6VHy++75p1_VU>Lfnc0+b& zJRs(&1!JuMKtj!Gtl<$Jpgkq;GXPY6*?Z<*qBQ!o005X~Up)NCXveOX66{)$jF+3ekEBVwg5HFSh0hsDoaoTf`} zciWp)x3}_&Aiq(Qz#g0;;_7bqm_BfafOKjMKNyG7x*3)Snz|}s3vOs)}9b!@};;q3oIIIa!+|isZ_i|z)3LtvPRus;DmeDrOH9#tM!5Ih>|$0 zIa}qM;(o;}<+Fc@>~T#%9S~{0Id)P=Q8^A~xzo}IHGopfv&+-(79(Y#Ri@)8&7Z~u z9*40(De+}-qH)$Y*P36Al}R8Pu8yJwa}Hqg62*_h2?pc*cW=XtQ?u{ewijl-6S#jB zar=}dCEMQyVi#GsN6RlwxjkLVq%}`1x93e7$&<9=1({-22!0ITZI3!JvnAf2aKe2hj&-9YgZX9iG^HE);wx^`NIv-r+@|c5w$L026D| zY3rI>?YeR4CtmpRl?e0fE2vz1eA#Q6Xho^lFv2|6xR>F`H?8V(%gX)q(+5Vux@?uo|D5fm%tgcM-8DwCHGmP=9s5 z`z&KtYIeGx<44al%v8->LQoJZeu5R+6}A--6$5^qU-jSOr&&{iOD#(xQy;r5mMGtI zm!!XPdO2MRN1<8*+Ho>u4ITVkTO9t2&n;4U*WBfid%Ih`D&p(Ca=R>Z|0-Ac7U}sJ z9w@C(WYhM!v$Z}E27UB!?j+biUVUD}SoNXyM4vQbMOW!tW?Ng6>L9z1-8>Vc+mqpw zg{%HhIj|lban~%P;dqpGRAX{~^7+|2idjx5I|$MHj-N!a$L&$?QEA@1_W|vn;j?wqI73}D_w$GUb=>>I*ag&g< z{%4)fu2t=~ev+Y*)eEIG4b-0=u4)Z-L+B$3KRc%Q^k3`q-VVAQS)E@E9zs?th4zM~ zhVEF;T08c$btCpi%?N8jYX0OlH=dU~<2+RtWiLMA^WjtAPvyV61HLVK+l%dxUHX#7 zy99-u6&MM$TImJ3RlMe)r)pZ4WQ#ziHsJk?;qS@zCS%C> zne_6o^84i%10#Q!&8LVn_Z$$My*5_gSC72**_U^coTiyEmS&&K#21eb<~*04nCfWF z3eakeu4YJHr%VKa)w zI4pRx1{Y#5;oW!dnjE?0q?J^d*xX7j{(kB?UJ{q&;lS}u={fCq;jna)E1S-~SN!9V zdHKYs(@EE!^GhsBfB&cBWi7MQsOh|EDtpDb=Hc-wZ=;?!SLTF^%?ORn$y`ek`{Lux`kT4Za(^W7&)|?aic-2OrkdJQk#2 zw4?W<5cKi%Fj{~5Y+Arm`l-Vrbw=Ya{~F3aAN<+o%bku_gRk0$QZJM(2~49{N4gO; zer&Z|N;dLN73a&1+)Vki@)p%)TcI3{&v?H^c&t-acIH9k{OZ`HgwF*Y1zDLV4Uq3r z2U#oV^;91hTbC+Nlg=yyY34U{nd?gP;-|@2m$^#%ckqh)fO6T1B4jbrB9y){f_iwG zHceP*opsVHW`4JtKGwx~d*P>dZIAE!AMe#&ZnLU5uV>`Ss45@#l`B^){qSF&l@1X4 zh8}bYiVb|YUfsX(b;nQ9uNO);O9-`;;U8|bZk?~3ML8mZky)FGTW=#rx-Hr)dX&tS zqGK}^6y$_us}?*u5=IIh7wqY533c3JP5VBW9NHLNJJE?<@0;7X8r4}-%qm=Da2^ys zL^LWjDpYo`kn{QLMI8enoN`XZP-B%s>cMrxO`FB8pZLatH`Xiqljk?rAuE>`*TQs_ zcXLmbGE6fp(~d@D2H+S3z{rEKp&(Rh~N@X2uvI(kV2;VA_9@%zj+Z{`PVW84EkGz>4OCS$0@9p4akJXAb^gl z!_@FlC=_&5R~@dcO>oD<-L+IfFenTLfx;nBT{Wl<0tQFG;h=vmFxMc%gNVSGn*U>t zJ41rKm`pkX0tpBRP!G^lr!hPs8oIi=5GV`+gQ;;f)O=Y~CN5Bo>Z|md!Ia>OXOQSj z5{(M_#fWpK`7x1TuCxD%fYZs44eL3pdfwFf%oRo9mbx z=|atn;TmQ~%{6{wO=);P3W3V}jrI61R_Bk{UkyQ_b1j<^7$kp!hdF~r0sS2{g7jx! z;D6-%2kY@?U$p;-g>apL{HpE$s`c+BZUg-i|7~9GF^l|QmiG6zL|?Z9Mjo<1=7qv{VsCIy9lXQ* zhEJ=17~6Wsy)-;EbvzO$E^=GEWx4I%K}^G)j5oHHrJAy<-Nu52r2*^`Kh4v*5nf)G z^Gz*P)ZQT<3^oRrY@{e+%Q!RS?eevkM?3J(_1~R?ehm=VLB7#)$dbfdRYYgpEp5t+ s3XUk+l1M+)O`IlT5V=EGecoN%KT@84gF@y2H$uSD?4)V2vD>Bp0cbL;?f?J) literal 0 HcmV?d00001 diff --git a/assets/icons/NFC/Reader_detect.png b/assets/icons/NFC/Reader_detect.png new file mode 100644 index 0000000000000000000000000000000000000000..56d3663eaa2666f68493fa3088f9beab1bcf0717 GIT binary patch literal 3771 zcmaJ@c{r4N`+r3CEm@Lu#*i&$jI|kKn;E+yjEtpaFvg@=jH$7dsBA4H*&AuGFO@Z+ zY@vjZvP(#E@E%K?#JuCYr}O^)`1L;5^E}`C{$BUzb1&b|b6rpTQAcYr;r+q@0EpSz zU|hKCVeX?Y$jf~nm0R%!0AWiq8hz9jjRw&fG=K6LA^?O8vt3Cz*Ev~}_3>4deO%;i zdzy=kAjk!EEmAs3RZ~ew(k@Qv-jIxQ(;iDpK822)INpSW$m=rBTB28l2L+~;?k8M+ z5O?+U=4AMT!1wj*pS!lJKA6sytgtJ31R4cJQ*HE|4I)JgQ3v;YyxiW}HaQJ3j}lg) z1CoLjeoDbx$~?eE1QK}|+$iuI;0fs$5d<2sS&cdeVmT6DQ5oJmkym&cnMp_N1tX;a z^RNU|9$;?86Uk0jbp>+xfK#2mK2yL^ZQzvJ#n1gfBzq$xoCol_tt7*flLUbF65}vH zfH6?gbL^@mfY$+}{q0-fz@RpuW9#m313az)8oMP$$^k)9K*u>QS_9w<2TpY;D~AAA zG5~3-Wq0Hshsz{qHMx_@C`Z<+z%8S^1hs<%+}$Au)w^xw4oe#nb`dhoA2 z?ptU6j6nWaU;Fs{lS-8C@hEG)jgQT5RvmH=^xP7<;xqa=(fUV?2@JFlz_>+zM`88jz`_nczLLg!T@-D+LR|eNxR^kF8E|>Bhs9Yk+p^9%1VsAV-UxTDc-xdc*3@4hR+jSbh>=V#yJ);9@Ye79Zq9v5<+xY}sB3j(G|M9UB-n#fT z-<~HdKB*|nMj=B!779c-XkmkQz&j4w6o3w>=fd$?!OItC5OSJX%++_U10zCl7IbQhio^R2Strt->sQoBhhkuZH~s z%LU-KwLphEqNmx@Ez^3_3e!rsq)y$aEPi zxQE+gkm!jjy;tq>$T_xPum0Igc-LiFTl?J7`zihV1LOkM$&bD;pY0h-Ip~=7*1fND z&iYH*7v5Ets9225<@Pv|x_s6?fqf)-*1kvS4tetZ*W}xAI!3Vh^w|uF44NBWvs&}K zOww!N6uT7F6a`HvuCOStXuL?oZN;quSY?MK(>XWXa^XD|{ z(zg`ru9*}S-h-p{?DX6#Tvl%Tn+Z&%2W{M8IttCI=clbiTpgEQ()gsIkf-lZ3nO|5 z7Nw@8;)`vHor|sK8w|@9^4WO}mUSMRQQ{Wuc52>g)}+Ml-RxP{A=j~d;e1)F31Y1b zQWTi0aIX%-dO^)!OwWFPA~M^7mOmcaF#G+$1?U!Ti}F2x%~}-CUm>c(KO)+_5Bbs{ zh=x>zwvYVbj6U9Cj?N{d5Yi^EB-QpJ9}HOCu#&h=Zu6c}nWD5&+8(I#t17A5W4~e- zGhMK?c^Y}f4#p1cU2nSXcfHRr$TER_(4Ebi&H9ivQFF>O#8a!fp!zA%wtU(%&ttK= zo*L~5_sGS&c^rfz zNIr6;nwMoQi^&bi7oJ_Xv1KA47CR(ftmvs25nRcTMjS(oXLjFNG`sL}HFXY3!uLq_ z4C+l)@9orRC9_?#`mITFq}t%iD{mZVSQ`ttctAW zg@Tbsi-wEj#n{oiZ}jhKWP9iZzisJ2e{`PdH50j;q7yh#65)h)iXv6bDnostN$#Z| z9@pfuiq;8Ba;D!*8F!~lr;tYDy5k-v-xxL4bkuY@wa~IpMo*wGDs%ieVVqtdKk^U{ zi8nsVBFbym=0@0gr56cih!Ntq@}UKb>p8U+G8T!KN-xbcl_~{v{C=}kX?-@mJE@y2 z9(^?8%lo$igwKR)EfJz>(Xr9)F=h$$IQ;%zSegN=cN85wf%%R}#f)c>U{3Hy+I9w- zrbUp`$YG;r`p?YTApRb22JmdW?HT(6aENA^A@$7ji609qv7gwVM5e;!(xDy4>7n@YK1rJ9mE{QvJly_ndd+hT@yqD?DDOon?a}|C2Vpv=_~28 z|GCZ*Vs!cTOX{^6=)n|$SAi8bOLlu`3sf9K6cWp)d=Z2Eg@N#5O=!o!?%sYPj@)5NJ_L&KF~6UQnS*1lPe zK-0R^N9rzDqiY|$Kt8P}=D+IhGB(3K#I54K;|v%3#;OP(HmJRe3gPwN^nV{1@v2|n zGJW-Y#Er)dJK#S++_c@SST`$+FPhs(-J~2Zb)*C>wDb1yZV4!hSAVE|H=x*Of^$iH ze|X+ny#2T5+w3KlwwR%q+l@PIpOopC(CN8#p^5c_Vu;~$*TYLD1^RzGr$|zSosW^Q`v-4?>yh6i?&u>uLhV*?ugJr5m->@Q%RSfGDeMaokUvLH zjohyepY`pYI4wb2dM3%7?6c%tn>DUC?)F}O%3LlVnc3_9)IIYN;w0rO^DA;Yx!?q?P6F%Rk;89oIbwBD)y5GUyo|G-1hzL&N4Y!XvD_A{Dt(7 z89`v$zB)QOAR{=0=tt1?(eo$xYJqfhbYV~!_cqdo86kA_5HL9C?+eUL$nf(=xL~aQ zPRI33zyVAq9RY>1SS$!j4?<&*pfETb4%N|x>gsB9Bea7re9Ltzk|ovwZcVzK`_ltTF@I+*D~ z{BOPgFL5v~lum@Y5QAxF8NS@J^H<(UMMt0+L;{n>z|m-Deh%_z0F6lt4xrINx_S^8 zNF7V?B~y2HH2#8Mu?SmgFq1&_CE8+4z+4gtne2zKFwn-<1Ycc#K7RoIKx^uSw=d6EjaRszv{v%$l^N;+ARIcV3TydkQgM-`;ga4=l z&XT)wIGo&}yJK8y7t_Vjl>^Mw=-6?+r?waiT*z?cK(Evlkf3>QCx^32O*o`}v$7O= zLoc5{N^(!zEvAy^^v2;N?D_L4B*T~5p4me}6@#favJF&P$70~$N+Z4>sq{OSKzO+{ zC^Io*QIEVcQfxSwTXHA&OH~GWUV$l>_^fcccLE1n)z($>w47$&FfNX(QvUvSI5`@2 z1n(7YC?Nn>F3l?3owvs((0fU7yZ^;*ukRD6Iy3uQlkMBTPo-serVnhg%x9 #include -#include +#include #ifdef __cplusplus extern "C" { diff --git a/furi/core/common_defines.h b/furi/core/common_defines.h index d75f7592..e95e45f7 100644 --- a/furi/core/common_defines.h +++ b/furi/core/common_defines.h @@ -88,6 +88,10 @@ extern "C" { #define FURI_BIT(x, n) (((x) >> (n)) & 1) #endif +#ifndef FURI_BIT_SET +#define FURI_BIT_SET(x, n) ((x) |= (1 << (n))) +#endif + #ifndef FURI_IS_IRQ_MASKED #define FURI_IS_IRQ_MASKED() (__get_PRIMASK() != 0U) #endif diff --git a/lib/SConscript b/lib/SConscript index a3617c5d..c5bc3947 100644 --- a/lib/SConscript +++ b/lib/SConscript @@ -70,6 +70,7 @@ libs = env.BuildModules( "infrared", "littlefs", "subghz", + "nfc", "appframe", "misc", "mbedtls", diff --git a/lib/misc.scons b/lib/misc.scons index 91a11ff6..5a826b18 100644 --- a/lib/misc.scons +++ b/lib/misc.scons @@ -7,7 +7,6 @@ env.Append( "#/lib/heatshrink", "#/lib/micro-ecc", "#/lib/nanopb", - "#/lib/nfc_protocols", "#/lib/u8g2", ], CPPDEFINES=[ @@ -24,7 +23,6 @@ sources = [] libs_recurse = [ "digital_signal", "micro-ecc", - "nfc_protocols", "one_wire", "u8g2", "update_util", diff --git a/lib/nfc/SConscript b/lib/nfc/SConscript new file mode 100644 index 00000000..657f3a9e --- /dev/null +++ b/lib/nfc/SConscript @@ -0,0 +1,16 @@ +Import("env") + +env.Append( + CPPPATH=[ + "#/lib/nfc", + ], +) + +libenv = env.Clone(FW_LIB_NAME="nfc") +libenv.ApplyLibFlags() + +sources = libenv.GlobRecursive("*.c*") + +lib = libenv.StaticLibrary("${FW_LIB_NAME}", sources) +libenv.Install("${LIB_DIST_DIR}", lib) +Return("lib") diff --git a/lib/nfc/helpers/mf_classic_dict.c b/lib/nfc/helpers/mf_classic_dict.c new file mode 100644 index 00000000..410ddbd8 --- /dev/null +++ b/lib/nfc/helpers/mf_classic_dict.c @@ -0,0 +1,148 @@ +#include "mf_classic_dict.h" + +#include +#include + +#define MF_CLASSIC_DICT_FLIPPER_PATH EXT_PATH("nfc/assets/mf_classic_dict.nfc") +#define MF_CLASSIC_DICT_USER_PATH EXT_PATH("nfc/assets/mf_classic_dict_user.nfc") + +#define TAG "MfClassicDict" + +#define NFC_MF_CLASSIC_KEY_LEN (13) + +struct MfClassicDict { + Stream* stream; + uint32_t total_keys; +}; + +bool mf_classic_dict_check_presence(MfClassicDictType dict_type) { + Storage* storage = furi_record_open(RECORD_STORAGE); + + bool dict_present = false; + if(dict_type == MfClassicDictTypeFlipper) { + dict_present = storage_common_stat(storage, MF_CLASSIC_DICT_FLIPPER_PATH, NULL) == FSE_OK; + } else if(dict_type == MfClassicDictTypeUser) { + dict_present = storage_common_stat(storage, MF_CLASSIC_DICT_USER_PATH, NULL) == FSE_OK; + } + + furi_record_close(RECORD_STORAGE); + + return dict_present; +} + +MfClassicDict* mf_classic_dict_alloc(MfClassicDictType dict_type) { + MfClassicDict* dict = malloc(sizeof(MfClassicDict)); + Storage* storage = furi_record_open(RECORD_STORAGE); + dict->stream = buffered_file_stream_alloc(storage); + furi_record_close(RECORD_STORAGE); + + bool dict_loaded = false; + do { + if(dict_type == MfClassicDictTypeFlipper) { + if(!buffered_file_stream_open( + dict->stream, MF_CLASSIC_DICT_FLIPPER_PATH, FSAM_READ, FSOM_OPEN_EXISTING)) { + buffered_file_stream_close(dict->stream); + break; + } + } else if(dict_type == MfClassicDictTypeUser) { + if(!buffered_file_stream_open( + dict->stream, MF_CLASSIC_DICT_USER_PATH, FSAM_READ_WRITE, FSOM_OPEN_ALWAYS)) { + buffered_file_stream_close(dict->stream); + break; + } + } + + // Read total amount of keys + string_t next_line; + string_init(next_line); + while(true) { + if(!stream_read_line(dict->stream, next_line)) break; + if(string_get_char(next_line, 0) == '#') continue; + if(string_size(next_line) != NFC_MF_CLASSIC_KEY_LEN) continue; + dict->total_keys++; + } + string_clear(next_line); + stream_rewind(dict->stream); + + dict_loaded = true; + FURI_LOG_I(TAG, "Loaded dictionary with %d keys", dict->total_keys); + } while(false); + + if(!dict_loaded) { + buffered_file_stream_close(dict->stream); + free(dict); + dict = NULL; + } + + return dict; +} + +void mf_classic_dict_free(MfClassicDict* dict) { + furi_assert(dict); + furi_assert(dict->stream); + + buffered_file_stream_close(dict->stream); + stream_free(dict->stream); + free(dict); +} + +uint32_t mf_classic_dict_get_total_keys(MfClassicDict* dict) { + furi_assert(dict); + + return dict->total_keys; +} + +bool mf_classic_dict_get_next_key(MfClassicDict* dict, uint64_t* key) { + furi_assert(dict); + furi_assert(dict->stream); + + uint8_t key_byte_tmp = 0; + string_t next_line; + string_init(next_line); + + bool key_read = false; + *key = 0ULL; + while(!key_read) { + if(!stream_read_line(dict->stream, next_line)) break; + if(string_get_char(next_line, 0) == '#') continue; + if(string_size(next_line) != NFC_MF_CLASSIC_KEY_LEN) continue; + for(uint8_t i = 0; i < 12; i += 2) { + args_char_to_hex( + string_get_char(next_line, i), string_get_char(next_line, i + 1), &key_byte_tmp); + *key |= (uint64_t)key_byte_tmp << 8 * (5 - i / 2); + } + key_read = true; + } + + string_clear(next_line); + return key_read; +} + +bool mf_classic_dict_rewind(MfClassicDict* dict) { + furi_assert(dict); + furi_assert(dict->stream); + + return stream_rewind(dict->stream); +} + +bool mf_classic_dict_add_key(MfClassicDict* dict, uint8_t* key) { + furi_assert(dict); + furi_assert(dict->stream); + + string_t key_str; + string_init(key_str); + for(size_t i = 0; i < 6; i++) { + string_cat_printf(key_str, "%02X", key[i]); + } + string_cat_printf(key_str, "\n"); + + bool key_added = false; + do { + if(!stream_seek(dict->stream, 0, StreamOffsetFromEnd)) break; + if(!stream_insert_string(dict->stream, key_str)) break; + key_added = true; + } while(false); + + string_clear(key_str); + return key_added; +} diff --git a/lib/nfc/helpers/mf_classic_dict.h b/lib/nfc/helpers/mf_classic_dict.h new file mode 100644 index 00000000..2654e668 --- /dev/null +++ b/lib/nfc/helpers/mf_classic_dict.h @@ -0,0 +1,28 @@ +#pragma once + +#include +#include +#include +#include +#include + +typedef enum { + MfClassicDictTypeUser, + MfClassicDictTypeFlipper, +} MfClassicDictType; + +typedef struct MfClassicDict MfClassicDict; + +bool mf_classic_dict_check_presence(MfClassicDictType dict_type); + +MfClassicDict* mf_classic_dict_alloc(MfClassicDictType dict_type); + +void mf_classic_dict_free(MfClassicDict* dict); + +uint32_t mf_classic_dict_get_total_keys(MfClassicDict* dict); + +bool mf_classic_dict_get_next_key(MfClassicDict* dict, uint64_t* key); + +bool mf_classic_dict_rewind(MfClassicDict* dict); + +bool mf_classic_dict_add_key(MfClassicDict* dict, uint8_t* key); diff --git a/applications/nfc/helpers/nfc_debug_pcap.c b/lib/nfc/helpers/nfc_debug_pcap.c similarity index 100% rename from applications/nfc/helpers/nfc_debug_pcap.c rename to lib/nfc/helpers/nfc_debug_pcap.c diff --git a/applications/nfc/helpers/nfc_debug_pcap.h b/lib/nfc/helpers/nfc_debug_pcap.h similarity index 100% rename from applications/nfc/helpers/nfc_debug_pcap.h rename to lib/nfc/helpers/nfc_debug_pcap.h diff --git a/applications/nfc/nfc_device.c b/lib/nfc/nfc_device.c similarity index 79% rename from applications/nfc/nfc_device.c rename to lib/nfc/nfc_device.c index a3bff23a..649a2c5f 100644 --- a/applications/nfc/nfc_device.c +++ b/lib/nfc/nfc_device.c @@ -3,20 +3,29 @@ #include "m-string.h" #include "nfc_types.h" -#include +#include +#include +#include #include +#define NFC_DEVICE_KEYS_FOLDER EXT_PATH("nfc/cache") +#define NFC_DEVICE_KEYS_EXTENSION ".keys" + static const char* nfc_file_header = "Flipper NFC device"; static const uint32_t nfc_file_version = 2; +static const char* nfc_keys_file_header = "Flipper NFC keys"; +static const uint32_t nfc_keys_file_version = 1; + // Protocols format versions -static const uint32_t nfc_mifare_classic_data_format_version = 1; +static const uint32_t nfc_mifare_classic_data_format_version = 2; NfcDevice* nfc_device_alloc() { NfcDevice* nfc_dev = malloc(sizeof(NfcDevice)); nfc_dev->storage = furi_record_open(RECORD_STORAGE); nfc_dev->dialogs = furi_record_open(RECORD_DIALOGS); string_init(nfc_dev->load_path); + string_init(nfc_dev->dev_data.parsed_data); return nfc_dev; } @@ -26,6 +35,7 @@ void nfc_device_free(NfcDevice* nfc_dev) { furi_record_close(RECORD_STORAGE); furi_record_close(RECORD_DIALOGS); string_clear(nfc_dev->load_path); + string_clear(nfc_dev->dev_data.parsed_data); free(nfc_dev); } @@ -648,6 +658,52 @@ bool nfc_device_load_bank_card_data(FlipperFormat* file, NfcDevice* dev) { return parsed; } +static void nfc_device_write_mifare_classic_block( + string_t block_str, + MfClassicData* data, + uint8_t block_num) { + string_reset(block_str); + bool is_sec_trailer = mf_classic_is_sector_trailer(block_num); + if(is_sec_trailer) { + uint8_t sector_num = mf_classic_get_sector_by_block(block_num); + MfClassicSectorTrailer* sec_tr = mf_classic_get_sector_trailer_by_sector(data, sector_num); + // Write key A + for(size_t i = 0; i < sizeof(sec_tr->key_a); i++) { + if(mf_classic_is_key_found(data, sector_num, MfClassicKeyA)) { + string_cat_printf(block_str, "%02X ", sec_tr->key_a[i]); + } else { + string_cat_printf(block_str, "?? "); + } + } + // Write Access bytes + for(size_t i = 0; i < MF_CLASSIC_ACCESS_BYTES_SIZE; i++) { + if(mf_classic_is_block_read(data, block_num)) { + string_cat_printf(block_str, "%02X ", sec_tr->access_bits[i]); + } else { + string_cat_printf(block_str, "?? "); + } + } + // Write key B + for(size_t i = 0; i < sizeof(sec_tr->key_b); i++) { + if(mf_classic_is_key_found(data, sector_num, MfClassicKeyB)) { + string_cat_printf(block_str, "%02X ", sec_tr->key_b[i]); + } else { + string_cat_printf(block_str, "?? "); + } + } + } else { + // Write data block + for(size_t i = 0; i < MF_CLASSIC_BLOCK_SIZE; i++) { + if(mf_classic_is_block_read(data, block_num)) { + string_cat_printf(block_str, "%02X ", data->block[block_num].value[i]); + } else { + string_cat_printf(block_str, "?? "); + } + } + } + string_strim(block_str); +} + static bool nfc_device_save_mifare_classic_data(FlipperFormat* file, NfcDevice* dev) { bool saved = false; MfClassicData* data = &dev->dev_data.mf_classic_data; @@ -669,23 +725,21 @@ static bool nfc_device_save_mifare_classic_data(FlipperFormat* file, NfcDevice* if(!flipper_format_write_uint32( file, "Data format version", &nfc_mifare_classic_data_format_version, 1)) break; - if(!flipper_format_write_comment_cstr( - file, "Key map is the bit mask indicating valid key in each sector")) + file, "Mifare Classic blocks, \'??\' means unknown data")) break; - if(!flipper_format_write_hex_uint64(file, "Key A map", &data->key_a_mask, 1)) break; - if(!flipper_format_write_hex_uint64(file, "Key B map", &data->key_b_mask, 1)) break; - - if(!flipper_format_write_comment_cstr(file, "Mifare Classic blocks")) break; bool block_saved = true; + string_t block_str; + string_init(block_str); for(size_t i = 0; i < blocks; i++) { string_printf(temp_str, "Block %d", i); - if(!flipper_format_write_hex( - file, string_get_cstr(temp_str), data->block[i].value, 16)) { + nfc_device_write_mifare_classic_block(block_str, data, i); + if(!flipper_format_write_string(file, string_get_cstr(temp_str), block_str)) { block_saved = false; break; } } + string_clear(block_str); if(!block_saved) break; saved = true; } while(false); @@ -694,6 +748,59 @@ static bool nfc_device_save_mifare_classic_data(FlipperFormat* file, NfcDevice* return saved; } +static void nfc_device_load_mifare_classic_block( + string_t block_str, + MfClassicData* data, + uint8_t block_num) { + string_strim(block_str); + MfClassicBlock block_tmp = {}; + bool is_sector_trailer = mf_classic_is_sector_trailer(block_num); + uint8_t sector_num = mf_classic_get_sector_by_block(block_num); + uint16_t block_unknown_bytes_mask = 0; + + string_strim(block_str); + for(size_t i = 0; i < MF_CLASSIC_BLOCK_SIZE; i++) { + char hi = string_get_char(block_str, 3 * i); + char low = string_get_char(block_str, 3 * i + 1); + uint8_t byte = 0; + if(hex_chars_to_uint8(hi, low, &byte)) { + block_tmp.value[i] = byte; + } else { + FURI_BIT_SET(block_unknown_bytes_mask, i); + } + } + + if(block_unknown_bytes_mask == 0xffff) { + // All data is unknown, exit + return; + } + + if(is_sector_trailer) { + MfClassicSectorTrailer* sec_tr_tmp = (MfClassicSectorTrailer*)&block_tmp; + // Load Key A + // Key A mask 0b0000000000111111 = 0x003f + if((block_unknown_bytes_mask & 0x003f) == 0) { + uint64_t key = nfc_util_bytes2num(sec_tr_tmp->key_a, sizeof(sec_tr_tmp->key_a)); + mf_classic_set_key_found(data, sector_num, MfClassicKeyA, key); + } + // Load Access Bits + // Access bits mask 0b0000001111000000 = 0x03c0 + if((block_unknown_bytes_mask & 0x03c0) == 0) { + mf_classic_set_block_read(data, block_num, &block_tmp); + } + // Load Key B + // Key B mask 0b1111110000000000 = 0xfc00 + if((block_unknown_bytes_mask & 0xfc00) == 0) { + uint64_t key = nfc_util_bytes2num(sec_tr_tmp->key_b, sizeof(sec_tr_tmp->key_b)); + mf_classic_set_key_found(data, sector_num, MfClassicKeyB, key); + } + } else { + if(block_unknown_bytes_mask == 0) { + mf_classic_set_block_read(data, block_num, &block_tmp); + } + } +} + static bool nfc_device_load_mifare_classic_data(FlipperFormat* file, NfcDevice* dev) { bool parsed = false; MfClassicData* data = &dev->dev_data.mf_classic_data; @@ -701,6 +808,7 @@ static bool nfc_device_load_mifare_classic_data(FlipperFormat* file, NfcDevice* uint32_t data_format_version = 0; string_init(temp_str); uint16_t data_blocks = 0; + memset(data, 0, sizeof(MfClassicData)); do { // Read Mifare Classic type @@ -715,29 +823,40 @@ static bool nfc_device_load_mifare_classic_data(FlipperFormat* file, NfcDevice* break; } + bool old_format = false; // Read Mifare Classic format version if(!flipper_format_read_uint32(file, "Data format version", &data_format_version, 1)) { // Load unread sectors with zero keys access for backward compatability if(!flipper_format_rewind(file)) break; - data->key_a_mask = 0xffffffffffffffff; - data->key_b_mask = 0xffffffffffffffff; + old_format = true; } else { - if(data_format_version != nfc_mifare_classic_data_format_version) break; - if(!flipper_format_read_hex_uint64(file, "Key A map", &data->key_a_mask, 1)) break; - if(!flipper_format_read_hex_uint64(file, "Key B map", &data->key_b_mask, 1)) break; + if(data_format_version < nfc_mifare_classic_data_format_version) { + old_format = true; + } } // Read Mifare Classic blocks bool block_read = true; + string_t block_str; + string_init(block_str); for(size_t i = 0; i < data_blocks; i++) { string_printf(temp_str, "Block %d", i); - if(!flipper_format_read_hex( - file, string_get_cstr(temp_str), data->block[i].value, 16)) { + if(!flipper_format_read_string(file, string_get_cstr(temp_str), block_str)) { block_read = false; break; } + nfc_device_load_mifare_classic_block(block_str, data, i); } + string_clear(block_str); if(!block_read) break; + + // Set keys and blocks as unknown for backward compatibility + if(old_format) { + data->key_a_mask = 0ULL; + data->key_b_mask = 0ULL; + memset(data->block_read_mask, 0, sizeof(data->block_read_mask)); + } + parsed = true; } while(false); @@ -745,6 +864,113 @@ static bool nfc_device_load_mifare_classic_data(FlipperFormat* file, NfcDevice* return parsed; } +static void nfc_device_get_key_cache_file_path(NfcDevice* dev, string_t file_path) { + uint8_t* uid = dev->dev_data.nfc_data.uid; + uint8_t uid_len = dev->dev_data.nfc_data.uid_len; + string_set_str(file_path, NFC_DEVICE_KEYS_FOLDER "/"); + for(size_t i = 0; i < uid_len; i++) { + string_cat_printf(file_path, "%02X", uid[i]); + } + string_cat_printf(file_path, NFC_DEVICE_KEYS_EXTENSION); +} + +static bool nfc_device_save_mifare_classic_keys(NfcDevice* dev) { + FlipperFormat* file = flipper_format_file_alloc(dev->storage); + MfClassicData* data = &dev->dev_data.mf_classic_data; + string_t temp_str; + string_init(temp_str); + + nfc_device_get_key_cache_file_path(dev, temp_str); + bool save_success = false; + do { + if(!storage_simply_mkdir(dev->storage, NFC_DEVICE_KEYS_FOLDER)) break; + if(!storage_simply_remove(dev->storage, string_get_cstr(temp_str))) break; + if(!flipper_format_file_open_always(file, string_get_cstr(temp_str))) break; + if(!flipper_format_write_header_cstr(file, nfc_keys_file_header, nfc_keys_file_version)) + break; + if(data->type == MfClassicType1k) { + if(!flipper_format_write_string_cstr(file, "Mifare Classic type", "1K")) break; + } else if(data->type == MfClassicType4k) { + if(!flipper_format_write_string_cstr(file, "Mifare Classic type", "4K")) break; + } + if(!flipper_format_write_hex_uint64(file, "Key A map", &data->key_a_mask, 1)) break; + if(!flipper_format_write_hex_uint64(file, "Key B map", &data->key_b_mask, 1)) break; + uint8_t sector_num = mf_classic_get_total_sectors_num(data->type); + bool key_save_success = true; + for(size_t i = 0; (i < sector_num) && (key_save_success); i++) { + MfClassicSectorTrailer* sec_tr = mf_classic_get_sector_trailer_by_sector(data, i); + if(FURI_BIT(data->key_a_mask, i)) { + string_printf(temp_str, "Key A sector %d", i); + key_save_success = + flipper_format_write_hex(file, string_get_cstr(temp_str), sec_tr->key_a, 6); + } + if(!key_save_success) break; + if(FURI_BIT(data->key_a_mask, i)) { + string_printf(temp_str, "Key B sector %d", i); + key_save_success = + flipper_format_write_hex(file, string_get_cstr(temp_str), sec_tr->key_b, 6); + } + } + save_success = key_save_success; + } while(false); + + flipper_format_free(file); + string_clear(temp_str); + return save_success; +} + +bool nfc_device_load_key_cache(NfcDevice* dev) { + furi_assert(dev); + string_t temp_str; + string_init(temp_str); + + MfClassicData* data = &dev->dev_data.mf_classic_data; + nfc_device_get_key_cache_file_path(dev, temp_str); + FlipperFormat* file = flipper_format_file_alloc(dev->storage); + + bool load_success = false; + do { + if(storage_common_stat(dev->storage, string_get_cstr(temp_str), NULL) != FSE_OK) break; + if(!flipper_format_file_open_existing(file, string_get_cstr(temp_str))) break; + uint32_t version = 0; + if(!flipper_format_read_header(file, temp_str, &version)) break; + if(string_cmp_str(temp_str, nfc_keys_file_header)) break; + if(version != nfc_keys_file_version) break; + if(!flipper_format_read_string(file, "Mifare Classic type", temp_str)) break; + if(!string_cmp_str(temp_str, "1K")) { + data->type = MfClassicType1k; + } else if(!string_cmp_str(temp_str, "4K")) { + data->type = MfClassicType4k; + } else { + break; + } + if(!flipper_format_read_hex_uint64(file, "Key A map", &data->key_a_mask, 1)) break; + if(!flipper_format_read_hex_uint64(file, "Key B map", &data->key_b_mask, 1)) break; + uint8_t sectors = mf_classic_get_total_sectors_num(data->type); + bool key_read_success = true; + for(size_t i = 0; (i < sectors) && (key_read_success); i++) { + MfClassicSectorTrailer* sec_tr = mf_classic_get_sector_trailer_by_sector(data, i); + if(FURI_BIT(data->key_a_mask, i)) { + string_printf(temp_str, "Key A sector %d", i); + key_read_success = + flipper_format_read_hex(file, string_get_cstr(temp_str), sec_tr->key_a, 6); + } + if(!key_read_success) break; + if(FURI_BIT(data->key_b_mask, i)) { + string_printf(temp_str, "Key B sector %d", i); + key_read_success = + flipper_format_read_hex(file, string_get_cstr(temp_str), sec_tr->key_b, 6); + } + } + load_success = key_read_success; + } while(false); + + string_clear(temp_str); + flipper_format_free(file); + + return load_success; +} + void nfc_device_set_name(NfcDevice* dev, const char* name) { furi_assert(dev); @@ -815,7 +1041,10 @@ static bool nfc_device_save_file( } else if(dev->format == NfcDeviceSaveFormatBankCard) { if(!nfc_device_save_bank_card_data(file, dev)) break; } else if(dev->format == NfcDeviceSaveFormatMifareClassic) { + // Save data if(!nfc_device_save_mifare_classic_data(file, dev)) break; + // Save keys cache + if(!nfc_device_save_mifare_classic_keys(dev)) break; } saved = true; } while(0); @@ -954,14 +1183,22 @@ bool nfc_file_select(NfcDevice* dev) { void nfc_device_data_clear(NfcDeviceData* dev_data) { if(dev_data->protocol == NfcDeviceProtocolMifareDesfire) { mf_df_clear(&dev_data->mf_df_data); + } else if(dev_data->protocol == NfcDeviceProtocolMifareClassic) { + memset(&dev_data->mf_classic_data, 0, sizeof(MfClassicData)); + } else if(dev_data->protocol == NfcDeviceProtocolMifareUl) { + memset(&dev_data->mf_ul_data, 0, sizeof(MfUltralightData)); + } else if(dev_data->protocol == NfcDeviceProtocolEMV) { + memset(&dev_data->emv_data, 0, sizeof(EmvData)); } + memset(&dev_data->nfc_data, 0, sizeof(FuriHalNfcDevData)); + dev_data->protocol = NfcDeviceProtocolUnknown; + string_reset(dev_data->parsed_data); } void nfc_device_clear(NfcDevice* dev) { furi_assert(dev); nfc_device_data_clear(&dev->dev_data); - memset(&dev->dev_data, 0, sizeof(dev->dev_data)); dev->format = NfcDeviceSaveFormatUid; string_reset(dev->load_path); } diff --git a/applications/nfc/nfc_device.h b/lib/nfc/nfc_device.h similarity index 89% rename from applications/nfc/nfc_device.h rename to lib/nfc/nfc_device.h index 5ffca5ca..e1ff6d42 100644 --- a/applications/nfc/nfc_device.h +++ b/lib/nfc/nfc_device.h @@ -6,10 +6,10 @@ #include #include -#include -#include -#include -#include +#include +#include +#include +#include #define NFC_DEV_NAME_MAX_LEN 22 #define NFC_READER_DATA_MAX_SIZE 64 @@ -51,6 +51,7 @@ typedef struct { MfClassicData mf_classic_data; MifareDesfireData mf_df_data; }; + string_t parsed_data; } NfcDeviceData; typedef struct { @@ -78,6 +79,8 @@ bool nfc_device_save_shadow(NfcDevice* dev, const char* dev_name); bool nfc_device_load(NfcDevice* dev, const char* file_path, bool show_dialog); +bool nfc_device_load_key_cache(NfcDevice* dev); + bool nfc_file_select(NfcDevice* dev); void nfc_device_data_clear(NfcDeviceData* dev); diff --git a/applications/nfc/nfc_types.c b/lib/nfc/nfc_types.c similarity index 100% rename from applications/nfc/nfc_types.c rename to lib/nfc/nfc_types.c diff --git a/applications/nfc/nfc_types.h b/lib/nfc/nfc_types.h similarity index 100% rename from applications/nfc/nfc_types.h rename to lib/nfc/nfc_types.h diff --git a/lib/nfc/nfc_worker.c b/lib/nfc/nfc_worker.c new file mode 100644 index 00000000..4a3176ff --- /dev/null +++ b/lib/nfc/nfc_worker.c @@ -0,0 +1,510 @@ +#include "nfc_worker_i.h" +#include + +#include +#include "parsers/nfc_supported_card.h" + +#define TAG "NfcWorker" + +/***************************** NFC Worker API *******************************/ + +NfcWorker* nfc_worker_alloc() { + NfcWorker* nfc_worker = malloc(sizeof(NfcWorker)); + + // Worker thread attributes + nfc_worker->thread = furi_thread_alloc(); + furi_thread_set_name(nfc_worker->thread, "NfcWorker"); + furi_thread_set_stack_size(nfc_worker->thread, 8192); + furi_thread_set_callback(nfc_worker->thread, nfc_worker_task); + furi_thread_set_context(nfc_worker->thread, nfc_worker); + + nfc_worker->callback = NULL; + nfc_worker->context = NULL; + nfc_worker->storage = furi_record_open(RECORD_STORAGE); + + // Initialize rfal + while(furi_hal_nfc_is_busy()) { + furi_delay_ms(10); + } + nfc_worker_change_state(nfc_worker, NfcWorkerStateReady); + + if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) { + nfc_worker->debug_pcap_worker = nfc_debug_pcap_alloc(nfc_worker->storage); + } + + return nfc_worker; +} + +void nfc_worker_free(NfcWorker* nfc_worker) { + furi_assert(nfc_worker); + + furi_thread_free(nfc_worker->thread); + + furi_record_close(RECORD_STORAGE); + + if(nfc_worker->debug_pcap_worker) nfc_debug_pcap_free(nfc_worker->debug_pcap_worker); + + free(nfc_worker); +} + +NfcWorkerState nfc_worker_get_state(NfcWorker* nfc_worker) { + return nfc_worker->state; +} + +void nfc_worker_start( + NfcWorker* nfc_worker, + NfcWorkerState state, + NfcDeviceData* dev_data, + NfcWorkerCallback callback, + void* context) { + furi_assert(nfc_worker); + furi_assert(dev_data); + while(furi_hal_nfc_is_busy()) { + furi_delay_ms(10); + } + + nfc_worker->callback = callback; + nfc_worker->context = context; + nfc_worker->dev_data = dev_data; + nfc_worker_change_state(nfc_worker, state); + furi_thread_start(nfc_worker->thread); +} + +void nfc_worker_stop(NfcWorker* nfc_worker) { + furi_assert(nfc_worker); + if(nfc_worker->state == NfcWorkerStateBroken || nfc_worker->state == NfcWorkerStateReady) { + return; + } + furi_hal_nfc_stop(); + nfc_worker_change_state(nfc_worker, NfcWorkerStateStop); + furi_thread_join(nfc_worker->thread); +} + +void nfc_worker_change_state(NfcWorker* nfc_worker, NfcWorkerState state) { + nfc_worker->state = state; +} + +/***************************** NFC Worker Thread *******************************/ + +int32_t nfc_worker_task(void* context) { + NfcWorker* nfc_worker = context; + + furi_hal_nfc_exit_sleep(); + + if(nfc_worker->state == NfcWorkerStateRead) { + nfc_worker_read(nfc_worker); + } else if(nfc_worker->state == NfcWorkerStateUidEmulate) { + nfc_worker_emulate_uid(nfc_worker); + } else if(nfc_worker->state == NfcWorkerStateEmulateApdu) { + nfc_worker_emulate_apdu(nfc_worker); + } else if(nfc_worker->state == NfcWorkerStateMfUltralightEmulate) { + nfc_worker_emulate_mf_ultralight(nfc_worker); + } else if(nfc_worker->state == NfcWorkerStateMfClassicEmulate) { + nfc_worker_emulate_mf_classic(nfc_worker); + } else if(nfc_worker->state == NfcWorkerStateMfClassicUserDictAttack) { + nfc_worker_mf_classic_dict_attack(nfc_worker, MfClassicDictTypeUser); + } else if(nfc_worker->state == NfcWorkerStateMfClassicFlipperDictAttack) { + nfc_worker_mf_classic_dict_attack(nfc_worker, MfClassicDictTypeFlipper); + } + furi_hal_nfc_sleep(); + nfc_worker_change_state(nfc_worker, NfcWorkerStateReady); + + return 0; +} + +static bool nfc_worker_read_mf_ultralight(NfcWorker* nfc_worker, FuriHalNfcTxRxContext* tx_rx) { + bool read_success = false; + MfUltralightReader reader = {}; + MfUltralightData data = {}; + + nfc_debug_pcap_prepare_tx_rx(nfc_worker->debug_pcap_worker, tx_rx, false); + do { + // Read card + if(!furi_hal_nfc_detect(&nfc_worker->dev_data->nfc_data, 200)) break; + if(!mf_ul_read_card(tx_rx, &reader, &data)) break; + // Copy data + nfc_worker->dev_data->mf_ul_data = data; + read_success = true; + } while(false); + + return read_success; +} + +static bool nfc_worker_read_mf_classic(NfcWorker* nfc_worker, FuriHalNfcTxRxContext* tx_rx) { + furi_assert(nfc_worker->callback); + bool read_success = false; + + nfc_debug_pcap_prepare_tx_rx(nfc_worker->debug_pcap_worker, tx_rx, false); + do { + // Try to read supported card + FURI_LOG_I(TAG, "Try read supported card ..."); + for(size_t i = 0; i < NfcSupportedCardTypeEnd; i++) { + if(nfc_supported_card[i].protocol == NfcDeviceProtocolMifareClassic) { + if(nfc_supported_card[i].verify(nfc_worker, tx_rx)) { + if(nfc_supported_card[i].read(nfc_worker, tx_rx)) { + read_success = true; + nfc_supported_card[i].parse(nfc_worker); + } + } + } + } + if(read_success) break; + // Try to read card with key cache + FURI_LOG_I(TAG, "Search for key cache ..."); + if(nfc_worker->callback(NfcWorkerEventReadMfClassicLoadKeyCache, nfc_worker->context)) { + FURI_LOG_I(TAG, "Load keys cache success. Start reading"); + uint8_t sectors_read = + mf_classic_update_card(tx_rx, &nfc_worker->dev_data->mf_classic_data); + uint8_t sectors_total = + mf_classic_get_total_sectors_num(nfc_worker->dev_data->mf_classic_data.type); + FURI_LOG_I(TAG, "Read %d sectors out of %d total", sectors_read, sectors_total); + read_success = (sectors_read == sectors_total); + } + } while(false); + + return read_success; +} + +static bool nfc_worker_read_mf_desfire(NfcWorker* nfc_worker, FuriHalNfcTxRxContext* tx_rx) { + bool read_success = false; + MifareDesfireData* data = &nfc_worker->dev_data->mf_df_data; + + nfc_debug_pcap_prepare_tx_rx(nfc_worker->debug_pcap_worker, tx_rx, false); + do { + if(!furi_hal_nfc_detect(&nfc_worker->dev_data->nfc_data, 300)) break; + if(!mf_df_read_card(tx_rx, data)) break; + read_success = true; + } while(false); + + return read_success; +} + +static bool nfc_worker_read_bank_card(NfcWorker* nfc_worker, FuriHalNfcTxRxContext* tx_rx) { + bool read_success = false; + EmvApplication emv_app = {}; + EmvData* result = &nfc_worker->dev_data->emv_data; + + nfc_debug_pcap_prepare_tx_rx(nfc_worker->debug_pcap_worker, tx_rx, false); + do { + // Read card + if(!furi_hal_nfc_detect(&nfc_worker->dev_data->nfc_data, 300)) break; + if(!emv_read_bank_card(tx_rx, &emv_app)) break; + // Copy data + // TODO Set EmvData to reader or like in mifare ultralight! + result->number_len = emv_app.card_number_len; + memcpy(result->number, emv_app.card_number, result->number_len); + result->aid_len = emv_app.aid_len; + memcpy(result->aid, emv_app.aid, result->aid_len); + if(emv_app.name_found) { + memcpy(result->name, emv_app.name, sizeof(emv_app.name)); + } + if(emv_app.exp_month) { + result->exp_mon = emv_app.exp_month; + result->exp_year = emv_app.exp_year; + } + if(emv_app.country_code) { + result->country_code = emv_app.country_code; + } + if(emv_app.currency_code) { + result->currency_code = emv_app.currency_code; + } + read_success = true; + } while(false); + + return read_success; +} + +static bool nfc_worker_read_nfca(NfcWorker* nfc_worker, FuriHalNfcTxRxContext* tx_rx) { + FuriHalNfcDevData* nfc_data = &nfc_worker->dev_data->nfc_data; + + bool card_read = false; + furi_hal_nfc_sleep(); + if(mf_ul_check_card_type(nfc_data->atqa[0], nfc_data->atqa[1], nfc_data->sak)) { + FURI_LOG_I(TAG, "Mifare Ultralight / NTAG detected"); + nfc_worker->dev_data->protocol = NfcDeviceProtocolMifareUl; + card_read = nfc_worker_read_mf_ultralight(nfc_worker, tx_rx); + } else if(mf_classic_check_card_type(nfc_data->atqa[0], nfc_data->atqa[1], nfc_data->sak)) { + FURI_LOG_I(TAG, "Mifare Classic detected"); + nfc_worker->dev_data->protocol = NfcDeviceProtocolMifareClassic; + nfc_worker->dev_data->mf_classic_data.type = + mf_classic_get_classic_type(nfc_data->atqa[0], nfc_data->atqa[1], nfc_data->sak); + card_read = nfc_worker_read_mf_classic(nfc_worker, tx_rx); + } else if(mf_df_check_card_type(nfc_data->atqa[0], nfc_data->atqa[1], nfc_data->sak)) { + FURI_LOG_I(TAG, "Mifare DESFire detected"); + nfc_worker->dev_data->protocol = NfcDeviceProtocolMifareDesfire; + if(!nfc_worker_read_mf_desfire(nfc_worker, tx_rx)) { + FURI_LOG_I(TAG, "Unknown card. Save UID"); + nfc_worker->dev_data->protocol = NfcDeviceProtocolUnknown; + } + card_read = true; + } else if(nfc_data->interface == FuriHalNfcInterfaceIsoDep) { + FURI_LOG_I(TAG, "ISO14443-4 card detected"); + nfc_worker->dev_data->protocol = NfcDeviceProtocolEMV; + if(!nfc_worker_read_bank_card(nfc_worker, tx_rx)) { + FURI_LOG_I(TAG, "Unknown card. Save UID"); + nfc_worker->dev_data->protocol = NfcDeviceProtocolUnknown; + } + card_read = true; + } + + return card_read; +} + +void nfc_worker_read(NfcWorker* nfc_worker) { + furi_assert(nfc_worker); + furi_assert(nfc_worker->callback); + + nfc_device_data_clear(nfc_worker->dev_data); + NfcDeviceData* dev_data = nfc_worker->dev_data; + FuriHalNfcDevData* nfc_data = &nfc_worker->dev_data->nfc_data; + FuriHalNfcTxRxContext tx_rx = {}; + NfcWorkerEvent event = 0; + bool card_not_detected_notified = false; + + while(nfc_worker->state == NfcWorkerStateRead) { + if(furi_hal_nfc_detect(nfc_data, 300)) { + // Process first found device + nfc_worker->callback(NfcWorkerEventCardDetected, nfc_worker->context); + card_not_detected_notified = false; + if(nfc_data->type == FuriHalNfcTypeA) { + if(nfc_worker_read_nfca(nfc_worker, &tx_rx)) { + if(dev_data->protocol == NfcDeviceProtocolMifareUl) { + event = NfcWorkerEventReadMfUltralight; + break; + } else if(dev_data->protocol == NfcDeviceProtocolMifareClassic) { + event = NfcWorkerEventReadMfClassicDone; + break; + } else if(dev_data->protocol == NfcDeviceProtocolMifareDesfire) { + event = NfcWorkerEventReadMfDesfire; + break; + } else if(dev_data->protocol == NfcDeviceProtocolEMV) { + event = NfcWorkerEventReadBankCard; + break; + } else if(dev_data->protocol == NfcDeviceProtocolUnknown) { + event = NfcWorkerEventReadUidNfcA; + break; + } + } else { + if(dev_data->protocol == NfcDeviceProtocolMifareClassic) { + event = NfcWorkerEventReadMfClassicDictAttackRequired; + break; + } + } + } else if(nfc_data->type == FuriHalNfcTypeB) { + event = NfcWorkerEventReadUidNfcB; + break; + } else if(nfc_data->type == FuriHalNfcTypeF) { + event = NfcWorkerEventReadUidNfcF; + break; + } else if(nfc_data->type == FuriHalNfcTypeV) { + event = NfcWorkerEventReadUidNfcV; + break; + } + } else { + if(!card_not_detected_notified) { + nfc_worker->callback(NfcWorkerEventNoCardDetected, nfc_worker->context); + card_not_detected_notified = true; + } + } + furi_hal_nfc_sleep(); + furi_delay_ms(100); + } + // Notify caller and exit + if(event > NfcWorkerEventReserved) { + nfc_worker->callback(event, nfc_worker->context); + } +} + +void nfc_worker_emulate_uid(NfcWorker* nfc_worker) { + FuriHalNfcTxRxContext tx_rx = {}; + nfc_debug_pcap_prepare_tx_rx(nfc_worker->debug_pcap_worker, &tx_rx, true); + FuriHalNfcDevData* data = &nfc_worker->dev_data->nfc_data; + NfcReaderRequestData* reader_data = &nfc_worker->dev_data->reader_data; + + while(nfc_worker->state == NfcWorkerStateUidEmulate) { + if(furi_hal_nfc_listen(data->uid, data->uid_len, data->atqa, data->sak, true, 100)) { + if(furi_hal_nfc_tx_rx(&tx_rx, 100)) { + reader_data->size = tx_rx.rx_bits / 8; + if(reader_data->size > 0) { + memcpy(reader_data->data, tx_rx.rx_data, reader_data->size); + if(nfc_worker->callback) { + nfc_worker->callback(NfcWorkerEventSuccess, nfc_worker->context); + } + } + } else { + FURI_LOG_E(TAG, "Failed to get reader commands"); + } + } + } +} + +void nfc_worker_emulate_apdu(NfcWorker* nfc_worker) { + FuriHalNfcTxRxContext tx_rx = {}; + nfc_debug_pcap_prepare_tx_rx(nfc_worker->debug_pcap_worker, &tx_rx, true); + FuriHalNfcDevData params = { + .uid = {0xCF, 0x72, 0xd4, 0x40}, + .uid_len = 4, + .atqa = {0x00, 0x04}, + .sak = 0x20, + .type = FuriHalNfcTypeA, + }; + + while(nfc_worker->state == NfcWorkerStateEmulateApdu) { + if(furi_hal_nfc_listen(params.uid, params.uid_len, params.atqa, params.sak, false, 300)) { + FURI_LOG_D(TAG, "POS terminal detected"); + if(emv_card_emulation(&tx_rx)) { + FURI_LOG_D(TAG, "EMV card emulated"); + } + } else { + FURI_LOG_D(TAG, "Can't find reader"); + } + furi_hal_nfc_sleep(); + furi_delay_ms(20); + } +} + +void nfc_worker_emulate_mf_ultralight(NfcWorker* nfc_worker) { + FuriHalNfcDevData* nfc_data = &nfc_worker->dev_data->nfc_data; + MfUltralightEmulator emulator = {}; + mf_ul_prepare_emulation(&emulator, &nfc_worker->dev_data->mf_ul_data); + while(nfc_worker->state == NfcWorkerStateMfUltralightEmulate) { + mf_ul_reset_emulation(&emulator, true); + furi_hal_nfc_emulate_nfca( + nfc_data->uid, + nfc_data->uid_len, + nfc_data->atqa, + nfc_data->sak, + mf_ul_prepare_emulation_response, + &emulator, + 5000); + // Check if data was modified + if(emulator.data_changed) { + nfc_worker->dev_data->mf_ul_data = emulator.data; + if(nfc_worker->callback) { + nfc_worker->callback(NfcWorkerEventSuccess, nfc_worker->context); + } + emulator.data_changed = false; + } + } +} + +void nfc_worker_mf_classic_dict_attack(NfcWorker* nfc_worker, MfClassicDictType type) { + furi_assert(nfc_worker); + furi_assert(nfc_worker->callback); + + MfClassicData* data = &nfc_worker->dev_data->mf_classic_data; + uint32_t total_sectors = mf_classic_get_total_sectors_num(data->type); + uint64_t key = 0; + FuriHalNfcTxRxContext tx_rx = {}; + bool card_found_notified = true; + bool card_removed_notified = false; + + // Load dictionary + MfClassicDict* dict = mf_classic_dict_alloc(type); + if(!dict) { + FURI_LOG_E(TAG, "Dictionary not found"); + nfc_worker->callback(NfcWorkerEventNoDictFound, nfc_worker->context); + mf_classic_dict_free(dict); + return; + } + + FURI_LOG_D(TAG, "Start Dictionary attack"); + for(size_t i = 0; i < total_sectors; i++) { + FURI_LOG_I(TAG, "Sector %d", i); + nfc_worker->callback(NfcWorkerEventNewSector, nfc_worker->context); + uint8_t block_num = mf_classic_get_sector_trailer_block_num_by_sector(i); + if(mf_classic_is_sector_read(data, i)) continue; + bool is_key_a_found = mf_classic_is_key_found(data, i, MfClassicKeyA); + bool is_key_b_found = mf_classic_is_key_found(data, i, MfClassicKeyB); + while(mf_classic_dict_get_next_key(dict, &key)) { + furi_hal_nfc_sleep(); + if(furi_hal_nfc_activate_nfca(200, NULL)) { + furi_hal_nfc_sleep(); + if(!card_found_notified) { + nfc_worker->callback(NfcWorkerEventCardDetected, nfc_worker->context); + card_found_notified = true; + card_removed_notified = false; + } + FURI_LOG_D( + TAG, + "Try to auth to sector %d with key %04lx%08lx", + i, + (uint32_t)(key >> 32), + (uint32_t)key); + if(!is_key_a_found) { + is_key_a_found = mf_classic_is_key_found(data, i, MfClassicKeyA); + if(mf_classic_authenticate(&tx_rx, block_num, key, MfClassicKeyA)) { + mf_classic_set_key_found(data, i, MfClassicKeyA, key); + nfc_worker->callback(NfcWorkerEventFoundKeyA, nfc_worker->context); + } + furi_hal_nfc_sleep(); + } + if(!is_key_b_found) { + is_key_b_found = mf_classic_is_key_found(data, i, MfClassicKeyB); + if(mf_classic_authenticate(&tx_rx, block_num, key, MfClassicKeyB)) { + mf_classic_set_key_found(data, i, MfClassicKeyB, key); + nfc_worker->callback(NfcWorkerEventFoundKeyB, nfc_worker->context); + } + } + if(is_key_a_found && is_key_b_found) break; + if(!((nfc_worker->state == NfcWorkerStateMfClassicUserDictAttack) || + (nfc_worker->state == NfcWorkerStateMfClassicFlipperDictAttack))) + break; + } else { + if(!card_removed_notified) { + nfc_worker->callback(NfcWorkerEventNoCardDetected, nfc_worker->context); + card_removed_notified = true; + card_found_notified = false; + } + if(!((nfc_worker->state == NfcWorkerStateMfClassicUserDictAttack) || + (nfc_worker->state == NfcWorkerStateMfClassicFlipperDictAttack))) + break; + } + } + if(!((nfc_worker->state == NfcWorkerStateMfClassicUserDictAttack) || + (nfc_worker->state == NfcWorkerStateMfClassicFlipperDictAttack))) + break; + mf_classic_read_sector(&tx_rx, data, i); + mf_classic_dict_rewind(dict); + } + mf_classic_dict_free(dict); + if((nfc_worker->state == NfcWorkerStateMfClassicUserDictAttack) || + (nfc_worker->state == NfcWorkerStateMfClassicFlipperDictAttack)) { + nfc_worker->callback(NfcWorkerEventSuccess, nfc_worker->context); + } else { + nfc_worker->callback(NfcWorkerEventAborted, nfc_worker->context); + } +} + +void nfc_worker_emulate_mf_classic(NfcWorker* nfc_worker) { + FuriHalNfcTxRxContext tx_rx = {}; + nfc_debug_pcap_prepare_tx_rx(nfc_worker->debug_pcap_worker, &tx_rx, true); + FuriHalNfcDevData* nfc_data = &nfc_worker->dev_data->nfc_data; + MfClassicEmulator emulator = { + .cuid = nfc_util_bytes2num(&nfc_data->uid[nfc_data->uid_len - 4], 4), + .data = nfc_worker->dev_data->mf_classic_data, + .data_changed = false, + }; + NfcaSignal* nfca_signal = nfca_signal_alloc(); + tx_rx.nfca_signal = nfca_signal; + + rfal_platform_spi_acquire(); + + furi_hal_nfc_listen_start(nfc_data); + while(nfc_worker->state == NfcWorkerStateMfClassicEmulate) { + if(furi_hal_nfc_listen_rx(&tx_rx, 300)) { + mf_classic_emulator(&emulator, &tx_rx); + } + } + if(emulator.data_changed) { + nfc_worker->dev_data->mf_classic_data = emulator.data; + if(nfc_worker->callback) { + nfc_worker->callback(NfcWorkerEventSuccess, nfc_worker->context); + } + emulator.data_changed = false; + } + + nfca_signal_free(nfca_signal); + + rfal_platform_spi_release(); +} diff --git a/applications/nfc/nfc_worker.h b/lib/nfc/nfc_worker.h similarity index 59% rename from applications/nfc/nfc_worker.h rename to lib/nfc/nfc_worker.h index a68f42d7..f6df406b 100755 --- a/applications/nfc/nfc_worker.h +++ b/lib/nfc/nfc_worker.h @@ -10,17 +10,15 @@ typedef enum { NfcWorkerStateBroken, NfcWorkerStateReady, // Main worker states - NfcWorkerStateDetect, - NfcWorkerStateEmulate, - NfcWorkerStateReadEMVApp, - NfcWorkerStateReadEMVData, + NfcWorkerStateRead, + NfcWorkerStateUidEmulate, + NfcWorkerStateMfUltralightEmulate, + NfcWorkerStateMfClassicEmulate, + NfcWorkerStateMfClassicUserDictAttack, + NfcWorkerStateMfClassicFlipperDictAttack, + // Debug NfcWorkerStateEmulateApdu, NfcWorkerStateField, - NfcWorkerStateReadMifareUltralight, - NfcWorkerStateEmulateMifareUltralight, - NfcWorkerStateReadMifareClassic, - NfcWorkerStateEmulateMifareClassic, - NfcWorkerStateReadMifareDesfire, // Transition NfcWorkerStateStop, } NfcWorkerState; @@ -29,21 +27,33 @@ typedef enum { // Reserve first 50 events for application events NfcWorkerEventReserved = 50, + // Nfc read events + NfcWorkerEventReadUidNfcB, + NfcWorkerEventReadUidNfcV, + NfcWorkerEventReadUidNfcF, + NfcWorkerEventReadUidNfcA, + NfcWorkerEventReadMfUltralight, + NfcWorkerEventReadMfDesfire, + NfcWorkerEventReadMfClassicDone, + NfcWorkerEventReadMfClassicLoadKeyCache, + NfcWorkerEventReadMfClassicDictAttackRequired, + NfcWorkerEventReadBankCard, + // Nfc worker common events NfcWorkerEventSuccess, NfcWorkerEventFail, + NfcWorkerEventAborted, + NfcWorkerEventCardDetected, NfcWorkerEventNoCardDetected, + // Mifare Classic events NfcWorkerEventNoDictFound, - NfcWorkerEventDetectedClassic1k, - NfcWorkerEventDetectedClassic4k, NfcWorkerEventNewSector, NfcWorkerEventFoundKeyA, NfcWorkerEventFoundKeyB, - NfcWorkerEventStartReading, } NfcWorkerEvent; -typedef void (*NfcWorkerCallback)(NfcWorkerEvent event, void* context); +typedef bool (*NfcWorkerCallback)(NfcWorkerEvent event, void* context); NfcWorker* nfc_worker_alloc(); diff --git a/lib/nfc/nfc_worker_i.h b/lib/nfc/nfc_worker_i.h new file mode 100644 index 00000000..f19f58d5 --- /dev/null +++ b/lib/nfc/nfc_worker_i.h @@ -0,0 +1,48 @@ +#pragma once + +#include "nfc_worker.h" + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "helpers/mf_classic_dict.h" +#include "helpers/nfc_debug_pcap.h" + +struct NfcWorker { + FuriThread* thread; + Storage* storage; + Stream* dict_stream; + + NfcDeviceData* dev_data; + + NfcWorkerCallback callback; + void* context; + + NfcWorkerState state; + + NfcDebugPcapWorker* debug_pcap_worker; +}; + +void nfc_worker_change_state(NfcWorker* nfc_worker, NfcWorkerState state); + +int32_t nfc_worker_task(void* context); + +void nfc_worker_read(NfcWorker* nfc_worker); + +void nfc_worker_emulate_uid(NfcWorker* nfc_worker); + +void nfc_worker_emulate_mf_ultralight(NfcWorker* nfc_worker); + +void nfc_worker_emulate_mf_classic(NfcWorker* nfc_worker); + +void nfc_worker_mf_classic_dict_attack(NfcWorker* nfc_worker, MfClassicDictType type); + +void nfc_worker_emulate_apdu(NfcWorker* nfc_worker); diff --git a/lib/nfc/parsers/nfc_supported_card.c b/lib/nfc/parsers/nfc_supported_card.c new file mode 100644 index 00000000..44eee838 --- /dev/null +++ b/lib/nfc/parsers/nfc_supported_card.c @@ -0,0 +1,12 @@ +#include "nfc_supported_card.h" + +#include "troyka_parser.h" + +NfcSupportedCard nfc_supported_card[NfcSupportedCardTypeEnd] = { + [NfcSupportedCardTypeTroyka] = { + .protocol = NfcDeviceProtocolMifareClassic, + .verify = troyka_parser_verify, + .read = troyka_parser_read, + .parse = troyka_parser_parse, + }, +}; diff --git a/lib/nfc/parsers/nfc_supported_card.h b/lib/nfc/parsers/nfc_supported_card.h new file mode 100644 index 00000000..5c94c78c --- /dev/null +++ b/lib/nfc/parsers/nfc_supported_card.h @@ -0,0 +1,27 @@ +#pragma once + +#include +#include "../nfc_worker.h" + +#include + +typedef enum { + NfcSupportedCardTypeTroyka, + + NfcSupportedCardTypeEnd, +} NfcSupportedCardType; + +typedef bool (*NfcSupportedCardVerify)(NfcWorker* nfc_worker, FuriHalNfcTxRxContext* tx_rx); + +typedef bool (*NfcSupportedCardRead)(NfcWorker* nfc_worker, FuriHalNfcTxRxContext* tx_rx); + +typedef bool (*NfcSupportedCardParse)(NfcWorker* nfc_worker); + +typedef struct { + NfcProtocol protocol; + NfcSupportedCardVerify verify; + NfcSupportedCardRead read; + NfcSupportedCardParse parse; +} NfcSupportedCard; + +extern NfcSupportedCard nfc_supported_card[NfcSupportedCardTypeEnd]; diff --git a/lib/nfc/parsers/troyka_parser.c b/lib/nfc/parsers/troyka_parser.c new file mode 100644 index 00000000..653887cb --- /dev/null +++ b/lib/nfc/parsers/troyka_parser.c @@ -0,0 +1,70 @@ +#include "nfc_supported_card.h" + +#include +#include + +static const MfClassicAuthContext troyka_keys[] = { + {.sector = 0, .key_a = 0xa0a1a2a3a4a5, .key_b = 0xfbf225dc5d58}, + {.sector = 1, .key_a = 0xa82607b01c0d, .key_b = 0x2910989b6880}, + {.sector = 2, .key_a = 0x2aa05ed1856f, .key_b = 0xeaac88e5dc99}, + {.sector = 3, .key_a = 0x2aa05ed1856f, .key_b = 0xeaac88e5dc99}, + {.sector = 4, .key_a = 0x73068f118c13, .key_b = 0x2b7f3253fac5}, + {.sector = 5, .key_a = 0xfbc2793d540b, .key_b = 0xd3a297dc2698}, + {.sector = 6, .key_a = 0x2aa05ed1856f, .key_b = 0xeaac88e5dc99}, + {.sector = 7, .key_a = 0xae3d65a3dad4, .key_b = 0x0f1c63013dba}, + {.sector = 8, .key_a = 0xa73f5dc1d333, .key_b = 0xe35173494a81}, + {.sector = 9, .key_a = 0x69a32f1c2f19, .key_b = 0x6b8bd9860763}, + {.sector = 10, .key_a = 0x9becdf3d9273, .key_b = 0xf8493407799d}, + {.sector = 11, .key_a = 0x08b386463229, .key_b = 0x5efbaecef46b}, + {.sector = 12, .key_a = 0xcd4c61c26e3d, .key_b = 0x31c7610de3b0}, + {.sector = 13, .key_a = 0xa82607b01c0d, .key_b = 0x2910989b6880}, + {.sector = 14, .key_a = 0x0e8f64340ba4, .key_b = 0x4acec1205d75}, + {.sector = 15, .key_a = 0x2aa05ed1856f, .key_b = 0xeaac88e5dc99}, +}; + +bool troyka_parser_verify(NfcWorker* nfc_worker, FuriHalNfcTxRxContext* tx_rx) { + furi_assert(nfc_worker); + UNUSED(nfc_worker); + + MfClassicAuthContext auth_ctx = { + .key_a = MF_CLASSIC_NO_KEY, + .key_b = MF_CLASSIC_NO_KEY, + .sector = 8, + }; + return mf_classic_auth_attempt(tx_rx, &auth_ctx, 0xa73f5dc1d333); +} + +bool troyka_parser_read(NfcWorker* nfc_worker, FuriHalNfcTxRxContext* tx_rx) { + furi_assert(nfc_worker); + + MfClassicReader reader = {}; + FuriHalNfcDevData* nfc_data = &nfc_worker->dev_data->nfc_data; + mf_classic_get_type(nfc_data->atqa[0], nfc_data->atqa[1], nfc_data->sak, &reader); + for(size_t i = 0; i < COUNT_OF(troyka_keys); i++) { + mf_classic_reader_add_sector( + &reader, troyka_keys[i].sector, troyka_keys[i].key_a, troyka_keys[i].key_b); + } + + return mf_classic_read_card(tx_rx, &reader, &nfc_worker->dev_data->mf_classic_data) == 16; +} + +bool troyka_parser_parse(NfcWorker* nfc_worker) { + MfClassicData* data = &nfc_worker->dev_data->mf_classic_data; + uint8_t* temp_ptr = &data->block[8 * 4 + 1].value[5]; + uint16_t balance = ((temp_ptr[0] << 8) | temp_ptr[1]) / 25; + temp_ptr = &data->block[8 * 4].value[3]; + uint32_t number = 0; + for(size_t i = 0; i < 4; i++) { + number <<= 8; + number |= temp_ptr[i]; + } + number >>= 4; + + string_printf( + nfc_worker->dev_data->parsed_data, + "Troyka Transport card\nNumber: %ld\nBalance: %d rub", + number, + balance); + + return true; +} diff --git a/lib/nfc/parsers/troyka_parser.h b/lib/nfc/parsers/troyka_parser.h new file mode 100644 index 00000000..0d5cee23 --- /dev/null +++ b/lib/nfc/parsers/troyka_parser.h @@ -0,0 +1,9 @@ +#pragma once + +#include "nfc_supported_card.h" + +bool troyka_parser_verify(NfcWorker* nfc_worker, FuriHalNfcTxRxContext* tx_rx); + +bool troyka_parser_read(NfcWorker* nfc_worker, FuriHalNfcTxRxContext* tx_rx); + +bool troyka_parser_parse(NfcWorker* nfc_worker); diff --git a/lib/nfc_protocols/crypto1.c b/lib/nfc/protocols/crypto1.c similarity index 100% rename from lib/nfc_protocols/crypto1.c rename to lib/nfc/protocols/crypto1.c diff --git a/lib/nfc_protocols/crypto1.h b/lib/nfc/protocols/crypto1.h similarity index 100% rename from lib/nfc_protocols/crypto1.h rename to lib/nfc/protocols/crypto1.h diff --git a/lib/nfc_protocols/emv.c b/lib/nfc/protocols/emv.c similarity index 100% rename from lib/nfc_protocols/emv.c rename to lib/nfc/protocols/emv.c diff --git a/lib/nfc_protocols/emv.h b/lib/nfc/protocols/emv.h similarity index 100% rename from lib/nfc_protocols/emv.h rename to lib/nfc/protocols/emv.h diff --git a/lib/nfc_protocols/mifare_classic.c b/lib/nfc/protocols/mifare_classic.c similarity index 71% rename from lib/nfc_protocols/mifare_classic.c rename to lib/nfc/protocols/mifare_classic.c index e35a1d6c..93fe6f69 100644 --- a/lib/nfc_protocols/mifare_classic.c +++ b/lib/nfc/protocols/mifare_classic.c @@ -25,6 +25,16 @@ typedef enum { MfClassicActionACWrite, } MfClassicAction; +const char* mf_classic_get_type_str(MfClassicType type) { + if(type == MfClassicType1k) { + return "MIFARE Classic 1K"; + } else if(type == MfClassicType4k) { + return "MIFARE Classic 4K"; + } else { + return "Unknown"; + } +} + static uint8_t mf_classic_get_first_block_num_of_sector(uint8_t sector) { furi_assert(sector < 40); if(sector < 32) { @@ -34,7 +44,16 @@ static uint8_t mf_classic_get_first_block_num_of_sector(uint8_t sector) { } } -static uint8_t mf_classic_get_sector_by_block(uint8_t block) { +uint8_t mf_classic_get_sector_trailer_block_num_by_sector(uint8_t sector) { + furi_assert(sector < 40); + if(sector < 32) { + return sector * 4 + 3; + } else { + return 32 * 4 + (sector - 32) * 16 + 15; + } +} + +uint8_t mf_classic_get_sector_by_block(uint8_t block) { if(block < 128) { return (block | 0x03) / 4; } else { @@ -47,7 +66,7 @@ static uint8_t mf_classic_get_blocks_num_in_sector(uint8_t sector) { return sector < 32 ? 4 : 16; } -static uint8_t mf_classic_get_sector_trailer(uint8_t block) { +uint8_t mf_classic_get_sector_trailer_num_by_block(uint8_t block) { if(block < 128) { return block | 0x03; } else { @@ -55,15 +74,21 @@ static uint8_t mf_classic_get_sector_trailer(uint8_t block) { } } -static bool mf_classic_is_sector_trailer(uint8_t block) { - return block == mf_classic_get_sector_trailer(block); +bool mf_classic_is_sector_trailer(uint8_t block) { + return block == mf_classic_get_sector_trailer_num_by_block(block); } -uint8_t mf_classic_get_total_sectors_num(MfClassicReader* reader) { - furi_assert(reader); - if(reader->type == MfClassicType1k) { +MfClassicSectorTrailer* + mf_classic_get_sector_trailer_by_sector(MfClassicData* data, uint8_t sector) { + furi_assert(data); + uint8_t sec_tr_block_num = mf_classic_get_sector_trailer_block_num_by_sector(sector); + return (MfClassicSectorTrailer*)data->block[sec_tr_block_num].value; +} + +uint8_t mf_classic_get_total_sectors_num(MfClassicType type) { + if(type == MfClassicType1k) { return MF_CLASSIC_1K_TOTAL_SECTORS_NUM; - } else if(reader->type == MfClassicType4k) { + } else if(type == MfClassicType4k) { return MF_CLASSIC_4K_TOTAL_SECTORS_NUM; } else { return 0; @@ -80,6 +105,104 @@ static uint16_t mf_classic_get_total_block_num(MfClassicType type) { } } +bool mf_classic_is_block_read(MfClassicData* data, uint8_t block_num) { + furi_assert(data); + + return (FURI_BIT(data->block_read_mask[block_num / 32], block_num % 32) == 1); +} + +void mf_classic_set_block_read(MfClassicData* data, uint8_t block_num, MfClassicBlock* block_data) { + furi_assert(data); + + if(mf_classic_is_sector_trailer(block_num)) { + memcpy(&data->block[block_num].value[6], &block_data->value[6], 4); + } else { + memcpy(data->block[block_num].value, block_data->value, MF_CLASSIC_BLOCK_SIZE); + } + FURI_BIT_SET(data->block_read_mask[block_num / 32], block_num % 32); +} + +bool mf_classic_is_key_found(MfClassicData* data, uint8_t sector_num, MfClassicKey key_type) { + furi_assert(data); + + bool key_found = false; + if(key_type == MfClassicKeyA) { + key_found = (FURI_BIT(data->key_a_mask, sector_num) == 1); + } else if(key_type == MfClassicKeyB) { + key_found = (FURI_BIT(data->key_b_mask, sector_num) == 1); + } + + return key_found; +} + +void mf_classic_set_key_found( + MfClassicData* data, + uint8_t sector_num, + MfClassicKey key_type, + uint64_t key) { + furi_assert(data); + + uint8_t key_arr[6] = {}; + MfClassicSectorTrailer* sec_trailer = + mf_classic_get_sector_trailer_by_sector(data, sector_num); + nfc_util_num2bytes(key, 6, key_arr); + if(key_type == MfClassicKeyA) { + memcpy(sec_trailer->key_a, key_arr, sizeof(sec_trailer->key_a)); + FURI_BIT_SET(data->key_a_mask, sector_num); + } else if(key_type == MfClassicKeyB) { + memcpy(sec_trailer->key_b, key_arr, sizeof(sec_trailer->key_b)); + FURI_BIT_SET(data->key_b_mask, sector_num); + } +} + +bool mf_classic_is_sector_read(MfClassicData* data, uint8_t sector_num) { + furi_assert(data); + + bool sector_read = false; + do { + if(!mf_classic_is_key_found(data, sector_num, MfClassicKeyA)) break; + if(!mf_classic_is_key_found(data, sector_num, MfClassicKeyB)) break; + uint8_t start_block = mf_classic_get_first_block_num_of_sector(sector_num); + uint8_t total_blocks = mf_classic_get_blocks_num_in_sector(sector_num); + uint8_t block_read = true; + for(size_t i = start_block; i < start_block + total_blocks; i++) { + block_read = mf_classic_is_block_read(data, i); + if(!block_read) break; + } + sector_read = block_read; + } while(false); + + return sector_read; +} + +void mf_classic_get_read_sectors_and_keys( + MfClassicData* data, + uint8_t* sectors_read, + uint8_t* keys_found) { + furi_assert(data); + *sectors_read = 0; + *keys_found = 0; + uint8_t sectors_total = mf_classic_get_total_sectors_num(data->type); + for(size_t i = 0; i < sectors_total; i++) { + if(mf_classic_is_key_found(data, i, MfClassicKeyA)) { + *keys_found += 1; + } + if(mf_classic_is_key_found(data, i, MfClassicKeyB)) { + *keys_found += 1; + } + uint8_t first_block = mf_classic_get_first_block_num_of_sector(i); + uint8_t total_blocks_in_sec = mf_classic_get_blocks_num_in_sector(i); + bool blocks_read = true; + for(size_t i = first_block; i < first_block + total_blocks_in_sec; i++) { + blocks_read = mf_classic_is_block_read(data, i); + if(!blocks_read) break; + } + if(blocks_read) { + *sectors_read += 1; + } + } +} + static bool mf_classic_is_allowed_access_sector_trailer( MfClassicEmulator* emulator, uint8_t block_num, @@ -126,7 +249,8 @@ static bool mf_classic_is_allowed_access_data_block( uint8_t block_num, MfClassicKey key, MfClassicAction action) { - uint8_t* sector_trailer = emulator->data.block[mf_classic_get_sector_trailer(block_num)].value; + uint8_t* sector_trailer = + emulator->data.block[mf_classic_get_sector_trailer_num_by_block(block_num)].value; uint8_t sector_block; if(block_num <= 128) { @@ -207,15 +331,18 @@ bool mf_classic_check_card_type(uint8_t ATQA0, uint8_t ATQA1, uint8_t SAK) { } } -bool mf_classic_get_type( - uint8_t* uid, - uint8_t uid_len, - uint8_t ATQA0, - uint8_t ATQA1, - uint8_t SAK, - MfClassicReader* reader) { +MfClassicType mf_classic_get_classic_type(int8_t ATQA0, uint8_t ATQA1, uint8_t SAK) { + UNUSED(ATQA1); + if((ATQA0 == 0x44 || ATQA0 == 0x04) && (SAK == 0x08 || SAK == 0x88 || SAK == 0x09)) { + return MfClassicType1k; + } else if((ATQA0 == 0x42 || ATQA0 == 0x02) && (SAK == 0x18)) { + return MfClassicType4k; + } + return MfClassicType1k; +} + +bool mf_classic_get_type(uint8_t ATQA0, uint8_t ATQA1, uint8_t SAK, MfClassicReader* reader) { UNUSED(ATQA1); - furi_assert(uid); furi_assert(reader); memset(reader, 0, sizeof(MfClassicReader)); @@ -226,14 +353,6 @@ bool mf_classic_get_type( } else { return false; } - - uint8_t* cuid_start = uid; - if(uid_len == 7) { - cuid_start = &uid[3]; - } - reader->cuid = (cuid_start[0] << 24) | (cuid_start[1] << 16) | (cuid_start[2] << 8) | - (cuid_start[3]); - return true; } @@ -246,7 +365,7 @@ void mf_classic_reader_add_sector( furi_assert(sector < MF_CLASSIC_SECTORS_MAX); furi_assert((key_a != MF_CLASSIC_NO_KEY) || (key_b != MF_CLASSIC_NO_KEY)); - if(reader->sectors_to_read < MF_CLASSIC_SECTORS_MAX - 1) { + if(reader->sectors_to_read < MF_CLASSIC_SECTORS_MAX) { reader->sector_reader[reader->sectors_to_read].key_a = key_a; reader->sector_reader[reader->sectors_to_read].key_b = key_b; reader->sector_reader[reader->sectors_to_read].sector_num = sector; @@ -254,9 +373,8 @@ void mf_classic_reader_add_sector( } } -void mf_classic_auth_init_context(MfClassicAuthContext* auth_ctx, uint32_t cuid, uint8_t sector) { +void mf_classic_auth_init_context(MfClassicAuthContext* auth_ctx, uint8_t sector) { furi_assert(auth_ctx); - auth_ctx->cuid = cuid; auth_ctx->sector = sector; auth_ctx->key_a = MF_CLASSIC_NO_KEY; auth_ctx->key_b = MF_CLASSIC_NO_KEY; @@ -264,17 +382,18 @@ void mf_classic_auth_init_context(MfClassicAuthContext* auth_ctx, uint32_t cuid, static bool mf_classic_auth( FuriHalNfcTxRxContext* tx_rx, - uint32_t cuid, uint32_t block, uint64_t key, MfClassicKey key_type, Crypto1* crypto) { bool auth_success = false; + uint32_t cuid = 0; memset(tx_rx->tx_data, 0, sizeof(tx_rx->tx_data)); memset(tx_rx->tx_parity, 0, sizeof(tx_rx->tx_parity)); tx_rx->tx_rx_type = FuriHalNfcTxRxTypeDefault; do { + if(!furi_hal_nfc_activate_nfca(200, &cuid)) break; if(key_type == MfClassicKeyA) { tx_rx->tx_data[0] = MF_CLASSIC_AUTH_KEY_A_CMD; } else { @@ -315,6 +434,19 @@ static bool mf_classic_auth( return auth_success; } +bool mf_classic_authenticate( + FuriHalNfcTxRxContext* tx_rx, + uint8_t block_num, + uint64_t key, + MfClassicKey key_type) { + furi_assert(tx_rx); + + Crypto1 crypto = {}; + bool key_found = mf_classic_auth(tx_rx, block_num, key, key_type, &crypto); + furi_hal_nfc_sleep(); + return key_found; +} + bool mf_classic_auth_attempt( FuriHalNfcTxRxContext* tx_rx, MfClassicAuthContext* auth_ctx, @@ -330,7 +462,6 @@ bool mf_classic_auth_attempt( // Try AUTH with key A if(mf_classic_auth( tx_rx, - auth_ctx->cuid, mf_classic_get_first_block_num_of_sector(auth_ctx->sector), key, MfClassicKeyA, @@ -342,14 +473,12 @@ bool mf_classic_auth_attempt( if(need_halt) { furi_hal_nfc_sleep(); - furi_hal_nfc_activate_nfca(300, &auth_ctx->cuid); } if(auth_ctx->key_b == MF_CLASSIC_NO_KEY) { // Try AUTH with key B if(mf_classic_auth( tx_rx, - auth_ctx->cuid, mf_classic_get_first_block_num_of_sector(auth_ctx->sector), key, MfClassicKeyB, @@ -410,7 +539,60 @@ bool mf_classic_read_block( return read_block_success; } -bool mf_classic_read_sector( +void mf_classic_read_sector(FuriHalNfcTxRxContext* tx_rx, MfClassicData* data, uint8_t sec_num) { + furi_assert(tx_rx); + furi_assert(data); + + furi_hal_nfc_sleep(); + bool key_a_found = mf_classic_is_key_found(data, sec_num, MfClassicKeyA); + bool key_b_found = mf_classic_is_key_found(data, sec_num, MfClassicKeyB); + uint8_t start_block = mf_classic_get_first_block_num_of_sector(sec_num); + uint8_t total_blocks = mf_classic_get_blocks_num_in_sector(sec_num); + MfClassicBlock block_tmp = {}; + uint64_t key = 0; + MfClassicSectorTrailer* sec_tr = mf_classic_get_sector_trailer_by_sector(data, sec_num); + Crypto1 crypto = {}; + + uint8_t blocks_read = 0; + do { + if(!key_a_found) break; + FURI_LOG_D(TAG, "Try to read blocks with key A"); + key = nfc_util_bytes2num(sec_tr->key_a, sizeof(sec_tr->key_a)); + if(!mf_classic_auth(tx_rx, start_block, key, MfClassicKeyA, &crypto)) break; + for(size_t i = start_block; i < start_block + total_blocks; i++) { + if(!mf_classic_is_block_read(data, i)) { + if(mf_classic_read_block(tx_rx, &crypto, i, &block_tmp)) { + mf_classic_set_block_read(data, i, &block_tmp); + blocks_read++; + } + } else { + blocks_read++; + } + } + FURI_LOG_D(TAG, "Read %d blocks out of %d", blocks_read, total_blocks); + } while(false); + do { + if(blocks_read == total_blocks) break; + if(!key_b_found) break; + FURI_LOG_D(TAG, "Try to read blocks with key B"); + key = nfc_util_bytes2num(sec_tr->key_b, sizeof(sec_tr->key_b)); + furi_hal_nfc_sleep(); + if(!mf_classic_auth(tx_rx, start_block, key, MfClassicKeyB, &crypto)) break; + for(size_t i = start_block; i < start_block + total_blocks; i++) { + if(!mf_classic_is_block_read(data, i)) { + if(mf_classic_read_block(tx_rx, &crypto, i, &block_tmp)) { + mf_classic_set_block_read(data, i, &block_tmp); + blocks_read++; + } + } else { + blocks_read++; + } + } + FURI_LOG_D(TAG, "Read %d blocks out of %d", blocks_read, total_blocks); + } while(false); +} + +static bool mf_classic_read_sector_with_reader( FuriHalNfcTxRxContext* tx_rx, Crypto1* crypto, MfClassicSectorReader* sector_reader, @@ -419,7 +601,6 @@ bool mf_classic_read_sector( furi_assert(sector_reader); furi_assert(sector); - uint32_t cuid = 0; uint64_t key; MfClassicKey key_type; uint8_t first_block; @@ -428,7 +609,6 @@ bool mf_classic_read_sector( furi_hal_nfc_sleep(); do { // Activate card - if(!furi_hal_nfc_activate_nfca(200, &cuid)) break; first_block = mf_classic_get_first_block_num_of_sector(sector_reader->sector_num); if(sector_reader->key_a != MF_CLASSIC_NO_KEY) { key = sector_reader->key_a; @@ -441,7 +621,7 @@ bool mf_classic_read_sector( } // Auth to first block in sector - if(!mf_classic_auth(tx_rx, cuid, first_block, key, key_type, crypto)) break; + if(!mf_classic_auth(tx_rx, first_block, key, key_type, crypto)) break; sector->total_blocks = mf_classic_get_blocks_num_in_sector(sector_reader->sector_num); // Read blocks @@ -478,18 +658,26 @@ uint8_t mf_classic_read_card( data->key_b_mask = 0; MfClassicSector temp_sector = {}; for(uint8_t i = 0; i < reader->sectors_to_read; i++) { - if(mf_classic_read_sector( + if(mf_classic_read_sector_with_reader( tx_rx, &reader->crypto, &reader->sector_reader[i], &temp_sector)) { uint8_t first_block = mf_classic_get_first_block_num_of_sector(reader->sector_reader[i].sector_num); for(uint8_t j = 0; j < temp_sector.total_blocks; j++) { - data->block[first_block + j] = temp_sector.block[j]; + mf_classic_set_block_read(data, first_block + j, &temp_sector.block[j]); } if(reader->sector_reader[i].key_a != MF_CLASSIC_NO_KEY) { - data->key_a_mask |= 1 << reader->sector_reader[i].sector_num; + mf_classic_set_key_found( + data, + reader->sector_reader[i].sector_num, + MfClassicKeyA, + reader->sector_reader[i].key_a); } if(reader->sector_reader[i].key_b != MF_CLASSIC_NO_KEY) { - data->key_b_mask |= 1 << reader->sector_reader[i].sector_num; + mf_classic_set_key_found( + data, + reader->sector_reader[i].sector_num, + MfClassicKeyB, + reader->sector_reader[i].key_b); } sectors_read++; } @@ -498,6 +686,46 @@ uint8_t mf_classic_read_card( return sectors_read; } +uint8_t mf_classic_update_card(FuriHalNfcTxRxContext* tx_rx, MfClassicData* data) { + furi_assert(tx_rx); + furi_assert(data); + + uint8_t sectors_read = 0; + Crypto1 crypto = {}; + uint8_t total_sectors = mf_classic_get_total_sectors_num(data->type); + uint64_t key_a = 0; + uint64_t key_b = 0; + MfClassicSectorReader sec_reader = {}; + MfClassicSector temp_sector = {}; + + for(size_t i = 0; i < total_sectors; i++) { + MfClassicSectorTrailer* sec_tr = mf_classic_get_sector_trailer_by_sector(data, i); + // Load key A + if(mf_classic_is_key_found(data, i, MfClassicKeyA)) { + sec_reader.key_a = nfc_util_bytes2num(sec_tr->key_a, 6); + } else { + sec_reader.key_a = MF_CLASSIC_NO_KEY; + } + // Load key B + if(mf_classic_is_key_found(data, i, MfClassicKeyB)) { + sec_reader.key_b = nfc_util_bytes2num(sec_tr->key_b, 6); + } else { + sec_reader.key_b = MF_CLASSIC_NO_KEY; + } + if((key_a != MF_CLASSIC_NO_KEY) || (key_b != MF_CLASSIC_NO_KEY)) { + sec_reader.sector_num = i; + if(mf_classic_read_sector_with_reader(tx_rx, &crypto, &sec_reader, &temp_sector)) { + uint8_t first_block = mf_classic_get_first_block_num_of_sector(i); + for(uint8_t j = 0; j < temp_sector.total_blocks; j++) { + mf_classic_set_block_read(data, first_block + j, &temp_sector.block[j]); + } + sectors_read++; + } + } + } + return sectors_read; +} + void mf_crypto1_decrypt( Crypto1* crypto, uint8_t* encrypted_data, @@ -573,7 +801,7 @@ bool mf_classic_emulator(MfClassicEmulator* emulator, FuriHalNfcTxRxContext* tx_ } else if(plain_data[0] == 0x60 || plain_data[0] == 0x61) { uint8_t block = plain_data[1]; uint64_t key = 0; - uint8_t sector_trailer_block = mf_classic_get_sector_trailer(block); + uint8_t sector_trailer_block = mf_classic_get_sector_trailer_num_by_block(block); MfClassicSectorTrailer* sector_trailer = (MfClassicSectorTrailer*)emulator->data.block[sector_trailer_block].value; if(plain_data[0] == 0x60) { @@ -635,21 +863,6 @@ bool mf_classic_emulator(MfClassicEmulator* emulator, FuriHalNfcTxRxContext* tx_ nr, ar); - // Check if we store valid key - if(access_key == MfClassicKeyA) { - if(FURI_BIT(emulator->data.key_a_mask, mf_classic_get_sector_by_block(block)) == - 0) { - FURI_LOG_D(TAG, "Unsupported sector key A for block %d", sector_trailer_block); - break; - } - } else if(access_key == MfClassicKeyB) { - if(FURI_BIT(emulator->data.key_b_mask, mf_classic_get_sector_by_block(block)) == - 0) { - FURI_LOG_D(TAG, "Unsupported sector key B for block %d", sector_trailer_block); - break; - } - } - crypto1_word(&emulator->crypto, nr, 1); uint32_t cardRr = ar ^ crypto1_word(&emulator->crypto, 0, 0); if(cardRr != prng_successor(nonce, 64)) { diff --git a/lib/nfc_protocols/mifare_classic.h b/lib/nfc/protocols/mifare_classic.h similarity index 54% rename from lib/nfc_protocols/mifare_classic.h rename to lib/nfc/protocols/mifare_classic.h index bbf34b2d..85f67b11 100644 --- a/lib/nfc_protocols/mifare_classic.h +++ b/lib/nfc/protocols/mifare_classic.h @@ -14,6 +14,8 @@ #define MF_CLASSIC_NO_KEY (0xFFFFFFFFFFFFFFFF) #define MF_CLASSIC_MAX_DATA_SIZE (16) +#define MF_CLASSIC_KEY_SIZE (6) +#define MF_CLASSIC_ACCESS_BYTES_SIZE (4) typedef enum { MfClassicType1k, @@ -30,9 +32,9 @@ typedef struct { } MfClassicBlock; typedef struct { - uint8_t key_a[6]; - uint8_t access_bits[4]; - uint8_t key_b[6]; + uint8_t key_a[MF_CLASSIC_KEY_SIZE]; + uint8_t access_bits[MF_CLASSIC_ACCESS_BYTES_SIZE]; + uint8_t key_b[MF_CLASSIC_KEY_SIZE]; } MfClassicSectorTrailer; typedef struct { @@ -42,13 +44,13 @@ typedef struct { typedef struct { MfClassicType type; + uint32_t block_read_mask[MF_CLASSIC_TOTAL_BLOCKS_MAX / 32]; uint64_t key_a_mask; uint64_t key_b_mask; MfClassicBlock block[MF_CLASSIC_TOTAL_BLOCKS_MAX]; } MfClassicData; typedef struct { - uint32_t cuid; uint8_t sector; uint64_t key_a; uint64_t key_b; @@ -62,9 +64,8 @@ typedef struct { typedef struct { MfClassicType type; - uint32_t cuid; - uint8_t sectors_to_read; Crypto1 crypto; + uint8_t sectors_to_read; MfClassicSectorReader sector_reader[MF_CLASSIC_SECTORS_MAX]; } MfClassicReader; @@ -75,19 +76,51 @@ typedef struct { bool data_changed; } MfClassicEmulator; +const char* mf_classic_get_type_str(MfClassicType type); + bool mf_classic_check_card_type(uint8_t ATQA0, uint8_t ATQA1, uint8_t SAK); -bool mf_classic_get_type( - uint8_t* uid, - uint8_t uid_len, - uint8_t ATQA0, - uint8_t ATQA1, - uint8_t SAK, - MfClassicReader* reader); +MfClassicType mf_classic_get_classic_type(int8_t ATQA0, uint8_t ATQA1, uint8_t SAK); -uint8_t mf_classic_get_total_sectors_num(MfClassicReader* reader); +bool mf_classic_get_type(uint8_t ATQA0, uint8_t ATQA1, uint8_t SAK, MfClassicReader* reader); -void mf_classic_auth_init_context(MfClassicAuthContext* auth_ctx, uint32_t cuid, uint8_t sector); +uint8_t mf_classic_get_total_sectors_num(MfClassicType type); + +uint8_t mf_classic_get_sector_trailer_block_num_by_sector(uint8_t sector); + +bool mf_classic_is_sector_trailer(uint8_t block); + +uint8_t mf_classic_get_sector_by_block(uint8_t block); + +bool mf_classic_is_key_found(MfClassicData* data, uint8_t sector_num, MfClassicKey key_type); + +void mf_classic_set_key_found( + MfClassicData* data, + uint8_t sector_num, + MfClassicKey key_type, + uint64_t key); + +bool mf_classic_is_block_read(MfClassicData* data, uint8_t block_num); + +void mf_classic_set_block_read(MfClassicData* data, uint8_t block_num, MfClassicBlock* block_data); + +bool mf_classic_is_sector_read(MfClassicData* data, uint8_t sector_num); + +void mf_classic_get_read_sectors_and_keys( + MfClassicData* data, + uint8_t* sectors_read, + uint8_t* keys_found); + +MfClassicSectorTrailer* + mf_classic_get_sector_trailer_by_sector(MfClassicData* data, uint8_t sector); + +void mf_classic_auth_init_context(MfClassicAuthContext* auth_ctx, uint8_t sector); + +bool mf_classic_authenticate( + FuriHalNfcTxRxContext* tx_rx, + uint8_t block_num, + uint64_t key, + MfClassicKey key_type); bool mf_classic_auth_attempt( FuriHalNfcTxRxContext* tx_rx, @@ -100,15 +133,13 @@ void mf_classic_reader_add_sector( uint64_t key_a, uint64_t key_b); -bool mf_classic_read_sector( - FuriHalNfcTxRxContext* tx_rx, - Crypto1* crypto, - MfClassicSectorReader* sector_reader, - MfClassicSector* sector); +void mf_classic_read_sector(FuriHalNfcTxRxContext* tx_rx, MfClassicData* data, uint8_t sec_num); uint8_t mf_classic_read_card( FuriHalNfcTxRxContext* tx_rx, MfClassicReader* reader, MfClassicData* data); +uint8_t mf_classic_update_card(FuriHalNfcTxRxContext* tx_rx, MfClassicData* data); + bool mf_classic_emulator(MfClassicEmulator* emulator, FuriHalNfcTxRxContext* tx_rx); diff --git a/lib/nfc_protocols/mifare_common.c b/lib/nfc/protocols/mifare_common.c similarity index 100% rename from lib/nfc_protocols/mifare_common.c rename to lib/nfc/protocols/mifare_common.c diff --git a/lib/nfc_protocols/mifare_common.h b/lib/nfc/protocols/mifare_common.h similarity index 100% rename from lib/nfc_protocols/mifare_common.h rename to lib/nfc/protocols/mifare_common.h diff --git a/lib/nfc_protocols/mifare_desfire.c b/lib/nfc/protocols/mifare_desfire.c similarity index 62% rename from lib/nfc_protocols/mifare_desfire.c rename to lib/nfc/protocols/mifare_desfire.c index 6f28dc5d..1822d5c1 100644 --- a/lib/nfc_protocols/mifare_desfire.c +++ b/lib/nfc/protocols/mifare_desfire.c @@ -2,6 +2,8 @@ #include #include +#define TAG "MifareDESFire" + void mf_df_clear(MifareDesfireData* data) { free(data->free_memory); if(data->master_key_settings) { @@ -449,3 +451,173 @@ bool mf_df_parse_read_data_response(uint8_t* buf, uint16_t len, MifareDesfireFil memcpy(out->contents, buf, len); return true; } + +bool mf_df_read_card(FuriHalNfcTxRxContext* tx_rx, MifareDesfireData* data) { + furi_assert(tx_rx); + furi_assert(data); + + bool card_read = false; + do { + // Get version + tx_rx->tx_bits = 8 * mf_df_prepare_get_version(tx_rx->tx_data); + if(!furi_hal_nfc_tx_rx_full(tx_rx)) { + FURI_LOG_W(TAG, "Bad exchange getting version"); + break; + } + if(!mf_df_parse_get_version_response(tx_rx->rx_data, tx_rx->rx_bits / 8, &data->version)) { + FURI_LOG_W(TAG, "Bad DESFire GET_VERSION responce"); + } + + // Get free memory + tx_rx->tx_bits = 8 * mf_df_prepare_get_free_memory(tx_rx->tx_data); + if(furi_hal_nfc_tx_rx_full(tx_rx)) { + data->free_memory = malloc(sizeof(MifareDesfireFreeMemory)); + if(!mf_df_parse_get_free_memory_response( + tx_rx->rx_data, tx_rx->rx_bits / 8, data->free_memory)) { + FURI_LOG_D(TAG, "Bad DESFire GET_FREE_MEMORY response (normal for pre-EV1 cards)"); + free(data->free_memory); + data->free_memory = NULL; + } + } + + // Get key settings + tx_rx->tx_bits = 8 * mf_df_prepare_get_key_settings(tx_rx->tx_data); + if(!furi_hal_nfc_tx_rx_full(tx_rx)) { + FURI_LOG_D(TAG, "Bad exchange getting key settings"); + } else { + data->master_key_settings = malloc(sizeof(MifareDesfireKeySettings)); + if(!mf_df_parse_get_key_settings_response( + tx_rx->rx_data, tx_rx->rx_bits / 8, data->master_key_settings)) { + FURI_LOG_W(TAG, "Bad DESFire GET_KEY_SETTINGS response"); + free(data->master_key_settings); + data->master_key_settings = NULL; + } else { + MifareDesfireKeyVersion** key_version_head = + &data->master_key_settings->key_version_head; + for(uint8_t key_id = 0; key_id < data->master_key_settings->max_keys; key_id++) { + tx_rx->tx_bits = 8 * mf_df_prepare_get_key_version(tx_rx->tx_data, key_id); + if(!furi_hal_nfc_tx_rx_full(tx_rx)) { + FURI_LOG_W(TAG, "Bad exchange getting key version"); + continue; + } + MifareDesfireKeyVersion* key_version = malloc(sizeof(MifareDesfireKeyVersion)); + memset(key_version, 0, sizeof(MifareDesfireKeyVersion)); + key_version->id = key_id; + if(!mf_df_parse_get_key_version_response( + tx_rx->rx_data, tx_rx->rx_bits / 8, key_version)) { + FURI_LOG_W(TAG, "Bad DESFire GET_KEY_VERSION response"); + free(key_version); + continue; + } + *key_version_head = key_version; + key_version_head = &key_version->next; + } + } + } + + // Get application IDs + tx_rx->tx_bits = 8 * mf_df_prepare_get_application_ids(tx_rx->tx_data); + if(!furi_hal_nfc_tx_rx_full(tx_rx)) { + FURI_LOG_W(TAG, "Bad exchange getting application IDs"); + break; + } else { + if(!mf_df_parse_get_application_ids_response( + tx_rx->rx_data, tx_rx->rx_bits / 8, &data->app_head)) { + FURI_LOG_W(TAG, "Bad DESFire GET_APPLICATION_IDS response"); + break; + } + } + + for(MifareDesfireApplication* app = data->app_head; app; app = app->next) { + tx_rx->tx_bits = 8 * mf_df_prepare_select_application(tx_rx->tx_data, app->id); + if(!furi_hal_nfc_tx_rx_full(tx_rx) || + !mf_df_parse_select_application_response(tx_rx->rx_data, tx_rx->rx_bits / 8)) { + FURI_LOG_W(TAG, "Bad exchange selecting application"); + continue; + } + tx_rx->tx_bits = 8 * mf_df_prepare_get_key_settings(tx_rx->tx_data); + if(!furi_hal_nfc_tx_rx_full(tx_rx)) { + FURI_LOG_W(TAG, "Bad exchange getting key settings"); + } else { + app->key_settings = malloc(sizeof(MifareDesfireKeySettings)); + memset(app->key_settings, 0, sizeof(MifareDesfireKeySettings)); + if(!mf_df_parse_get_key_settings_response( + tx_rx->rx_data, tx_rx->rx_bits / 8, app->key_settings)) { + FURI_LOG_W(TAG, "Bad DESFire GET_KEY_SETTINGS response"); + free(app->key_settings); + app->key_settings = NULL; + continue; + } + + MifareDesfireKeyVersion** key_version_head = &app->key_settings->key_version_head; + for(uint8_t key_id = 0; key_id < app->key_settings->max_keys; key_id++) { + tx_rx->tx_bits = 8 * mf_df_prepare_get_key_version(tx_rx->tx_data, key_id); + if(!furi_hal_nfc_tx_rx_full(tx_rx)) { + FURI_LOG_W(TAG, "Bad exchange getting key version"); + continue; + } + MifareDesfireKeyVersion* key_version = malloc(sizeof(MifareDesfireKeyVersion)); + memset(key_version, 0, sizeof(MifareDesfireKeyVersion)); + key_version->id = key_id; + if(!mf_df_parse_get_key_version_response( + tx_rx->rx_data, tx_rx->rx_bits / 8, key_version)) { + FURI_LOG_W(TAG, "Bad DESFire GET_KEY_VERSION response"); + free(key_version); + continue; + } + *key_version_head = key_version; + key_version_head = &key_version->next; + } + } + + tx_rx->tx_bits = 8 * mf_df_prepare_get_file_ids(tx_rx->tx_data); + if(!furi_hal_nfc_tx_rx_full(tx_rx)) { + FURI_LOG_W(TAG, "Bad exchange getting file IDs"); + } else { + if(!mf_df_parse_get_file_ids_response( + tx_rx->rx_data, tx_rx->rx_bits / 8, &app->file_head)) { + FURI_LOG_W(TAG, "Bad DESFire GET_FILE_IDS response"); + } + } + + for(MifareDesfireFile* file = app->file_head; file; file = file->next) { + tx_rx->tx_bits = 8 * mf_df_prepare_get_file_settings(tx_rx->tx_data, file->id); + if(!furi_hal_nfc_tx_rx_full(tx_rx)) { + FURI_LOG_W(TAG, "Bad exchange getting file settings"); + continue; + } + if(!mf_df_parse_get_file_settings_response( + tx_rx->rx_data, tx_rx->rx_bits / 8, file)) { + FURI_LOG_W(TAG, "Bad DESFire GET_FILE_SETTINGS response"); + continue; + } + switch(file->type) { + case MifareDesfireFileTypeStandard: + case MifareDesfireFileTypeBackup: + tx_rx->tx_bits = 8 * mf_df_prepare_read_data(tx_rx->tx_data, file->id, 0, 0); + break; + case MifareDesfireFileTypeValue: + tx_rx->tx_bits = 8 * mf_df_prepare_get_value(tx_rx->tx_data, file->id); + break; + case MifareDesfireFileTypeLinearRecord: + case MifareDesfireFileTypeCyclicRecord: + tx_rx->tx_bits = + 8 * mf_df_prepare_read_records(tx_rx->tx_data, file->id, 0, 0); + break; + } + if(!furi_hal_nfc_tx_rx_full(tx_rx)) { + FURI_LOG_W(TAG, "Bad exchange reading file %d", file->id); + continue; + } + if(!mf_df_parse_read_data_response(tx_rx->rx_data, tx_rx->rx_bits / 8, file)) { + FURI_LOG_W(TAG, "Bad response reading file %d", file->id); + continue; + } + } + } + + card_read = true; + } while(false); + + return card_read; +} diff --git a/lib/nfc_protocols/mifare_desfire.h b/lib/nfc/protocols/mifare_desfire.h similarity index 98% rename from lib/nfc_protocols/mifare_desfire.h rename to lib/nfc/protocols/mifare_desfire.h index dbe0802e..e59743a2 100644 --- a/lib/nfc_protocols/mifare_desfire.h +++ b/lib/nfc/protocols/mifare_desfire.h @@ -4,6 +4,8 @@ #include #include +#include + #define MF_DF_GET_VERSION (0x60) #define MF_DF_GET_FREE_MEMORY (0x6E) #define MF_DF_GET_KEY_SETTINGS (0x45) @@ -163,3 +165,5 @@ uint16_t mf_df_prepare_read_data(uint8_t* dest, uint8_t file_id, uint32_t offset uint16_t mf_df_prepare_get_value(uint8_t* dest, uint8_t file_id); uint16_t mf_df_prepare_read_records(uint8_t* dest, uint8_t file_id, uint32_t offset, uint32_t len); bool mf_df_parse_read_data_response(uint8_t* buf, uint16_t len, MifareDesfireFile* out); + +bool mf_df_read_card(FuriHalNfcTxRxContext* tx_rx, MifareDesfireData* data); diff --git a/lib/nfc_protocols/mifare_ultralight.c b/lib/nfc/protocols/mifare_ultralight.c similarity index 100% rename from lib/nfc_protocols/mifare_ultralight.c rename to lib/nfc/protocols/mifare_ultralight.c diff --git a/lib/nfc_protocols/mifare_ultralight.h b/lib/nfc/protocols/mifare_ultralight.h similarity index 100% rename from lib/nfc_protocols/mifare_ultralight.h rename to lib/nfc/protocols/mifare_ultralight.h diff --git a/lib/nfc_protocols/nfc_util.c b/lib/nfc/protocols/nfc_util.c similarity index 100% rename from lib/nfc_protocols/nfc_util.c rename to lib/nfc/protocols/nfc_util.c diff --git a/lib/nfc_protocols/nfc_util.h b/lib/nfc/protocols/nfc_util.h similarity index 100% rename from lib/nfc_protocols/nfc_util.h rename to lib/nfc/protocols/nfc_util.h diff --git a/lib/nfc_protocols/nfca.c b/lib/nfc/protocols/nfca.c similarity index 100% rename from lib/nfc_protocols/nfca.c rename to lib/nfc/protocols/nfca.c diff --git a/lib/nfc_protocols/nfca.h b/lib/nfc/protocols/nfca.h similarity index 100% rename from lib/nfc_protocols/nfca.h rename to lib/nfc/protocols/nfca.h