diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d3ebb9ad..b491c600 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -15,11 +15,8 @@ env: jobs: main: - runs-on: [self-hosted,FlipperZero] + runs-on: [self-hosted,FlipperZeroShell] steps: - - name: 'Cleanup workspace' - uses: AutoModality/action-clean@v1 - - name: 'Decontaminate previous build leftovers' run: | if [ -d .git ] @@ -32,12 +29,8 @@ jobs: uses: actions/checkout@v2 with: fetch-depth: 0 - submodules: true ref: ${{ github.event.pull_request.head.sha }} - - name: 'Build docker image' - uses: ./.github/actions/docker - - name: 'Make artifacts directory' run: | test -d artifacts && rm -rf artifacts || true @@ -71,40 +64,38 @@ jobs: run: | tar czpf artifacts/flipper-z-any-scripts-${{steps.names.outputs.suffix}}.tgz scripts - - name: 'Build the firmware in docker' - uses: ./.github/actions/docker - with: - run: | - set -e - for TARGET in ${TARGETS} - do - ./fbt TARGET_HW=`echo ${TARGET} | sed 's/f//'` --with-updater updater_package ${{ startsWith(github.ref, 'refs/tags') && 'DEBUG=0 COMPACT=1' || '' }} - done + - name: 'Build the firmware' + run: | + set -e + for TARGET in ${TARGETS} + do + FBT_TOOLCHAIN_PATH=/opt ./fbt TARGET_HW=`echo ${TARGET} | sed 's/f//'` updater_package ${{ startsWith(github.ref, 'refs/tags') && 'DEBUG=0 COMPACT=1' || '' }} + done - name: 'Move upload files' if: ${{ !github.event.pull_request.head.repo.fork }} - uses: ./.github/actions/docker - with: - run: | - set -e - for TARGET in ${TARGETS} - do - mv dist/${TARGET}-*/* artifacts/ - done + run: | + set -e + for TARGET in ${TARGETS} + do + mv dist/${TARGET}-*/* artifacts/ + done - name: 'Bundle self-update package' if: ${{ !github.event.pull_request.head.repo.fork }} - uses: ./.github/actions/docker - with: - run: | - set -e - for UPDATEBUNDLE in artifacts/*/ - do - BUNDLE_NAME=`echo $UPDATEBUNDLE | cut -d'/' -f2` - echo Packaging ${BUNDLE_NAME} - tar czpf artifacts/flipper-z-${BUNDLE_NAME}.tgz -C artifacts ${BUNDLE_NAME} - rm -rf artifacts/${BUNDLE_NAME} - done + run: | + set -e + for UPDATEBUNDLE in artifacts/*/ + do + BUNDLE_NAME=`echo $UPDATEBUNDLE | cut -d'/' -f2` + echo Packaging ${BUNDLE_NAME} + tar czpf artifacts/flipper-z-${BUNDLE_NAME}.tgz -C artifacts ${BUNDLE_NAME} + rm -rf artifacts/${BUNDLE_NAME} + done + + - name: "Check for uncommited changes" + run: | + git diff --exit-code - name: 'Bundle resources' if: ${{ !github.event.pull_request.head.repo.fork }} @@ -113,29 +104,23 @@ jobs: - name: 'Bundle core2 firmware' if: ${{ !github.event.pull_request.head.repo.fork }} - uses: ./.github/actions/docker - with: - run: | - ./fbt copro_dist - tar czpf artifacts/flipper-z-any-core2_firmware-${{steps.names.outputs.suffix}}.tgz -C assets core2_firmware + run: | + FBT_TOOLCHAIN_PATH=/opt ./fbt copro_dist + tar czpf artifacts/flipper-z-any-core2_firmware-${{steps.names.outputs.suffix}}.tgz -C assets core2_firmware - name: 'Upload artifacts to update server' if: ${{ !github.event.pull_request.head.repo.fork }} - uses: burnett01/rsync-deployments@5.1 - with: - switches: -avzP --delete --mkpath - path: artifacts/ - remote_path: "${{ secrets.RSYNC_DEPLOY_BASE_PATH }}${{steps.names.outputs.artifacts-path}}/" - remote_host: ${{ secrets.RSYNC_DEPLOY_HOST }} - remote_port: ${{ secrets.RSYNC_DEPLOY_PORT }} - remote_user: ${{ secrets.RSYNC_DEPLOY_USER }} - remote_key: ${{ secrets.RSYNC_DEPLOY_KEY }} + run: | + echo "${{ secrets.RSYNC_DEPLOY_KEY }}" > deploy_key; + chmod 600 ./deploy_key; + rsync -avzP --mkpath \ + -e 'ssh -p ${{ secrets.RSYNC_DEPLOY_PORT }} -i ./deploy_key' \ + artifacts/ ${{ secrets.RSYNC_DEPLOY_USER }}@${{ secrets.RSYNC_DEPLOY_HOST }}:"${{ secrets.RSYNC_DEPLOY_BASE_PATH }}${{steps.names.outputs.artifacts-path}}/"; + rm ./deploy_key; - name: 'Trigger update server reindex' if: ${{ !github.event.pull_request.head.repo.fork }} - uses: wei/curl@master - with: - args: -X POST -F 'key=${{ secrets.REINDEX_KEY }}' ${{ secrets.REINDEX_URL }} + run: curl -X POST -F 'key=${{ secrets.REINDEX_KEY }}' ${{ secrets.REINDEX_URL }} - name: 'Find Previous Comment' if: ${{ !github.event.pull_request.head.repo.fork && github.event.pull_request }} @@ -161,11 +146,8 @@ jobs: compact: if: ${{ !startsWith(github.ref, 'refs/tags') }} - runs-on: [self-hosted,FlipperZero] + runs-on: [self-hosted,FlipperZeroShell] steps: - - name: 'Cleanup workspace' - uses: AutoModality/action-clean@v1 - - name: 'Decontaminate previous build leftovers' run: | if [ -d .git ] @@ -181,9 +163,6 @@ jobs: submodules: true ref: ${{ github.event.pull_request.head.sha }} - - name: 'Build docker image' - uses: ./.github/actions/docker - - name: 'Generate suffix and folder name' id: names run: | @@ -203,12 +182,10 @@ jobs: echo "WORKFLOW_BRANCH_OR_TAG=${BRANCH_OR_TAG}" >> $GITHUB_ENV echo "DIST_SUFFIX=${SUFFIX}" >> $GITHUB_ENV - - name: 'Build the firmware in docker' - uses: ./.github/actions/docker - with: - run: | - set -e - for TARGET in ${TARGETS} - do - ./fbt TARGET_HW=`echo ${TARGET} | sed 's/f//'` --with-updater updater_package DEBUG=0 COMPACT=1 - done + - name: 'Build the firmware' + run: | + set -e + for TARGET in ${TARGETS} + do + FBT_TOOLCHAIN_PATH=/opt ./fbt TARGET_HW=`echo ${TARGET} | sed 's/f//'` updater_package DEBUG=0 COMPACT=1 + done diff --git a/.github/workflows/build_toolchain.yml b/.github/workflows/build_toolchain.yml deleted file mode 100644 index 452dfbee..00000000 --- a/.github/workflows/build_toolchain.yml +++ /dev/null @@ -1,46 +0,0 @@ -name: 'Build toolchain Docker image' - -on: - push: - branches: - - dev - tags: - - '*' - -jobs: - build: - runs-on: ubuntu-latest - steps: - - name: Checkout code - uses: actions/checkout@v2 - with: - fetch-depth: 0 - - name: Docker meta - id: meta - uses: docker/metadata-action@v3 - with: - images: flipperdevices/flipperzero-toolchain - flavor: latest=${{ startsWith(github.ref, 'refs/tags/') && !endsWith(github.ref, 'rc')}} - tags: | - type=ref,event=branch - type=ref,event=tag - - name: Set up QEMU - uses: docker/setup-qemu-action@v1 - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v1 - - name: Login to DockerHub - uses: docker/login-action@v1 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - name: Build and push - id: docker_build - uses: docker/build-push-action@v2 - with: - context: docker/ - push: true - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} - platforms: linux/amd64,linux/arm64 - cache-from: type=registry,ref=flipperdevices/flipperzero-toolchain:buildcache - cache-to: type=registry,ref=flipperdevices/flipperzero-toolchain:buildcache,mode=max diff --git a/.github/workflows/check_submodules.yml b/.github/workflows/check_submodules.yml index b02f9a8d..f9699be8 100644 --- a/.github/workflows/check_submodules.yml +++ b/.github/workflows/check_submodules.yml @@ -1,17 +1,47 @@ -name: 'Check submodules' +name: 'Check submodules branch' on: + push: + branches: + - dev + - "release*" + tags: + - '*' pull_request: jobs: - protobuf: - runs-on: ubuntu-latest + check_protobuf: + runs-on: [self-hosted, FlipperZeroShell] steps: - - name: 'Checkout code' - uses: actions/checkout@v2 - - name: 'Check submodule commit branch' - uses: jtmullen/submodule-branch-check-action@v1 - with: - path: assets/protobuf - branch: dev - fetch_depth: 50 + - name: 'Decontaminate previous build leftovers' + run: | + if [ -d .git ] + then + git submodule status \ + || git checkout `git rev-list --max-parents=0 HEAD | tail -n 1` + fi + + - name: 'Checkout code' + uses: actions/checkout@v2 + with: + fetch-depth: 0 + + - name: 'Check protobuf branch' + run: | + SUB_PATH="assets/protobuf"; + SUB_BRANCH="dev"; + SUB_COMMITS_MIN=40; + cd "$SUB_PATH"; + SUBMODULE_HASH="$(git rev-parse HEAD)"; + BRANCHES=$(git branch -r --contains "$SUBMODULE_HASH"); + COMMITS_IN_BRANCH="$(git rev-list --count dev)"; + if [ $COMMITS_IN_BRANCH -lt $SUB_COMMITS_MIN ]; then + echo "::set-output name=fails::error"; + echo "::error::Error: Too low commits in $SUB_BRANCH of submodule $SUB_PATH: $COMMITS_IN_BRANCH(expected $SUB_COMMITS_MIN+)"; + exit 1; + fi + if ! grep -q "/$SUB_BRANCH" <<< "$BRANCHES"; then + echo "::set-output name=fails::error"; + echo "::error::Error: Submodule $SUB_PATH is not on branch $SUB_BRANCH"; + exit 1; + fi diff --git a/.github/workflows/lint_c.yml b/.github/workflows/lint_c.yml index f834586d..aaff396e 100644 --- a/.github/workflows/lint_c.yml +++ b/.github/workflows/lint_c.yml @@ -1,6 +1,6 @@ name: 'Lint C/C++ with clang-format' -on: +on: push: branches: - dev @@ -14,11 +14,8 @@ env: jobs: lint_c_cpp: - runs-on: [self-hosted,FlipperZero] + runs-on: [self-hosted,FlipperZeroShell] steps: - - name: 'Cleanup workspace' - uses: AutoModality/action-clean@v1 - - name: 'Decontaminate previous build leftovers' run: | if [ -d .git ] @@ -31,23 +28,10 @@ jobs: uses: actions/checkout@v2 with: fetch-depth: 0 - submodules: true - - - name: 'Docker cache' - uses: satackey/action-docker-layer-caching@v0.0.11 - continue-on-error: true - with: - key: docker-cache-${{ hashFiles('docker/**') }}-{hash} - restore-keys: docker-cache-${{ hashFiles('docker/**') }}- - - - name: 'Build docker image' - uses: ./.github/actions/docker - name: 'Check code formatting' id: syntax_check - uses: ./.github/actions/docker - with: - run: SET_GH_OUTPUT=1 ./fbt lint + run: SET_GH_OUTPUT=1 FBT_TOOLCHAIN_PATH=/opt ./fbt lint - name: Report code formatting errors if: failure() && steps.syntax_check.outputs.errors && github.event.pull_request @@ -59,4 +43,4 @@ jobs: ``` ${{ steps.syntax_check.outputs.errors }} ``` - You might want to run `docker compose exec dev make format` for an auto-fix. + You might want to run `./fbt format` for an auto-fix. diff --git a/.github/workflows/lint_python.yml b/.github/workflows/lint_python.yml index e665378b..c059f434 100644 --- a/.github/workflows/lint_python.yml +++ b/.github/workflows/lint_python.yml @@ -1,6 +1,6 @@ name: 'Python Lint' -on: +on: push: branches: - dev @@ -11,11 +11,8 @@ on: jobs: lint_python: - runs-on: ubuntu-latest + runs-on: [self-hosted,FlipperZeroShell] steps: - - name: 'Cleanup workspace' - uses: AutoModality/action-clean@v1 - - name: 'Decontaminate previous build leftovers' run: | if [ -d .git ] @@ -29,8 +26,5 @@ jobs: with: fetch-depth: 0 - - name: 'Setup python' - uses: actions/setup-python@v2 - - - name: 'Check python code with black' - uses: psf/black@20.8b1 + - name: 'Check code formatting' + run: SET_GH_OUTPUT=1 FBT_TOOLCHAIN_PATH=/opt ./fbt lint_py diff --git a/.github/workflows/reindex.yml b/.github/workflows/reindex.yml index 78f9cbea..ea850e70 100644 --- a/.github/workflows/reindex.yml +++ b/.github/workflows/reindex.yml @@ -7,9 +7,8 @@ on: jobs: reindex: name: 'Reindex updates' - runs-on: [self-hosted,FlipperZero] + runs-on: [self-hosted,FlipperZeroShell] steps: - name: Trigger reindex - uses: wei/curl@master - with: - args: -X POST -F 'key=${{ secrets.REINDEX_KEY }}' ${{ secrets.REINDEX_URL }} + run: | + curl -X POST -F 'key=${{ secrets.REINDEX_KEY }}' ${{ secrets.REINDEX_URL }} diff --git a/ReadMe.md b/ReadMe.md index f3a35056..36a887dc 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -29,11 +29,11 @@ They both must be flashed in the order described. With Flipper attached over USB: -`./fbt --with-updater flash_usb` +`./fbt flash_usb` Just building the package: -`./fbt --with-updater updater_package` +`./fbt updater_package` To update, copy the resulting directory to Flipper's SD card and navigate to `update.fuf` file in Archive app. diff --git a/SConstruct b/SConstruct index 7cdf88fc..fe731e35 100644 --- a/SConstruct +++ b/SConstruct @@ -7,6 +7,7 @@ # construction of certain targets behind command-line options. import os +import subprocess EnsurePythonVersion(3, 8) @@ -33,8 +34,10 @@ 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; log_output debug/openocd.log' ${[SINGLEQUOTEFUNC(OPENOCD_OPTS)]}"], + tools=["fbt_dist", "openocd", "blackmagic", "jflash"], + OPENOCD_GDB_PIPE=[ + "|openocd -c 'gdb_port pipe; log_output debug/openocd.log' ${[SINGLEQUOTEFUNC(OPENOCD_OPTS)]}" + ], GDBOPTS_BASE=[ "-ex", "target extended-remote ${GDBREMOTE}", @@ -61,6 +64,7 @@ distenv = coreenv.Clone( "-ex", "compare-sections", ], + JFLASHPROJECT="${ROOT_DIR.abspath}/debug/fw.jflash", ENV=os.environ, ) @@ -71,7 +75,9 @@ firmware_env = distenv.AddFwProject( ) # If enabled, initialize updater-related targets -if GetOption("fullenv"): +if GetOption("fullenv") or any( + filter(lambda target: "updater" in target or "flash_usb" in target, BUILD_TARGETS) +): updater_env = distenv.AddFwProject( base_env=coreenv, fw_type="updater", @@ -79,11 +85,11 @@ if GetOption("fullenv"): ) # Target for self-update package - dist_arguments = [ - "-r", - '"${ROOT_DIR.abspath}/assets/resources"', + dist_basic_arguments = [ "--bundlever", '"${UPDATE_VERSION_STRING}"', + ] + dist_radio_arguments = [ "--radio", '"${ROOT_DIR.abspath}/${COPRO_STACK_BIN_DIR}/${COPRO_STACK_BIN}"', "--radiotype", @@ -92,16 +98,34 @@ if GetOption("fullenv"): "--obdata", '"${ROOT_DIR.abspath}/${COPRO_OB_DATA}"', ] - if distenv["UPDATE_SPLASH"]: - dist_arguments += [ + dist_resource_arguments = [ + "-r", + '"${ROOT_DIR.abspath}/assets/resources"', + ] + dist_splash_arguments = ( + [ "--splash", distenv.subst("assets/slideshow/$UPDATE_SPLASH"), ] + if distenv["UPDATE_SPLASH"] + else [] + ) selfupdate_dist = distenv.DistCommand( "updater_package", (distenv["DIST_DEPENDS"], firmware_env["FW_RESOURCES"]), - DIST_EXTRA=dist_arguments, + DIST_EXTRA=[ + *dist_basic_arguments, + *dist_radio_arguments, + *dist_resource_arguments, + *dist_splash_arguments, + ], + ) + + selfupdate_min_dist = distenv.DistCommand( + "updater_minpackage", + distenv["DIST_DEPENDS"], + DIST_EXTRA=dist_basic_arguments, ) # Updater debug @@ -121,18 +145,16 @@ if GetOption("fullenv"): ) # Installation over USB & CLI - usb_update_package = distenv.UsbInstall( - "#build/usbinstall.flag", - ( - distenv["DIST_DEPENDS"], - firmware_env["FW_RESOURCES"], - selfupdate_dist, - ), + usb_update_package = distenv.AddUsbFlashTarget( + "#build/usbinstall.flag", (firmware_env["FW_RESOURCES"], selfupdate_dist) ) - if distenv["FORCE"]: - distenv.AlwaysBuild(usb_update_package) - distenv.Depends(usb_update_package, selfupdate_dist) - distenv.Alias("flash_usb", usb_update_package) + distenv.Alias("flash_usb_full", usb_update_package) + + usb_minupdate_package = distenv.AddUsbFlashTarget( + "#build/minusbinstall.flag", (selfupdate_min_dist,) + ) + distenv.Alias("flash_usb", usb_minupdate_package) + # Target for copying & renaming binaries to dist folder basic_dist = distenv.DistCommand("fw_dist", distenv["DIST_DEPENDS"]) @@ -147,8 +169,9 @@ 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_jflash = distenv.AddJFlashTarget(firmware_env) +distenv.Alias("jflash", firmware_jflash) firmware_bm_flash = distenv.PhonyTarget( "flash_blackmagic", @@ -209,6 +232,46 @@ distenv.PhonyTarget( LINT_SOURCES=firmware_env["LINT_SOURCES"], ) +# PY_LINT_SOURCES contains recursively-built modules' SConscript files + application manifests +# Here we add additional Python files residing in repo root +firmware_env.Append( + PY_LINT_SOURCES=[ + # Py code folders + "site_scons", + "scripts", + # Extra files + "applications/extapps.scons", + "SConstruct", + "firmware.scons", + "fbt_options.py", + ] +) + + +black_commandline = "@${PYTHON3} -m black ${PY_BLACK_ARGS} ${PY_LINT_SOURCES}" +black_base_args = ["--include", '"\\.scons|\\.py|SConscript|SConstruct"'] + +distenv.PhonyTarget( + "lint_py", + black_commandline, + PY_BLACK_ARGS=[ + "--check", + "--diff", + *black_base_args, + ], + PY_LINT_SOURCES=firmware_env["PY_LINT_SOURCES"], +) + +distenv.PhonyTarget( + "format_py", + black_commandline, + PY_BLACK_ARGS=black_base_args, + PY_LINT_SOURCES=firmware_env["PY_LINT_SOURCES"], +) + +# Start Flipper CLI via PySerial's miniterm +distenv.PhonyTarget("cli", "${PYTHON3} scripts/serial_cli.py") + # Find blackmagic probe diff --git a/applications/extapps.scons b/applications/extapps.scons index a53620b9..11b59757 100644 --- a/applications/extapps.scons +++ b/applications/extapps.scons @@ -38,6 +38,8 @@ appenv.AppendUnique( "-Wl,--no-export-dynamic", "-fvisibility=hidden", "-Wl,-e${APP_ENTRY}", + "-Xlinker", + "-Map=${TARGET}.map", ], ) diff --git a/applications/ibutton/ibutton.c b/applications/ibutton/ibutton.c index 30accd46..5ccb1f6c 100644 --- a/applications/ibutton/ibutton.c +++ b/applications/ibutton/ibutton.c @@ -5,7 +5,7 @@ #include "m-string.h" #include #include -#include "rpc/rpc_app.h" +#include #define TAG "iButtonApp" @@ -58,7 +58,7 @@ static void ibutton_make_app_folder(iButton* ibutton) { } } -static bool ibutton_load_key_data(iButton* ibutton, string_t key_path, bool show_dialog) { +bool ibutton_load_key_data(iButton* ibutton, string_t key_path, bool show_dialog) { FlipperFormat* file = flipper_format_file_alloc(ibutton->storage); bool result = false; string_t data; @@ -99,33 +99,20 @@ static bool ibutton_load_key_data(iButton* ibutton, string_t key_path, bool show return result; } -static bool ibutton_rpc_command_callback(RpcAppSystemEvent event, const char* arg, void* context) { +static void ibutton_rpc_command_callback(RpcAppSystemEvent event, void* context) { furi_assert(context); iButton* ibutton = context; - bool result = false; - if(event == RpcAppEventSessionClose) { - rpc_system_app_set_callback(ibutton->rpc_ctx, NULL, NULL); - ibutton->rpc_ctx = NULL; - view_dispatcher_send_custom_event(ibutton->view_dispatcher, iButtonCustomEventRpcExit); - result = true; + view_dispatcher_send_custom_event( + ibutton->view_dispatcher, iButtonCustomEventRpcSessionClose); } else if(event == RpcAppEventAppExit) { view_dispatcher_send_custom_event(ibutton->view_dispatcher, iButtonCustomEventRpcExit); - result = true; } else if(event == RpcAppEventLoadFile) { - if(arg) { - 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; - } - } + view_dispatcher_send_custom_event(ibutton->view_dispatcher, iButtonCustomEventRpcLoad); + } else { + rpc_system_app_confirm(ibutton->rpc_ctx, event, false); } - - return result; } bool ibutton_custom_event_callback(void* context, uint32_t event) { diff --git a/applications/ibutton/ibutton_custom_event.h b/applications/ibutton/ibutton_custom_event.h index 25dfc31d..1e2f0300 100644 --- a/applications/ibutton/ibutton_custom_event.h +++ b/applications/ibutton/ibutton_custom_event.h @@ -12,4 +12,5 @@ enum iButtonCustomEvent { iButtonCustomEventRpcLoad, iButtonCustomEventRpcExit, + iButtonCustomEventRpcSessionClose, }; diff --git a/applications/ibutton/ibutton_i.h b/applications/ibutton/ibutton_i.h index de3065c3..9d4354d0 100644 --- a/applications/ibutton/ibutton_i.h +++ b/applications/ibutton/ibutton_i.h @@ -78,6 +78,7 @@ typedef enum { } iButtonNotificationMessage; bool ibutton_file_select(iButton* ibutton); +bool ibutton_load_key_data(iButton* ibutton, string_t key_path, bool show_dialog); bool ibutton_save_key(iButton* ibutton, const char* key_name); bool ibutton_delete_key(iButton* ibutton); void ibutton_text_store_set(iButton* ibutton, const char* text, ...); diff --git a/applications/ibutton/scenes/ibutton_scene_rpc.c b/applications/ibutton/scenes/ibutton_scene_rpc.c index 14f7df63..a3f5eeee 100644 --- a/applications/ibutton/scenes/ibutton_scene_rpc.c +++ b/applications/ibutton/scenes/ibutton_scene_rpc.c @@ -1,5 +1,6 @@ #include "../ibutton_i.h" #include +#include void ibutton_scene_rpc_on_enter(void* context) { iButton* ibutton = context; @@ -26,23 +27,40 @@ bool ibutton_scene_rpc_on_event(void* context, SceneManagerEvent event) { if(event.type == SceneManagerEventTypeCustom) { consumed = true; 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); + const char* arg = rpc_system_app_get_data(ibutton->rpc_ctx); + bool result = false; + if(arg) { + 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); + 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); + result = 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); + rpc_system_app_confirm(ibutton->rpc_ctx, RpcAppEventLoadFile, result); } else if(event.event == iButtonCustomEventRpcExit) { + rpc_system_app_confirm(ibutton->rpc_ctx, RpcAppEventAppExit, true); + ibutton_notification_message(ibutton, iButtonNotificationMessageBlinkStop); + view_dispatcher_stop(ibutton->view_dispatcher); + } else if(event.event == iButtonCustomEventRpcSessionClose) { + rpc_system_app_set_callback(ibutton->rpc_ctx, NULL, NULL); + ibutton->rpc_ctx = NULL; ibutton_notification_message(ibutton, iButtonNotificationMessageBlinkStop); view_dispatcher_stop(ibutton->view_dispatcher); } diff --git a/applications/infrared/infrared.c b/applications/infrared/infrared.c index 4b7a4671..cbbd375d 100644 --- a/applications/infrared/infrared.c +++ b/applications/infrared/infrared.c @@ -36,52 +36,29 @@ static void infrared_tick_event_callback(void* context) { scene_manager_handle_tick_event(infrared->scene_manager); } -static bool - infrared_rpc_command_callback(RpcAppSystemEvent event, const char* arg, void* context) { +static void infrared_rpc_command_callback(RpcAppSystemEvent event, void* context) { furi_assert(context); Infrared* infrared = context; - - if(!infrared->rpc_ctx) { - return false; - } - - bool result = false; + furi_assert(infrared->rpc_ctx); if(event == RpcAppEventSessionClose) { - rpc_system_app_set_callback(infrared->rpc_ctx, NULL, NULL); - infrared->rpc_ctx = NULL; view_dispatcher_send_custom_event( - infrared->view_dispatcher, InfraredCustomEventTypeBackPressed); - result = true; + infrared->view_dispatcher, InfraredCustomEventTypeRpcSessionClose); } else if(event == RpcAppEventAppExit) { view_dispatcher_send_custom_event( - infrared->view_dispatcher, InfraredCustomEventTypeBackPressed); - result = true; + infrared->view_dispatcher, InfraredCustomEventTypeRpcExit); } else if(event == RpcAppEventLoadFile) { - if(arg) { - string_set_str(infrared->file_path, arg); - result = infrared_remote_load(infrared->remote, infrared->file_path); - infrared_worker_tx_set_get_signal_callback( - 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); - } + view_dispatcher_send_custom_event( + infrared->view_dispatcher, InfraredCustomEventTypeRpcLoad); } else if(event == RpcAppEventButtonPress) { - if(arg) { - size_t button_index = 0; - if(infrared_remote_find_button_by_name(infrared->remote, arg, &button_index)) { - infrared_tx_start_button_index(infrared, button_index); - result = true; - } - } + view_dispatcher_send_custom_event( + infrared->view_dispatcher, InfraredCustomEventTypeRpcButtonPress); } else if(event == RpcAppEventButtonRelease) { - infrared_tx_stop(infrared); - result = true; + view_dispatcher_send_custom_event( + infrared->view_dispatcher, InfraredCustomEventTypeRpcButtonRelease); + } else { + rpc_system_app_confirm(infrared->rpc_ctx, event, false); } - - return result; } static void infrared_find_vacant_remote_name(string_t name, const char* path) { diff --git a/applications/infrared/infrared_custom_event.h b/applications/infrared/infrared_custom_event.h index 29bd61f1..09440dde 100644 --- a/applications/infrared/infrared_custom_event.h +++ b/applications/infrared/infrared_custom_event.h @@ -14,7 +14,12 @@ enum InfraredCustomEventType { InfraredCustomEventTypePopupClosed, InfraredCustomEventTypeButtonSelected, InfraredCustomEventTypeBackPressed, - InfraredCustomEventTypeRpcLoaded, + + InfraredCustomEventTypeRpcLoad, + InfraredCustomEventTypeRpcExit, + InfraredCustomEventTypeRpcButtonPress, + InfraredCustomEventTypeRpcButtonRelease, + InfraredCustomEventTypeRpcSessionClose, }; #pragma pack(push, 1) diff --git a/applications/infrared/scenes/infrared_scene_rpc.c b/applications/infrared/scenes/infrared_scene_rpc.c index e31e7fb6..1d970f6a 100644 --- a/applications/infrared/scenes/infrared_scene_rpc.c +++ b/applications/infrared/scenes/infrared_scene_rpc.c @@ -28,12 +28,45 @@ 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) { + } else if(event.event == InfraredCustomEventTypeRpcLoad) { + bool result = false; + const char* arg = rpc_system_app_get_data(infrared->rpc_ctx); + if(arg) { + string_set_str(infrared->file_path, arg); + result = infrared_remote_load(infrared->remote, infrared->file_path); + infrared_worker_tx_set_get_signal_callback( + infrared->worker, infrared_worker_tx_get_signal_steady_callback, infrared); + infrared_worker_tx_set_signal_sent_callback( + infrared->worker, infrared_signal_sent_callback, infrared); + } 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); + + rpc_system_app_confirm(infrared->rpc_ctx, RpcAppEventLoadFile, result); + } else if(event.event == InfraredCustomEventTypeRpcButtonPress) { + bool result = false; + const char* arg = rpc_system_app_get_data(infrared->rpc_ctx); + if(arg) { + size_t button_index = 0; + if(infrared_remote_find_button_by_name(infrared->remote, arg, &button_index)) { + infrared_tx_start_button_index(infrared, button_index); + result = true; + } + } + rpc_system_app_confirm(infrared->rpc_ctx, RpcAppEventButtonRelease, result); + } else if(event.event == InfraredCustomEventTypeRpcButtonRelease) { + infrared_tx_stop(infrared); + rpc_system_app_confirm(infrared->rpc_ctx, RpcAppEventButtonRelease, true); + } else if(event.event == InfraredCustomEventTypeRpcExit) { + view_dispatcher_stop(infrared->view_dispatcher); + rpc_system_app_confirm(infrared->rpc_ctx, RpcAppEventAppExit, true); + } else if(event.event == InfraredCustomEventTypeRpcSessionClose) { + rpc_system_app_set_callback(infrared->rpc_ctx, NULL, NULL); + infrared->rpc_ctx = NULL; + view_dispatcher_stop(infrared->view_dispatcher); } } return consumed; diff --git a/applications/lfrfid/lfrfid_app.cpp b/applications/lfrfid/lfrfid_app.cpp index 329f052b..29e99b74 100644 --- a/applications/lfrfid/lfrfid_app.cpp +++ b/applications/lfrfid/lfrfid_app.cpp @@ -25,7 +25,7 @@ #include #include -#include "rpc/rpc_app.h" +#include const char* LfRfidApp::app_folder = ANY_PATH("lfrfid"); const char* LfRfidApp::app_extension = ".rfid"; @@ -48,38 +48,25 @@ LfRfidApp::~LfRfidApp() { } } -static bool rpc_command_callback(RpcAppSystemEvent event, const char* arg, void* context) { +static void rpc_command_callback(RpcAppSystemEvent rpc_event, void* context) { furi_assert(context); LfRfidApp* app = static_cast(context); - bool result = false; - - if(event == RpcAppEventSessionClose) { - rpc_system_app_set_callback(app->rpc_ctx, NULL, NULL); - app->rpc_ctx = NULL; + if(rpc_event == RpcAppEventSessionClose) { + LfRfidApp::Event event; + event.type = LfRfidApp::EventType::RpcSessionClose; + app->view_controller.send_event(&event); + } else if(rpc_event == RpcAppEventAppExit) { LfRfidApp::Event event; event.type = LfRfidApp::EventType::Exit; app->view_controller.send_event(&event); - result = true; - } else if(event == RpcAppEventAppExit) { + } else if(rpc_event == RpcAppEventLoadFile) { LfRfidApp::Event event; - event.type = LfRfidApp::EventType::Exit; + event.type = LfRfidApp::EventType::RpcLoadFile; app->view_controller.send_event(&event); - result = true; - } else if(event == RpcAppEventLoadFile) { - if(arg) { - string_set_str(app->file_path, arg); - if(app->load_key_data(app->file_path, &(app->worker.key), false)) { - LfRfidApp::Event event; - event.type = LfRfidApp::EventType::EmulateStart; - app->view_controller.send_event(&event); - app->worker.start_emulate(); - result = true; - } - } + } else { + rpc_system_app_confirm(app->rpc_ctx, rpc_event, false); } - - return result; } void LfRfidApp::run(void* _args) { diff --git a/applications/lfrfid/lfrfid_app.h b/applications/lfrfid/lfrfid_app.h index 3372552f..b0d4c589 100644 --- a/applications/lfrfid/lfrfid_app.h +++ b/applications/lfrfid/lfrfid_app.h @@ -33,6 +33,8 @@ public: Retry, Exit, EmulateStart, + RpcLoadFile, + RpcSessionClose, }; enum class SceneType : uint8_t { diff --git a/applications/lfrfid/scene/lfrfid_app_scene_rpc.cpp b/applications/lfrfid/scene/lfrfid_app_scene_rpc.cpp index bc070ce6..a32982af 100644 --- a/applications/lfrfid/scene/lfrfid_app_scene_rpc.cpp +++ b/applications/lfrfid/scene/lfrfid_app_scene_rpc.cpp @@ -1,6 +1,7 @@ #include "lfrfid_app_scene_rpc.h" #include #include +#include static const NotificationSequence sequence_blink_start_magenta = { &message_blink_start_10, @@ -36,6 +37,16 @@ bool LfRfidAppSceneRpc::on_event(LfRfidApp* app, LfRfidApp::Event* event) { LfRfidApp::Event view_event; view_event.type = LfRfidApp::EventType::Back; app->view_controller.send_event(&view_event); + rpc_system_app_confirm(app->rpc_ctx, RpcAppEventAppExit, true); + } else if(event->type == LfRfidApp::EventType::RpcSessionClose) { + // Detach RPC + rpc_system_app_set_callback(app->rpc_ctx, NULL, NULL); + app->rpc_ctx = NULL; + + consumed = true; + LfRfidApp::Event view_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; @@ -45,7 +56,22 @@ bool LfRfidAppSceneRpc::on_event(LfRfidApp* app, LfRfidApp::Event* event) { popup->set_text(app->text_store.text, 89, 43, AlignCenter, AlignTop); notification_message(app->notification, &sequence_blink_start_magenta); + } else if(event->type == LfRfidApp::EventType::RpcLoadFile) { + const char* arg = rpc_system_app_get_data(app->rpc_ctx); + bool result = false; + if(arg) { + string_set_str(app->file_path, arg); + if(app->load_key_data(app->file_path, &(app->worker.key), false)) { + LfRfidApp::Event event; + event.type = LfRfidApp::EventType::EmulateStart; + app->view_controller.send_event(&event); + app->worker.start_emulate(); + result = true; + } + } + rpc_system_app_confirm(app->rpc_ctx, RpcAppEventLoadFile, result); } + return consumed; } diff --git a/applications/nfc/helpers/nfc_custom_event.h b/applications/nfc/helpers/nfc_custom_event.h index fbd54b27..4227a5b1 100644 --- a/applications/nfc/helpers/nfc_custom_event.h +++ b/applications/nfc/helpers/nfc_custom_event.h @@ -11,4 +11,5 @@ enum NfcCustomEvent { NfcCustomEventDictAttackDone, NfcCustomEventDictAttackSkip, NfcCustomEventRpcLoad, + NfcCustomEventRpcSessionClose, }; diff --git a/applications/nfc/nfc.c b/applications/nfc/nfc.c index b19f92f2..32e74e8f 100644 --- a/applications/nfc/nfc.c +++ b/applications/nfc/nfc.c @@ -13,78 +13,21 @@ bool nfc_back_event_callback(void* context) { return scene_manager_handle_back_event(nfc->scene_manager); } -void nfc_rpc_exit_callback(Nfc* nfc) { - if(nfc->rpc_state == NfcRpcStateEmulating) { - // Stop worker - nfc_worker_stop(nfc->worker); - } else if(nfc->rpc_state == NfcRpcStateEmulated) { - // Stop worker - nfc_worker_stop(nfc->worker); - // Save data in shadow file - nfc_device_save_shadow(nfc->dev, nfc->dev->dev_name); - } - 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; - } -} - -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) { +static void nfc_rpc_command_callback(RpcAppSystemEvent event, void* context) { furi_assert(context); Nfc* nfc = context; - if(!nfc->rpc_ctx) { - return false; - } - - bool result = false; + furi_assert(nfc->rpc_ctx); if(event == RpcAppEventSessionClose) { - rpc_system_app_set_callback(nfc->rpc_ctx, NULL, NULL); - nfc->rpc_ctx = NULL; - view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventViewExit); - result = true; + view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventRpcSessionClose); } else if(event == RpcAppEventAppExit) { view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventViewExit); - result = true; } else if(event == RpcAppEventLoadFile) { - if((arg) && (nfc->rpc_state == NfcRpcStateIdle)) { - if(nfc_device_load(nfc->dev, arg, false)) { - if(nfc->dev->format == NfcDeviceSaveFormatMifareUl) { - nfc_worker_start( - nfc->worker, - NfcWorkerStateMfUltralightEmulate, - &nfc->dev->dev_data, - nfc_rpc_emulate_callback, - nfc); - } else if(nfc->dev->format == NfcDeviceSaveFormatMifareClassic) { - nfc_worker_start( - nfc->worker, - NfcWorkerStateMfClassicEmulate, - &nfc->dev->dev_data, - nfc_rpc_emulate_callback, - nfc); - } else { - nfc_worker_start( - nfc->worker, NfcWorkerStateUidEmulate, &nfc->dev->dev_data, NULL, nfc); - } - nfc->rpc_state = NfcRpcStateEmulating; - view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventRpcLoad); - result = true; - } - } + view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventRpcLoad); + } else { + rpc_system_app_confirm(nfc->rpc_ctx, event, false); } - - return result; } Nfc* nfc_alloc() { @@ -163,6 +106,21 @@ Nfc* nfc_alloc() { void nfc_free(Nfc* nfc) { furi_assert(nfc); + if(nfc->rpc_state == NfcRpcStateEmulating) { + // Stop worker + nfc_worker_stop(nfc->worker); + } else if(nfc->rpc_state == NfcRpcStateEmulated) { + // Stop worker + nfc_worker_stop(nfc->worker); + // Save data in shadow file + nfc_device_save_shadow(nfc->dev, nfc->dev->dev_name); + } + if(nfc->rpc_ctx) { + rpc_system_app_send_exited(nfc->rpc_ctx); + rpc_system_app_set_callback(nfc->rpc_ctx, NULL, NULL); + nfc->rpc_ctx = NULL; + } + // Nfc device nfc_device_free(nfc->dev); diff --git a/applications/nfc/nfc_i.h b/applications/nfc/nfc_i.h index 84c0e7f0..5a916e80 100755 --- a/applications/nfc/nfc_i.h +++ b/applications/nfc/nfc_i.h @@ -102,5 +102,3 @@ 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_rpc.c b/applications/nfc/scenes/nfc_scene_rpc.c index 582dff8e..94beccc6 100644 --- a/applications/nfc/scenes/nfc_scene_rpc.c +++ b/applications/nfc/scenes/nfc_scene_rpc.c @@ -14,6 +14,14 @@ void nfc_scene_rpc_on_enter(void* context) { notification_message(nfc->notifications, &sequence_display_backlight_on); } +static bool nfc_scene_rpc_emulate_callback(NfcWorkerEvent event, void* context) { + UNUSED(event); + Nfc* nfc = context; + + nfc->rpc_state = NfcRpcStateEmulated; + return true; +} + bool nfc_scene_rpc_on_event(void* context, SceneManagerEvent event) { Nfc* nfc = context; Popup* popup = nfc->popup; @@ -22,13 +30,47 @@ bool nfc_scene_rpc_on_event(void* context, SceneManagerEvent event) { if(event.type == SceneManagerEventTypeCustom) { consumed = true; if(event.event == NfcCustomEventViewExit) { + rpc_system_app_confirm(nfc->rpc_ctx, RpcAppEventAppExit, true); + view_dispatcher_stop(nfc->view_dispatcher); + nfc_blink_stop(nfc); + } else if(event.event == NfcCustomEventRpcSessionClose) { + rpc_system_app_set_callback(nfc->rpc_ctx, NULL, NULL); + nfc->rpc_ctx = NULL; view_dispatcher_stop(nfc->view_dispatcher); nfc_blink_stop(nfc); } else if(event.event == NfcCustomEventRpcLoad) { - nfc_blink_start(nfc); + bool result = false; + const char* arg = rpc_system_app_get_data(nfc->rpc_ctx); + if((arg) && (nfc->rpc_state == NfcRpcStateIdle)) { + if(nfc_device_load(nfc->dev, arg, false)) { + if(nfc->dev->format == NfcDeviceSaveFormatMifareUl) { + nfc_worker_start( + nfc->worker, + NfcWorkerStateMfUltralightEmulate, + &nfc->dev->dev_data, + nfc_scene_rpc_emulate_callback, + nfc); + } else if(nfc->dev->format == NfcDeviceSaveFormatMifareClassic) { + nfc_worker_start( + nfc->worker, + NfcWorkerStateMfClassicEmulate, + &nfc->dev->dev_data, + nfc_scene_rpc_emulate_callback, + nfc); + } else { + nfc_worker_start( + nfc->worker, NfcWorkerStateUidEmulate, &nfc->dev->dev_data, NULL, nfc); + } + nfc->rpc_state = NfcRpcStateEmulating; + result = true; - nfc_text_store_set(nfc, "emulating\n%s", nfc->dev->dev_name); - popup_set_text(popup, nfc->text_store, 82, 32, AlignCenter, AlignTop); + 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); + } + } + + rpc_system_app_confirm(nfc->rpc_ctx, RpcAppEventLoadFile, result); } } return consumed; @@ -38,7 +80,6 @@ void nfc_scene_rpc_on_exit(void* context) { Nfc* nfc = context; Popup* popup = nfc->popup; - nfc_rpc_exit_callback(nfc); nfc_blink_stop(nfc); popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom); diff --git a/applications/rpc/rpc_app.c b/applications/rpc/rpc_app.c index e349e61c..555cec8c 100644 --- a/applications/rpc/rpc_app.c +++ b/applications/rpc/rpc_app.c @@ -6,24 +6,18 @@ #include "rpc_app.h" #define TAG "RpcSystemApp" -#define APP_BUTTON_TIMEOUT 1000 struct RpcAppSystem { RpcSession* session; RpcAppSystemCallback app_callback; void* app_context; PB_Main* state_msg; - FuriTimer* timer; + + uint32_t last_id; + char* last_data; }; -static void rpc_system_app_timer_callback(void* context) { - furi_assert(context); - RpcAppSystem* rpc_app = context; - - if(rpc_app->app_callback) { - rpc_app->app_callback(RpcAppEventButtonRelease, NULL, rpc_app->app_context); - } -} +#define RPC_SYSTEM_APP_TEMP_ARGS_SIZE 16 static void rpc_system_app_start_process(const PB_Main* request, void* context) { furi_assert(request); @@ -33,9 +27,12 @@ static void rpc_system_app_start_process(const PB_Main* request, void* context) RpcAppSystem* rpc_app = context; RpcSession* session = rpc_app->session; furi_assert(session); - char args_temp[16]; + char args_temp[RPC_SYSTEM_APP_TEMP_ARGS_SIZE]; - FURI_LOG_D(TAG, "Start"); + furi_assert(!rpc_app->last_id); + furi_assert(!rpc_app->last_data); + + FURI_LOG_D(TAG, "StartProcess: id %d", request->command_id); PB_CommandStatus result = PB_CommandStatus_ERROR_APP_CANT_START; @@ -43,9 +40,9 @@ static void rpc_system_app_start_process(const PB_Main* request, void* context) const char* app_name = request->content.app_start_request.name; if(app_name) { const char* app_args = request->content.app_start_request.args; - if(strcmp(app_args, "RPC") == 0) { + if(app_args && strcmp(app_args, "RPC") == 0) { // If app is being started in RPC mode - pass RPC context via args string - snprintf(args_temp, 16, "RPC %08lX", (uint32_t)rpc_app); + snprintf(args_temp, RPC_SYSTEM_APP_TEMP_ARGS_SIZE, "RPC %08lX", (uint32_t)rpc_app); app_args = args_temp; } LoaderStatus status = loader_start(loader, app_name, app_args); @@ -58,7 +55,7 @@ static void rpc_system_app_start_process(const PB_Main* request, void* context) } else if(status == LoaderStatusOk) { result = PB_CommandStatus_OK; } else { - furi_assert(0); + furi_crash("Programming Error"); } } else { result = PB_CommandStatus_ERROR_INVALID_PARAMETERS; @@ -66,6 +63,7 @@ static void rpc_system_app_start_process(const PB_Main* request, void* context) furi_record_close(RECORD_LOADER); + FURI_LOG_D(TAG, "StartProcess: response id %d, result %d", request->command_id, result); rpc_send_and_release_empty(session, request->command_id, result); } @@ -93,6 +91,7 @@ static void rpc_system_app_lock_status_process(const PB_Main* request, void* con furi_record_close(RECORD_LOADER); + FURI_LOG_D(TAG, "LockStatus: response"); rpc_send_and_release(session, &response); pb_release(&PB_Main_msg, &response); } @@ -109,17 +108,17 @@ static void rpc_system_app_exit_request(const PB_Main* request, void* context) { PB_CommandStatus status; if(rpc_app->app_callback) { - if(rpc_app->app_callback(RpcAppEventAppExit, NULL, rpc_app->app_context)) { - status = PB_CommandStatus_OK; - furi_timer_stop(rpc_app->timer); - } else { - status = PB_CommandStatus_ERROR_APP_CMD_ERROR; - } + FURI_LOG_D(TAG, "ExitRequest: id %d", request->command_id); + furi_assert(!rpc_app->last_id); + furi_assert(!rpc_app->last_data); + rpc_app->last_id = request->command_id; + rpc_app->app_callback(RpcAppEventAppExit, rpc_app->app_context); } else { status = PB_CommandStatus_ERROR_APP_NOT_RUNNING; + FURI_LOG_E( + TAG, "ExitRequest: APP_NOT_RUNNING, id %d, status: %d", request->command_id, status); + rpc_send_and_release_empty(session, request->command_id, status); } - - rpc_send_and_release_empty(session, request->command_id, status); } static void rpc_system_app_load_file(const PB_Main* request, void* context) { @@ -133,17 +132,18 @@ static void rpc_system_app_load_file(const PB_Main* request, void* context) { PB_CommandStatus status; if(rpc_app->app_callback) { - const char* file_path = request->content.app_load_file_request.path; - if(rpc_app->app_callback(RpcAppEventLoadFile, file_path, rpc_app->app_context)) { - status = PB_CommandStatus_OK; - } else { - status = PB_CommandStatus_ERROR_APP_CMD_ERROR; - } + FURI_LOG_D(TAG, "LoadFile: id %d", request->command_id); + furi_assert(!rpc_app->last_id); + furi_assert(!rpc_app->last_data); + rpc_app->last_id = request->command_id; + rpc_app->last_data = strdup(request->content.app_load_file_request.path); + rpc_app->app_callback(RpcAppEventLoadFile, rpc_app->app_context); } else { status = PB_CommandStatus_ERROR_APP_NOT_RUNNING; + FURI_LOG_E( + TAG, "LoadFile: APP_NOT_RUNNING, id %d, status: %d", request->command_id, status); + rpc_send_and_release_empty(session, request->command_id, status); } - - rpc_send_and_release_empty(session, request->command_id, status); } static void rpc_system_app_button_press(const PB_Main* request, void* context) { @@ -157,18 +157,18 @@ static void rpc_system_app_button_press(const PB_Main* request, void* context) { PB_CommandStatus status; if(rpc_app->app_callback) { - 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; - furi_timer_start(rpc_app->timer, APP_BUTTON_TIMEOUT); - } else { - status = PB_CommandStatus_ERROR_APP_CMD_ERROR; - } + FURI_LOG_D(TAG, "ButtonPress"); + furi_assert(!rpc_app->last_id); + furi_assert(!rpc_app->last_data); + rpc_app->last_id = request->command_id; + rpc_app->last_data = strdup(request->content.app_button_press_request.args); + rpc_app->app_callback(RpcAppEventButtonPress, rpc_app->app_context); } else { status = PB_CommandStatus_ERROR_APP_NOT_RUNNING; + FURI_LOG_E( + TAG, "ButtonPress: APP_NOT_RUNNING, id %d, status: %d", request->command_id, status); + rpc_send_and_release_empty(session, request->command_id, status); } - - rpc_send_and_release_empty(session, request->command_id, status); } static void rpc_system_app_button_release(const PB_Main* request, void* context) { @@ -182,17 +182,17 @@ static void rpc_system_app_button_release(const PB_Main* request, void* context) PB_CommandStatus status; if(rpc_app->app_callback) { - if(rpc_app->app_callback(RpcAppEventButtonRelease, NULL, rpc_app->app_context)) { - status = PB_CommandStatus_OK; - furi_timer_stop(rpc_app->timer); - } else { - status = PB_CommandStatus_ERROR_APP_CMD_ERROR; - } + FURI_LOG_D(TAG, "ButtonRelease"); + furi_assert(!rpc_app->last_id); + furi_assert(!rpc_app->last_data); + rpc_app->last_id = request->command_id; + rpc_app->app_callback(RpcAppEventButtonRelease, rpc_app->app_context); } else { status = PB_CommandStatus_ERROR_APP_NOT_RUNNING; + FURI_LOG_E( + TAG, "ButtonRelease: APP_NOT_RUNNING, id %d, status: %d", request->command_id, status); + rpc_send_and_release_empty(session, request->command_id, status); } - - rpc_send_and_release_empty(session, request->command_id, status); } void rpc_system_app_send_started(RpcAppSystem* rpc_app) { @@ -201,6 +201,8 @@ void rpc_system_app_send_started(RpcAppSystem* rpc_app) { furi_assert(session); rpc_app->state_msg->content.app_state_response.state = PB_App_AppState_APP_STARTED; + + FURI_LOG_D(TAG, "SendStarted"); rpc_send(session, rpc_app->state_msg); } @@ -210,9 +212,46 @@ void rpc_system_app_send_exited(RpcAppSystem* rpc_app) { furi_assert(session); rpc_app->state_msg->content.app_state_response.state = PB_App_AppState_APP_CLOSED; + + FURI_LOG_D(TAG, "SendExit"); rpc_send(session, rpc_app->state_msg); } +const char* rpc_system_app_get_data(RpcAppSystem* rpc_app) { + furi_assert(rpc_app); + furi_assert(rpc_app->last_data); + return rpc_app->last_data; +} + +void rpc_system_app_confirm(RpcAppSystem* rpc_app, RpcAppSystemEvent event, bool result) { + furi_assert(rpc_app); + RpcSession* session = rpc_app->session; + furi_assert(session); + furi_assert(rpc_app->last_id); + + PB_CommandStatus status = result ? PB_CommandStatus_OK : PB_CommandStatus_ERROR_APP_CMD_ERROR; + + uint32_t last_id = 0; + switch(event) { + case RpcAppEventAppExit: + case RpcAppEventLoadFile: + case RpcAppEventButtonPress: + case RpcAppEventButtonRelease: + last_id = rpc_app->last_id; + rpc_app->last_id = 0; + if(rpc_app->last_data) { + free(rpc_app->last_data); + rpc_app->last_data = NULL; + } + FURI_LOG_D(TAG, "AppConfirm: event %d last_id %d status %d", event, last_id, status); + rpc_send_and_release_empty(session, last_id, status); + break; + default: + furi_crash("RPC App state programming Error"); + break; + } +} + void rpc_system_app_set_callback(RpcAppSystem* rpc_app, RpcAppSystemCallback callback, void* ctx) { furi_assert(rpc_app); @@ -226,8 +265,6 @@ void* rpc_system_app_alloc(RpcSession* session) { RpcAppSystem* rpc_app = malloc(sizeof(RpcAppSystem)); rpc_app->session = 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; @@ -265,12 +302,16 @@ void rpc_system_app_free(void* context) { RpcSession* session = rpc_app->session; furi_assert(session); - furi_timer_free(rpc_app->timer); - if(rpc_app->app_callback) { - rpc_app->app_callback(RpcAppEventSessionClose, NULL, rpc_app->app_context); + rpc_app->app_callback(RpcAppEventSessionClose, rpc_app->app_context); } + while(rpc_app->app_callback) { + furi_delay_tick(1); + } + + if(rpc_app->last_data) free(rpc_app->last_data); + free(rpc_app->state_msg); free(rpc_app); } diff --git a/applications/rpc/rpc_app.h b/applications/rpc/rpc_app.h index 4e00922f..635c9f8c 100644 --- a/applications/rpc/rpc_app.h +++ b/applications/rpc/rpc_app.h @@ -13,7 +13,7 @@ typedef enum { RpcAppEventButtonRelease, } RpcAppSystemEvent; -typedef bool (*RpcAppSystemCallback)(RpcAppSystemEvent event, const char* arg, void* context); +typedef void (*RpcAppSystemCallback)(RpcAppSystemEvent event, void* context); typedef struct RpcAppSystem RpcAppSystem; @@ -23,6 +23,10 @@ void rpc_system_app_send_started(RpcAppSystem* rpc_app); void rpc_system_app_send_exited(RpcAppSystem* rpc_app); +const char* rpc_system_app_get_data(RpcAppSystem* rpc_app); + +void rpc_system_app_confirm(RpcAppSystem* rpc_app, RpcAppSystemEvent event, bool result); + #ifdef __cplusplus } #endif diff --git a/applications/rpc/rpc_storage.c b/applications/rpc/rpc_storage.c index 89c94b03..d2b43ff6 100644 --- a/applications/rpc/rpc_storage.c +++ b/applications/rpc/rpc_storage.c @@ -594,23 +594,19 @@ static void rpc_system_storage_backup_create_process(const PB_Main* request, voi FURI_LOG_D(TAG, "BackupCreate"); - RpcSession* session = (RpcSession*)context; + RpcStorageSystem* rpc_storage = context; + RpcSession* session = rpc_storage->session; furi_assert(session); - PB_Main* response = malloc(sizeof(PB_Main)); - response->command_id = request->command_id; - response->has_next = false; - 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(RECORD_STORAGE); - rpc_send_and_release(session, response); - free(response); + rpc_send_and_release_empty( + session, request->command_id, backup_ok ? PB_CommandStatus_OK : PB_CommandStatus_ERROR); } static void rpc_system_storage_backup_restore_process(const PB_Main* request, void* context) { @@ -619,24 +615,19 @@ static void rpc_system_storage_backup_restore_process(const PB_Main* request, vo FURI_LOG_D(TAG, "BackupRestore"); - RpcSession* session = (RpcSession*)context; + RpcStorageSystem* rpc_storage = context; + RpcSession* session = rpc_storage->session; furi_assert(session); - PB_Main* response = malloc(sizeof(PB_Main)); - response->command_id = request->command_id; - response->has_next = false; - response->command_status = PB_CommandStatus_OK; - 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(RECORD_STORAGE); - rpc_send_and_release(session, response); - free(response); + rpc_send_and_release_empty( + session, request->command_id, backup_ok ? PB_CommandStatus_OK : PB_CommandStatus_ERROR); } void* rpc_system_storage_alloc(RpcSession* session) { diff --git a/applications/storage/storages/storage_ext.c b/applications/storage/storages/storage_ext.c index 4a9d4218..7341a6ec 100644 --- a/applications/storage/storages/storage_ext.c +++ b/applications/storage/storages/storage_ext.c @@ -26,8 +26,7 @@ static FS_Error storage_ext_parse_error(SDError error); static bool sd_mount_card(StorageData* storage, bool notify) { bool result = false; - const uint8_t max_init_counts = 10; - uint8_t counter = max_init_counts; + uint8_t counter = BSP_SD_MaxMountRetryCount(); uint8_t bsp_result; SDData* sd_data = storage->data; diff --git a/applications/subghz/helpers/subghz_custom_event.h b/applications/subghz/helpers/subghz_custom_event.h index 801a8ae9..765c9e25 100644 --- a/applications/subghz/helpers/subghz_custom_event.h +++ b/applications/subghz/helpers/subghz_custom_event.h @@ -47,6 +47,9 @@ typedef enum { SubGhzCustomEventSceneStay, SubGhzCustomEventSceneRpcLoad, + SubGhzCustomEventSceneRpcButtonPress, + SubGhzCustomEventSceneRpcButtonRelease, + SubGhzCustomEventSceneRpcSessionClose, SubGhzCustomEventViewReceiverOK, SubGhzCustomEventViewReceiverConfig, diff --git a/applications/subghz/helpers/subghz_types.h b/applications/subghz/helpers/subghz_types.h index 1b9fe816..8da4c8f5 100644 --- a/applications/subghz/helpers/subghz_types.h +++ b/applications/subghz/helpers/subghz_types.h @@ -72,11 +72,11 @@ typedef enum { SubGhzViewIdTestPacket, } SubGhzViewId; -struct SubGhzPesetDefinition { +struct SubGhzPresetDefinition { string_t name; uint32_t frequency; uint8_t* data; size_t data_size; }; -typedef struct SubGhzPesetDefinition SubGhzPesetDefinition; +typedef struct SubGhzPresetDefinition SubGhzPresetDefinition; diff --git a/applications/subghz/scenes/subghz_scene_receiver_info.c b/applications/subghz/scenes/subghz_scene_receiver_info.c index 40051eee..cbda1bc7 100644 --- a/applications/subghz/scenes/subghz_scene_receiver_info.c +++ b/applications/subghz/scenes/subghz_scene_receiver_info.c @@ -28,8 +28,8 @@ static bool subghz_scene_receiver_info_update_parser(void* context) { subghz->txrx->decoder_result, subghz_history_get_raw_data(subghz->txrx->history, subghz->txrx->idx_menu_chosen)); - SubGhzPesetDefinition* preset = - subghz_history_get_presset(subghz->txrx->history, subghz->txrx->idx_menu_chosen); + SubGhzPresetDefinition* preset = + subghz_history_get_preset_def(subghz->txrx->history, subghz->txrx->idx_menu_chosen); subghz_preset_init( subghz, string_get_cstr(preset->name), diff --git a/applications/subghz/scenes/subghz_scene_rpc.c b/applications/subghz/scenes/subghz_scene_rpc.c index 844f5c16..c6f7df26 100644 --- a/applications/subghz/scenes/subghz_scene_rpc.c +++ b/applications/subghz/scenes/subghz_scene_rpc.c @@ -22,20 +22,60 @@ bool subghz_scene_rpc_on_event(void* context, SceneManagerEvent event) { if(event.type == SceneManagerEventTypeCustom) { consumed = true; if(event.event == SubGhzCustomEventSceneExit) { + if(subghz->txrx->txrx_state == SubGhzTxRxStateTx) { + subghz_tx_stop(subghz); + subghz_sleep(subghz); + } view_dispatcher_stop(subghz->view_dispatcher); + rpc_system_app_confirm(subghz->rpc_ctx, RpcAppEventAppExit, true); + } else if(event.event == SubGhzCustomEventSceneRpcSessionClose) { + rpc_system_app_set_callback(subghz->rpc_ctx, NULL, NULL); + subghz->rpc_ctx = NULL; + subghz_blink_stop(subghz); + if(subghz->txrx->txrx_state == SubGhzTxRxStateTx) { + subghz_tx_stop(subghz); + subghz_sleep(subghz); + } + view_dispatcher_send_custom_event(subghz->view_dispatcher, SubGhzCustomEventSceneExit); + } else if(event.event == SubGhzCustomEventSceneRpcButtonPress) { + bool result = false; + if(subghz->txrx->txrx_state == SubGhzTxRxStateSleep) { + subghz_blink_start(subghz); + result = subghz_tx_start(subghz, subghz->txrx->fff_data); + result = true; + } + rpc_system_app_confirm(subghz->rpc_ctx, RpcAppEventButtonPress, result); + } else if(event.event == SubGhzCustomEventSceneRpcButtonRelease) { + bool result = false; + if(subghz->txrx->txrx_state == SubGhzTxRxStateTx) { + subghz_blink_stop(subghz); + subghz_tx_stop(subghz); + subghz_sleep(subghz); + result = true; + } + rpc_system_app_confirm(subghz->rpc_ctx, RpcAppEventButtonRelease, result); } else if(event.event == SubGhzCustomEventSceneRpcLoad) { - string_t file_name; - string_init(file_name); - path_extract_filename(subghz->file_path, file_name, true); + bool result = false; + const char* arg = rpc_system_app_get_data(subghz->rpc_ctx); + if(arg) { + if(subghz_key_load(subghz, arg, false)) { + string_set_str(subghz->file_path, arg); + result = true; + 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); + 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); + string_clear(file_name); + } + } + rpc_system_app_confirm(subghz->rpc_ctx, RpcAppEventLoadFile, result); } } return consumed; diff --git a/applications/subghz/subghz.c b/applications/subghz/subghz.c index 271fe041..4631d7a3 100644 --- a/applications/subghz/subghz.c +++ b/applications/subghz/subghz.c @@ -35,57 +35,38 @@ void subghz_tick_event_callback(void* context) { scene_manager_handle_tick_event(subghz->scene_manager); } -static bool subghz_rpc_command_callback(RpcAppSystemEvent event, const char* arg, void* context) { +static void subghz_rpc_command_callback(RpcAppSystemEvent event, void* context) { furi_assert(context); SubGhz* subghz = context; - if(!subghz->rpc_ctx) { - return false; - } - - bool result = false; + furi_assert(subghz->rpc_ctx); 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); - subghz_sleep(subghz); - } - result = true; + view_dispatcher_send_custom_event( + subghz->view_dispatcher, SubGhzCustomEventSceneRpcSessionClose); } else if(event == RpcAppEventAppExit) { view_dispatcher_send_custom_event(subghz->view_dispatcher, SubGhzCustomEventSceneExit); - if(subghz->txrx->txrx_state == SubGhzTxRxStateTx) { - subghz_tx_stop(subghz); - subghz_sleep(subghz); - } - result = true; } else if(event == RpcAppEventLoadFile) { - 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; - } - } + view_dispatcher_send_custom_event(subghz->view_dispatcher, SubGhzCustomEventSceneRpcLoad); } 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); - } + view_dispatcher_send_custom_event( + subghz->view_dispatcher, SubGhzCustomEventSceneRpcButtonPress); } 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; - } + view_dispatcher_send_custom_event( + subghz->view_dispatcher, SubGhzCustomEventSceneRpcButtonRelease); + } else { + rpc_system_app_confirm(subghz->rpc_ctx, event, false); } +} - return result; +void subghz_blink_start(SubGhz* instance) { + furi_assert(instance); + notification_message(instance->notifications, &sequence_blink_start_magenta); +} + +void subghz_blink_stop(SubGhz* instance) { + furi_assert(instance); + notification_message(instance->notifications, &sequence_blink_stop); } SubGhz* subghz_alloc() { @@ -199,7 +180,7 @@ SubGhz* subghz_alloc() { //init Worker & Protocol & History & KeyBoard subghz->lock = SubGhzLockOff; subghz->txrx = malloc(sizeof(SubGhzTxRx)); - subghz->txrx->preset = malloc(sizeof(SubGhzPesetDefinition)); + subghz->txrx->preset = malloc(sizeof(SubGhzPresetDefinition)); string_init(subghz->txrx->preset->name); subghz_preset_init( subghz, "AM650", subghz_setting_get_default_frequency(subghz->setting), NULL, 0); @@ -237,7 +218,7 @@ 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_blink_stop(subghz); subghz->rpc_ctx = NULL; } diff --git a/applications/subghz/subghz_history.c b/applications/subghz/subghz_history.c index f234f4c7..820a13d1 100644 --- a/applications/subghz/subghz_history.c +++ b/applications/subghz/subghz_history.c @@ -12,7 +12,7 @@ typedef struct { string_t item_str; FlipperFormat* flipper_string; uint8_t type; - SubGhzPesetDefinition* preset; + SubGhzPresetDefinition* preset; } SubGhzHistoryItem; ARRAY_DEF(SubGhzHistoryItemArray, SubGhzHistoryItem, M_POD_OPLIST) @@ -61,7 +61,7 @@ uint32_t subghz_history_get_frequency(SubGhzHistory* instance, uint16_t idx) { return item->preset->frequency; } -SubGhzPesetDefinition* subghz_history_get_presset(SubGhzHistory* instance, uint16_t idx) { +SubGhzPresetDefinition* subghz_history_get_preset_def(SubGhzHistory* instance, uint16_t idx) { furi_assert(instance); SubGhzHistoryItem* item = SubGhzHistoryItemArray_get(instance->history->data, idx); return item->preset; @@ -139,7 +139,7 @@ void subghz_history_get_text_item_menu(SubGhzHistory* instance, string_t output, bool subghz_history_add_to_history( SubGhzHistory* instance, void* context, - SubGhzPesetDefinition* preset) { + SubGhzPresetDefinition* preset) { furi_assert(instance); furi_assert(context); @@ -159,7 +159,7 @@ 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->preset = malloc(sizeof(SubGhzPresetDefinition)); item->type = decoder_base->protocol->type; item->preset->frequency = preset->frequency; string_init(item->preset->name); diff --git a/applications/subghz/subghz_history.h b/applications/subghz/subghz_history.h index 0af56a40..adbcfc18 100644 --- a/applications/subghz/subghz_history.h +++ b/applications/subghz/subghz_history.h @@ -35,7 +35,7 @@ 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); +SubGhzPresetDefinition* subghz_history_get_preset_def(SubGhzHistory* instance, uint16_t idx); /** Get preset to history[idx] * @@ -88,13 +88,13 @@ bool subghz_history_get_text_space_left(SubGhzHistory* instance, string_t output * * @param instance - SubGhzHistory instance * @param context - SubGhzProtocolCommon context - * @param preset - SubGhzPesetDefinition preset + * @param preset - SubGhzPresetDefinition preset * @return bool; */ bool subghz_history_add_to_history( SubGhzHistory* instance, void* context, - SubGhzPesetDefinition* preset); + SubGhzPresetDefinition* 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 b8232fdb..00cc922c 100644 --- a/applications/subghz/subghz_i.c +++ b/applications/subghz/subghz_i.c @@ -331,8 +331,10 @@ bool subghz_key_load(SubGhz* subghz, const char* file_path, bool show_dialog) { subghz->txrx->decoder_result = subghz_receiver_search_decoder_base_by_name( subghz->txrx->receiver, string_get_cstr(temp_str)); if(subghz->txrx->decoder_result) { - subghz_protocol_decoder_base_deserialize( - subghz->txrx->decoder_result, subghz->txrx->fff_data); + if(!subghz_protocol_decoder_base_deserialize( + subghz->txrx->decoder_result, subghz->txrx->fff_data)) { + break; + } } else { FURI_LOG_E(TAG, "Protocol not found"); break; diff --git a/applications/subghz/subghz_i.h b/applications/subghz/subghz_i.h index 52c3ba59..99a0f8a2 100644 --- a/applications/subghz/subghz_i.h +++ b/applications/subghz/subghz_i.h @@ -49,7 +49,7 @@ struct SubGhzTxRx { SubGhzProtocolDecoderBase* decoder_result; FlipperFormat* fff_data; - SubGhzPesetDefinition* preset; + SubGhzPresetDefinition* preset; SubGhzHistory* history; uint16_t idx_menu_chosen; SubGhzTxRxState txrx_state; @@ -108,6 +108,10 @@ 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); + +void subghz_blink_start(SubGhz* instance); +void subghz_blink_stop(SubGhz* instance); + bool subghz_tx_start(SubGhz* subghz, FlipperFormat* flipper_format); void subghz_tx_stop(SubGhz* subghz); void subghz_dialog_message_show_only_rx(SubGhz* subghz); diff --git a/applications/subghz/views/subghz_read_raw.c b/applications/subghz/views/subghz_read_raw.c index de8f371b..ccffaf42 100644 --- a/applications/subghz/views/subghz_read_raw.c +++ b/applications/subghz/views/subghz_read_raw.c @@ -216,8 +216,8 @@ void subghz_read_raw_draw(Canvas* canvas, SubGhzReadRAWModel* model) { uint8_t graphics_mode = 1; canvas_set_color(canvas, ColorBlack); canvas_set_font(canvas, FontSecondary); - canvas_draw_str(canvas, 5, 8, string_get_cstr(model->frequency_str)); - canvas_draw_str(canvas, 40, 8, string_get_cstr(model->preset_str)); + canvas_draw_str(canvas, 5, 7, string_get_cstr(model->frequency_str)); + canvas_draw_str(canvas, 40, 7, string_get_cstr(model->preset_str)); canvas_draw_str_aligned( canvas, 126, 0, AlignRight, AlignTop, string_get_cstr(model->sample_write)); diff --git a/applications/unit_tests/stream/stream_test.c b/applications/unit_tests/stream/stream_test.c index 36155e33..b5a2d398 100644 --- a/applications/unit_tests/stream/stream_test.c +++ b/applications/unit_tests/stream/stream_test.c @@ -387,6 +387,34 @@ MU_TEST(stream_split_test) { furi_record_close(RECORD_STORAGE); } +MU_TEST(stream_buffered_write_after_read_test) { + const char* prefix = "I write "; + const char* substr = "Hello there"; + + const size_t substr_len = strlen(substr); + const size_t prefix_len = strlen(prefix); + const size_t buf_size = substr_len + 1; + + char buf[buf_size]; + memset(buf, 0, buf_size); + + Storage* storage = furi_record_open(RECORD_STORAGE); + Stream* stream = buffered_file_stream_alloc(storage); + mu_check(buffered_file_stream_open( + stream, EXT_PATH("filestream.str"), FSAM_READ_WRITE, FSOM_CREATE_ALWAYS)); + mu_assert_int_eq(strlen(stream_test_data), stream_write_cstring(stream, stream_test_data)); + mu_check(stream_rewind(stream)); + mu_assert_int_eq(prefix_len, stream_read(stream, (uint8_t*)buf, prefix_len)); + mu_assert_string_eq(prefix, buf); + mu_assert_int_eq(substr_len, stream_write(stream, (uint8_t*)substr, substr_len)); + mu_check(stream_seek(stream, prefix_len, StreamOffsetFromStart)); + mu_assert_int_eq(substr_len, stream_read(stream, (uint8_t*)buf, substr_len)); + mu_assert_string_eq(substr, buf); + + stream_free(stream); + furi_record_close(RECORD_STORAGE); +} + MU_TEST(stream_buffered_large_file_test) { string_t input_data; string_t output_data; @@ -470,6 +498,7 @@ 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_write_after_read_test); MU_RUN_TEST(stream_buffered_large_file_test); } diff --git a/assets/SConscript b/assets/SConscript index 46cc2ca2..ecb10956 100644 --- a/assets/SConscript +++ b/assets/SConscript @@ -103,8 +103,7 @@ if assetsenv["IS_BASE_FIRMWARE"]: ) assetsenv.Precious(resources) assetsenv.NoClean(resources) - if assetsenv["FORCE"]: - assetsenv.AlwaysBuild(resources) + assetsenv.AlwaysBuild(resources) # Exporting resources node to external environment env["FW_RESOURCES"] = resources diff --git a/assets/icons/Archive/ble_10px.png b/assets/icons/Archive/ble_10px.png deleted file mode 100644 index d7ebdcf8..00000000 Binary files a/assets/icons/Archive/ble_10px.png and /dev/null differ diff --git a/assets/icons/BLE/BLE_HID/Ble_connected_38x34.png b/assets/icons/BLE/BLE_HID/Ble_connected_38x34.png deleted file mode 100644 index ed5514df..00000000 Binary files a/assets/icons/BLE/BLE_HID/Ble_connected_38x34.png and /dev/null differ diff --git a/assets/icons/BLE/BLE_HID/Ble_disconnected_24x34.png b/assets/icons/BLE/BLE_HID/Ble_disconnected_24x34.png deleted file mode 100644 index 6f135c11..00000000 Binary files a/assets/icons/BLE/BLE_HID/Ble_disconnected_24x34.png and /dev/null differ diff --git a/assets/icons/Dolphin/DolphinFirstStart0_70x53.png b/assets/icons/Dolphin/DolphinFirstStart0_70x53.png deleted file mode 100644 index 7255f679..00000000 Binary files a/assets/icons/Dolphin/DolphinFirstStart0_70x53.png and /dev/null differ diff --git a/assets/icons/Dolphin/DolphinFirstStart1_59x53.png b/assets/icons/Dolphin/DolphinFirstStart1_59x53.png deleted file mode 100644 index 85bdb5d1..00000000 Binary files a/assets/icons/Dolphin/DolphinFirstStart1_59x53.png and /dev/null differ diff --git a/assets/icons/Dolphin/DolphinFirstStart2_59x51.png b/assets/icons/Dolphin/DolphinFirstStart2_59x51.png deleted file mode 100644 index e1fd177e..00000000 Binary files a/assets/icons/Dolphin/DolphinFirstStart2_59x51.png and /dev/null differ diff --git a/assets/icons/Dolphin/DolphinFirstStart3_57x48.png b/assets/icons/Dolphin/DolphinFirstStart3_57x48.png deleted file mode 100644 index 04466fd8..00000000 Binary files a/assets/icons/Dolphin/DolphinFirstStart3_57x48.png and /dev/null differ diff --git a/assets/icons/Dolphin/DolphinFirstStart4_67x53.png b/assets/icons/Dolphin/DolphinFirstStart4_67x53.png deleted file mode 100644 index 2855bd5c..00000000 Binary files a/assets/icons/Dolphin/DolphinFirstStart4_67x53.png and /dev/null differ diff --git a/assets/icons/Dolphin/DolphinFirstStart5_54x49.png b/assets/icons/Dolphin/DolphinFirstStart5_54x49.png deleted file mode 100644 index 28ee477f..00000000 Binary files a/assets/icons/Dolphin/DolphinFirstStart5_54x49.png and /dev/null differ diff --git a/assets/icons/Dolphin/DolphinFirstStart6_58x54.png b/assets/icons/Dolphin/DolphinFirstStart6_58x54.png deleted file mode 100644 index cc9cd908..00000000 Binary files a/assets/icons/Dolphin/DolphinFirstStart6_58x54.png and /dev/null differ diff --git a/assets/icons/Dolphin/DolphinOkay_41x43.png b/assets/icons/Dolphin/DolphinOkay_41x43.png deleted file mode 100644 index 52cc98b1..00000000 Binary files a/assets/icons/Dolphin/DolphinOkay_41x43.png and /dev/null differ diff --git a/assets/icons/Infrared/InfraredLearn_128x64.png b/assets/icons/Infrared/InfraredLearn_128x64.png deleted file mode 100644 index 80fe3ce1..00000000 Binary files a/assets/icons/Infrared/InfraredLearn_128x64.png and /dev/null differ diff --git a/assets/icons/Infrared/InfraredSendShort_128x34.png b/assets/icons/Infrared/InfraredSendShort_128x34.png deleted file mode 100644 index 377f97ef..00000000 Binary files a/assets/icons/Infrared/InfraredSendShort_128x34.png and /dev/null differ diff --git a/assets/icons/Infrared/InfraredSend_128x64.png b/assets/icons/Infrared/InfraredSend_128x64.png deleted file mode 100644 index 33e2cecb..00000000 Binary files a/assets/icons/Infrared/InfraredSend_128x64.png and /dev/null differ diff --git a/assets/icons/Interface/DoorLocked_10x56.png b/assets/icons/Interface/DoorLocked_10x56.png deleted file mode 100644 index d83d28a8..00000000 Binary files a/assets/icons/Interface/DoorLocked_10x56.png and /dev/null differ diff --git a/assets/icons/Interface/PassportBottom_128x17.png b/assets/icons/Interface/PassportBottom_128x17.png deleted file mode 100644 index e4caa754..00000000 Binary files a/assets/icons/Interface/PassportBottom_128x17.png and /dev/null differ diff --git a/assets/icons/Interface/PassportLeft_6x47.png b/assets/icons/Interface/PassportLeft_6x47.png deleted file mode 100644 index fc854c4a..00000000 Binary files a/assets/icons/Interface/PassportLeft_6x47.png and /dev/null differ diff --git a/assets/icons/MainMenu/Bluetooth_14/frame_01.png b/assets/icons/MainMenu/Bluetooth_14/frame_01.png deleted file mode 100644 index 3b107335..00000000 Binary files a/assets/icons/MainMenu/Bluetooth_14/frame_01.png and /dev/null differ diff --git a/assets/icons/MainMenu/Bluetooth_14/frame_02.png b/assets/icons/MainMenu/Bluetooth_14/frame_02.png deleted file mode 100644 index 748a0d9d..00000000 Binary files a/assets/icons/MainMenu/Bluetooth_14/frame_02.png and /dev/null differ diff --git a/assets/icons/MainMenu/Bluetooth_14/frame_03.png b/assets/icons/MainMenu/Bluetooth_14/frame_03.png deleted file mode 100644 index 7a90fea5..00000000 Binary files a/assets/icons/MainMenu/Bluetooth_14/frame_03.png and /dev/null differ diff --git a/assets/icons/MainMenu/Bluetooth_14/frame_04.png b/assets/icons/MainMenu/Bluetooth_14/frame_04.png deleted file mode 100644 index 8baed331..00000000 Binary files a/assets/icons/MainMenu/Bluetooth_14/frame_04.png and /dev/null differ diff --git a/assets/icons/MainMenu/Bluetooth_14/frame_05.png b/assets/icons/MainMenu/Bluetooth_14/frame_05.png deleted file mode 100644 index 41d3347d..00000000 Binary files a/assets/icons/MainMenu/Bluetooth_14/frame_05.png and /dev/null differ diff --git a/assets/icons/MainMenu/Bluetooth_14/frame_06.png b/assets/icons/MainMenu/Bluetooth_14/frame_06.png deleted file mode 100644 index 06013e7e..00000000 Binary files a/assets/icons/MainMenu/Bluetooth_14/frame_06.png and /dev/null differ diff --git a/assets/icons/MainMenu/Bluetooth_14/frame_rate b/assets/icons/MainMenu/Bluetooth_14/frame_rate deleted file mode 100644 index e440e5c8..00000000 --- a/assets/icons/MainMenu/Bluetooth_14/frame_rate +++ /dev/null @@ -1 +0,0 @@ -3 \ No newline at end of file diff --git a/assets/icons/MainMenu/Games_14/frame_01.png b/assets/icons/MainMenu/Games_14/frame_01.png deleted file mode 100644 index f471e059..00000000 Binary files a/assets/icons/MainMenu/Games_14/frame_01.png and /dev/null differ diff --git a/assets/icons/MainMenu/Games_14/frame_02.png b/assets/icons/MainMenu/Games_14/frame_02.png deleted file mode 100644 index 7f06f6c6..00000000 Binary files a/assets/icons/MainMenu/Games_14/frame_02.png and /dev/null differ diff --git a/assets/icons/MainMenu/Games_14/frame_03.png b/assets/icons/MainMenu/Games_14/frame_03.png deleted file mode 100644 index 15c412be..00000000 Binary files a/assets/icons/MainMenu/Games_14/frame_03.png and /dev/null differ diff --git a/assets/icons/MainMenu/Games_14/frame_04.png b/assets/icons/MainMenu/Games_14/frame_04.png deleted file mode 100644 index 6d539b5c..00000000 Binary files a/assets/icons/MainMenu/Games_14/frame_04.png and /dev/null differ diff --git a/assets/icons/MainMenu/Games_14/frame_05.png b/assets/icons/MainMenu/Games_14/frame_05.png deleted file mode 100644 index de0ae5d1..00000000 Binary files a/assets/icons/MainMenu/Games_14/frame_05.png and /dev/null differ diff --git a/assets/icons/MainMenu/Games_14/frame_06.png b/assets/icons/MainMenu/Games_14/frame_06.png deleted file mode 100644 index 6753b7a2..00000000 Binary files a/assets/icons/MainMenu/Games_14/frame_06.png and /dev/null differ diff --git a/assets/icons/MainMenu/Games_14/frame_07.png b/assets/icons/MainMenu/Games_14/frame_07.png deleted file mode 100644 index 597451e8..00000000 Binary files a/assets/icons/MainMenu/Games_14/frame_07.png and /dev/null differ diff --git a/assets/icons/MainMenu/Games_14/frame_08.png b/assets/icons/MainMenu/Games_14/frame_08.png deleted file mode 100644 index 2109b6b0..00000000 Binary files a/assets/icons/MainMenu/Games_14/frame_08.png and /dev/null differ diff --git a/assets/icons/MainMenu/Games_14/frame_09.png b/assets/icons/MainMenu/Games_14/frame_09.png deleted file mode 100644 index 65f1af5d..00000000 Binary files a/assets/icons/MainMenu/Games_14/frame_09.png and /dev/null differ diff --git a/assets/icons/MainMenu/Games_14/frame_rate b/assets/icons/MainMenu/Games_14/frame_rate deleted file mode 100644 index e440e5c8..00000000 --- a/assets/icons/MainMenu/Games_14/frame_rate +++ /dev/null @@ -1 +0,0 @@ -3 \ No newline at end of file diff --git a/assets/icons/MainMenu/Passport_14/frame_01.png b/assets/icons/MainMenu/Passport_14/frame_01.png deleted file mode 100644 index 97da3465..00000000 Binary files a/assets/icons/MainMenu/Passport_14/frame_01.png and /dev/null differ diff --git a/assets/icons/MainMenu/Passport_14/frame_02.png b/assets/icons/MainMenu/Passport_14/frame_02.png deleted file mode 100644 index ecb66c5c..00000000 Binary files a/assets/icons/MainMenu/Passport_14/frame_02.png and /dev/null differ diff --git a/assets/icons/MainMenu/Passport_14/frame_03.png b/assets/icons/MainMenu/Passport_14/frame_03.png deleted file mode 100644 index 7164af22..00000000 Binary files a/assets/icons/MainMenu/Passport_14/frame_03.png and /dev/null differ diff --git a/assets/icons/MainMenu/Passport_14/frame_04.png b/assets/icons/MainMenu/Passport_14/frame_04.png deleted file mode 100644 index f28f77e2..00000000 Binary files a/assets/icons/MainMenu/Passport_14/frame_04.png and /dev/null differ diff --git a/assets/icons/MainMenu/Passport_14/frame_05.png b/assets/icons/MainMenu/Passport_14/frame_05.png deleted file mode 100644 index 7d01eb34..00000000 Binary files a/assets/icons/MainMenu/Passport_14/frame_05.png and /dev/null differ diff --git a/assets/icons/MainMenu/Passport_14/frame_06.png b/assets/icons/MainMenu/Passport_14/frame_06.png deleted file mode 100644 index c445fae0..00000000 Binary files a/assets/icons/MainMenu/Passport_14/frame_06.png and /dev/null differ diff --git a/assets/icons/MainMenu/Passport_14/frame_07.png b/assets/icons/MainMenu/Passport_14/frame_07.png deleted file mode 100644 index 1b868072..00000000 Binary files a/assets/icons/MainMenu/Passport_14/frame_07.png and /dev/null differ diff --git a/assets/icons/MainMenu/Passport_14/frame_08.png b/assets/icons/MainMenu/Passport_14/frame_08.png deleted file mode 100644 index a16cee96..00000000 Binary files a/assets/icons/MainMenu/Passport_14/frame_08.png and /dev/null differ diff --git a/assets/icons/MainMenu/Passport_14/frame_09.png b/assets/icons/MainMenu/Passport_14/frame_09.png deleted file mode 100644 index c581a9e8..00000000 Binary files a/assets/icons/MainMenu/Passport_14/frame_09.png and /dev/null differ diff --git a/assets/icons/MainMenu/Passport_14/frame_10.png b/assets/icons/MainMenu/Passport_14/frame_10.png deleted file mode 100644 index f217e9bb..00000000 Binary files a/assets/icons/MainMenu/Passport_14/frame_10.png and /dev/null differ diff --git a/assets/icons/MainMenu/Passport_14/frame_rate b/assets/icons/MainMenu/Passport_14/frame_rate deleted file mode 100644 index e440e5c8..00000000 --- a/assets/icons/MainMenu/Passport_14/frame_rate +++ /dev/null @@ -1 +0,0 @@ -3 \ No newline at end of file diff --git a/assets/icons/MainMenu/Power_14/frame_01.png b/assets/icons/MainMenu/Power_14/frame_01.png deleted file mode 100644 index 382d7132..00000000 Binary files a/assets/icons/MainMenu/Power_14/frame_01.png and /dev/null differ diff --git a/assets/icons/MainMenu/Power_14/frame_rate b/assets/icons/MainMenu/Power_14/frame_rate deleted file mode 100644 index e440e5c8..00000000 --- a/assets/icons/MainMenu/Power_14/frame_rate +++ /dev/null @@ -1 +0,0 @@ -3 \ No newline at end of file diff --git a/assets/icons/MainMenu/Tamagotchi_14/frame_01.png b/assets/icons/MainMenu/Tamagotchi_14/frame_01.png deleted file mode 100644 index 4e33581b..00000000 Binary files a/assets/icons/MainMenu/Tamagotchi_14/frame_01.png and /dev/null differ diff --git a/assets/icons/MainMenu/Tamagotchi_14/frame_02.png b/assets/icons/MainMenu/Tamagotchi_14/frame_02.png deleted file mode 100644 index 4de357a5..00000000 Binary files a/assets/icons/MainMenu/Tamagotchi_14/frame_02.png and /dev/null differ diff --git a/assets/icons/MainMenu/Tamagotchi_14/frame_03.png b/assets/icons/MainMenu/Tamagotchi_14/frame_03.png deleted file mode 100644 index c2c11f61..00000000 Binary files a/assets/icons/MainMenu/Tamagotchi_14/frame_03.png and /dev/null differ diff --git a/assets/icons/MainMenu/Tamagotchi_14/frame_04.png b/assets/icons/MainMenu/Tamagotchi_14/frame_04.png deleted file mode 100644 index 43645f94..00000000 Binary files a/assets/icons/MainMenu/Tamagotchi_14/frame_04.png and /dev/null differ diff --git a/assets/icons/MainMenu/Tamagotchi_14/frame_05.png b/assets/icons/MainMenu/Tamagotchi_14/frame_05.png deleted file mode 100644 index a0040ebd..00000000 Binary files a/assets/icons/MainMenu/Tamagotchi_14/frame_05.png and /dev/null differ diff --git a/assets/icons/MainMenu/Tamagotchi_14/frame_06.png b/assets/icons/MainMenu/Tamagotchi_14/frame_06.png deleted file mode 100644 index a5ee9796..00000000 Binary files a/assets/icons/MainMenu/Tamagotchi_14/frame_06.png and /dev/null differ diff --git a/assets/icons/MainMenu/Tamagotchi_14/frame_rate b/assets/icons/MainMenu/Tamagotchi_14/frame_rate deleted file mode 100644 index e440e5c8..00000000 --- a/assets/icons/MainMenu/Tamagotchi_14/frame_rate +++ /dev/null @@ -1 +0,0 @@ -3 \ No newline at end of file diff --git a/assets/icons/PIN/Pin_cell_13x13.png b/assets/icons/PIN/Pin_cell_13x13.png deleted file mode 100644 index 1b1ff0c2..00000000 Binary files a/assets/icons/PIN/Pin_cell_13x13.png and /dev/null differ diff --git a/assets/icons/StatusBar/BadUsb_9x8.png b/assets/icons/StatusBar/BadUsb_9x8.png deleted file mode 100644 index 010769e4..00000000 Binary files a/assets/icons/StatusBar/BadUsb_9x8.png and /dev/null differ diff --git a/assets/icons/StatusBar/Battery_19x8.png b/assets/icons/StatusBar/Battery_19x8.png deleted file mode 100644 index 1265d7c1..00000000 Binary files a/assets/icons/StatusBar/Battery_19x8.png and /dev/null differ diff --git a/assets/icons/StatusBar/PlaceholderL_11x13.png b/assets/icons/StatusBar/PlaceholderL_11x13.png deleted file mode 100644 index a6a56127..00000000 Binary files a/assets/icons/StatusBar/PlaceholderL_11x13.png and /dev/null differ diff --git a/assets/icons/StatusBar/PlaceholderR_30x13.png b/assets/icons/StatusBar/PlaceholderR_30x13.png deleted file mode 100644 index bc1c9367..00000000 Binary files a/assets/icons/StatusBar/PlaceholderR_30x13.png and /dev/null differ diff --git a/assets/resources/Manifest b/assets/resources/Manifest index a0aeb67b..b353e342 100644 --- a/assets/resources/Manifest +++ b/assets/resources/Manifest @@ -1,5 +1,5 @@ V:0 -T:1655152832 +T:1658906571 D:badusb D:dolphin D:infrared @@ -232,10 +232,10 @@ F:41b4f08774249014cb8d3dffa5f5c07d:1757:nfc/assets/currency_code.nfc F:c60e862919731b0bd538a1001bbc1098:17453:nfc/assets/mf_classic_dict.nfc D:subghz/assets F:dda1ef895b8a25fde57c874feaaef997:650:subghz/assets/came_atomo -F:610a0ffa2479a874f2060eb2348104c5:2712:subghz/assets/keeloq_mfcodes +F:788eef2cc74e29f3388463d6607dab0d:3264:subghz/assets/keeloq_mfcodes F:9214f9c10463b746a27e82ce0b96e040:465:subghz/assets/keeloq_mfcodes_user F:653bd8d349055a41e1152e557d4a52d3:202:subghz/assets/nice_flor_s -F:c6ec4374275cd20f482ecd46de9f53e3:528:subghz/assets/setting_user +F:c1c63fbd5f5aa3ea504027014652191f:1150:subghz/assets/setting_user D:u2f/assets F:7e11e688e39034bbb9d88410044795e1:365:u2f/assets/cert.der F:f60b88c20ed479ed9684e249f7134618:264:u2f/assets/cert_key.u2f diff --git a/debug/fw.jflash b/debug/fw.jflash new file mode 100644 index 00000000..8621efb4 --- /dev/null +++ b/debug/fw.jflash @@ -0,0 +1,90 @@ + AppVersion = 76803 + FileVersion = 2 +[GENERAL] + aATEModuleSel[24] = 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ConnectMode = 0 + CurrentFile = "..\build\latest\firmware.bin" + DataFileSAddr = 0x08000000 + GUIMode = 0 + HostName = "" + TargetIF = 1 + USBPort = 0 + USBSerialNo = 0x00000000 + UseATEModuleSelection = 0 +[JTAG] + IRLen = 0 + MultipleTargets = 0 + NumDevices = 0 + Speed0 = 8000 + Speed1 = 8000 + TAP_Number = 0 + UseAdaptive0 = 0 + UseAdaptive1 = 0 + UseMaxSpeed0 = 0 + UseMaxSpeed1 = 0 +[CPU] + NumInitSteps = 2 + InitStep0_Action = "Reset" + InitStep0_Value0 = 0x00000000 + InitStep0_Value1 = 0x00000000 + InitStep0_Comment = "" + InitStep1_Action = "Halt" + InitStep1_Value0 = 0xFFFFFFFF + InitStep1_Value1 = 0xFFFFFFFF + InitStep1_Comment = "" + NumExitSteps = 1 + ExitStep0_Action = "Reset" + ExitStep0_Value0 = 0x00000005 + ExitStep0_Value1 = 0x00000032 + ExitStep0_Comment = "" + UseScriptFile = 0 + ScriptFile = "" + UseRAM = 1 + RAMAddr = 0x20000000 + RAMSize = 0x00030000 + CheckCoreID = 1 + CoreID = 0x6BA02477 + CoreIDMask = 0x0F000FFF + UseAutoSpeed = 0x00000001 + ClockSpeed = 0x00000000 + EndianMode = 0 + ChipName = "ST STM32WB55RG" +[FLASH] + aRangeSel[1] = 0-255 + BankName = "Internal flash" + BankSelMode = 1 + BaseAddr = 0x08000000 + NumBanks = 1 +[PRODUCTION] + AutoPerformsDisconnect = 0 + AutoPerformsErase = 1 + AutoPerformsProgram = 1 + AutoPerformsSecure = 0 + AutoPerformsStartApp = 1 + AutoPerformsUnsecure = 0 + AutoPerformsVerify = 0 + EnableFixedVTref = 0 + EnableTargetPower = 0 + EraseType = 1 + FixedVTref = 0x00000CE4 + MonitorVTref = 0 + MonitorVTrefMax = 0x0000157C + MonitorVTrefMin = 0x000003E8 + OverrideTimeouts = 0 + ProgramSN = 0 + SerialFile = "" + SNAddr = 0x00000000 + SNInc = 0x00000001 + SNLen = 0x00000004 + SNListFile = "" + SNValue = 0x00000001 + StartAppType = 1 + TargetPowerDelay = 0x00000014 + TimeoutErase = 0x00003A98 + TimeoutProgram = 0x00002710 + TimeoutVerify = 0x00002710 + VerifyType = 1 +[PERFORMANCE] + DisableSkipBlankDataOnProgram = 0x00000000 + PerfromBlankCheckPriorEraseChip = 0x00000001 + PerfromBlankCheckPriorEraseSelectedSectors = 0x00000001 diff --git a/documentation/OTA.md b/documentation/OTA.md index 3e82336c..2a6b0984 100644 --- a/documentation/OTA.md +++ b/documentation/OTA.md @@ -110,7 +110,12 @@ Even if something goes wrong, Updater gives you an option to retry failed operat ## Full package -To build a basic update package, run `./fbt --with-updater COMPACT=1 DEBUG=0 updater_package` +To build full update package, including firmware, radio stack and resources for SD card, run `./fbt COMPACT=1 DEBUG=0 updater_package` + + +## Minimal package + +To build minimal update package, including only firmware, run `./fbt COMPACT=1 DEBUG=0 updater_minpackage` ## Customizing update bundles @@ -118,7 +123,7 @@ To build a basic update package, run `./fbt --with-updater COMPACT=1 DEBUG=0 upd Default update packages are built with Bluetooth Light stack. You can pick a different stack, if your firmware version supports it, and build a bundle with it passing stack type and binary name to `fbt`: -`./fbt --with-updater updater_package COMPACT=1 DEBUG=0 COPRO_OB_DATA=scripts/ob_custradio.data COPRO_STACK_BIN=stm32wb5x_BLE_Stack_full_fw.bin COPRO_STACK_TYPE=ble_full` +`./fbt updater_package COMPACT=1 DEBUG=0 COPRO_OB_DATA=scripts/ob_custradio.data COPRO_STACK_BIN=stm32wb5x_BLE_Stack_full_fw.bin COPRO_STACK_TYPE=ble_full` Note that `COPRO_OB_DATA` must point to a valid file in `scripts` folder containing reference Option Byte data matching to your radio stack type. diff --git a/documentation/fbt.md b/documentation/fbt.md index af10cd9c..c658ce20 100644 --- a/documentation/fbt.md +++ b/documentation/fbt.md @@ -20,7 +20,7 @@ Make sure that `gcc-arm-none-eabi` toolchain & OpenOCD executables are in system To build with FBT, call it specifying configuration options & targets to build. For example, -`./fbt --with-updater COMPACT=1 DEBUG=0 VERBOSE=1 updater_package copro_dist` +`./fbt COMPACT=1 DEBUG=0 VERBOSE=1 updater_package copro_dist` To run cleanup (think of `make clean`) for specified targets, add `-c` option. @@ -31,16 +31,18 @@ FBT keeps track of internal dependencies, so you only need to build the highest- ### High-level (what you most likely need) - `fw_dist` - build & publish firmware to `dist` folder. This is a default target, when no other are specified -- `updater_package` - build self-update package. _Requires `--with-updater` option_ +- `updater_package`, `updater_minpackage` - build self-update package. Minimal version only inclues firmware's DFU file; full version also includes radio stack & resources for SD card - `copro_dist` - bundle Core2 FUS+stack binaries for qFlipper - `flash` - flash attached device with OpenOCD over ST-Link -- `flash_usb` - build, upload and install update package to device over USB. _Requires `--with-updater` option_ +- `flash_usb`, `flash_usb_full` - build, upload and install update package to device over USB. See details on `updater_package`, `updater_minpackage` - `debug` - build and flash firmware, then attach with gdb with firmware's .elf loaded -- `debug_updater` - attach gdb with updater's .elf loaded. _Requires `--with-updater` option_ -- `debug_other` - attach gdb without loading any .elf. Allows to manually add external elf files with `add-symbol-file` in gdb. +- `debug_other` - attach gdb without loading any .elf. Allows to manually add external elf files with `add-symbol-file` in gdb +- `updater_debug` - attach gdb with updater's .elf loaded - `blackmagic` - debug firmware with Blackmagic probe (WiFi dev board) - `openocd` - just start OpenOCD - `get_blackmagic` - output blackmagic address in gdb remote format. Useful for IDE integration +- `lint`, `format` - run clang-tidy on C source code to check and reformat it according to `.clang-format` specs +- `lint_py`, `format_py` - run [black](https://black.readthedocs.io/en/stable/index.html) on Python source code, build system files & application manifests ### Firmware targets @@ -49,9 +51,11 @@ FBT keeps track of internal dependencies, so you only need to build the highest- - Check out `--extra-ext-apps` for force adding extra apps to external build - `firmware_snake_game_list`, etc - generate source + assembler listing for app's .elf - `flash`, `firmware_flash` - flash current version to attached device with OpenOCD over ST-Link +- `jflash` - flash current version to attached device with JFlash using J-Link probe. JFlash executable must be on your $PATH - `flash_blackmagic` - flash current version to attached device with Blackmagic probe - `firmware_all`, `updater_all` - build basic set of binaries - `firmware_list`, `updater_list` - generate source + assembler listing +- `firmware_cdb`, `updater_cdb` - generate `compilation_database.json` file for external tools and IDEs. It can be created without actually building the firmware. ### Assets @@ -66,7 +70,7 @@ 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 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 +- `--with-updater` - enables updater-related targets and dependency tracking. Enabling this option introduces extra startup time costs, so use it when bundling update packages. _Explicily enabling this should no longer be required, fbt now has specific handling for updater-related targets_ - `--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 diff --git a/fbt b/fbt index 0ea572b1..981489dd 100755 --- a/fbt +++ b/fbt @@ -4,14 +4,20 @@ # unofficial strict mode set -eu; -SCONS_DEFAULT_FLAGS="-Q --warn=target-not-built"; +# private variables SCRIPT_PATH="$(cd "$(dirname "$0")" && pwd -P)"; +SCONS_DEFAULT_FLAGS="-Q --warn=target-not-built"; -if [ -z "${FBT_NOENV:-}" ]; then +# public variables +FBT_NOENV="${FBT_NOENV:-""}"; +FBT_NO_SYNC="${FBT_NO_SYNC:-""}"; +FBT_TOOLCHAIN_PATH="${FBT_TOOLCHAIN_PATH:-$SCRIPT_PATH}"; + +if [ -z "$FBT_NOENV" ]; then . "$SCRIPT_PATH/scripts/toolchain/fbtenv.sh"; fi -if [ -z "${FBT_NO_SYNC:-}" ]; then +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; @@ -19,4 +25,4 @@ if [ -z "${FBT_NO_SYNC:-}" ]; then git submodule update --init; fi -python3 "$SCRIPT_PATH/lib/scons/scripts/scons.py" $SCONS_DEFAULT_FLAGS "$@" \ No newline at end of file +python3 "$SCRIPT_PATH/lib/scons/scripts/scons.py" $SCONS_DEFAULT_FLAGS "$@" diff --git a/fbt_options.py b/fbt_options.py index fb2a0d36..7276f579 100644 --- a/fbt_options.py +++ b/fbt_options.py @@ -80,6 +80,7 @@ FIRMWARE_APPS = { ], "unit_tests": [ "basic_services", + "updater_app", "unit_tests", ], } diff --git a/firmware.scons b/firmware.scons index 438ac8e7..76f0b52d 100644 --- a/firmware.scons +++ b/firmware.scons @@ -9,7 +9,11 @@ from fbt.util import ( # Building initial C environment for libs env = ENV.Clone( - tools=["compilation_db", "fwbin", "fbt_apps"], + tools=[ + ("compilation_db", {"COMPILATIONDB_COMSTR": "\tCDB\t${TARGET}"}), + "fwbin", + "fbt_apps", + ], COMPILATIONDB_USE_ABSPATH=False, BUILD_DIR=fw_build_meta["build_dir"], IS_BASE_FIRMWARE=fw_build_meta["type"] == "firmware", @@ -76,7 +80,6 @@ if not env["VERBOSE"]: HEXCOMSTR="\tHEX\t${TARGET}", BINCOMSTR="\tBIN\t${TARGET}", DFUCOMSTR="\tDFU\t${TARGET}", - OPENOCDCOMSTR="\tFLASH\t${SOURCE}", ) @@ -139,7 +142,7 @@ apps_c = fwenv.ApplicationsC( Value(fwenv["APPS"]), ) # Adding dependency on manifest files so apps.c is rebuilt when any manifest is changed -fwenv.Depends(apps_c, fwenv.GlobRecursive("*.fam", "applications")) +fwenv.Depends(apps_c, fwenv.GlobRecursive("*.fam", "#/applications")) sources = [apps_c] # Gather sources only from app folders in current configuration @@ -164,6 +167,8 @@ fwenv.AppendUnique( "-u", "_printf_float", "-n", + "-Xlinker", + "-Map=${TARGET}.map", ], ) @@ -202,7 +207,6 @@ 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 @@ -232,7 +236,8 @@ if should_gen_cdb_and_link_dir(fwenv, BUILD_TARGETS): fwcdb = fwenv.CompilationDatabase() # without filtering, both updater & firmware commands would be generated fwenv.Replace(COMPILATIONDB_PATH_FILTER=fwenv.subst("*${FW_FLAVOR}*")) - Depends(fwcdb, fwelf) + AlwaysBuild(fwcdb) + Alias(fwenv["FIRMWARE_BUILD_CFG"] + "_cdb", fwcdb) fw_artifacts.append(fwcdb) # Adding as a phony target, so folder link is updated even if elf didn't change diff --git a/firmware/targets/f7/Src/update.c b/firmware/targets/f7/Src/update.c index af247195..36204829 100644 --- a/firmware/targets/f7/Src/update.c +++ b/firmware/targets/f7/Src/update.c @@ -22,6 +22,21 @@ static FATFS* pfs = NULL; } \ } +static bool flipper_update_mount_sd() { + for(int i = 0; i < BSP_SD_MaxMountRetryCount(); ++i) { + if(BSP_SD_Init((i % 2) == 0) != MSD_OK) { + /* Next attempt will be without card reset, let it settle */ + furi_delay_ms(1000); + continue; + } + + if(f_mount(pfs, "/", 1) == FR_OK) { + return true; + } + } + return false; +} + static bool flipper_update_init() { furi_hal_clock_init(); furi_hal_rtc_init(); @@ -34,13 +49,9 @@ static bool flipper_update_init() { return false; } - if(BSP_SD_Init(true)) { - return false; - } - pfs = malloc(sizeof(FATFS)); - CHECK_FRESULT(f_mount(pfs, "/", 1)); - return true; + + return flipper_update_mount_sd(); } static bool flipper_update_load_stage(const string_t work_dir, UpdateManifest* manifest) { diff --git a/firmware/targets/f7/fatfs/stm32_adafruit_sd.c b/firmware/targets/f7/fatfs/stm32_adafruit_sd.c index 1ca38abe..6db430a5 100644 --- a/firmware/targets/f7/fatfs/stm32_adafruit_sd.c +++ b/firmware/targets/f7/fatfs/stm32_adafruit_sd.c @@ -331,6 +331,10 @@ void SD_SPI_Bus_To_Normal_State() { * @{ */ +uint8_t BSP_SD_MaxMountRetryCount() { + return 10; +} + /** * @brief Initializes the SD/SD communication. * @param None diff --git a/firmware/targets/f7/fatfs/stm32_adafruit_sd.h b/firmware/targets/f7/fatfs/stm32_adafruit_sd.h index 74a0e0c2..e0c5e3be 100644 --- a/firmware/targets/f7/fatfs/stm32_adafruit_sd.h +++ b/firmware/targets/f7/fatfs/stm32_adafruit_sd.h @@ -198,6 +198,7 @@ typedef struct { /** @defgroup STM32_ADAFRUIT_SD_Exported_Functions * @{ */ +uint8_t BSP_SD_MaxMountRetryCount(); uint8_t BSP_SD_Init(bool reset_card); uint8_t BSP_SD_ReadBlocks(uint32_t* pData, uint32_t ReadAddr, uint32_t NumOfBlocks, uint32_t Timeout); diff --git a/firmware/targets/f7/stm32wb55xx_flash.ld b/firmware/targets/f7/stm32wb55xx_flash.ld index 1d0e916b..20314ba3 100644 --- a/firmware/targets/f7/stm32wb55xx_flash.ld +++ b/firmware/targets/f7/stm32wb55xx_flash.ld @@ -75,6 +75,7 @@ SECTIONS .text : { . = ALIGN(4); + *lib*.a:*(.text .text.*) /* code from libraries before apps */ *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ diff --git a/lib/loclass.scons b/lib/loclass.scons index ba43dd6e..a657f042 100644 --- a/lib/loclass.scons +++ b/lib/loclass.scons @@ -4,8 +4,6 @@ env.Append( CPPPATH=[ "#/lib/loclass", ], - CPPDEFINES=[ - ], ) diff --git a/lib/mbedtls.scons b/lib/mbedtls.scons index 35de7e6f..1b0bec87 100644 --- a/lib/mbedtls.scons +++ b/lib/mbedtls.scons @@ -5,8 +5,6 @@ env.Append( "#/lib/mbedtls", "#/lib/mbedtls/include", ], - CPPDEFINES=[ - ], ) diff --git a/lib/subghz/blocks/generic.c b/lib/subghz/blocks/generic.c index 187c30e6..353ff18b 100644 --- a/lib/subghz/blocks/generic.c +++ b/lib/subghz/blocks/generic.c @@ -23,7 +23,7 @@ void subghz_block_generic_get_preset_name(const char* preset_name, string_t pres bool subghz_block_generic_serialize( SubGhzBlockGeneric* instance, FlipperFormat* flipper_format, - SubGhzPesetDefinition* preset) { + SubGhzPresetDefinition* preset) { furi_assert(instance); bool res = false; string_t temp_str; diff --git a/lib/subghz/blocks/generic.h b/lib/subghz/blocks/generic.h index e1256ea4..56a7fc2d 100644 --- a/lib/subghz/blocks/generic.h +++ b/lib/subghz/blocks/generic.h @@ -31,13 +31,13 @@ void subghz_block_generic_get_preset_name(const char* preset_name, string_t pres * Serialize data SubGhzBlockGeneric. * @param instance Pointer to a SubGhzBlockGeneric instance * @param flipper_format Pointer to a FlipperFormat instance - * @param preset The modulation on which the signal was received, SubGhzPesetDefinition + * @param preset The modulation on which the signal was received, SubGhzPresetDefinition * @return true On success */ bool subghz_block_generic_serialize( SubGhzBlockGeneric* instance, FlipperFormat* flipper_format, - SubGhzPesetDefinition* preset); + SubGhzPresetDefinition* preset); /** * Deserialize data SubGhzBlockGeneric. diff --git a/lib/subghz/protocols/base.c b/lib/subghz/protocols/base.c index 32c64cce..06542f5e 100644 --- a/lib/subghz/protocols/base.c +++ b/lib/subghz/protocols/base.c @@ -26,7 +26,7 @@ bool subghz_protocol_decoder_base_get_string( bool subghz_protocol_decoder_base_serialize( SubGhzProtocolDecoderBase* decoder_base, FlipperFormat* flipper_format, - SubGhzPesetDefinition* preset) { + SubGhzPresetDefinition* preset) { bool status = false; if(decoder_base->protocol && decoder_base->protocol->decoder && diff --git a/lib/subghz/protocols/base.h b/lib/subghz/protocols/base.h index ad237bbe..a1a7478d 100644 --- a/lib/subghz/protocols/base.h +++ b/lib/subghz/protocols/base.h @@ -43,13 +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 preset The modulation on which the signal was received, SubGhzPesetDefinition + * @param preset The modulation on which the signal was received, SubGhzPresetDefinition * @return true On success */ bool subghz_protocol_decoder_base_serialize( SubGhzProtocolDecoderBase* decoder_base, FlipperFormat* flipper_format, - SubGhzPesetDefinition* preset); + SubGhzPresetDefinition* preset); /** * Deserialize data SubGhzProtocolDecoderBase. diff --git a/lib/subghz/protocols/came.c b/lib/subghz/protocols/came.c index 1d2045ca..d28b735c 100644 --- a/lib/subghz/protocols/came.c +++ b/lib/subghz/protocols/came.c @@ -145,7 +145,13 @@ bool subghz_protocol_encoder_came_deserialize(void* context, FlipperFormat* flip FURI_LOG_E(TAG, "Deserialize error"); break; } - + if((instance->generic.data_count_bit != + subghz_protocol_came_const.min_count_bit_for_found) && + (instance->generic.data_count_bit != + 2 * subghz_protocol_came_const.min_count_bit_for_found)) { + FURI_LOG_E(TAG, "Wrong number of bits in key"); + break; + } //optional parameter parameter flipper_format_read_uint32( flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); @@ -284,7 +290,7 @@ uint8_t subghz_protocol_decoder_came_get_hash_data(void* context) { bool subghz_protocol_decoder_came_serialize( void* context, FlipperFormat* flipper_format, - SubGhzPesetDefinition* preset) { + SubGhzPresetDefinition* preset) { furi_assert(context); SubGhzProtocolDecoderCame* instance = context; return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); @@ -293,7 +299,21 @@ bool subghz_protocol_decoder_came_serialize( bool subghz_protocol_decoder_came_deserialize(void* context, FlipperFormat* flipper_format) { furi_assert(context); SubGhzProtocolDecoderCame* instance = context; - return subghz_block_generic_deserialize(&instance->generic, flipper_format); + bool ret = false; + do { + if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { + break; + } + if((instance->generic.data_count_bit != + subghz_protocol_came_const.min_count_bit_for_found) && + (instance->generic.data_count_bit != + 2 * subghz_protocol_came_const.min_count_bit_for_found)) { + FURI_LOG_E(TAG, "Wrong number of bits in key"); + break; + } + ret = true; + } while(false); + return ret; } void subghz_protocol_decoder_came_get_string(void* context, string_t output) { diff --git a/lib/subghz/protocols/came.h b/lib/subghz/protocols/came.h index abd3044b..c2648c05 100644 --- a/lib/subghz/protocols/came.h +++ b/lib/subghz/protocols/came.h @@ -83,13 +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 preset The modulation on which the signal was received, SubGhzPesetDefinition + * @param preset The modulation on which the signal was received, SubGhzPresetDefinition * @return true On success */ bool subghz_protocol_decoder_came_serialize( void* context, FlipperFormat* flipper_format, - SubGhzPesetDefinition* preset); + SubGhzPresetDefinition* preset); /** * Deserialize data SubGhzProtocolDecoderCame. diff --git a/lib/subghz/protocols/came_atomo.c b/lib/subghz/protocols/came_atomo.c index 2178b4d1..0c3cdd8a 100644 --- a/lib/subghz/protocols/came_atomo.c +++ b/lib/subghz/protocols/came_atomo.c @@ -301,7 +301,7 @@ uint8_t subghz_protocol_decoder_came_atomo_get_hash_data(void* context) { bool subghz_protocol_decoder_came_atomo_serialize( void* context, FlipperFormat* flipper_format, - SubGhzPesetDefinition* preset) { + SubGhzPresetDefinition* preset) { furi_assert(context); SubGhzProtocolDecoderCameAtomo* instance = context; return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); @@ -310,7 +310,19 @@ bool subghz_protocol_decoder_came_atomo_serialize( bool subghz_protocol_decoder_came_atomo_deserialize(void* context, FlipperFormat* flipper_format) { furi_assert(context); SubGhzProtocolDecoderCameAtomo* instance = context; - return subghz_block_generic_deserialize(&instance->generic, flipper_format); + bool ret = false; + do { + if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { + break; + } + if(instance->generic.data_count_bit != + subghz_protocol_came_atomo_const.min_count_bit_for_found) { + FURI_LOG_E(TAG, "Wrong number of bits in key"); + break; + } + ret = true; + } while(false); + return ret; } void subghz_protocol_decoder_came_atomo_get_string(void* context, string_t output) { diff --git a/lib/subghz/protocols/came_atomo.h b/lib/subghz/protocols/came_atomo.h index eaba74c8..70a79eca 100644 --- a/lib/subghz/protocols/came_atomo.h +++ b/lib/subghz/protocols/came_atomo.h @@ -48,13 +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 preset The modulation on which the signal was received, SubGhzPesetDefinition + * @param preset The modulation on which the signal was received, SubGhzPresetDefinition * @return true On success */ bool subghz_protocol_decoder_came_atomo_serialize( void* context, FlipperFormat* flipper_format, - SubGhzPesetDefinition* preset); + SubGhzPresetDefinition* preset); /** * Deserialize data SubGhzProtocolDecoderCameAtomo. diff --git a/lib/subghz/protocols/came_twee.c b/lib/subghz/protocols/came_twee.c index 7310d6f9..ef352bf6 100644 --- a/lib/subghz/protocols/came_twee.c +++ b/lib/subghz/protocols/came_twee.c @@ -250,7 +250,11 @@ bool subghz_protocol_encoder_came_twee_deserialize(void* context, FlipperFormat* FURI_LOG_E(TAG, "Deserialize error"); break; } - + if(instance->generic.data_count_bit != + subghz_protocol_came_twee_const.min_count_bit_for_found) { + FURI_LOG_E(TAG, "Wrong number of bits in key"); + break; + } //optional parameter parameter flipper_format_read_uint32( flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); @@ -418,7 +422,7 @@ uint8_t subghz_protocol_decoder_came_twee_get_hash_data(void* context) { bool subghz_protocol_decoder_came_twee_serialize( void* context, FlipperFormat* flipper_format, - SubGhzPesetDefinition* preset) { + SubGhzPresetDefinition* preset) { furi_assert(context); SubGhzProtocolDecoderCameTwee* instance = context; return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); @@ -427,7 +431,19 @@ bool subghz_protocol_decoder_came_twee_serialize( bool subghz_protocol_decoder_came_twee_deserialize(void* context, FlipperFormat* flipper_format) { furi_assert(context); SubGhzProtocolDecoderCameTwee* instance = context; - return subghz_block_generic_deserialize(&instance->generic, flipper_format); + bool ret = false; + do { + if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { + break; + } + if(instance->generic.data_count_bit != + subghz_protocol_came_twee_const.min_count_bit_for_found) { + FURI_LOG_E(TAG, "Wrong number of bits in key"); + break; + } + ret = true; + } while(false); + return ret; } void subghz_protocol_decoder_came_twee_get_string(void* context, string_t output) { diff --git a/lib/subghz/protocols/came_twee.h b/lib/subghz/protocols/came_twee.h index 66a89423..42e6ddaf 100644 --- a/lib/subghz/protocols/came_twee.h +++ b/lib/subghz/protocols/came_twee.h @@ -83,13 +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 preset The modulation on which the signal was received, SubGhzPesetDefinition + * @param preset The modulation on which the signal was received, SubGhzPresetDefinition * @return true On success */ bool subghz_protocol_decoder_came_twee_serialize( void* context, FlipperFormat* flipper_format, - SubGhzPesetDefinition* preset); + SubGhzPresetDefinition* preset); /** * Deserialize data SubGhzProtocolDecoderCameTwee. diff --git a/lib/subghz/protocols/chamberlain_code.c b/lib/subghz/protocols/chamberlain_code.c index 40958421..3128b71e 100644 --- a/lib/subghz/protocols/chamberlain_code.c +++ b/lib/subghz/protocols/chamberlain_code.c @@ -215,7 +215,11 @@ bool subghz_protocol_encoder_chamb_code_deserialize(void* context, FlipperFormat FURI_LOG_E(TAG, "Deserialize error"); break; } - + if(instance->generic.data_count_bit < + subghz_protocol_chamb_code_const.min_count_bit_for_found) { + FURI_LOG_E(TAG, "Wrong number of bits in key"); + break; + } //optional parameter parameter flipper_format_read_uint32( flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); @@ -423,7 +427,7 @@ uint8_t subghz_protocol_decoder_chamb_code_get_hash_data(void* context) { bool subghz_protocol_decoder_chamb_code_serialize( void* context, FlipperFormat* flipper_format, - SubGhzPesetDefinition* preset) { + SubGhzPresetDefinition* preset) { furi_assert(context); SubGhzProtocolDecoderChamb_Code* instance = context; return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); @@ -432,7 +436,19 @@ bool subghz_protocol_decoder_chamb_code_serialize( bool subghz_protocol_decoder_chamb_code_deserialize(void* context, FlipperFormat* flipper_format) { furi_assert(context); SubGhzProtocolDecoderChamb_Code* instance = context; - return subghz_block_generic_deserialize(&instance->generic, flipper_format); + bool ret = false; + do { + if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { + break; + } + if(instance->generic.data_count_bit < + subghz_protocol_chamb_code_const.min_count_bit_for_found) { + FURI_LOG_E(TAG, "Wrong number of bits in key"); + break; + } + ret = true; + } while(false); + return ret; } void subghz_protocol_decoder_chamb_code_get_string(void* context, string_t output) { diff --git a/lib/subghz/protocols/chamberlain_code.h b/lib/subghz/protocols/chamberlain_code.h index e25e54c2..1ac2f9f9 100644 --- a/lib/subghz/protocols/chamberlain_code.h +++ b/lib/subghz/protocols/chamberlain_code.h @@ -83,13 +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 preset The modulation on which the signal was received, SubGhzPesetDefinition + * @param preset The modulation on which the signal was received, SubGhzPresetDefinition * @return true On success */ bool subghz_protocol_decoder_chamb_code_serialize( void* context, FlipperFormat* flipper_format, - SubGhzPesetDefinition* preset); + SubGhzPresetDefinition* preset); /** * Deserialize data SubGhzProtocolDecoderChamb_Code. diff --git a/lib/subghz/protocols/faac_slh.c b/lib/subghz/protocols/faac_slh.c index caa8e5eb..8b90f471 100644 --- a/lib/subghz/protocols/faac_slh.c +++ b/lib/subghz/protocols/faac_slh.c @@ -115,7 +115,7 @@ void subghz_protocol_decoder_faac_slh_feed(void* context, bool level, uint32_t d if(duration >= ((uint32_t)subghz_protocol_faac_slh_const.te_short * 3 + subghz_protocol_faac_slh_const.te_delta)) { instance->decoder.parser_step = FaacSLHDecoderStepFoundPreambula; - if(instance->decoder.decode_count_bit >= + if(instance->decoder.decode_count_bit == subghz_protocol_faac_slh_const.min_count_bit_for_found) { instance->generic.data = instance->decoder.decode_data; instance->generic.data_count_bit = instance->decoder.decode_count_bit; @@ -183,7 +183,7 @@ uint8_t subghz_protocol_decoder_faac_slh_get_hash_data(void* context) { bool subghz_protocol_decoder_faac_slh_serialize( void* context, FlipperFormat* flipper_format, - SubGhzPesetDefinition* preset) { + SubGhzPresetDefinition* preset) { furi_assert(context); SubGhzProtocolDecoderFaacSLH* instance = context; return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); @@ -192,7 +192,19 @@ bool subghz_protocol_decoder_faac_slh_serialize( bool subghz_protocol_decoder_faac_slh_deserialize(void* context, FlipperFormat* flipper_format) { furi_assert(context); SubGhzProtocolDecoderFaacSLH* instance = context; - return subghz_block_generic_deserialize(&instance->generic, flipper_format); + bool ret = false; + do { + if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { + break; + } + if(instance->generic.data_count_bit != + subghz_protocol_faac_slh_const.min_count_bit_for_found) { + FURI_LOG_E(TAG, "Wrong number of bits in key"); + break; + } + ret = true; + } while(false); + return ret; } void subghz_protocol_decoder_faac_slh_get_string(void* context, string_t output) { diff --git a/lib/subghz/protocols/faac_slh.h b/lib/subghz/protocols/faac_slh.h index f1ad1452..fe7a7926 100644 --- a/lib/subghz/protocols/faac_slh.h +++ b/lib/subghz/protocols/faac_slh.h @@ -49,13 +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 preset The modulation on which the signal was received, SubGhzPesetDefinition + * @param preset The modulation on which the signal was received, SubGhzPresetDefinition * @return true On success */ bool subghz_protocol_decoder_faac_slh_serialize( void* context, FlipperFormat* flipper_format, - SubGhzPesetDefinition* preset); + SubGhzPresetDefinition* preset); /** * Deserialize data SubGhzProtocolDecoderFaacSLH. diff --git a/lib/subghz/protocols/gate_tx.c b/lib/subghz/protocols/gate_tx.c index a172eb3c..66174d01 100644 --- a/lib/subghz/protocols/gate_tx.c +++ b/lib/subghz/protocols/gate_tx.c @@ -138,7 +138,11 @@ bool subghz_protocol_encoder_gate_tx_deserialize(void* context, FlipperFormat* f FURI_LOG_E(TAG, "Deserialize error"); break; } - + if(instance->generic.data_count_bit != + subghz_protocol_gate_tx_const.min_count_bit_for_found) { + FURI_LOG_E(TAG, "Wrong number of bits in key"); + break; + } //optional parameter parameter flipper_format_read_uint32( flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); @@ -289,7 +293,7 @@ uint8_t subghz_protocol_decoder_gate_tx_get_hash_data(void* context) { bool subghz_protocol_decoder_gate_tx_serialize( void* context, FlipperFormat* flipper_format, - SubGhzPesetDefinition* preset) { + SubGhzPresetDefinition* preset) { furi_assert(context); SubGhzProtocolDecoderGateTx* instance = context; return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); @@ -298,7 +302,19 @@ bool subghz_protocol_decoder_gate_tx_serialize( bool subghz_protocol_decoder_gate_tx_deserialize(void* context, FlipperFormat* flipper_format) { furi_assert(context); SubGhzProtocolDecoderGateTx* instance = context; - return subghz_block_generic_deserialize(&instance->generic, flipper_format); + bool ret = false; + do { + if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { + break; + } + if(instance->generic.data_count_bit != + subghz_protocol_gate_tx_const.min_count_bit_for_found) { + FURI_LOG_E(TAG, "Wrong number of bits in key"); + break; + } + ret = true; + } while(false); + return ret; } void subghz_protocol_decoder_gate_tx_get_string(void* context, string_t output) { diff --git a/lib/subghz/protocols/gate_tx.h b/lib/subghz/protocols/gate_tx.h index f296a27e..17157681 100644 --- a/lib/subghz/protocols/gate_tx.h +++ b/lib/subghz/protocols/gate_tx.h @@ -83,13 +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 preset The modulation on which the signal was received, SubGhzPesetDefinition + * @param preset The modulation on which the signal was received, SubGhzPresetDefinition * @return true On success */ bool subghz_protocol_decoder_gate_tx_serialize( void* context, FlipperFormat* flipper_format, - SubGhzPesetDefinition* preset); + SubGhzPresetDefinition* preset); /** * Deserialize data SubGhzProtocolDecoderGateTx. diff --git a/lib/subghz/protocols/holtek.c b/lib/subghz/protocols/holtek.c index c24bdf6f..eeb24026 100644 --- a/lib/subghz/protocols/holtek.c +++ b/lib/subghz/protocols/holtek.c @@ -151,7 +151,11 @@ bool subghz_protocol_encoder_holtek_deserialize(void* context, FlipperFormat* fl FURI_LOG_E(TAG, "Deserialize error"); break; } - + if(instance->generic.data_count_bit != + subghz_protocol_holtek_const.min_count_bit_for_found) { + FURI_LOG_E(TAG, "Wrong number of bits in key"); + break; + } //optional parameter parameter flipper_format_read_uint32( flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); @@ -322,7 +326,7 @@ uint8_t subghz_protocol_decoder_holtek_get_hash_data(void* context) { bool subghz_protocol_decoder_holtek_serialize( void* context, FlipperFormat* flipper_format, - SubGhzPesetDefinition* preset) { + SubGhzPresetDefinition* preset) { furi_assert(context); SubGhzProtocolDecoderHoltek* instance = context; return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); @@ -331,7 +335,19 @@ bool subghz_protocol_decoder_holtek_serialize( bool subghz_protocol_decoder_holtek_deserialize(void* context, FlipperFormat* flipper_format) { furi_assert(context); SubGhzProtocolDecoderHoltek* instance = context; - return subghz_block_generic_deserialize(&instance->generic, flipper_format); + bool ret = false; + do { + if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { + break; + } + if(instance->generic.data_count_bit != + subghz_protocol_holtek_const.min_count_bit_for_found) { + FURI_LOG_E(TAG, "Wrong number of bits in key"); + break; + } + ret = true; + } while(false); + return ret; } void subghz_protocol_decoder_holtek_get_string(void* context, string_t output) { diff --git a/lib/subghz/protocols/holtek.h b/lib/subghz/protocols/holtek.h index cc962dcc..df7dd644 100644 --- a/lib/subghz/protocols/holtek.h +++ b/lib/subghz/protocols/holtek.h @@ -83,13 +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 preset The modulation on which the signal was received, SubGhzPesetDefinition + * @param preset The modulation on which the signal was received, SubGhzPresetDefinition * @return true On success */ bool subghz_protocol_decoder_holtek_serialize( void* context, FlipperFormat* flipper_format, - SubGhzPesetDefinition* preset); + SubGhzPresetDefinition* preset); /** * Deserialize data SubGhzProtocolDecoderHoltek. diff --git a/lib/subghz/protocols/hormann.c b/lib/subghz/protocols/hormann.c index 696aaf61..ac631251 100644 --- a/lib/subghz/protocols/hormann.c +++ b/lib/subghz/protocols/hormann.c @@ -154,7 +154,11 @@ bool subghz_protocol_encoder_hormann_deserialize(void* context, FlipperFormat* f FURI_LOG_E(TAG, "Deserialize error"); break; } - + if(instance->generic.data_count_bit != + subghz_protocol_hormann_const.min_count_bit_for_found) { + FURI_LOG_E(TAG, "Wrong number of bits in key"); + break; + } //optional parameter parameter flipper_format_read_uint32( flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); @@ -310,7 +314,7 @@ uint8_t subghz_protocol_decoder_hormann_get_hash_data(void* context) { bool subghz_protocol_decoder_hormann_serialize( void* context, FlipperFormat* flipper_format, - SubGhzPesetDefinition* preset) { + SubGhzPresetDefinition* preset) { furi_assert(context); SubGhzProtocolDecoderHormann* instance = context; return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); @@ -319,7 +323,19 @@ bool subghz_protocol_decoder_hormann_serialize( bool subghz_protocol_decoder_hormann_deserialize(void* context, FlipperFormat* flipper_format) { furi_assert(context); SubGhzProtocolDecoderHormann* instance = context; - return subghz_block_generic_deserialize(&instance->generic, flipper_format); + bool ret = false; + do { + if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { + break; + } + if(instance->generic.data_count_bit != + subghz_protocol_hormann_const.min_count_bit_for_found) { + FURI_LOG_E(TAG, "Wrong number of bits in key"); + break; + } + ret = true; + } while(false); + return ret; } void subghz_protocol_decoder_hormann_get_string(void* context, string_t output) { diff --git a/lib/subghz/protocols/hormann.h b/lib/subghz/protocols/hormann.h index 04634ff0..45d6eb22 100644 --- a/lib/subghz/protocols/hormann.h +++ b/lib/subghz/protocols/hormann.h @@ -83,13 +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 preset The modulation on which the signal was received, SubGhzPesetDefinition + * @param preset The modulation on which the signal was received, SubGhzPresetDefinition * @return true On success */ bool subghz_protocol_decoder_hormann_serialize( void* context, FlipperFormat* flipper_format, - SubGhzPesetDefinition* preset); + SubGhzPresetDefinition* preset); /** * Deserialize data SubGhzProtocolDecoderHormann. diff --git a/lib/subghz/protocols/ido.c b/lib/subghz/protocols/ido.c index 2f5a9195..91446844 100644 --- a/lib/subghz/protocols/ido.c +++ b/lib/subghz/protocols/ido.c @@ -182,7 +182,7 @@ uint8_t subghz_protocol_decoder_ido_get_hash_data(void* context) { bool subghz_protocol_decoder_ido_serialize( void* context, FlipperFormat* flipper_format, - SubGhzPesetDefinition* preset) { + SubGhzPresetDefinition* preset) { furi_assert(context); SubGhzProtocolDecoderIDo* instance = context; return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); @@ -191,7 +191,18 @@ bool subghz_protocol_decoder_ido_serialize( bool subghz_protocol_decoder_ido_deserialize(void* context, FlipperFormat* flipper_format) { furi_assert(context); SubGhzProtocolDecoderIDo* instance = context; - return subghz_block_generic_deserialize(&instance->generic, flipper_format); + bool ret = false; + do { + if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { + break; + } + if(instance->generic.data_count_bit != subghz_protocol_ido_const.min_count_bit_for_found) { + FURI_LOG_E(TAG, "Wrong number of bits in key"); + break; + } + ret = true; + } while(false); + return ret; } void subghz_protocol_decoder_ido_get_string(void* context, string_t output) { diff --git a/lib/subghz/protocols/ido.h b/lib/subghz/protocols/ido.h index d2328218..4fe4e740 100644 --- a/lib/subghz/protocols/ido.h +++ b/lib/subghz/protocols/ido.h @@ -49,13 +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 preset The modulation on which the signal was received, SubGhzPesetDefinition + * @param preset The modulation on which the signal was received, SubGhzPresetDefinition * @return true On success */ bool subghz_protocol_decoder_ido_serialize( void* context, FlipperFormat* flipper_format, - SubGhzPesetDefinition* preset); + SubGhzPresetDefinition* preset); /** * Deserialize data SubGhzProtocolDecoderIDo. diff --git a/lib/subghz/protocols/keeloq.c b/lib/subghz/protocols/keeloq.c index de18e294..526a6b34 100644 --- a/lib/subghz/protocols/keeloq.c +++ b/lib/subghz/protocols/keeloq.c @@ -174,7 +174,7 @@ bool subghz_protocol_keeloq_create_data( uint8_t btn, uint16_t cnt, const char* manufacture_name, - SubGhzPesetDefinition* preset) { + SubGhzPresetDefinition* preset) { furi_assert(context); SubGhzProtocolEncoderKeeloq* instance = context; instance->generic.serial = serial; @@ -264,7 +264,11 @@ bool subghz_protocol_encoder_keeloq_deserialize(void* context, FlipperFormat* fl FURI_LOG_E(TAG, "Deserialize error"); break; } - + if(instance->generic.data_count_bit != + subghz_protocol_keeloq_const.min_count_bit_for_found) { + FURI_LOG_E(TAG, "Wrong number of bits in key"); + break; + } subghz_protocol_keeloq_check_remote_controller( &instance->generic, instance->keystore, &instance->manufacture_name); @@ -631,7 +635,7 @@ uint8_t subghz_protocol_decoder_keeloq_get_hash_data(void* context) { bool subghz_protocol_decoder_keeloq_serialize( void* context, FlipperFormat* flipper_format, - SubGhzPesetDefinition* preset) { + SubGhzPresetDefinition* preset) { furi_assert(context); SubGhzProtocolDecoderKeeloq* instance = context; subghz_protocol_keeloq_check_remote_controller( @@ -656,6 +660,11 @@ bool subghz_protocol_decoder_keeloq_deserialize(void* context, FlipperFormat* fl FURI_LOG_E(TAG, "Deserialize error"); break; } + if(instance->generic.data_count_bit != + subghz_protocol_keeloq_const.min_count_bit_for_found) { + FURI_LOG_E(TAG, "Wrong number of bits in key"); + break; + } res = true; } while(false); diff --git a/lib/subghz/protocols/keeloq.h b/lib/subghz/protocols/keeloq.h index 2a590b0d..e1485e5e 100644 --- a/lib/subghz/protocols/keeloq.h +++ b/lib/subghz/protocols/keeloq.h @@ -32,7 +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 preset Modulation, SubGhzPesetDefinition + * @param preset Modulation, SubGhzPresetDefinition * @return true On success */ bool subghz_protocol_keeloq_create_data( @@ -42,7 +42,7 @@ bool subghz_protocol_keeloq_create_data( uint8_t btn, uint16_t cnt, const char* manufacture_name, - SubGhzPesetDefinition* preset); + SubGhzPresetDefinition* preset); /** * Deserialize and generating an upload to send. @@ -103,13 +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 preset The modulation on which the signal was received, SubGhzPesetDefinition + * @param preset The modulation on which the signal was received, SubGhzPresetDefinition * @return true On success */ bool subghz_protocol_decoder_keeloq_serialize( void* context, FlipperFormat* flipper_format, - SubGhzPesetDefinition* preset); + SubGhzPresetDefinition* preset); /** * Deserialize data SubGhzProtocolDecoderKeeloq. diff --git a/lib/subghz/protocols/kia.c b/lib/subghz/protocols/kia.c index 069eb8f1..6fc10617 100644 --- a/lib/subghz/protocols/kia.c +++ b/lib/subghz/protocols/kia.c @@ -12,7 +12,7 @@ static const SubGhzBlockConst subghz_protocol_kia_const = { .te_short = 250, .te_long = 500, .te_delta = 100, - .min_count_bit_for_found = 60, + .min_count_bit_for_found = 61, }; struct SubGhzProtocolDecoderKIA { @@ -145,7 +145,7 @@ void subghz_protocol_decoder_kia_feed(void* context, bool level, uint32_t durati (uint32_t)(subghz_protocol_kia_const.te_long + subghz_protocol_kia_const.te_delta * 2)) { //Found stop bit instance->decoder.parser_step = KIADecoderStepReset; - if(instance->decoder.decode_count_bit >= + if(instance->decoder.decode_count_bit == subghz_protocol_kia_const.min_count_bit_for_found) { instance->generic.data = instance->decoder.decode_data; instance->generic.data_count_bit = instance->decoder.decode_count_bit; @@ -233,7 +233,7 @@ uint8_t subghz_protocol_decoder_kia_get_hash_data(void* context) { bool subghz_protocol_decoder_kia_serialize( void* context, FlipperFormat* flipper_format, - SubGhzPesetDefinition* preset) { + SubGhzPresetDefinition* preset) { furi_assert(context); SubGhzProtocolDecoderKIA* instance = context; return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); @@ -242,7 +242,18 @@ bool subghz_protocol_decoder_kia_serialize( bool subghz_protocol_decoder_kia_deserialize(void* context, FlipperFormat* flipper_format) { furi_assert(context); SubGhzProtocolDecoderKIA* instance = context; - return subghz_block_generic_deserialize(&instance->generic, flipper_format); + bool ret = false; + do { + if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { + break; + } + if(instance->generic.data_count_bit != subghz_protocol_kia_const.min_count_bit_for_found) { + FURI_LOG_E(TAG, "Wrong number of bits in key"); + break; + } + ret = true; + } while(false); + return ret; } void subghz_protocol_decoder_kia_get_string(void* context, string_t output) { diff --git a/lib/subghz/protocols/kia.h b/lib/subghz/protocols/kia.h index a3294046..743ab7cb 100644 --- a/lib/subghz/protocols/kia.h +++ b/lib/subghz/protocols/kia.h @@ -49,13 +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 preset The modulation on which the signal was received, SubGhzPesetDefinition + * @param preset The modulation on which the signal was received, SubGhzPresetDefinition * @return true On success */ bool subghz_protocol_decoder_kia_serialize( void* context, FlipperFormat* flipper_format, - SubGhzPesetDefinition* preset); + SubGhzPresetDefinition* preset); /** * Deserialize data SubGhzProtocolDecoderKIA. diff --git a/lib/subghz/protocols/linear.c b/lib/subghz/protocols/linear.c index a8c9dad6..c989a618 100644 --- a/lib/subghz/protocols/linear.c +++ b/lib/subghz/protocols/linear.c @@ -156,7 +156,11 @@ bool subghz_protocol_encoder_linear_deserialize(void* context, FlipperFormat* fl FURI_LOG_E(TAG, "Deserialize error"); break; } - + if(instance->generic.data_count_bit != + subghz_protocol_linear_const.min_count_bit_for_found) { + FURI_LOG_E(TAG, "Wrong number of bits in key"); + break; + } //optional parameter parameter flipper_format_read_uint32( flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); @@ -299,7 +303,7 @@ uint8_t subghz_protocol_decoder_linear_get_hash_data(void* context) { bool subghz_protocol_decoder_linear_serialize( void* context, FlipperFormat* flipper_format, - SubGhzPesetDefinition* preset) { + SubGhzPresetDefinition* preset) { furi_assert(context); SubGhzProtocolDecoderLinear* instance = context; return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); @@ -308,7 +312,19 @@ bool subghz_protocol_decoder_linear_serialize( bool subghz_protocol_decoder_linear_deserialize(void* context, FlipperFormat* flipper_format) { furi_assert(context); SubGhzProtocolDecoderLinear* instance = context; - return subghz_block_generic_deserialize(&instance->generic, flipper_format); + bool ret = false; + do { + if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { + break; + } + if(instance->generic.data_count_bit != + subghz_protocol_linear_const.min_count_bit_for_found) { + FURI_LOG_E(TAG, "Wrong number of bits in key"); + break; + } + ret = true; + } while(false); + return ret; } void subghz_protocol_decoder_linear_get_string(void* context, string_t output) { diff --git a/lib/subghz/protocols/linear.h b/lib/subghz/protocols/linear.h index 5060d444..035b130c 100644 --- a/lib/subghz/protocols/linear.h +++ b/lib/subghz/protocols/linear.h @@ -83,13 +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 preset The modulation on which the signal was received, SubGhzPesetDefinition + * @param preset The modulation on which the signal was received, SubGhzPresetDefinition * @return true On success */ bool subghz_protocol_decoder_linear_serialize( void* context, FlipperFormat* flipper_format, - SubGhzPesetDefinition* preset); + SubGhzPresetDefinition* preset); /** * Deserialize data SubGhzProtocolDecoderLinear. diff --git a/lib/subghz/protocols/megacode.c b/lib/subghz/protocols/megacode.c index 8a1f67b5..bfe1a76b 100644 --- a/lib/subghz/protocols/megacode.c +++ b/lib/subghz/protocols/megacode.c @@ -184,7 +184,11 @@ bool subghz_protocol_encoder_megacode_deserialize(void* context, FlipperFormat* FURI_LOG_E(TAG, "Deserialize error"); break; } - + if(instance->generic.data_count_bit != + subghz_protocol_megacode_const.min_count_bit_for_found) { + FURI_LOG_E(TAG, "Wrong number of bits in key"); + break; + } //optional parameter parameter flipper_format_read_uint32( flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); @@ -270,7 +274,7 @@ void subghz_protocol_decoder_megacode_feed(void* context, bool level, uint32_t d if(!level) { //save interval if(duration >= (subghz_protocol_megacode_const.te_short * 10)) { instance->decoder.parser_step = MegaCodeDecoderStepReset; - if(instance->decoder.decode_count_bit >= + if(instance->decoder.decode_count_bit == subghz_protocol_megacode_const.min_count_bit_for_found) { instance->generic.data = instance->decoder.decode_data; instance->generic.data_count_bit = instance->decoder.decode_count_bit; @@ -380,7 +384,7 @@ uint8_t subghz_protocol_decoder_megacode_get_hash_data(void* context) { bool subghz_protocol_decoder_megacode_serialize( void* context, FlipperFormat* flipper_format, - SubGhzPesetDefinition* preset) { + SubGhzPresetDefinition* preset) { furi_assert(context); SubGhzProtocolDecoderMegaCode* instance = context; return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); @@ -389,7 +393,19 @@ bool subghz_protocol_decoder_megacode_serialize( bool subghz_protocol_decoder_megacode_deserialize(void* context, FlipperFormat* flipper_format) { furi_assert(context); SubGhzProtocolDecoderMegaCode* instance = context; - return subghz_block_generic_deserialize(&instance->generic, flipper_format); + bool ret = false; + do { + if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { + break; + } + if(instance->generic.data_count_bit != + subghz_protocol_megacode_const.min_count_bit_for_found) { + FURI_LOG_E(TAG, "Wrong number of bits in key"); + break; + } + ret = true; + } while(false); + return ret; } void subghz_protocol_decoder_megacode_get_string(void* context, string_t output) { diff --git a/lib/subghz/protocols/megacode.h b/lib/subghz/protocols/megacode.h index f25011d7..c8010665 100644 --- a/lib/subghz/protocols/megacode.h +++ b/lib/subghz/protocols/megacode.h @@ -83,13 +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 preset The modulation on which the signal was received, SubGhzPesetDefinition + * @param preset The modulation on which the signal was received, SubGhzPresetDefinition * @return true On success */ bool subghz_protocol_decoder_megacode_serialize( void* context, FlipperFormat* flipper_format, - SubGhzPesetDefinition* preset); + SubGhzPresetDefinition* preset); /** * Deserialize data SubGhzProtocolDecoderMegaCode. diff --git a/lib/subghz/protocols/nero_radio.c b/lib/subghz/protocols/nero_radio.c index 7dcb5975..b6b1587f 100644 --- a/lib/subghz/protocols/nero_radio.c +++ b/lib/subghz/protocols/nero_radio.c @@ -163,7 +163,11 @@ bool subghz_protocol_encoder_nero_radio_deserialize(void* context, FlipperFormat FURI_LOG_E(TAG, "Deserialize error"); break; } - + if(instance->generic.data_count_bit != + subghz_protocol_nero_radio_const.min_count_bit_for_found) { + FURI_LOG_E(TAG, "Wrong number of bits in key"); + break; + } //optional parameter parameter flipper_format_read_uint32( flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); @@ -294,7 +298,7 @@ void subghz_protocol_decoder_nero_radio_feed(void* context, bool level, uint32_t subghz_protocol_blocks_add_bit(&instance->decoder, 1); } instance->decoder.parser_step = NeroRadioDecoderStepReset; - if(instance->decoder.decode_count_bit >= + if(instance->decoder.decode_count_bit == subghz_protocol_nero_radio_const.min_count_bit_for_found) { instance->generic.data = instance->decoder.decode_data; instance->generic.data_count_bit = instance->decoder.decode_count_bit; @@ -342,7 +346,7 @@ uint8_t subghz_protocol_decoder_nero_radio_get_hash_data(void* context) { bool subghz_protocol_decoder_nero_radio_serialize( void* context, FlipperFormat* flipper_format, - SubGhzPesetDefinition* preset) { + SubGhzPresetDefinition* preset) { furi_assert(context); SubGhzProtocolDecoderNeroRadio* instance = context; return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); @@ -351,7 +355,19 @@ bool subghz_protocol_decoder_nero_radio_serialize( bool subghz_protocol_decoder_nero_radio_deserialize(void* context, FlipperFormat* flipper_format) { furi_assert(context); SubGhzProtocolDecoderNeroRadio* instance = context; - return subghz_block_generic_deserialize(&instance->generic, flipper_format); + bool ret = false; + do { + if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { + break; + } + if(instance->generic.data_count_bit != + subghz_protocol_nero_radio_const.min_count_bit_for_found) { + FURI_LOG_E(TAG, "Wrong number of bits in key"); + break; + } + ret = true; + } while(false); + return ret; } void subghz_protocol_decoder_nero_radio_get_string(void* context, string_t output) { diff --git a/lib/subghz/protocols/nero_radio.h b/lib/subghz/protocols/nero_radio.h index f1c540d5..f04dc2b3 100644 --- a/lib/subghz/protocols/nero_radio.h +++ b/lib/subghz/protocols/nero_radio.h @@ -83,13 +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 preset The modulation on which the signal was received, SubGhzPesetDefinition + * @param preset The modulation on which the signal was received, SubGhzPresetDefinition * @return true On success */ bool subghz_protocol_decoder_nero_radio_serialize( void* context, FlipperFormat* flipper_format, - SubGhzPesetDefinition* preset); + SubGhzPresetDefinition* preset); /** * Deserialize data SubGhzProtocolDecoderNeroRadio. diff --git a/lib/subghz/protocols/nero_sketch.c b/lib/subghz/protocols/nero_sketch.c index a4e9f2cf..0b87ec11 100644 --- a/lib/subghz/protocols/nero_sketch.c +++ b/lib/subghz/protocols/nero_sketch.c @@ -157,7 +157,11 @@ bool subghz_protocol_encoder_nero_sketch_deserialize(void* context, FlipperForma FURI_LOG_E(TAG, "Deserialize error"); break; } - + if(instance->generic.data_count_bit != + subghz_protocol_nero_sketch_const.min_count_bit_for_found) { + FURI_LOG_E(TAG, "Wrong number of bits in key"); + break; + } //optional parameter parameter flipper_format_read_uint32( flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); @@ -271,7 +275,7 @@ void subghz_protocol_decoder_nero_sketch_feed(void* context, bool level, uint32_ subghz_protocol_nero_sketch_const.te_delta * 2)) { //Found stop bit instance->decoder.parser_step = NeroSketchDecoderStepReset; - if(instance->decoder.decode_count_bit >= + if(instance->decoder.decode_count_bit == subghz_protocol_nero_sketch_const.min_count_bit_for_found) { instance->generic.data = instance->decoder.decode_data; instance->generic.data_count_bit = instance->decoder.decode_count_bit; @@ -327,7 +331,7 @@ uint8_t subghz_protocol_decoder_nero_sketch_get_hash_data(void* context) { bool subghz_protocol_decoder_nero_sketch_serialize( void* context, FlipperFormat* flipper_format, - SubGhzPesetDefinition* preset) { + SubGhzPresetDefinition* preset) { furi_assert(context); SubGhzProtocolDecoderNeroSketch* instance = context; return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); @@ -336,7 +340,19 @@ bool subghz_protocol_decoder_nero_sketch_serialize( bool subghz_protocol_decoder_nero_sketch_deserialize(void* context, FlipperFormat* flipper_format) { furi_assert(context); SubGhzProtocolDecoderNeroSketch* instance = context; - return subghz_block_generic_deserialize(&instance->generic, flipper_format); + bool ret = false; + do { + if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { + break; + } + if(instance->generic.data_count_bit != + subghz_protocol_nero_sketch_const.min_count_bit_for_found) { + FURI_LOG_E(TAG, "Wrong number of bits in key"); + break; + } + ret = true; + } while(false); + return ret; } void subghz_protocol_decoder_nero_sketch_get_string(void* context, string_t output) { diff --git a/lib/subghz/protocols/nero_sketch.h b/lib/subghz/protocols/nero_sketch.h index af93a9d9..ab592b48 100644 --- a/lib/subghz/protocols/nero_sketch.h +++ b/lib/subghz/protocols/nero_sketch.h @@ -83,13 +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 preset The modulation on which the signal was received, SubGhzPesetDefinition + * @param preset The modulation on which the signal was received, SubGhzPresetDefinition * @return true On success */ bool subghz_protocol_decoder_nero_sketch_serialize( void* context, FlipperFormat* flipper_format, - SubGhzPesetDefinition* preset); + SubGhzPresetDefinition* preset); /** * Deserialize data SubGhzProtocolDecoderNeroSketch. diff --git a/lib/subghz/protocols/nice_flo.c b/lib/subghz/protocols/nice_flo.c index 1b8e0308..236b4222 100644 --- a/lib/subghz/protocols/nice_flo.c +++ b/lib/subghz/protocols/nice_flo.c @@ -138,7 +138,13 @@ bool subghz_protocol_encoder_nice_flo_deserialize(void* context, FlipperFormat* FURI_LOG_E(TAG, "Deserialize error"); break; } - + if((instance->generic.data_count_bit != + subghz_protocol_nice_flo_const.min_count_bit_for_found) && + (instance->generic.data_count_bit != + 2 * subghz_protocol_nice_flo_const.min_count_bit_for_found)) { + FURI_LOG_E(TAG, "Wrong number of bits in key"); + break; + } //optional parameter parameter flipper_format_read_uint32( flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); @@ -277,7 +283,7 @@ uint8_t subghz_protocol_decoder_nice_flo_get_hash_data(void* context) { bool subghz_protocol_decoder_nice_flo_serialize( void* context, FlipperFormat* flipper_format, - SubGhzPesetDefinition* preset) { + SubGhzPresetDefinition* preset) { furi_assert(context); SubGhzProtocolDecoderNiceFlo* instance = context; return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); @@ -286,7 +292,21 @@ bool subghz_protocol_decoder_nice_flo_serialize( bool subghz_protocol_decoder_nice_flo_deserialize(void* context, FlipperFormat* flipper_format) { furi_assert(context); SubGhzProtocolDecoderNiceFlo* instance = context; - return subghz_block_generic_deserialize(&instance->generic, flipper_format); + bool ret = false; + do { + if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { + break; + } + if((instance->generic.data_count_bit != + subghz_protocol_nice_flo_const.min_count_bit_for_found) && + (instance->generic.data_count_bit != + 2 * subghz_protocol_nice_flo_const.min_count_bit_for_found)) { + FURI_LOG_E(TAG, "Wrong number of bits in key"); + break; + } + ret = true; + } while(false); + return ret; } void subghz_protocol_decoder_nice_flo_get_string(void* context, string_t output) { diff --git a/lib/subghz/protocols/nice_flo.h b/lib/subghz/protocols/nice_flo.h index f7d48dfa..0873e81b 100644 --- a/lib/subghz/protocols/nice_flo.h +++ b/lib/subghz/protocols/nice_flo.h @@ -83,13 +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 preset The modulation on which the signal was received, SubGhzPesetDefinition + * @param preset The modulation on which the signal was received, SubGhzPresetDefinition * @return true On success */ bool subghz_protocol_decoder_nice_flo_serialize( void* context, FlipperFormat* flipper_format, - SubGhzPesetDefinition* preset); + SubGhzPresetDefinition* preset); /** * Deserialize data SubGhzProtocolDecoderNiceFlo. diff --git a/lib/subghz/protocols/nice_flor_s.c b/lib/subghz/protocols/nice_flor_s.c index 381e7bd1..1d370e85 100644 --- a/lib/subghz/protocols/nice_flor_s.c +++ b/lib/subghz/protocols/nice_flor_s.c @@ -237,7 +237,7 @@ void subghz_protocol_decoder_nice_flor_s_feed(void* context, bool level, uint32_ subghz_protocol_nice_flor_s_const.te_delta) { //Found STOP bit instance->decoder.parser_step = NiceFlorSDecoderStepReset; - if(instance->decoder.decode_count_bit >= + if(instance->decoder.decode_count_bit == subghz_protocol_nice_flor_s_const.min_count_bit_for_found) { instance->generic.data = instance->decoder.decode_data; instance->generic.data_count_bit = instance->decoder.decode_count_bit; @@ -330,7 +330,7 @@ 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, - SubGhzPesetDefinition* preset) { + SubGhzPresetDefinition* preset) { furi_assert(context); SubGhzProtocolDecoderNiceFlorS* instance = context; return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); @@ -339,7 +339,19 @@ bool subghz_protocol_decoder_nice_flor_s_serialize( bool subghz_protocol_decoder_nice_flor_s_deserialize(void* context, FlipperFormat* flipper_format) { furi_assert(context); SubGhzProtocolDecoderNiceFlorS* instance = context; - return subghz_block_generic_deserialize(&instance->generic, flipper_format); + bool ret = false; + do { + if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { + break; + } + if(instance->generic.data_count_bit != + subghz_protocol_nice_flor_s_const.min_count_bit_for_found) { + FURI_LOG_E(TAG, "Wrong number of bits in key"); + break; + } + ret = true; + } while(false); + return ret; } void subghz_protocol_decoder_nice_flor_s_get_string(void* context, string_t output) { diff --git a/lib/subghz/protocols/nice_flor_s.h b/lib/subghz/protocols/nice_flor_s.h index fc27da38..7d98876f 100644 --- a/lib/subghz/protocols/nice_flor_s.h +++ b/lib/subghz/protocols/nice_flor_s.h @@ -49,13 +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 preset The modulation on which the signal was received, SubGhzPesetDefinition + * @param preset The modulation on which the signal was received, SubGhzPresetDefinition * @return true On success */ bool subghz_protocol_decoder_nice_flor_s_serialize( void* context, FlipperFormat* flipper_format, - SubGhzPesetDefinition* preset); + SubGhzPresetDefinition* preset); /** * Deserialize data SubGhzProtocolDecoderNiceFlorS. diff --git a/lib/subghz/protocols/power_smart.c b/lib/subghz/protocols/power_smart.c index 3c356ff8..53e9f338 100644 --- a/lib/subghz/protocols/power_smart.c +++ b/lib/subghz/protocols/power_smart.c @@ -201,7 +201,11 @@ bool subghz_protocol_encoder_power_smart_deserialize(void* context, FlipperForma FURI_LOG_E(TAG, "Deserialize error"); break; } - + if(instance->generic.data_count_bit != + subghz_protocol_power_smart_const.min_count_bit_for_found) { + FURI_LOG_E(TAG, "Wrong number of bits in key"); + break; + } //optional parameter parameter flipper_format_read_uint32( flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); @@ -345,7 +349,7 @@ uint8_t subghz_protocol_decoder_power_smart_get_hash_data(void* context) { bool subghz_protocol_decoder_power_smart_serialize( void* context, FlipperFormat* flipper_format, - SubGhzPesetDefinition* preset) { + SubGhzPresetDefinition* preset) { furi_assert(context); SubGhzProtocolDecoderPowerSmart* instance = context; return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); @@ -354,7 +358,19 @@ bool subghz_protocol_decoder_power_smart_serialize( bool subghz_protocol_decoder_power_smart_deserialize(void* context, FlipperFormat* flipper_format) { furi_assert(context); SubGhzProtocolDecoderPowerSmart* instance = context; - return subghz_block_generic_deserialize(&instance->generic, flipper_format); + bool ret = false; + do { + if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { + break; + } + if(instance->generic.data_count_bit != + subghz_protocol_power_smart_const.min_count_bit_for_found) { + FURI_LOG_E(TAG, "Wrong number of bits in key"); + break; + } + ret = true; + } while(false); + return ret; } void subghz_protocol_decoder_power_smart_get_string(void* context, string_t output) { diff --git a/lib/subghz/protocols/power_smart.h b/lib/subghz/protocols/power_smart.h index e6445ca4..f6e9571b 100644 --- a/lib/subghz/protocols/power_smart.h +++ b/lib/subghz/protocols/power_smart.h @@ -83,13 +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 preset The modulation on which the signal was received, SubGhzPesetDefinition + * @param preset The modulation on which the signal was received, SubGhzPresetDefinition * @return true On success */ bool subghz_protocol_decoder_power_smart_serialize( void* context, FlipperFormat* flipper_format, - SubGhzPesetDefinition* preset); + SubGhzPresetDefinition* preset); /** * Deserialize data SubGhzProtocolDecoderPowerSmart. diff --git a/lib/subghz/protocols/princeton.c b/lib/subghz/protocols/princeton.c index ce34d32c..0f100137 100644 --- a/lib/subghz/protocols/princeton.c +++ b/lib/subghz/protocols/princeton.c @@ -158,6 +158,11 @@ bool subghz_protocol_encoder_princeton_deserialize(void* context, FlipperFormat* FURI_LOG_E(TAG, "Missing TE"); break; } + if(instance->generic.data_count_bit != + subghz_protocol_princeton_const.min_count_bit_for_found) { + FURI_LOG_E(TAG, "Wrong number of bits in key"); + break; + } //optional parameter parameter flipper_format_read_uint32( flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); @@ -300,7 +305,7 @@ uint8_t subghz_protocol_decoder_princeton_get_hash_data(void* context) { bool subghz_protocol_decoder_princeton_serialize( void* context, FlipperFormat* flipper_format, - SubGhzPesetDefinition* preset) { + SubGhzPresetDefinition* preset) { furi_assert(context); SubGhzProtocolDecoderPrinceton* instance = context; bool res = subghz_block_generic_serialize(&instance->generic, flipper_format, preset); @@ -320,6 +325,11 @@ bool subghz_protocol_decoder_princeton_deserialize(void* context, FlipperFormat* FURI_LOG_E(TAG, "Deserialize error"); break; } + if(instance->generic.data_count_bit != + subghz_protocol_princeton_const.min_count_bit_for_found) { + FURI_LOG_E(TAG, "Wrong number of bits in key"); + break; + } if(!flipper_format_rewind(flipper_format)) { FURI_LOG_E(TAG, "Rewind error"); break; diff --git a/lib/subghz/protocols/princeton.h b/lib/subghz/protocols/princeton.h index fb126f2d..9c296c4a 100644 --- a/lib/subghz/protocols/princeton.h +++ b/lib/subghz/protocols/princeton.h @@ -83,13 +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 preset The modulation on which the signal was received, SubGhzPesetDefinition + * @param preset The modulation on which the signal was received, SubGhzPresetDefinition * @return true On success */ bool subghz_protocol_decoder_princeton_serialize( void* context, FlipperFormat* flipper_format, - SubGhzPesetDefinition* preset); + SubGhzPresetDefinition* preset); /** * Deserialize data SubGhzProtocolDecoderPrinceton. diff --git a/lib/subghz/protocols/raw.c b/lib/subghz/protocols/raw.c index 92f20438..9ab649a7 100644 --- a/lib/subghz/protocols/raw.c +++ b/lib/subghz/protocols/raw.c @@ -57,6 +57,7 @@ const SubGhzProtocolDecoder subghz_protocol_raw_decoder = { .get_hash_data = NULL, .serialize = NULL, + .deserialize = subghz_protocol_decoder_raw_deserialize, .get_string = subghz_protocol_decoder_raw_get_string, }; @@ -83,7 +84,7 @@ const SubGhzProtocol subghz_protocol_raw = { bool subghz_protocol_raw_save_to_file_init( SubGhzProtocolDecoderRAW* instance, const char* dev_name, - SubGhzPesetDefinition* preset) { + SubGhzPresetDefinition* preset) { furi_assert(instance); instance->storage = furi_record_open(RECORD_STORAGE); @@ -246,9 +247,18 @@ void subghz_protocol_decoder_raw_feed(void* context, bool level, uint32_t durati } } +bool subghz_protocol_decoder_raw_deserialize(void* context, FlipperFormat* flipper_format) { + furi_assert(context); + UNUSED(context); + UNUSED(flipper_format); + //ToDo stub, for backwards compatibility + return true; +} + void subghz_protocol_decoder_raw_get_string(void* context, string_t output) { furi_assert(context); //SubGhzProtocolDecoderRAW* instance = context; + UNUSED(context); //ToDo no use string_cat_printf(output, "RAW Date"); } diff --git a/lib/subghz/protocols/raw.h b/lib/subghz/protocols/raw.h index a6435d33..00654ad2 100644 --- a/lib/subghz/protocols/raw.h +++ b/lib/subghz/protocols/raw.h @@ -17,13 +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 preset The modulation on which the signal was received, SubGhzPesetDefinition + * @param preset The modulation on which the signal was received, SubGhzPresetDefinition * @return true On success */ bool subghz_protocol_raw_save_to_file_init( SubGhzProtocolDecoderRAW* instance, const char* dev_name, - SubGhzPesetDefinition* preset); + SubGhzPresetDefinition* preset); /** * Stop writing file to flash @@ -65,6 +65,14 @@ void subghz_protocol_decoder_raw_reset(void* context); */ void subghz_protocol_decoder_raw_feed(void* context, bool level, uint32_t duration); +/** + * Deserialize data SubGhzProtocolDecoderRAW. + * @param context Pointer to a SubGhzProtocolDecoderRAW instance + * @param flipper_format Pointer to a FlipperFormat instance + * @return true On success + */ +bool subghz_protocol_decoder_raw_deserialize(void* context, FlipperFormat* flipper_format); + /** * Getting a textual representation of the received data. * @param context Pointer to a SubGhzProtocolDecoderRAW instance diff --git a/lib/subghz/protocols/scher_khan.c b/lib/subghz/protocols/scher_khan.c index 7c9aa6a7..dd8d4c8f 100644 --- a/lib/subghz/protocols/scher_khan.c +++ b/lib/subghz/protocols/scher_khan.c @@ -251,7 +251,7 @@ uint8_t subghz_protocol_decoder_scher_khan_get_hash_data(void* context) { bool subghz_protocol_decoder_scher_khan_serialize( void* context, FlipperFormat* flipper_format, - SubGhzPesetDefinition* preset) { + SubGhzPresetDefinition* preset) { furi_assert(context); SubGhzProtocolDecoderScherKhan* instance = context; return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); diff --git a/lib/subghz/protocols/scher_khan.h b/lib/subghz/protocols/scher_khan.h index b22e8934..391ccc41 100644 --- a/lib/subghz/protocols/scher_khan.h +++ b/lib/subghz/protocols/scher_khan.h @@ -49,13 +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 preset The modulation on which the signal was received, SubGhzPesetDefinition + * @param preset The modulation on which the signal was received, SubGhzPresetDefinition * @return true On success */ bool subghz_protocol_decoder_scher_khan_serialize( void* context, FlipperFormat* flipper_format, - SubGhzPesetDefinition* preset); + SubGhzPresetDefinition* preset); /** * Deserialize data SubGhzProtocolDecoderScherKhan. diff --git a/lib/subghz/protocols/secplus_v1.c b/lib/subghz/protocols/secplus_v1.c index 119c0307..25c35ce5 100644 --- a/lib/subghz/protocols/secplus_v1.c +++ b/lib/subghz/protocols/secplus_v1.c @@ -273,7 +273,11 @@ bool subghz_protocol_encoder_secplus_v1_deserialize(void* context, FlipperFormat FURI_LOG_E(TAG, "Deserialize error"); break; } - + if(instance->generic.data_count_bit != + 2 * subghz_protocol_secplus_v1_const.min_count_bit_for_found) { + FURI_LOG_E(TAG, "Wrong number of bits in key"); + break; + } //optional parameter parameter flipper_format_read_uint32( flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); @@ -515,7 +519,7 @@ uint8_t subghz_protocol_decoder_secplus_v1_get_hash_data(void* context) { bool subghz_protocol_decoder_secplus_v1_serialize( void* context, FlipperFormat* flipper_format, - SubGhzPesetDefinition* preset) { + SubGhzPresetDefinition* preset) { furi_assert(context); SubGhzProtocolDecoderSecPlus_v1* instance = context; return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); @@ -524,7 +528,19 @@ bool subghz_protocol_decoder_secplus_v1_serialize( bool subghz_protocol_decoder_secplus_v1_deserialize(void* context, FlipperFormat* flipper_format) { furi_assert(context); SubGhzProtocolDecoderSecPlus_v1* instance = context; - return subghz_block_generic_deserialize(&instance->generic, flipper_format); + bool ret = false; + do { + if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { + break; + } + if(instance->generic.data_count_bit != + 2 * subghz_protocol_secplus_v1_const.min_count_bit_for_found) { + FURI_LOG_E(TAG, "Wrong number of bits in key"); + break; + } + ret = true; + } while(false); + return ret; } bool subghz_protocol_secplus_v1_check_fixed(uint32_t fixed) { diff --git a/lib/subghz/protocols/secplus_v1.h b/lib/subghz/protocols/secplus_v1.h index 5447e3f8..8ae1c0cb 100644 --- a/lib/subghz/protocols/secplus_v1.h +++ b/lib/subghz/protocols/secplus_v1.h @@ -82,13 +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 preset The modulation on which the signal was received, SubGhzPesetDefinition + * @param preset The modulation on which the signal was received, SubGhzPresetDefinition * @return true On success */ bool subghz_protocol_decoder_secplus_v1_serialize( void* context, FlipperFormat* flipper_format, - SubGhzPesetDefinition* preset); + SubGhzPresetDefinition* preset); /** * Deserialize data SubGhzProtocolDecoderSecPlus_v1. diff --git a/lib/subghz/protocols/secplus_v2.c b/lib/subghz/protocols/secplus_v2.c index 837b2638..37dc1c82 100644 --- a/lib/subghz/protocols/secplus_v2.c +++ b/lib/subghz/protocols/secplus_v2.c @@ -514,7 +514,11 @@ bool subghz_protocol_encoder_secplus_v2_deserialize(void* context, FlipperFormat FURI_LOG_E(TAG, "Deserialize error"); break; } - + if(instance->generic.data_count_bit != + subghz_protocol_secplus_v2_const.min_count_bit_for_found) { + FURI_LOG_E(TAG, "Wrong number of bits in key"); + break; + } uint8_t key_data[sizeof(uint64_t)] = {0}; if(!flipper_format_read_hex( flipper_format, "Secplus_packet_1", key_data, sizeof(uint64_t))) { @@ -588,7 +592,7 @@ bool subghz_protocol_secplus_v2_create_data( uint32_t serial, uint8_t btn, uint32_t cnt, - SubGhzPesetDefinition* preset) { + SubGhzPresetDefinition* preset) { furi_assert(context); SubGhzProtocolEncoderSecPlus_v2* instance = context; instance->generic.serial = serial; @@ -689,7 +693,7 @@ void subghz_protocol_decoder_secplus_v2_feed(void* context, bool level, uint32_t } else if( duration >= (uint32_t)(subghz_protocol_secplus_v2_const.te_long * 2 + subghz_protocol_secplus_v2_const.te_delta)) { - if(instance->decoder.decode_count_bit >= + if(instance->decoder.decode_count_bit == subghz_protocol_secplus_v2_const.min_count_bit_for_found) { instance->generic.data = instance->decoder.decode_data; instance->generic.data_count_bit = instance->decoder.decode_count_bit; @@ -755,7 +759,7 @@ uint8_t subghz_protocol_decoder_secplus_v2_get_hash_data(void* context) { bool subghz_protocol_decoder_secplus_v2_serialize( void* context, FlipperFormat* flipper_format, - SubGhzPesetDefinition* preset) { + SubGhzPresetDefinition* preset) { furi_assert(context); SubGhzProtocolDecoderSecPlus_v2* instance = context; bool res = subghz_block_generic_serialize(&instance->generic, flipper_format, preset); @@ -782,6 +786,11 @@ bool subghz_protocol_decoder_secplus_v2_deserialize(void* context, FlipperFormat FURI_LOG_E(TAG, "Deserialize error"); break; } + if(instance->generic.data_count_bit != + subghz_protocol_secplus_v2_const.min_count_bit_for_found) { + FURI_LOG_E(TAG, "Wrong number of bits in key"); + break; + } if(!flipper_format_rewind(flipper_format)) { FURI_LOG_E(TAG, "Rewind error"); break; diff --git a/lib/subghz/protocols/secplus_v2.h b/lib/subghz/protocols/secplus_v2.h index 43bce629..9e9ae2a7 100644 --- a/lib/subghz/protocols/secplus_v2.h +++ b/lib/subghz/protocols/secplus_v2.h @@ -52,7 +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 preset Modulation, SubGhzPesetDefinition + * @param preset Modulation, SubGhzPresetDefinition * @return true On success */ bool subghz_protocol_secplus_v2_create_data( @@ -61,7 +61,7 @@ bool subghz_protocol_secplus_v2_create_data( uint32_t serial, uint8_t btn, uint32_t cnt, - SubGhzPesetDefinition* preset); + SubGhzPresetDefinition* preset); /** * Allocate SubGhzProtocolDecoderSecPlus_v2. @@ -101,13 +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 preset The modulation on which the signal was received, SubGhzPesetDefinition + * @param preset The modulation on which the signal was received, SubGhzPresetDefinition * @return true On success */ bool subghz_protocol_decoder_secplus_v2_serialize( void* context, FlipperFormat* flipper_format, - SubGhzPesetDefinition* preset); + SubGhzPresetDefinition* preset); /** * Deserialize data SubGhzProtocolDecoderSecPlus_v2. diff --git a/lib/subghz/protocols/somfy_keytis.c b/lib/subghz/protocols/somfy_keytis.c index d2df9eff..7a3b2186 100644 --- a/lib/subghz/protocols/somfy_keytis.c +++ b/lib/subghz/protocols/somfy_keytis.c @@ -382,7 +382,7 @@ uint8_t subghz_protocol_decoder_somfy_keytis_get_hash_data(void* context) { bool subghz_protocol_decoder_somfy_keytis_serialize( void* context, FlipperFormat* flipper_format, - SubGhzPesetDefinition* preset) { + SubGhzPresetDefinition* preset) { furi_assert(context); SubGhzProtocolDecoderSomfyKeytis* instance = context; bool res = subghz_block_generic_serialize(&instance->generic, flipper_format, preset); @@ -403,6 +403,11 @@ bool subghz_protocol_decoder_somfy_keytis_deserialize(void* context, FlipperForm FURI_LOG_E(TAG, "Deserialize error"); break; } + if(instance->generic.data_count_bit != + subghz_protocol_somfy_keytis_const.min_count_bit_for_found) { + FURI_LOG_E(TAG, "Wrong number of bits in key"); + break; + } if(!flipper_format_rewind(flipper_format)) { FURI_LOG_E(TAG, "Rewind error"); break; diff --git a/lib/subghz/protocols/somfy_keytis.h b/lib/subghz/protocols/somfy_keytis.h index 46193994..29f96cd6 100644 --- a/lib/subghz/protocols/somfy_keytis.h +++ b/lib/subghz/protocols/somfy_keytis.h @@ -49,13 +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 preset The modulation on which the signal was received, SubGhzPesetDefinition + * @param preset The modulation on which the signal was received, SubGhzPresetDefinition * @return true On success */ bool subghz_protocol_decoder_somfy_keytis_serialize( void* context, FlipperFormat* flipper_format, - SubGhzPesetDefinition* preset); + SubGhzPresetDefinition* preset); /** * Deserialize data SubGhzProtocolDecoderSomfyKeytis. diff --git a/lib/subghz/protocols/somfy_telis.c b/lib/subghz/protocols/somfy_telis.c index 039cb8ee..b9aac577 100644 --- a/lib/subghz/protocols/somfy_telis.c +++ b/lib/subghz/protocols/somfy_telis.c @@ -339,7 +339,7 @@ uint8_t subghz_protocol_decoder_somfy_telis_get_hash_data(void* context) { bool subghz_protocol_decoder_somfy_telis_serialize( void* context, FlipperFormat* flipper_format, - SubGhzPesetDefinition* preset) { + SubGhzPresetDefinition* preset) { furi_assert(context); SubGhzProtocolDecoderSomfyTelis* instance = context; return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); @@ -348,7 +348,19 @@ bool subghz_protocol_decoder_somfy_telis_serialize( bool subghz_protocol_decoder_somfy_telis_deserialize(void* context, FlipperFormat* flipper_format) { furi_assert(context); SubGhzProtocolDecoderSomfyTelis* instance = context; - return subghz_block_generic_deserialize(&instance->generic, flipper_format); + bool ret = false; + do { + if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { + break; + } + if(instance->generic.data_count_bit != + subghz_protocol_somfy_telis_const.min_count_bit_for_found) { + FURI_LOG_E(TAG, "Wrong number of bits in key"); + break; + } + ret = true; + } while(false); + return ret; } void subghz_protocol_decoder_somfy_telis_get_string(void* context, string_t output) { diff --git a/lib/subghz/protocols/somfy_telis.h b/lib/subghz/protocols/somfy_telis.h index ce474769..ff5b45e2 100644 --- a/lib/subghz/protocols/somfy_telis.h +++ b/lib/subghz/protocols/somfy_telis.h @@ -49,13 +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 preset The modulation on which the signal was received, SubGhzPesetDefinition + * @param preset The modulation on which the signal was received, SubGhzPresetDefinition * @return true On success */ bool subghz_protocol_decoder_somfy_telis_serialize( void* context, FlipperFormat* flipper_format, - SubGhzPesetDefinition* preset); + SubGhzPresetDefinition* preset); /** * Deserialize data SubGhzProtocolDecoderSomfyTelis. diff --git a/lib/subghz/protocols/star_line.c b/lib/subghz/protocols/star_line.c index 4492338a..757b5662 100644 --- a/lib/subghz/protocols/star_line.c +++ b/lib/subghz/protocols/star_line.c @@ -320,7 +320,7 @@ uint8_t subghz_protocol_decoder_star_line_get_hash_data(void* context) { bool subghz_protocol_decoder_star_line_serialize( void* context, FlipperFormat* flipper_format, - SubGhzPesetDefinition* preset) { + SubGhzPresetDefinition* preset) { furi_assert(context); SubGhzProtocolDecoderStarLine* instance = context; subghz_protocol_star_line_check_remote_controller( @@ -332,6 +332,11 @@ bool subghz_protocol_decoder_star_line_serialize( FURI_LOG_E(TAG, "Unable to add manufacture name"); res = false; } + if(res && instance->generic.data_count_bit != + subghz_protocol_star_line_const.min_count_bit_for_found) { + FURI_LOG_E(TAG, "Wrong number of bits in key"); + res = false; + } return res; } diff --git a/lib/subghz/protocols/star_line.h b/lib/subghz/protocols/star_line.h index b48f1c21..e240954b 100644 --- a/lib/subghz/protocols/star_line.h +++ b/lib/subghz/protocols/star_line.h @@ -49,13 +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 preset The modulation on which the signal was received, SubGhzPesetDefinition + * @param preset The modulation on which the signal was received, SubGhzPresetDefinition * @return true On success */ bool subghz_protocol_decoder_star_line_serialize( void* context, FlipperFormat* flipper_format, - SubGhzPesetDefinition* preset); + SubGhzPresetDefinition* preset); /** * Deserialize data SubGhzProtocolDecoderStarLine. diff --git a/lib/subghz/types.h b/lib/subghz/types.h index 41a04cb1..32b70b65 100644 --- a/lib/subghz/types.h +++ b/lib/subghz/types.h @@ -31,8 +31,10 @@ typedef void* (*SubGhzAlloc)(SubGhzEnvironment* environment); typedef void (*SubGhzFree)(void* context); // Serialize and Deserialize -typedef bool ( - *SubGhzSerialize)(void* context, FlipperFormat* flipper_format, SubGhzPesetDefinition* preset); +typedef bool (*SubGhzSerialize)( + void* context, + FlipperFormat* flipper_format, + SubGhzPresetDefinition* preset); typedef bool (*SubGhzDeserialize)(void* context, FlipperFormat* flipper_format); // Decoder specific diff --git a/lib/toolbox/stream/buffered_file_stream.c b/lib/toolbox/stream/buffered_file_stream.c index 5db276d3..2f2359a0 100644 --- a/lib/toolbox/stream/buffered_file_stream.c +++ b/lib/toolbox/stream/buffered_file_stream.c @@ -1,5 +1,6 @@ #include "buffered_file_stream.h" +#include "core/check.h" #include "stream_i.h" #include "file_stream.h" #include "stream_cache.h" @@ -38,6 +39,8 @@ const StreamVTable buffered_file_stream_vtable = { .delete_and_insert = (StreamDeleteAndInsertFn)buffered_file_stream_delete_and_insert, }; +static bool buffered_file_stream_unread(BufferedFileStream* stream); + Stream* buffered_file_stream_alloc(Storage* storage) { BufferedFileStream* stream = malloc(sizeof(BufferedFileStream)); @@ -125,8 +128,12 @@ 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) { - stream_cache_drop(stream->cache); - return stream_write(stream->file_stream, data, size); + size_t need_to_write = size; + do { + if(!buffered_file_stream_unread(stream)) break; + need_to_write -= stream_write(stream->file_stream, data, size); + } while(false); + return size - need_to_write; } static size_t buffered_file_stream_read(BufferedFileStream* stream, uint8_t* data, size_t size) { @@ -150,6 +157,19 @@ static bool buffered_file_stream_delete_and_insert( 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); + return buffered_file_stream_unread(stream) && + stream_delete_and_insert(stream->file_stream, delete_size, write_callback, ctx); +} + +// Drop read cache and adjust the underlying stream seek position +static bool buffered_file_stream_unread(BufferedFileStream* stream) { + bool success = true; + const size_t cache_size = stream_cache_size(stream->cache); + const size_t cache_pos = stream_cache_pos(stream->cache); + if(cache_pos < cache_size) { + const int32_t offset = cache_size - cache_pos; + success = stream_seek(stream->file_stream, -offset, StreamOffsetFromCurrent); + } + stream_cache_drop(stream->cache); + return success; } diff --git a/scripts/flipper/storage.py b/scripts/flipper/storage.py index 3d1b46b9..5fa8a2c8 100644 --- a/scripts/flipper/storage.py +++ b/scripts/flipper/storage.py @@ -53,13 +53,14 @@ class FlipperStorage: CLI_PROMPT = ">: " CLI_EOL = "\r\n" - def __init__(self, portname: str, portbaud: int = 115200): + def __init__(self, portname: str, chunk_size: int = 8192): self.port = serial.Serial() self.port.port = portname self.port.timeout = 2 - self.port.baudrate = portbaud + self.port.baudrate = 115200 # Doesn't matter for VCP self.read = BufferedRead(self.port) self.last_error = "" + self.chunk_size = chunk_size def start(self): self.port.open() @@ -192,7 +193,7 @@ class FlipperStorage: with open(filename_from, "rb") as file: filesize = os.fstat(file.fileno()).st_size - buffer_size = 512 + buffer_size = self.chunk_size while True: filedata = file.read(buffer_size) size = len(filedata) @@ -221,7 +222,7 @@ class FlipperStorage: def read_file(self, filename): """Receive file from Flipper, and get filedata (bytes)""" - buffer_size = 512 + buffer_size = self.chunk_size self.send_and_wait_eol( 'storage read_chunks "' + filename + '" ' + str(buffer_size) + "\r" ) @@ -355,7 +356,7 @@ class FlipperStorage: """Hash of local file""" hash_md5 = hashlib.md5() with open(filename, "rb") as f: - for chunk in iter(lambda: f.read(4096), b""): + for chunk in iter(lambda: f.read(self.chunk_size), b""): hash_md5.update(chunk) return hash_md5.hexdigest() diff --git a/scripts/selfupdate.py b/scripts/selfupdate.py index 6d705747..1c16c5ca 100644 --- a/scripts/selfupdate.py +++ b/scripts/selfupdate.py @@ -14,14 +14,6 @@ import serial.tools.list_ports as list_ports class Main(App): def init(self): self.parser.add_argument("-p", "--port", help="CDC Port", default="auto") - self.parser.add_argument( - "-b", - "--baud", - help="Port Baud rate", - required=False, - default=115200 * 4, - type=int, - ) self.parser.add_argument("manifest_path", help="Manifest path") self.parser.add_argument( @@ -64,7 +56,7 @@ class Main(App): if not (port := resolve_port(self.logger, self.args.port)): return 1 - storage = FlipperStorage(port, self.args.baud) + storage = FlipperStorage(port) storage.start() try: @@ -99,6 +91,7 @@ class Main(App): self.logger.error(f"Error: {storage.last_error}") return -3 + # return -11 storage.send_and_wait_eol( f"update install {flipper_update_path}/{manifest_name}\r" ) diff --git a/scripts/serial_cli.py b/scripts/serial_cli.py new file mode 100644 index 00000000..e07e6bfb --- /dev/null +++ b/scripts/serial_cli.py @@ -0,0 +1,14 @@ +import logging +import subprocess +from flipper.utils.cdc import resolve_port + + +def main(): + logger = logging.getLogger() + if not (port := resolve_port(logger, "auto")): + return 1 + subprocess.call(["python3", "-m", "serial.tools.miniterm", "--raw", port, "230400"]) + + +if __name__ == "__main__": + main() diff --git a/scripts/storage.py b/scripts/storage.py index 0ddc2fc0..167ba88e 100755 --- a/scripts/storage.py +++ b/scripts/storage.py @@ -14,14 +14,7 @@ import tempfile class Main(App): def init(self): self.parser.add_argument("-p", "--port", help="CDC Port", default="auto") - self.parser.add_argument( - "-b", - "--baud", - help="Port Baud rate", - required=False, - default=115200 * 4, - type=int, - ) + self.subparsers = self.parser.add_subparsers(help="sub-command help") self.parser_mkdir = self.subparsers.add_parser("mkdir", help="Create directory") @@ -77,7 +70,7 @@ class Main(App): if not (port := resolve_port(self.logger, self.args.port)): return None - storage = FlipperStorage(port, self.args.baud) + storage = FlipperStorage(port) storage.start() return storage diff --git a/scripts/toolchain/fbtenv.cmd b/scripts/toolchain/fbtenv.cmd index 1a9af5a4..471ce835 100644 --- a/scripts/toolchain/fbtenv.cmd +++ b/scripts/toolchain/fbtenv.cmd @@ -13,7 +13,7 @@ if not [%FBT_NOENV%] == [] ( exit /b 0 ) -set "FLIPPER_TOOLCHAIN_VERSION=3" +set "FLIPPER_TOOLCHAIN_VERSION=8" set "FBT_TOOLCHAIN_ROOT=%FBT_ROOT%\toolchain\i686-windows" diff --git a/scripts/toolchain/fbtenv.sh b/scripts/toolchain/fbtenv.sh index 55bc89b0..654b1fe0 100755 --- a/scripts/toolchain/fbtenv.sh +++ b/scripts/toolchain/fbtenv.sh @@ -1,54 +1,211 @@ #!/bin/sh -# unofficial strict mode -set -eu; +# shellcheck disable=SC2034,SC2016,SC2086 -FLIPPER_TOOLCHAIN_VERSION="3"; +# public variables +DEFAULT_SCRIPT_PATH="$(pwd -P)"; +SCRIPT_PATH="${SCRIPT_PATH:-$DEFAULT_SCRIPT_PATH}"; +FBT_TOOLCHAIN_VERSION="${FBT_TOOLCHAIN_VERSION:-"8"}"; +FBT_TOOLCHAIN_PATH="${FBT_TOOLCHAIN_PATH:-$SCRIPT_PATH}"; -get_kernel_type() +fbtenv_check_sourced() { - SYS_TYPE="$(uname -s)" + case "${ZSH_EVAL_CONTEXT:-""}" in *:file:*) + return 0;; + esac + case ${0##*/} in dash|-dash|bash|-bash|ksh|-ksh|sh|-sh) + return 0;; + esac + if [ "$(basename $0)" = "fbt" ]; then + return 0; + fi + echo "Running this script manually is wrong, please source it"; + echo "Example:"; + printf "\tsource scripts/toolchain/fbtenv.sh\n"; + return 1; +} + +fbtenv_check_script_path() +{ + if [ ! -x "$SCRIPT_PATH/fbt" ]; then + echo "Please source this script being into flipperzero-firmware root directory, or specify 'SCRIPT_PATH' manually"; + echo "Example:"; + printf "\tSCRIPT_PATH=lang/c/flipperzero-firmware source lang/c/flipperzero-firmware/scripts/fbtenv.sh\n"; + echo "If current directory is right, type 'unset SCRIPT_PATH' and try again" + return 1; + fi + return 0; +} + +fbtenv_get_kernel_type() +{ + SYS_TYPE="$(uname -s)"; + ARCH_TYPE="$(uname -m)"; + if [ "$ARCH_TYPE" != "x86_64" ] && [ "$SYS_TYPE" != "Darwin" ]; then + echo "Now we provide toolchain only for x86_64 arhitecture, sorry.."; + return 1; + fi if [ "$SYS_TYPE" = "Darwin" ]; then - TOOLCHAIN_PATH="toolchain/x86_64-darwin"; + fbtenv_check_rosetta || return 1; + TOOLCHAIN_ARCH_DIR="$FBT_TOOLCHAIN_PATH/toolchain/x86_64-darwin"; + TOOLCHAIN_URL="https://update.flipperzero.one/builds/toolchain/gcc-arm-none-eabi-10.3-x86_64-darwin-flipper-$FBT_TOOLCHAIN_VERSION.tar.gz"; elif [ "$SYS_TYPE" = "Linux" ]; then - TOOLCHAIN_PATH="toolchain/x86_64-linux"; + TOOLCHAIN_ARCH_DIR="$FBT_TOOLCHAIN_PATH/toolchain/x86_64-linux"; + TOOLCHAIN_URL="https://update.flipperzero.one/builds/toolchain/gcc-arm-none-eabi-10.3-x86_64-linux-flipper-$FBT_TOOLCHAIN_VERSION.tar.gz"; elif echo "$SYS_TYPE" | grep -q "MINGW"; then echo "In MinGW shell use \"fbt.cmd\" instead of \"fbt\""; - exit 1; + return 1; else - echo "Sorry, your system is not supported. Please report your configuration to us."; - exit 1; + echo "Your system is not recognized. Sorry.. Please report us your configuration."; + return 1; fi + return 0; } -check_download_toolchain() +fbtenv_check_rosetta() { - 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; + if [ "$ARCH_TYPE" = "arm64" ]; then + if ! /usr/bin/pgrep -q oahd; then + echo "Flipper Zero Toolchain needs Rosetta2 to run under Apple Silicon"; + echo "Please instal it by typing 'softwareupdate --install-rosetta --agree-to-license'"; + return 1; + fi fi + return 0; } -download_toolchain() +fbtenv_check_tar() { - chmod 755 "$SCRIPT_PATH/scripts/toolchain/unix-toolchain-download.sh"; - "$SCRIPT_PATH/scripts/toolchain/unix-toolchain-download.sh" "$FLIPPER_TOOLCHAIN_VERSION" || exit 1; + printf "Checking tar.."; + if ! tar --version > /dev/null 2>&1; then + echo "no"; + return 1; + fi + echo "yes"; + return 0; } -main() +fbtenv_check_downloaded_toolchain() { - if [ -z "${SCRIPT_PATH:-}" ]; then - echo "Manual running of this script is not allowed."; - exit 1; + printf "Checking downloaded toolchain tgz.."; + if [ ! -f "$FBT_TOOLCHAIN_PATH/toolchain/$TOOLCHAIN_TAR" ]; then + echo "no"; + return 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"; + echo "yes"; + return 0; } -main; + +fbtenv_download_toolchain_tar() +{ + echo "Downloading toolchain:"; + mkdir -p "$FBT_TOOLCHAIN_PATH/toolchain" || return 1; + "$DOWNLOADER" $DOWNLOADER_ARGS "$FBT_TOOLCHAIN_PATH/toolchain/$TOOLCHAIN_TAR" "$TOOLCHAIN_URL" || return 1; + echo "done"; + return 0; +} + +fbtenv_remove_old_tooclhain() +{ + printf "Removing old toolchain (if exist).."; + rm -rf "${TOOLCHAIN_ARCH_DIR}"; + echo "done"; +} + +fbtenv_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%"; +} + +fbtenv_unpack_toolchain() +{ + echo "Unpacking toolchain:"; + tar -xvf "$FBT_TOOLCHAIN_PATH/toolchain/$TOOLCHAIN_TAR" -C "$FBT_TOOLCHAIN_PATH/toolchain" 2>&1 | fbtenv_show_unpack_percentage; + mkdir -p "$FBT_TOOLCHAIN_PATH/toolchain" || return 1; + mv "$FBT_TOOLCHAIN_PATH/toolchain/$TOOLCHAIN_DIR" "$TOOLCHAIN_ARCH_DIR" || return 1; + echo "done"; + return 0; +} + +fbtenv_clearing() +{ + printf "Clearing.."; + rm -rf "${FBT_TOOLCHAIN_PATH:?}/toolchain/$TOOLCHAIN_TAR"; + echo "done"; + return 0; +} + +fbtenv_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 $FBT_TOOLCHAIN_PATH/toolchain/ dir mannualy"; + return 1; + fi + echo "yes" + DOWNLOADER="wget"; + DOWNLOADER_ARGS="--show-progress --progress=bar:force -qO"; + return 0; + fi + echo "yes" + DOWNLOADER="curl"; + DOWNLOADER_ARGS="--progress-bar -SLo"; + return 0; +} + +fbtenv_check_download_toolchain() +{ + if [ ! -d "$TOOLCHAIN_ARCH_DIR" ]; then + fbtenv_download_toolchain || return 1; + elif [ ! -f "$TOOLCHAIN_ARCH_DIR/VERSION" ]; then + fbtenv_download_toolchain || return 1; + elif [ "$(cat "$TOOLCHAIN_ARCH_DIR/VERSION")" -ne "$FBT_TOOLCHAIN_VERSION" ]; then + fbtenv_download_toolchain || return 1; + fi + return 0; +} + +fbtenv_download_toolchain() +{ + fbtenv_check_tar || return 1; + TOOLCHAIN_TAR="$(basename "$TOOLCHAIN_URL")"; + TOOLCHAIN_DIR="$(echo "$TOOLCHAIN_TAR" | sed "s/-$FBT_TOOLCHAIN_VERSION.tar.gz//g")"; + if ! fbtenv_check_downloaded_toolchain; then + fbtenv_curl_wget_check || return 1; + fbtenv_download_toolchain_tar; + fi + fbtenv_remove_old_tooclhain; + fbtenv_unpack_toolchain || { fbtenv_clearing && return 1; }; + fbtenv_clearing; + return 0; +} + +fbtenv_main() +{ + fbtenv_check_sourced || return 1; + fbtenv_check_script_path || return 1; + fbtenv_get_kernel_type || return 1; + fbtenv_check_download_toolchain || return 1; + PATH="$TOOLCHAIN_ARCH_DIR/python/bin:$PATH"; + PATH="$TOOLCHAIN_ARCH_DIR/bin:$PATH"; + PATH="$TOOLCHAIN_ARCH_DIR/protobuf/bin:$PATH"; + PATH="$TOOLCHAIN_ARCH_DIR/openocd/bin:$PATH"; +} + +fbtenv_main; diff --git a/scripts/toolchain/unix-toolchain-download.sh b/scripts/toolchain/unix-toolchain-download.sh deleted file mode 100755 index 386be2a3..00000000 --- a/scripts/toolchain/unix-toolchain-download.sh +++ /dev/null @@ -1,135 +0,0 @@ -#!/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/site_scons/site_tools/fbt_apps.py b/site_scons/site_tools/fbt_apps.py index 2ffdcae3..2cd63b70 100644 --- a/site_scons/site_tools/fbt_apps.py +++ b/site_scons/site_tools/fbt_apps.py @@ -1,8 +1,9 @@ from SCons.Builder import Builder from SCons.Action import Action -from SCons.Errors import UserError - +from SCons.Warnings import warn, WarningOnByDefault import SCons +import os.path + from fbt.appmanifest import ( FlipperAppType, AppManager, @@ -17,12 +18,14 @@ from fbt.appmanifest import ( def LoadApplicationManifests(env): appmgr = env["APPMGR"] = AppManager() - for entry in env.Glob("#/applications/*", source=True): + for entry in env.Glob("#/applications/*", ondisk=True, 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) + app_manifest_file_path = os.path.join(entry.abspath, "application.fam") + appmgr.load_manifest(app_manifest_file_path, entry.name) + env.Append(PY_LINT_SOURCES=[app_manifest_file_path]) except FlipperManifestException as e: - raise UserError(e) + warn(WarningOnByDefault, str(e)) def PrepareApplicationsBuild(env): @@ -64,6 +67,7 @@ def generate(env): build_apps_c, "${APPSCOMSTR}", ), + suffix=".c", ), } ) diff --git a/site_scons/site_tools/fbt_dist.py b/site_scons/site_tools/fbt_dist.py index 7c28c69c..399b7ecd 100644 --- a/site_scons/site_tools/fbt_dist.py +++ b/site_scons/site_tools/fbt_dist.py @@ -66,9 +66,38 @@ def AddOpenOCDFlashTarget(env, targetenv, **kw): **kw, ) env.Alias(targetenv.subst("${FIRMWARE_BUILD_CFG}_flash"), openocd_target) + if env["FORCE"]: + env.AlwaysBuild(openocd_target) return openocd_target +def AddJFlashTarget(env, targetenv, **kw): + jflash_target = env.JFlash( + "#build/jflash-${BUILD_CFG}-flash.flag", + targetenv["FW_BIN"], + JFLASHADDR=targetenv.subst("$IMAGE_BASE_ADDRESS"), + BUILD_CFG=targetenv.subst("${FIRMWARE_BUILD_CFG}"), + **kw, + ) + env.Alias(targetenv.subst("${FIRMWARE_BUILD_CFG}_jflash"), jflash_target) + if env["FORCE"]: + env.AlwaysBuild(jflash_target) + return jflash_target + + +def AddUsbFlashTarget(env, file_flag, extra_deps, **kw): + usb_update = env.UsbInstall( + file_flag, + ( + env["DIST_DEPENDS"], + *extra_deps, + ), + ) + if env["FORCE"]: + env.AlwaysBuild(usb_update) + return usb_update + + def DistCommand(env, name, source, **kw): target = f"dist_{name}" command = env.Command( @@ -86,6 +115,8 @@ def generate(env): env.AddMethod(AddFwProject) env.AddMethod(DistCommand) env.AddMethod(AddOpenOCDFlashTarget) + env.AddMethod(AddJFlashTarget) + env.AddMethod(AddUsbFlashTarget) env.SetDefault( COPRO_MCU_FAMILY="STM32WB5x", diff --git a/site_scons/site_tools/jflash.py b/site_scons/site_tools/jflash.py new file mode 100644 index 00000000..aea7279b --- /dev/null +++ b/site_scons/site_tools/jflash.py @@ -0,0 +1,27 @@ +from SCons.Builder import Builder +from SCons.Defaults import Touch + + +def generate(env): + env.SetDefault( + JFLASH="JFlash" if env.subst("$PLATFORM") == "win32" else "JFlashExe", + JFLASHFLAGS=[ + "-auto", + "-exit", + ], + JFLASHCOM="${JFLASH} -openprj${JFLASHPROJECT} -open${SOURCE},${JFLASHADDR} ${JFLASHFLAGS}", + ) + env.Append( + BUILDERS={ + "JFlash": Builder( + action=[ + "${JFLASHCOM}", + Touch("${TARGET}"), + ], + ), + } + ) + + +def exists(env): + return True diff --git a/site_scons/site_tools/sconsmodular.py b/site_scons/site_tools/sconsmodular.py index db0cb8f3..778c664e 100644 --- a/site_scons/site_tools/sconsmodular.py +++ b/site_scons/site_tools/sconsmodular.py @@ -1,5 +1,6 @@ import posixpath import os +from SCons.Errors import UserError def BuildModule(env, module): @@ -8,9 +9,9 @@ def BuildModule(env, module): if not os.path.exists(module_sconscript): module_sconscript = posixpath.join(src_dir, f"{module}.scons") if not os.path.exists(module_sconscript): - print(f"Cannot build module {module}: scons file not found") - Exit(2) + raise UserError(f"Cannot build module {module}: scons file not found") + env.Append(PY_LINT_SOURCES=[module_sconscript]) return env.SConscript( module_sconscript, variant_dir=posixpath.join(env.subst("$BUILD_DIR"), module),