diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 38b1d7b68..252310af6 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -129,7 +129,7 @@ jobs: - name: 'Find previous comment' if: ${{ !github.event.pull_request.head.repo.fork && matrix.target == env.DEFAULT_TARGET && github.event.pull_request }} - uses: peter-evans/find-comment@v2 + uses: peter-evans/find-comment@v3 id: find-comment with: issue-number: ${{ github.event.pull_request.number }} @@ -138,7 +138,7 @@ jobs: - name: 'Create or update comment' if: ${{ !github.event.pull_request.head.repo.fork && matrix.target == env.DEFAULT_TARGET && github.event.pull_request }} - uses: peter-evans/create-or-update-comment@v3 + uses: peter-evans/create-or-update-comment@v4 with: comment-id: ${{ steps.find-comment.outputs.comment-id }} issue-number: ${{ github.event.pull_request.number }} @@ -147,6 +147,7 @@ jobs: - [📦 Update package](https://update.flipperzero.one/builds/firmware/${{steps.names.outputs.branch_name}}/flipper-z-${{steps.names.outputs.default_target}}-update-${{steps.names.outputs.suffix}}.tgz) - [📥 DFU file](https://update.flipperzero.one/builds/firmware/${{steps.names.outputs.branch_name}}/flipper-z-${{steps.names.outputs.default_target}}-full-${{steps.names.outputs.suffix}}.dfu) - [☁️ Web/App updater](https://lab.flipper.net/?url=https://update.flipperzero.one/builds/firmware/${{steps.names.outputs.branch_name}}/flipper-z-${{steps.names.outputs.default_target}}-update-${{steps.names.outputs.suffix}}.tgz&channel=${{steps.names.outputs.branch_name}}&version=${{steps.names.outputs.commit_sha}}) + - [📊 Size report](https://fw-reports.flipp.dev/?branch=${{steps.names.outputs.branch_name}}) edit-mode: replace - name: 'SDK submission to staging catalog' diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml new file mode 100644 index 000000000..1fa025085 --- /dev/null +++ b/.github/workflows/docs.yml @@ -0,0 +1,78 @@ +name: 'Generate documentation with Doxygen' + +on: + push: + branches: + - dev + pull_request: + +env: + TARGETS: f7 + DEFAULT_TARGET: f7 + +jobs: + check-secret: + if: ${{ github.event.pull_request.head.repo.fork == false }} + runs-on: ubuntu-latest + outputs: + s3-valid-config: ${{ steps.check.outputs.s3-valid-config }} + + steps: + - name: 'Check if S3 key exists' + id: check + run: | + if [[ -z "${{ secrets.FW_DOCS_AWS_ACCESS_KEY }}" || -z "${{ secrets.FW_DOCS_AWS_SECRET_KEY }}" || -z "${{ secrets.FW_DOCS_AWS_BUCKET }}" ]]; then + echo "s3-valid-config=false" >> $GITHUB_OUTPUT; + else + echo "s3-valid-config=true" >> $GITHUB_OUTPUT; + fi + + doxygen: + if: ${{ github.event.pull_request.head.repo.fork == false }} + runs-on: ubuntu-latest + needs: check-secret + steps: + - name: 'Wipe workspace' + run: find ./ -mount -maxdepth 1 -exec rm -rf {} \; + + - name: 'Checkout code' + uses: actions/checkout@v4 + with: + submodules: true + fetch-depth: 1 + ref: ${{ github.event.pull_request.head.sha }} + + - name: 'Get commit details' + id: names + run: | + if [[ ${{ github.event_name }} == 'pull_request' ]]; then + TYPE="pull" + elif [[ "${{ github.ref }}" == "refs/tags/"* ]]; then + TYPE="tag" + else + TYPE="other" + fi + python3 scripts/get_env.py "--event_file=${{ github.event_path }}" "--type=$TYPE" + + - name: 'Generate documentation' + uses: mattnotmitt/doxygen-action@edge + env: + DOXY_SRC_ROOT: "${{ github.workspace }}" + DOXY_CONFIG_DIR: "${{ github.workspace }}/documentation/doxygen" + DOXY_OUTPUT_DIR: "${{ github.workspace }}/documentation/doxygen/build" + with: + working-directory: 'documentation/' + doxyfile-path: './doxygen/Doxyfile-awesome.cfg' + + - name: 'Upload documentation' + if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/dev' && needs.check-secret.outputs.s3-valid-config == 'true' }} + uses: jakejarvis/s3-sync-action@v0.5.1 + env: + AWS_S3_BUCKET: "${{ secrets.FW_DOCS_AWS_BUCKET }}" + AWS_ACCESS_KEY_ID: "${{ secrets.FW_DOCS_AWS_ACCESS_KEY }}" + AWS_SECRET_ACCESS_KEY: "${{ secrets.FW_DOCS_AWS_SECRET_KEY }}" + AWS_REGION: "${{ secrets.FW_DOCS_AWS_REGION }}" + SOURCE_DIR: "./documentation/doxygen/build/html" + DEST_DIR: "${{steps.names.outputs.branch_name}}" + with: + args: "--delete" diff --git a/.github/workflows/pvs_studio.yml b/.github/workflows/pvs_studio.yml index 4527e2920..8eb6fea48 100644 --- a/.github/workflows/pvs_studio.yml +++ b/.github/workflows/pvs_studio.yml @@ -48,6 +48,9 @@ jobs: WARNINGS=0 ./fbt COMPACT=1 PVSNOBROWSER=1 firmware_pvs || WARNINGS=1 echo "warnings=${WARNINGS}" >> $GITHUB_OUTPUT + if [[ $WARNINGS -ne 0 ]]; then + echo "report-url=https://pvs.flipp.dev/${{steps.names.outputs.branch_name}}/${{steps.names.outputs.default_target}}-${{steps.names.outputs.suffix}}/index.html" >> $GITHUB_OUTPUT + fi - name: 'Upload report' if: ${{ !github.event.pull_request.head.repo.fork && (steps.pvs-warn.outputs.warnings != 0) }} @@ -62,7 +65,7 @@ jobs: - name: 'Find Previous Comment' if: ${{ !github.event.pull_request.head.repo.fork && github.event.pull_request && (steps.pvs-warn.outputs.warnings != 0) }} - uses: peter-evans/find-comment@v2 + uses: peter-evans/find-comment@v3 id: fc with: issue-number: ${{ github.event.pull_request.number }} @@ -71,18 +74,19 @@ jobs: - name: 'Create or update comment' if: ${{ !github.event.pull_request.head.repo.fork && github.event.pull_request && (steps.pvs-warn.outputs.warnings != 0) }} - uses: peter-evans/create-or-update-comment@v1 + uses: peter-evans/create-or-update-comment@v4 with: comment-id: ${{ steps.fc.outputs.comment-id }} issue-number: ${{ github.event.pull_request.number }} body: | **PVS-Studio report for commit `${{steps.names.outputs.commit_sha}}`:** - - [Report](https://pvs.flipp.dev/${{steps.names.outputs.branch_name}}/${{steps.names.outputs.default_target}}-${{steps.names.outputs.suffix}}/index.html) + - [Report](${{ steps.pvs-warn.outputs.report-url }}) edit-mode: replace - name: 'Raise exception' if: ${{ steps.pvs-warn.outputs.warnings != 0 }} run: | echo "Please fix all PVS warnings before merge" + echo "Report: ${{ steps.pvs-warn.outputs.report-url }}" + echo "[PVS report](${{ steps.pvs-warn.outputs.report-url }})" >> $GITHUB_STEP_SUMMARY exit 1 - diff --git a/.gitmodules b/.gitmodules index 52cf4a207..c4c68a6a7 100644 --- a/.gitmodules +++ b/.gitmodules @@ -37,4 +37,7 @@ url = https://github.com/STMicroelectronics/stm32wbxx_hal_driver [submodule "lib/stm32wb_copro"] path = lib/stm32wb_copro - url = https://github.com/flipperdevices/stm32wb_copro.git + url = https://github.com/flipperdevices/stm32wb_copro.git +[submodule "documentation/doxygen/doxygen-awesome-css"] + path = documentation/doxygen/doxygen-awesome-css + url = https://github.com/jothepro/doxygen-awesome-css.git diff --git a/.pvsconfig b/.pvsconfig index 49c63ad73..b6001ca5c 100644 --- a/.pvsconfig +++ b/.pvsconfig @@ -1,10 +1,10 @@ # MLib macros we can't do much about. //-V:M_LET:1048,1044 //-V:M_EACH:1048,1044 -//-V:ARRAY_DEF:760,747,568,776,729,712,654 -//-V:LIST_DEF:760,747,568,712,729,654,776 +//-V:ARRAY_DEF:760,747,568,776,729,712,654,1103 +//-V:LIST_DEF:760,747,568,712,729,654,776,1103 //-V:BPTREE_DEF2:779,1086,557,773,512 -//-V:DICT_DEF2:779,524,776,760,1044,1001,729,590,568,747,685 +//-V:DICT_DEF2:779,524,776,760,1044,1001,729,590,568,747,685,1103 //-V:ALGO_DEF:1048,747,1044 //-V:TUPLE_DEF2:524,590,1001,760 @@ -42,8 +42,5 @@ # Model-related warnings //-V:with_view_model:1044,1048 -# Functions that always return the same error code -//-V:picopass_device_decrypt:1048 - # Examples //V_EXCLUDE_PATH applications/examples/ \ No newline at end of file diff --git a/.vscode/ReadMe.md b/.vscode/ReadMe.md index 5aed0435c..c7fc69f78 100644 --- a/.vscode/ReadMe.md +++ b/.vscode/ReadMe.md @@ -1,4 +1,4 @@ -# Visual Studio Code workspace for Flipper Zero +# Visual Studio Code workspace for Flipper Zero {#vscode} ## Setup diff --git a/.vscode/example/cpptools/c_cpp_properties.json b/.vscode/example/cpptools/c_cpp_properties.json index d1cac63e9..3f8d15a5d 100644 --- a/.vscode/example/cpptools/c_cpp_properties.json +++ b/.vscode/example/cpptools/c_cpp_properties.json @@ -5,27 +5,24 @@ "compilerPath": "${workspaceFolder}/toolchain/x86_64-windows/bin/arm-none-eabi-gcc.exe", "intelliSenseMode": "gcc-arm", "compileCommands": "${workspaceFolder}/build/latest/compile_commands.json", - "configurationProvider": "ms-vscode.cpptools", - "cStandard": "gnu17", - "cppStandard": "c++17" + "cStandard": "gnu23", + "cppStandard": "c++20" }, { "name": "Linux", "compilerPath": "${workspaceFolder}/toolchain/x86_64-linux/bin/arm-none-eabi-gcc", "intelliSenseMode": "gcc-arm", "compileCommands": "${workspaceFolder}/build/latest/compile_commands.json", - "configurationProvider": "ms-vscode.cpptools", - "cStandard": "gnu17", - "cppStandard": "c++17" + "cStandard": "gnu23", + "cppStandard": "c++20" }, { "name": "Mac", "compilerPath": "${workspaceFolder}/toolchain/x86_64-darwin/bin/arm-none-eabi-gcc", "intelliSenseMode": "gcc-arm", "compileCommands": "${workspaceFolder}/build/latest/compile_commands.json", - "configurationProvider": "ms-vscode.cpptools", - "cStandard": "gnu17", - "cppStandard": "c++17" + "cStandard": "gnu23", + "cppStandard": "c++20" } ], "version": 4 diff --git a/.vscode/example/settings.json b/.vscode/example/settings.json index 819917146..a59194901 100644 --- a/.vscode/example/settings.json +++ b/.vscode/example/settings.json @@ -1,6 +1,6 @@ { - "C_Cpp.default.cStandard": "gnu17", - "C_Cpp.default.cppStandard": "c++17", + "C_Cpp.default.cStandard": "gnu23", + "C_Cpp.default.cppStandard": "c++20", "python.formatting.provider": "black", "workbench.tree.indent": 12, "cortex-debug.enableTelemetry": false, @@ -14,7 +14,7 @@ "*.scons": "python", "SConscript": "python", "SConstruct": "python", - "*.fam": "python", + "*.fam": "python" }, "clangd.arguments": [ // We might be able to tighten this a bit more to only include the correct toolchain. diff --git a/ReadMe.md b/ReadMe.md index 387ac2de7..34776ebd1 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -11,6 +11,7 @@ - [Flipper Zero Official Website](https://flipperzero.one). A simple way to explain to your friends what Flipper Zero can do. - [Flipper Zero Firmware Update](https://update.flipperzero.one). Improvements for your dolphin: latest firmware releases, upgrade tools for PC and mobile devices. - [User Documentation](https://docs.flipperzero.one). Learn more about your dolphin: specs, usage guides, and anything you want to ask. +- [Developer Documentation](https://developer.flipper.net/flipperzero/doxygen). Dive into the Flipper Zero Firmware source code: build system, firmware structure, and more. # Contributing @@ -18,7 +19,7 @@ Our main goal is to build a healthy and sustainable community around Flipper, so ## I need help -The best place to search for answers is our [User Documentation](https://docs.flipperzero.one). If you can't find the answer there, check our [Discord Server](https://flipp.dev/discord) or our [Forum](https://forum.flipperzero.one/). +The best place to search for answers is our [User Documentation](https://docs.flipperzero.one). If you can't find the answer there, check our [Discord Server](https://flipp.dev/discord) or our [Forum](https://forum.flipperzero.one/). If you want to contribute to the firmware development, or modify it for your own needs, you can also check our [Developer Documentation](https://developer.flipper.net/flipperzero/doxygen). ## I want to report an issue @@ -95,7 +96,8 @@ Make sure your Flipper is on, and your firmware is functioning. Connect your Fli - [Hardware combos and Un-bricking](/documentation/KeyCombo.md) - recovering your Flipper from the most nasty situations - [Flipper File Formats](/documentation/file_formats) - everything about how Flipper stores your data and how you can work with it - [Universal Remotes](/documentation/UniversalRemotes.md) - contributing your infrared remote to the universal remote database -- And much more in the [documentation](/documentation) folder +- [Firmware Roadmap](/documentation/RoadMap.md) +- And much more in the [Developer Documentation](https://developer.flipper.net/flipperzero/doxygen) # Project structure diff --git a/SConstruct b/SConstruct index 6d24da920..532c37b7f 100644 --- a/SConstruct +++ b/SConstruct @@ -7,7 +7,7 @@ # construction of certain targets behind command-line options. import os -from fbt.util import path_as_posix +from fbt.util import open_browser_action DefaultEnvironment(tools=[]) @@ -42,6 +42,7 @@ distenv = coreenv.Clone( "openocd", "blackmagic", "jflash", + "doxygen", ], ENV=os.environ, UPDATE_BUNDLE_DIR="dist/${DIST_DIR}/f${TARGET_HW}-update-${DIST_SUFFIX}", @@ -66,6 +67,7 @@ if GetOption("fullenv") or any( # Target for self-update package dist_basic_arguments = [ + "${ARGS}", "--bundlever", "${UPDATE_VERSION_STRING}", ] @@ -182,6 +184,7 @@ fap_deploy = distenv.PhonyTarget( "send", "${SOURCE}", "/ext/apps", + "${ARGS}", ] ] ), @@ -208,7 +211,7 @@ distenv.Alias("jflash", firmware_jflash) distenv.PhonyTarget( "gdb_trace_all", - "$GDB $GDBOPTS $SOURCES $GDBFLASH", + [["${GDB}", "${GDBOPTS}", "${SOURCES}", "${GDBFLASH}"]], source=firmware_env["FW_ELF"], GDBOPTS="${GDBOPTS_BASE}", GDBREMOTE="${OPENOCD_GDB_PIPE}", @@ -227,7 +230,7 @@ firmware_debug = distenv.PhonyTarget( source=firmware_env["FW_ELF"], GDBOPTS="${GDBOPTS_BASE}", GDBREMOTE="${OPENOCD_GDB_PIPE}", - FBT_FAP_DEBUG_ELF_ROOT=path_as_posix(firmware_env.subst("$FBT_FAP_DEBUG_ELF_ROOT")), + FBT_FAP_DEBUG_ELF_ROOT=firmware_env["FBT_FAP_DEBUG_ELF_ROOT"], ) distenv.Depends(firmware_debug, firmware_flash) @@ -237,7 +240,7 @@ distenv.PhonyTarget( source=firmware_env["FW_ELF"], GDBOPTS="${GDBOPTS_BASE} ${GDBOPTS_BLACKMAGIC}", GDBREMOTE="${BLACKMAGIC_ADDR}", - FBT_FAP_DEBUG_ELF_ROOT=path_as_posix(firmware_env.subst("$FBT_FAP_DEBUG_ELF_ROOT")), + FBT_FAP_DEBUG_ELF_ROOT=firmware_env["FBT_FAP_DEBUG_ELF_ROOT"], ) # Debug alien elf @@ -272,19 +275,35 @@ distenv.PhonyTarget( # Just start OpenOCD distenv.PhonyTarget( "openocd", - "${OPENOCDCOM}", + [["${OPENOCDCOM}", "${ARGS}"]], ) # Linter distenv.PhonyTarget( "lint", - [["${PYTHON3}", "${FBT_SCRIPT_DIR}/lint.py", "check", "${LINT_SOURCES}"]], + [ + [ + "${PYTHON3}", + "${FBT_SCRIPT_DIR}/lint.py", + "check", + "${LINT_SOURCES}", + "${ARGS}", + ] + ], LINT_SOURCES=[n.srcnode() for n in firmware_env["LINT_SOURCES"]], ) distenv.PhonyTarget( "format", - [["${PYTHON3}", "${FBT_SCRIPT_DIR}/lint.py", "format", "${LINT_SOURCES}"]], + [ + [ + "${PYTHON3}", + "${FBT_SCRIPT_DIR}/lint.py", + "format", + "${LINT_SOURCES}", + "${ARGS}", + ] + ], LINT_SOURCES=[n.srcnode() for n in firmware_env["LINT_SOURCES"]], ) @@ -307,7 +326,16 @@ firmware_env.Append( ) -black_commandline = "@${PYTHON3} -m black ${PY_BLACK_ARGS} ${PY_LINT_SOURCES}" +black_commandline = [ + [ + "@${PYTHON3}", + "-m", + "black", + "${PY_BLACK_ARGS}", + "${PY_LINT_SOURCES}", + "${ARGS}", + ] +] black_base_args = [ "--include", '"(\\.scons|\\.py|SConscript|SConstruct|\\.fam)$"', @@ -333,12 +361,28 @@ distenv.PhonyTarget( # Start Flipper CLI via PySerial's miniterm distenv.PhonyTarget( - "cli", [["${PYTHON3}", "${FBT_SCRIPT_DIR}/serial_cli.py", "-p", "${FLIP_PORT}"]] + "cli", + [ + [ + "${PYTHON3}", + "${FBT_SCRIPT_DIR}/serial_cli.py", + "-p", + "${FLIP_PORT}", + "${ARGS}", + ] + ], ) -# Update WiFi devboard firmware +# Update WiFi devboard firmware with release channel distenv.PhonyTarget( - "devboard_flash", [["${PYTHON3}", "${FBT_SCRIPT_DIR}/wifi_board.py"]] + "devboard_flash", + [ + [ + "${PYTHON3}", + "${FBT_SCRIPT_DIR}/wifi_board.py", + "${ARGS}", + ] + ], ) @@ -353,7 +397,7 @@ distenv.PhonyTarget( distenv.PhonyTarget( "get_stlink", distenv.Action( - lambda **kw: distenv.GetDevices(), + lambda **_: distenv.GetDevices(), None, ), ) @@ -376,3 +420,18 @@ distenv.PhonyTarget( "env", "@echo $( ${FBT_SCRIPT_DIR.abspath}/toolchain/fbtenv.sh $)", ) + +doxy_build = distenv.DoxyBuild( + "documentation/doxygen/build/html/index.html", + "documentation/doxygen/Doxyfile-awesome.cfg", + doxy_env_variables={ + "DOXY_SRC_ROOT": Dir(".").abspath, + "DOXY_BUILD_DIR": Dir("documentation/doxygen/build").abspath, + "DOXY_CONFIG_DIR": "documentation/doxygen", + }, +) +distenv.Alias("doxygen", doxy_build) +distenv.AlwaysBuild(doxy_build) + +# Open generated documentation in browser +distenv.PhonyTarget("doxy", open_browser_action, source=doxy_build) diff --git a/applications/debug/accessor/accessor_app.h b/applications/debug/accessor/accessor_app.h index 2afd796d5..bfd5c06e1 100644 --- a/applications/debug/accessor/accessor_app.h +++ b/applications/debug/accessor/accessor_app.h @@ -11,29 +11,29 @@ class AccessorApp { public: void run(void); - AccessorApp(); - ~AccessorApp(); + AccessorApp(void); + ~AccessorApp(void); enum class Scene : uint8_t { Exit, Start, }; - AccessorAppViewManager* get_view_manager(); + AccessorAppViewManager* get_view_manager(void); void switch_to_next_scene(Scene index); void search_and_switch_to_previous_scene(std::initializer_list scenes_list); bool switch_to_previous_scene(uint8_t count = 1); - Scene get_previous_scene(); + Scene get_previous_scene(void); - void notify_green_blink(); - void notify_success(); + void notify_green_blink(void); + void notify_success(void); - char* get_text_store(); - uint8_t get_text_store_size(); + char* get_text_store(void); + uint8_t get_text_store_size(void); void set_text_store(const char* text...); - WIEGAND* get_wiegand(); - OneWireHost* get_one_wire(); + WIEGAND* get_wiegand(void); + OneWireHost* get_one_wire(void); private: std::list previous_scenes_list = {Scene::Exit}; diff --git a/applications/debug/accessor/accessor_view_manager.cpp b/applications/debug/accessor/accessor_view_manager.cpp index db723d68c..955c0b286 100644 --- a/applications/debug/accessor/accessor_view_manager.cpp +++ b/applications/debug/accessor/accessor_view_manager.cpp @@ -1,6 +1,6 @@ #include "accessor_view_manager.h" #include "accessor_event.h" -#include +#include "callback_connector.h" AccessorAppViewManager::AccessorAppViewManager() { event_queue = furi_message_queue_alloc(10, sizeof(AccessorEvent)); diff --git a/applications/debug/accessor/accessor_view_manager.h b/applications/debug/accessor/accessor_view_manager.h index 8cd437797..66e54e41c 100644 --- a/applications/debug/accessor/accessor_view_manager.h +++ b/applications/debug/accessor/accessor_view_manager.h @@ -15,16 +15,16 @@ public: FuriMessageQueue* event_queue; - AccessorAppViewManager(); - ~AccessorAppViewManager(); + AccessorAppViewManager(void); + ~AccessorAppViewManager(void); void switch_to(ViewType type); void receive_event(AccessorEvent* event); void send_event(AccessorEvent* event); - Submenu* get_submenu(); - Popup* get_popup(); + Submenu* get_submenu(void); + Popup* get_popup(void); private: ViewDispatcher* view_dispatcher; diff --git a/lib/callback-connector/callback-connector.h b/applications/debug/accessor/callback_connector.h similarity index 90% rename from lib/callback-connector/callback-connector.h rename to applications/debug/accessor/callback_connector.h index 10fec3e2d..dd99c5b26 100644 --- a/lib/callback-connector/callback-connector.h +++ b/applications/debug/accessor/callback_connector.h @@ -1,10 +1,13 @@ #ifndef CALLBACKCONNECTOR_H #define CALLBACKCONNECTOR_H + +#ifdef __cplusplus #include namespace cbc { namespace Details { -template class FuncMemberWrapper { +template +class FuncMemberWrapper { public: FuncMemberWrapper() = delete; using member_fun_t = Ret (T::*)(Args...); @@ -43,7 +46,8 @@ template typename FuncMemberWrapper::const_member_fun_t FuncMemberWrapper::const_member{}; -template struct FunctorWrapper { +template +struct FunctorWrapper { public: static std::function functor; static auto instatiate(Functor fn) { @@ -75,7 +79,8 @@ auto const_instantiate(T* t, Ret (T::*ptr)(Args...) const) { return FuncMemberWrapper::instantiate(t, ptr); } -template auto const_instantiate(T* t, Func ptr) { +template +auto const_instantiate(T* t, Func ptr) { return const_instantiate(t, ptr); } @@ -91,9 +96,11 @@ auto obtain_connector(T* t, Ret (T::*ptr)(Args...) const) { return Details::FuncMemberWrapper::instantiate(t, ptr); } -template auto obtain_connector(Functor functor) { +template +auto obtain_connector(Functor functor) { return Details::deducer(std::move(functor), &Functor::operator()); } } //end of cbc scope +#endif // __cplusplus #endif // CALLBACKCONNECTOR_H diff --git a/applications/debug/accessor/helpers/wiegand.cpp b/applications/debug/accessor/helpers/wiegand.cpp index 10b284eaa..f20b09120 100644 --- a/applications/debug/accessor/helpers/wiegand.cpp +++ b/applications/debug/accessor/helpers/wiegand.cpp @@ -2,12 +2,12 @@ #include #include -volatile unsigned long WIEGAND::_cardTempHigh = 0; -volatile unsigned long WIEGAND::_cardTemp = 0; -volatile unsigned long WIEGAND::_lastWiegand = 0; +unsigned long WIEGAND::_cardTempHigh = 0; +unsigned long WIEGAND::_cardTemp = 0; +unsigned long WIEGAND::_lastWiegand = 0; unsigned long WIEGAND::_code = 0; unsigned long WIEGAND::_codeHigh = 0; -volatile int WIEGAND::_bitCount = 0; +int WIEGAND::_bitCount = 0; int WIEGAND::_wiegandType = 0; constexpr uint32_t clocks_in_ms = 64 * 1000; @@ -98,10 +98,7 @@ void WIEGAND::ReadD1() { _lastWiegand = DWT->CYCCNT; // Keep track of last wiegand bit received } -unsigned long WIEGAND::GetCardId( - volatile unsigned long* codehigh, - volatile unsigned long* codelow, - char bitlength) { +unsigned long WIEGAND::GetCardId(unsigned long* codehigh, unsigned long* codelow, char bitlength) { if(bitlength == 26) // EM tag return (*codelow & 0x1FFFFFE) >> 1; diff --git a/applications/debug/accessor/helpers/wiegand.h b/applications/debug/accessor/helpers/wiegand.h index 8127f4286..1e1ab6bc8 100644 --- a/applications/debug/accessor/helpers/wiegand.h +++ b/applications/debug/accessor/helpers/wiegand.h @@ -2,28 +2,26 @@ class WIEGAND { public: - WIEGAND(); - void begin(); - void end(); - bool available(); - unsigned long getCode(); - unsigned long getCodeHigh(); - int getWiegandType(); + WIEGAND(void); + void begin(void); + void end(void); + bool available(void); + unsigned long getCode(void); + unsigned long getCodeHigh(void); + int getWiegandType(void); - static void ReadD0(); - static void ReadD1(); + static void ReadD0(void); + static void ReadD1(void); private: - static bool DoWiegandConversion(); - static unsigned long GetCardId( - volatile unsigned long* codehigh, - volatile unsigned long* codelow, - char bitlength); + static bool DoWiegandConversion(void); + static unsigned long + GetCardId(unsigned long* codehigh, unsigned long* codelow, char bitlength); - static volatile unsigned long _cardTempHigh; - static volatile unsigned long _cardTemp; - static volatile unsigned long _lastWiegand; - static volatile int _bitCount; + static unsigned long _cardTempHigh; + static unsigned long _cardTemp; + static unsigned long _lastWiegand; + static int _bitCount; static int _wiegandType; static unsigned long _code; static unsigned long _codeHigh; diff --git a/applications/debug/accessor/scene/accessor_scene_start.cpp b/applications/debug/accessor/scene/accessor_scene_start.cpp index 6f5a4d112..d31001d2d 100644 --- a/applications/debug/accessor/scene/accessor_scene_start.cpp +++ b/applications/debug/accessor/scene/accessor_scene_start.cpp @@ -1,7 +1,7 @@ #include "../accessor_app.h" #include "../accessor_view_manager.h" #include "../accessor_event.h" -#include +#include "callback_connector.h" #include "accessor_scene_start.h" void AccessorSceneStart::on_enter(AccessorApp* app) { diff --git a/applications/debug/battery_test_app/battery_test_app.c b/applications/debug/battery_test_app/battery_test_app.c index eabf3c04b..5f9934e77 100644 --- a/applications/debug/battery_test_app/battery_test_app.c +++ b/applications/debug/battery_test_app/battery_test_app.c @@ -12,7 +12,8 @@ void battery_test_dialog_callback(DialogExResult result, void* context) { } } -uint32_t battery_test_exit_confirm_view() { +uint32_t battery_test_exit_confirm_view(void* context) { + UNUSED(context); return BatteryTestAppViewExitDialog; } @@ -31,7 +32,7 @@ static void battery_test_battery_info_update_model(void* context) { notification_message(app->notifications, &sequence_display_backlight_on); } -BatteryTestApp* battery_test_alloc() { +BatteryTestApp* battery_test_alloc(void) { BatteryTestApp* app = malloc(sizeof(BatteryTestApp)); // Records diff --git a/applications/debug/battery_test_app/views/battery_info.c b/applications/debug/battery_test_app/views/battery_info.c index 5353a2e2a..4b5dcd627 100644 --- a/applications/debug/battery_test_app/views/battery_info.c +++ b/applications/debug/battery_test_app/views/battery_info.c @@ -116,7 +116,7 @@ static void battery_info_draw_callback(Canvas* canvas, void* context) { draw_stat(canvas, 104, 42, &I_Health_16x16, health); } -BatteryInfo* battery_info_alloc() { +BatteryInfo* battery_info_alloc(void) { BatteryInfo* battery_info = malloc(sizeof(BatteryInfo)); battery_info->view = view_alloc(); view_set_context(battery_info->view, battery_info); diff --git a/applications/debug/battery_test_app/views/battery_info.h b/applications/debug/battery_test_app/views/battery_info.h index 7bfacf69e..403caac4b 100644 --- a/applications/debug/battery_test_app/views/battery_info.h +++ b/applications/debug/battery_test_app/views/battery_info.h @@ -14,7 +14,7 @@ typedef struct { uint8_t health; } BatteryInfoModel; -BatteryInfo* battery_info_alloc(); +BatteryInfo* battery_info_alloc(void); void battery_info_free(BatteryInfo* battery_info); diff --git a/applications/debug/bt_debug_app/bt_debug_app.c b/applications/debug/bt_debug_app/bt_debug_app.c index bf13f6570..109feee60 100644 --- a/applications/debug/bt_debug_app/bt_debug_app.c +++ b/applications/debug/bt_debug_app/bt_debug_app.c @@ -28,7 +28,7 @@ uint32_t bt_debug_start_view(void* context) { return BtDebugAppViewSubmenu; } -BtDebugApp* bt_debug_app_alloc() { +BtDebugApp* bt_debug_app_alloc(void) { BtDebugApp* app = malloc(sizeof(BtDebugApp)); // Gui diff --git a/applications/debug/bt_debug_app/views/bt_carrier_test.c b/applications/debug/bt_debug_app/views/bt_carrier_test.c index 8e2240495..23066434b 100644 --- a/applications/debug/bt_debug_app/views/bt_carrier_test.c +++ b/applications/debug/bt_debug_app/views/bt_carrier_test.c @@ -129,7 +129,7 @@ static void bt_test_carrier_timer_callback(void* context) { } } -BtCarrierTest* bt_carrier_test_alloc() { +BtCarrierTest* bt_carrier_test_alloc(void) { BtCarrierTest* bt_carrier_test = malloc(sizeof(BtCarrierTest)); bt_carrier_test->bt_test = bt_test_alloc(); bt_test_set_context(bt_carrier_test->bt_test, bt_carrier_test); diff --git a/applications/debug/bt_debug_app/views/bt_carrier_test.h b/applications/debug/bt_debug_app/views/bt_carrier_test.h index 51a400890..07fedccc1 100644 --- a/applications/debug/bt_debug_app/views/bt_carrier_test.h +++ b/applications/debug/bt_debug_app/views/bt_carrier_test.h @@ -3,7 +3,7 @@ typedef struct BtCarrierTest BtCarrierTest; -BtCarrierTest* bt_carrier_test_alloc(); +BtCarrierTest* bt_carrier_test_alloc(void); void bt_carrier_test_free(BtCarrierTest* bt_carrier_test); diff --git a/applications/debug/bt_debug_app/views/bt_packet_test.c b/applications/debug/bt_debug_app/views/bt_packet_test.c index 8a56a3003..c30c6b5d2 100644 --- a/applications/debug/bt_debug_app/views/bt_packet_test.c +++ b/applications/debug/bt_debug_app/views/bt_packet_test.c @@ -97,7 +97,7 @@ static void bt_test_packet_timer_callback(void* context) { } } -BtPacketTest* bt_packet_test_alloc() { +BtPacketTest* bt_packet_test_alloc(void) { BtPacketTest* bt_packet_test = malloc(sizeof(BtPacketTest)); bt_packet_test->bt_test = bt_test_alloc(); bt_test_set_context(bt_packet_test->bt_test, bt_packet_test); diff --git a/applications/debug/bt_debug_app/views/bt_packet_test.h b/applications/debug/bt_debug_app/views/bt_packet_test.h index 8ea449b21..e31af3218 100644 --- a/applications/debug/bt_debug_app/views/bt_packet_test.h +++ b/applications/debug/bt_debug_app/views/bt_packet_test.h @@ -3,7 +3,7 @@ typedef struct BtPacketTest BtPacketTest; -BtPacketTest* bt_packet_test_alloc(); +BtPacketTest* bt_packet_test_alloc(void); void bt_packet_test_free(BtPacketTest* bt_packet_test); diff --git a/applications/debug/bt_debug_app/views/bt_test.c b/applications/debug/bt_debug_app/views/bt_test.c index cd52b8650..792ebfd8f 100644 --- a/applications/debug/bt_debug_app/views/bt_test.c +++ b/applications/debug/bt_debug_app/views/bt_test.c @@ -305,7 +305,7 @@ void bt_test_process_back(BtTest* bt_test) { } } -BtTest* bt_test_alloc() { +BtTest* bt_test_alloc(void) { BtTest* bt_test = malloc(sizeof(BtTest)); bt_test->view = view_alloc(); view_set_context(bt_test->view, bt_test); diff --git a/applications/debug/bt_debug_app/views/bt_test.h b/applications/debug/bt_debug_app/views/bt_test.h index 2d738cbd0..9d5ea26ec 100644 --- a/applications/debug/bt_debug_app/views/bt_test.h +++ b/applications/debug/bt_debug_app/views/bt_test.h @@ -12,7 +12,7 @@ typedef void (*BtTestBackCallback)(void* context); typedef struct BtTestParam BtTestParam; typedef void (*BtTestParamChangeCallback)(BtTestParam* param); -BtTest* bt_test_alloc(); +BtTest* bt_test_alloc(void); void bt_test_free(BtTest* bt_test); diff --git a/applications/debug/ccid_test/ccid_test_app.c b/applications/debug/ccid_test/ccid_test_app.c index 3d7fba39d..50b356696 100644 --- a/applications/debug/ccid_test/ccid_test_app.c +++ b/applications/debug/ccid_test/ccid_test_app.c @@ -90,7 +90,7 @@ uint32_t ccid_test_exit(void* context) { return VIEW_NONE; } -CcidTestApp* ccid_test_app_alloc() { +CcidTestApp* ccid_test_app_alloc(void) { CcidTestApp* app = malloc(sizeof(CcidTestApp)); // Gui diff --git a/applications/debug/crash_test/crash_test.c b/applications/debug/crash_test/crash_test.c index 92f1668be..ae0074fe1 100644 --- a/applications/debug/crash_test/crash_test.c +++ b/applications/debug/crash_test/crash_test.c @@ -50,7 +50,7 @@ static void crash_test_submenu_callback(void* context, uint32_t index) { furi_halt("Crash test: furi_halt"); break; default: - furi_crash("Programming error"); + furi_crash(); } } @@ -59,7 +59,7 @@ static uint32_t crash_test_exit_callback(void* context) { return VIEW_NONE; } -CrashTest* crash_test_alloc() { +CrashTest* crash_test_alloc(void) { CrashTest* instance = malloc(sizeof(CrashTest)); View* view = NULL; diff --git a/applications/debug/direct_draw/direct_draw.c b/applications/debug/direct_draw/direct_draw.c index 63e03530a..bc1e55459 100644 --- a/applications/debug/direct_draw/direct_draw.c +++ b/applications/debug/direct_draw/direct_draw.c @@ -26,7 +26,7 @@ static void gui_input_events_callback(const void* value, void* ctx) { } } -static DirectDraw* direct_draw_alloc() { +static DirectDraw* direct_draw_alloc(void) { DirectDraw* instance = malloc(sizeof(DirectDraw)); instance->input = furi_record_open(RECORD_INPUT_EVENTS); diff --git a/applications/debug/display_test/display_test.c b/applications/debug/display_test/display_test.c index 8065a23a1..ac1b6c65d 100644 --- a/applications/debug/display_test/display_test.c +++ b/applications/debug/display_test/display_test.c @@ -121,7 +121,7 @@ static void display_config_set_contrast(VariableItem* item) { display_test_reload_config(instance); } -DisplayTest* display_test_alloc() { +DisplayTest* display_test_alloc(void) { DisplayTest* instance = malloc(sizeof(DisplayTest)); View* view = NULL; diff --git a/applications/debug/display_test/view_display_test.c b/applications/debug/display_test/view_display_test.c index b47c74c6c..d4fe433ef 100644 --- a/applications/debug/display_test/view_display_test.c +++ b/applications/debug/display_test/view_display_test.c @@ -154,7 +154,7 @@ static void view_display_test_timer_callback(void* context) { instance->view, ViewDisplayTestModel * model, { model->counter++; }, true); } -ViewDisplayTest* view_display_test_alloc() { +ViewDisplayTest* view_display_test_alloc(void) { ViewDisplayTest* instance = malloc(sizeof(ViewDisplayTest)); instance->view = view_alloc(); diff --git a/applications/debug/display_test/view_display_test.h b/applications/debug/display_test/view_display_test.h index cafa142a8..ca78e5ffe 100644 --- a/applications/debug/display_test/view_display_test.h +++ b/applications/debug/display_test/view_display_test.h @@ -5,7 +5,7 @@ typedef struct ViewDisplayTest ViewDisplayTest; -ViewDisplayTest* view_display_test_alloc(); +ViewDisplayTest* view_display_test_alloc(void); void view_display_test_free(ViewDisplayTest* instance); diff --git a/applications/debug/expansion_test/expansion_test.c b/applications/debug/expansion_test/expansion_test.c index a0b8b42e8..fc7fb1894 100644 --- a/applications/debug/expansion_test/expansion_test.c +++ b/applications/debug/expansion_test/expansion_test.c @@ -81,7 +81,7 @@ static void expansion_test_app_serial_rx_callback( } } -static ExpansionTestApp* expansion_test_app_alloc() { +static ExpansionTestApp* expansion_test_app_alloc(void) { ExpansionTestApp* instance = malloc(sizeof(ExpansionTestApp)); instance->buf = furi_stream_buffer_alloc(RECEIVE_BUFFER_SIZE, 1); return instance; diff --git a/applications/debug/lfrfid_debug/lfrfid_debug.c b/applications/debug/lfrfid_debug/lfrfid_debug.c index 63d66b68b..8776f8b7a 100644 --- a/applications/debug/lfrfid_debug/lfrfid_debug.c +++ b/applications/debug/lfrfid_debug/lfrfid_debug.c @@ -12,7 +12,7 @@ static bool lfrfid_debug_back_event_callback(void* context) { return scene_manager_handle_back_event(app->scene_manager); } -static LfRfidDebug* lfrfid_debug_alloc() { +static LfRfidDebug* lfrfid_debug_alloc(void) { LfRfidDebug* app = malloc(sizeof(LfRfidDebug)); app->view_dispatcher = view_dispatcher_alloc(); diff --git a/applications/debug/lfrfid_debug/views/lfrfid_debug_view_tune.c b/applications/debug/lfrfid_debug/views/lfrfid_debug_view_tune.c index 9e48a7e27..6b9501e5b 100644 --- a/applications/debug/lfrfid_debug/views/lfrfid_debug_view_tune.c +++ b/applications/debug/lfrfid_debug/views/lfrfid_debug_view_tune.c @@ -170,7 +170,7 @@ static bool lfrfid_debug_view_tune_input_callback(InputEvent* event, void* conte return consumed; } -LfRfidTuneView* lfrfid_debug_view_tune_alloc() { +LfRfidTuneView* lfrfid_debug_view_tune_alloc(void) { LfRfidTuneView* tune_view = malloc(sizeof(LfRfidTuneView)); tune_view->view = view_alloc(); view_set_context(tune_view->view, tune_view); diff --git a/applications/debug/lfrfid_debug/views/lfrfid_debug_view_tune.h b/applications/debug/lfrfid_debug/views/lfrfid_debug_view_tune.h index be54b63f9..a0ee4cbf5 100644 --- a/applications/debug/lfrfid_debug/views/lfrfid_debug_view_tune.h +++ b/applications/debug/lfrfid_debug/views/lfrfid_debug_view_tune.h @@ -3,7 +3,7 @@ typedef struct LfRfidTuneView LfRfidTuneView; -LfRfidTuneView* lfrfid_debug_view_tune_alloc(); +LfRfidTuneView* lfrfid_debug_view_tune_alloc(void); void lfrfid_debug_view_tune_free(LfRfidTuneView* tune_view); diff --git a/applications/debug/locale_test/locale_test.c b/applications/debug/locale_test/locale_test.c index a7cbd52f8..1ca077db1 100644 --- a/applications/debug/locale_test/locale_test.c +++ b/applications/debug/locale_test/locale_test.c @@ -53,7 +53,7 @@ static uint32_t locale_test_exit(void* context) { return VIEW_NONE; } -static LocaleTestApp* locale_test_alloc() { +static LocaleTestApp* locale_test_alloc(void) { LocaleTestApp* app = malloc(sizeof(LocaleTestApp)); // Gui diff --git a/applications/debug/rpc_debug_app/rpc_debug_app.c b/applications/debug/rpc_debug_app/rpc_debug_app.c index 2a0756383..5e53c221e 100644 --- a/applications/debug/rpc_debug_app/rpc_debug_app.c +++ b/applications/debug/rpc_debug_app/rpc_debug_app.c @@ -83,7 +83,7 @@ static bool rpc_debug_app_rpc_init_rpc(RpcDebugApp* app, const char* args) { return ret; } -static RpcDebugApp* rpc_debug_app_alloc() { +static RpcDebugApp* rpc_debug_app_alloc(void) { RpcDebugApp* app = malloc(sizeof(RpcDebugApp)); app->gui = furi_record_open(RECORD_GUI); diff --git a/applications/debug/speaker_debug/speaker_debug.c b/applications/debug/speaker_debug/speaker_debug.c index e01d5b8ec..82a6fbc77 100644 --- a/applications/debug/speaker_debug/speaker_debug.c +++ b/applications/debug/speaker_debug/speaker_debug.c @@ -21,7 +21,7 @@ typedef struct { Cli* cli; } SpeakerDebugApp; -static SpeakerDebugApp* speaker_app_alloc() { +static SpeakerDebugApp* speaker_app_alloc(void) { SpeakerDebugApp* app = (SpeakerDebugApp*)malloc(sizeof(SpeakerDebugApp)); app->music_worker = music_worker_alloc(); app->message_queue = furi_message_queue_alloc(8, sizeof(SpeakerDebugAppMessage)); diff --git a/applications/debug/subghz_test/protocol/princeton_for_testing.c b/applications/debug/subghz_test/protocol/princeton_for_testing.c index 334a8241b..70f323937 100644 --- a/applications/debug/subghz_test/protocol/princeton_for_testing.c +++ b/applications/debug/subghz_test/protocol/princeton_for_testing.c @@ -38,7 +38,7 @@ typedef enum { PrincetonDecoderStepCheckDuration, } PrincetonDecoderStep; -SubGhzEncoderPrinceton* subghz_encoder_princeton_for_testing_alloc() { +SubGhzEncoderPrinceton* subghz_encoder_princeton_for_testing_alloc(void) { SubGhzEncoderPrinceton* instance = malloc(sizeof(SubGhzEncoderPrinceton)); return instance; } diff --git a/applications/debug/subghz_test/protocol/princeton_for_testing.h b/applications/debug/subghz_test/protocol/princeton_for_testing.h index 7b4201d38..281cb148b 100644 --- a/applications/debug/subghz_test/protocol/princeton_for_testing.h +++ b/applications/debug/subghz_test/protocol/princeton_for_testing.h @@ -15,7 +15,7 @@ typedef void (*SubGhzDecoderPrincetonCallback)(SubGhzDecoderPrinceton* parser, v * Allocate SubGhzEncoderPrinceton * @return pointer to SubGhzEncoderPrinceton instance */ -SubGhzEncoderPrinceton* subghz_encoder_princeton_for_testing_alloc(); +SubGhzEncoderPrinceton* subghz_encoder_princeton_for_testing_alloc(void); /** * Free SubGhzEncoderPrinceton instance @@ -69,7 +69,7 @@ LevelDuration subghz_encoder_princeton_for_testing_yield(void* context); * Allocate SubGhzDecoderPrinceton * @return SubGhzDecoderPrinceton* */ -SubGhzDecoderPrinceton* subghz_decoder_princeton_for_testing_alloc(); +SubGhzDecoderPrinceton* subghz_decoder_princeton_for_testing_alloc(void); /** * Free SubGhzDecoderPrinceton diff --git a/applications/debug/subghz_test/scenes/subghz_test_scene_show_only_rx.c b/applications/debug/subghz_test/scenes/subghz_test_scene_show_only_rx.c index 3d5a54355..d8eade41d 100644 --- a/applications/debug/subghz_test/scenes/subghz_test_scene_show_only_rx.c +++ b/applications/debug/subghz_test/scenes/subghz_test_scene_show_only_rx.c @@ -12,7 +12,7 @@ void subghz_test_scene_show_only_rx_on_enter(void* context) { // Setup view Popup* popup = app->popup; - const char* header_text = "Transmission is blocked"; + const char* header_text = "Transmission is Blocked"; const char* message_text = "Transmission on\nthis frequency is\nrestricted in\nyour region"; if(!furi_hal_region_is_provisioned()) { header_text = "Firmware update needed"; diff --git a/applications/debug/subghz_test/subghz_test_app.c b/applications/debug/subghz_test/subghz_test_app.c index 704941fb2..6eba864f6 100644 --- a/applications/debug/subghz_test/subghz_test_app.c +++ b/applications/debug/subghz_test/subghz_test_app.c @@ -21,7 +21,7 @@ static void subghz_test_app_tick_event_callback(void* context) { scene_manager_handle_tick_event(app->scene_manager); } -SubGhzTestApp* subghz_test_app_alloc() { +SubGhzTestApp* subghz_test_app_alloc(void) { SubGhzTestApp* app = malloc(sizeof(SubGhzTestApp)); // GUI diff --git a/applications/debug/subghz_test/views/subghz_test_carrier.c b/applications/debug/subghz_test/views/subghz_test_carrier.c index 53e309b7c..a941cd4bb 100644 --- a/applications/debug/subghz_test/views/subghz_test_carrier.c +++ b/applications/debug/subghz_test/views/subghz_test_carrier.c @@ -186,7 +186,7 @@ void subghz_test_carrier_rssi_timer_callback(void* context) { false); } -SubGhzTestCarrier* subghz_test_carrier_alloc() { +SubGhzTestCarrier* subghz_test_carrier_alloc(void) { SubGhzTestCarrier* subghz_test_carrier = malloc(sizeof(SubGhzTestCarrier)); // View allocation and configuration diff --git a/applications/debug/subghz_test/views/subghz_test_carrier.h b/applications/debug/subghz_test/views/subghz_test_carrier.h index 7db3343ed..3d6c4a38d 100644 --- a/applications/debug/subghz_test/views/subghz_test_carrier.h +++ b/applications/debug/subghz_test/views/subghz_test_carrier.h @@ -15,7 +15,7 @@ void subghz_test_carrier_set_callback( SubGhzTestCarrierCallback callback, void* context); -SubGhzTestCarrier* subghz_test_carrier_alloc(); +SubGhzTestCarrier* subghz_test_carrier_alloc(void); void subghz_test_carrier_free(SubGhzTestCarrier* subghz_test_carrier); diff --git a/applications/debug/subghz_test/views/subghz_test_packet.c b/applications/debug/subghz_test/views/subghz_test_packet.c index 1f3458296..d50f10ad4 100644 --- a/applications/debug/subghz_test/views/subghz_test_packet.c +++ b/applications/debug/subghz_test/views/subghz_test_packet.c @@ -236,7 +236,7 @@ void subghz_test_packet_exit(void* context) { furi_hal_subghz_sleep(); } -SubGhzTestPacket* subghz_test_packet_alloc() { +SubGhzTestPacket* subghz_test_packet_alloc(void) { SubGhzTestPacket* instance = malloc(sizeof(SubGhzTestPacket)); // View allocation and configuration diff --git a/applications/debug/subghz_test/views/subghz_test_packet.h b/applications/debug/subghz_test/views/subghz_test_packet.h index f384cf4fe..3a8204f1f 100644 --- a/applications/debug/subghz_test/views/subghz_test_packet.h +++ b/applications/debug/subghz_test/views/subghz_test_packet.h @@ -15,7 +15,7 @@ void subghz_test_packet_set_callback( SubGhzTestPacketCallback callback, void* context); -SubGhzTestPacket* subghz_test_packet_alloc(); +SubGhzTestPacket* subghz_test_packet_alloc(void); void subghz_test_packet_free(SubGhzTestPacket* subghz_test_packet); diff --git a/applications/debug/subghz_test/views/subghz_test_static.c b/applications/debug/subghz_test/views/subghz_test_static.c index 6764fd5ca..22ad662c5 100644 --- a/applications/debug/subghz_test/views/subghz_test_static.c +++ b/applications/debug/subghz_test/views/subghz_test_static.c @@ -164,7 +164,7 @@ void subghz_test_static_exit(void* context) { furi_hal_subghz_sleep(); } -SubGhzTestStatic* subghz_test_static_alloc() { +SubGhzTestStatic* subghz_test_static_alloc(void) { SubGhzTestStatic* instance = malloc(sizeof(SubGhzTestStatic)); // View allocation and configuration diff --git a/applications/debug/subghz_test/views/subghz_test_static.h b/applications/debug/subghz_test/views/subghz_test_static.h index 902036431..3bb6156f7 100644 --- a/applications/debug/subghz_test/views/subghz_test_static.h +++ b/applications/debug/subghz_test/views/subghz_test_static.h @@ -15,7 +15,7 @@ void subghz_test_static_set_callback( SubGhzTestStaticCallback callback, void* context); -SubGhzTestStatic* subghz_test_static_alloc(); +SubGhzTestStatic* subghz_test_static_alloc(void); void subghz_test_static_free(SubGhzTestStatic* subghz_static); diff --git a/applications/debug/unit_tests/bit_lib/bit_lib_test.c b/applications/debug/unit_tests/bit_lib/bit_lib_test.c index 42b494413..239a3b562 100644 --- a/applications/debug/unit_tests/bit_lib/bit_lib_test.c +++ b/applications/debug/unit_tests/bit_lib/bit_lib_test.c @@ -734,7 +734,7 @@ MU_TEST_SUITE(test_bit_lib) { MU_RUN_TEST(test_bit_lib_bytes_to_num_bcd); } -int run_minunit_test_bit_lib() { +int run_minunit_test_bit_lib(void) { MU_RUN_SUITE(test_bit_lib); return MU_EXIT_CODE; } \ No newline at end of file diff --git a/applications/debug/unit_tests/bt/bt_test.c b/applications/debug/unit_tests/bt/bt_test.c index 32cf6533f..a09b9894b 100644 --- a/applications/debug/unit_tests/bt/bt_test.c +++ b/applications/debug/unit_tests/bt/bt_test.c @@ -17,7 +17,7 @@ typedef struct { BtTest* bt_test = NULL; -void bt_test_alloc() { +void bt_test_alloc(void) { bt_test = malloc(sizeof(BtTest)); bt_test->storage = furi_record_open(RECORD_STORAGE); bt_test->nvm_ram_buff_dut = malloc(BT_TEST_NVM_RAM_BUFF_SIZE); @@ -27,7 +27,7 @@ void bt_test_alloc() { bt_test->bt_keys_storage, bt_test->nvm_ram_buff_dut, BT_TEST_NVM_RAM_BUFF_SIZE); } -void bt_test_free() { +void bt_test_free(void) { furi_check(bt_test); free(bt_test->nvm_ram_buff_ref); free(bt_test->nvm_ram_buff_dut); @@ -37,7 +37,7 @@ void bt_test_free() { bt_test = NULL; } -static void bt_test_keys_storage_profile() { +static void bt_test_keys_storage_profile(void) { // Emulate nvm change on initial connection const int nvm_change_size_on_connection = 88; for(size_t i = 0; i < nvm_change_size_on_connection; i++) { @@ -82,7 +82,7 @@ static void bt_test_keys_storage_profile() { "Wrong buffer loaded"); } -static void bt_test_keys_remove_test_file() { +static void bt_test_keys_remove_test_file(void) { mu_assert( storage_simply_remove(bt_test->storage, BT_TEST_KEY_STORAGE_FILE_PATH), "Can't remove test file"); @@ -104,7 +104,7 @@ MU_TEST_SUITE(test_bt) { bt_test_free(); } -int run_minunit_test_bt() { +int run_minunit_test_bt(void) { MU_RUN_SUITE(test_bt); return MU_EXIT_CODE; } diff --git a/applications/debug/unit_tests/datetimelib/datetimelib_test.c b/applications/debug/unit_tests/datetimelib/datetimelib_test.c index 42bc7dbed..c171a4413 100644 --- a/applications/debug/unit_tests/datetimelib/datetimelib_test.c +++ b/applications/debug/unit_tests/datetimelib/datetimelib_test.c @@ -112,7 +112,7 @@ MU_TEST_SUITE(test_datetime_validate_datetime) { MU_TEST(test_datetime_timestamp_to_datetime_min) { uint32_t test_value = 0; - DateTime min_datetime_expected = {0, 0, 0, 1, 1, 1970, 0}; + DateTime min_datetime_expected = {0, 0, 0, 1, 1, 1970, 4}; DateTime result = {0}; datetime_timestamp_to_datetime(test_value, &result); @@ -122,7 +122,7 @@ MU_TEST(test_datetime_timestamp_to_datetime_min) { MU_TEST(test_datetime_timestamp_to_datetime_max) { uint32_t test_value = UINT32_MAX; - DateTime max_datetime_expected = {6, 28, 15, 7, 2, 2106, 0}; + DateTime max_datetime_expected = {6, 28, 15, 7, 2, 2106, 7}; DateTime result = {0}; datetime_timestamp_to_datetime(test_value, &result); @@ -141,10 +141,26 @@ MU_TEST(test_datetime_timestamp_to_datetime_to_timestamp) { mu_assert_int_eq(test_value, result); } +MU_TEST(test_datetime_timestamp_to_datetime_weekday) { + uint32_t test_value = 1709748421; // Wed Mar 06 18:07:01 2024 UTC + + DateTime datetime = {0}; + datetime_timestamp_to_datetime(test_value, &datetime); + + mu_assert_int_eq(datetime.hour, 18); + mu_assert_int_eq(datetime.minute, 7); + mu_assert_int_eq(datetime.second, 1); + mu_assert_int_eq(datetime.day, 6); + mu_assert_int_eq(datetime.month, 3); + mu_assert_int_eq(datetime.weekday, 3); + mu_assert_int_eq(datetime.year, 2024); +} + MU_TEST_SUITE(test_datetime_timestamp_to_datetime_suite) { MU_RUN_TEST(test_datetime_timestamp_to_datetime_min); MU_RUN_TEST(test_datetime_timestamp_to_datetime_max); MU_RUN_TEST(test_datetime_timestamp_to_datetime_to_timestamp); + MU_RUN_TEST(test_datetime_timestamp_to_datetime_weekday); } MU_TEST(test_datetime_datetime_to_timestamp_min) { @@ -166,7 +182,7 @@ MU_TEST_SUITE(test_datetime_datetime_to_timestamp_suite) { MU_RUN_TEST(test_datetime_datetime_to_timestamp_max); } -int run_minunit_test_datetime() { +int run_minunit_test_datetime(void) { MU_RUN_SUITE(test_datetime_timestamp_to_datetime_suite); MU_RUN_SUITE(test_datetime_datetime_to_timestamp_suite); MU_RUN_SUITE(test_datetime_validate_datetime); diff --git a/applications/debug/unit_tests/dialogs/dialogs_file_browser_options.c b/applications/debug/unit_tests/dialogs/dialogs_file_browser_options.c index 2d5bad4c8..657b933df 100644 --- a/applications/debug/unit_tests/dialogs/dialogs_file_browser_options.c +++ b/applications/debug/unit_tests/dialogs/dialogs_file_browser_options.c @@ -25,7 +25,7 @@ MU_TEST_SUITE(dialogs_file_browser_options) { MU_RUN_TEST(test_dialog_file_browser_set_basic_options_should_init_all_fields); } -int run_minunit_test_dialogs_file_browser_options() { +int run_minunit_test_dialogs_file_browser_options(void) { MU_RUN_SUITE(dialogs_file_browser_options); return MU_EXIT_CODE; diff --git a/applications/debug/unit_tests/expansion/expansion_test.c b/applications/debug/unit_tests/expansion/expansion_test.c index 50fe1b9f4..c6a143ed3 100644 --- a/applications/debug/unit_tests/expansion/expansion_test.c +++ b/applications/debug/unit_tests/expansion/expansion_test.c @@ -194,7 +194,7 @@ MU_TEST_SUITE(test_expansion_suite) { MU_RUN_TEST(test_expansion_garbage_input); } -int run_minunit_test_expansion() { +int run_minunit_test_expansion(void) { MU_RUN_SUITE(test_expansion_suite); return MU_EXIT_CODE; } diff --git a/applications/debug/unit_tests/flipper_format/flipper_format_string_test.c b/applications/debug/unit_tests/flipper_format/flipper_format_string_test.c index 920a22a43..99bb5dda5 100644 --- a/applications/debug/unit_tests/flipper_format/flipper_format_string_test.c +++ b/applications/debug/unit_tests/flipper_format/flipper_format_string_test.c @@ -331,7 +331,7 @@ MU_TEST_SUITE(flipper_format_string_suite) { MU_RUN_TEST(flipper_format_file_test); } -int run_minunit_test_flipper_format_string() { +int run_minunit_test_flipper_format_string(void) { MU_RUN_SUITE(flipper_format_string_suite); return MU_EXIT_CODE; } diff --git a/applications/debug/unit_tests/flipper_format/flipper_format_test.c b/applications/debug/unit_tests/flipper_format/flipper_format_test.c index 012e905b6..471055fb0 100644 --- a/applications/debug/unit_tests/flipper_format/flipper_format_test.c +++ b/applications/debug/unit_tests/flipper_format/flipper_format_test.c @@ -103,14 +103,14 @@ static bool storage_write_string(const char* path, const char* data) { return result; } -static void tests_setup() { +static void tests_setup(void) { Storage* storage = furi_record_open(RECORD_STORAGE); mu_assert(storage_simply_remove_recursive(storage, TEST_DIR_NAME), "Cannot clean data"); mu_assert(storage_simply_mkdir(storage, TEST_DIR_NAME), "Cannot create dir"); furi_record_close(RECORD_STORAGE); } -static void tests_teardown() { +static void tests_teardown(void) { Storage* storage = furi_record_open(RECORD_STORAGE); mu_assert(storage_simply_remove_recursive(storage, TEST_DIR_NAME), "Cannot clean data"); furi_record_close(RECORD_STORAGE); @@ -545,7 +545,7 @@ MU_TEST_SUITE(flipper_format) { tests_teardown(); } -int run_minunit_test_flipper_format() { +int run_minunit_test_flipper_format(void) { MU_RUN_SUITE(flipper_format); return MU_EXIT_CODE; } diff --git a/applications/debug/unit_tests/float_tools/float_tools_test.c b/applications/debug/unit_tests/float_tools/float_tools_test.c index fc5b4ecfd..91ac46937 100644 --- a/applications/debug/unit_tests/float_tools/float_tools_test.c +++ b/applications/debug/unit_tests/float_tools/float_tools_test.c @@ -54,7 +54,7 @@ MU_TEST_SUITE(float_tools_suite) { MU_RUN_TEST(float_tools_equal_test); } -int run_minunit_test_float_tools() { +int run_minunit_test_float_tools(void) { MU_RUN_SUITE(float_tools_suite); return MU_EXIT_CODE; } diff --git a/applications/debug/unit_tests/furi/furi_memmgr_test.c b/applications/debug/unit_tests/furi/furi_memmgr_test.c index 9012eed78..01e2c17f6 100644 --- a/applications/debug/unit_tests/furi/furi_memmgr_test.c +++ b/applications/debug/unit_tests/furi/furi_memmgr_test.c @@ -4,7 +4,7 @@ #include #include -void test_furi_memmgr() { +void test_furi_memmgr(void) { void* ptr; // allocate memory case diff --git a/applications/debug/unit_tests/furi/furi_pubsub_test.c b/applications/debug/unit_tests/furi/furi_pubsub_test.c index ddaeb746d..8925ff42e 100644 --- a/applications/debug/unit_tests/furi/furi_pubsub_test.c +++ b/applications/debug/unit_tests/furi/furi_pubsub_test.c @@ -15,7 +15,7 @@ void test_pubsub_handler(const void* arg, void* ctx) { pubsub_context_value = *(uint32_t*)ctx; } -void test_furi_pubsub() { +void test_furi_pubsub(void) { FuriPubSub* test_pubsub = NULL; FuriPubSubSubscription* test_pubsub_subscription = NULL; diff --git a/applications/debug/unit_tests/furi/furi_record_test.c b/applications/debug/unit_tests/furi/furi_record_test.c index 236e1efc5..10a5a8393 100644 --- a/applications/debug/unit_tests/furi/furi_record_test.c +++ b/applications/debug/unit_tests/furi/furi_record_test.c @@ -5,7 +5,7 @@ #define TEST_RECORD_NAME "test/holding" -void test_furi_create_open() { +void test_furi_create_open(void) { // Test that record does not exist mu_check(furi_record_exists(TEST_RECORD_NAME) == false); diff --git a/applications/debug/unit_tests/furi/furi_string_test.c b/applications/debug/unit_tests/furi/furi_string_test.c index 6cbcc0dcc..853076b67 100644 --- a/applications/debug/unit_tests/furi/furi_string_test.c +++ b/applications/debug/unit_tests/furi/furi_string_test.c @@ -462,7 +462,7 @@ MU_TEST_SUITE(test_suite) { MU_RUN_TEST(mu_test_furi_string_utf8); } -int run_minunit_test_furi_string() { +int run_minunit_test_furi_string(void) { MU_RUN_SUITE(test_suite); return MU_EXIT_CODE; diff --git a/applications/debug/unit_tests/furi/furi_test.c b/applications/debug/unit_tests/furi/furi_test.c index 33ec5fd01..e287f9927 100644 --- a/applications/debug/unit_tests/furi/furi_test.c +++ b/applications/debug/unit_tests/furi/furi_test.c @@ -4,11 +4,11 @@ #include "../minunit.h" // v2 tests -void test_furi_create_open(); -void test_furi_concurrent_access(); -void test_furi_pubsub(); +void test_furi_create_open(void); +void test_furi_concurrent_access(void); +void test_furi_pubsub(void); -void test_furi_memmgr(); +void test_furi_memmgr(void); static int foo = 0; @@ -50,7 +50,7 @@ MU_TEST_SUITE(test_suite) { MU_RUN_TEST(mu_test_furi_memmgr); } -int run_minunit_test_furi() { +int run_minunit_test_furi(void) { MU_RUN_SUITE(test_suite); return MU_EXIT_CODE; diff --git a/applications/debug/unit_tests/furi_hal/furi_hal_crypto_tests.c b/applications/debug/unit_tests/furi_hal/furi_hal_crypto_tests.c index b06d51130..c2bd6c5f8 100644 --- a/applications/debug/unit_tests/furi_hal/furi_hal_crypto_tests.c +++ b/applications/debug/unit_tests/furi_hal/furi_hal_crypto_tests.c @@ -409,16 +409,16 @@ static const uint8_t tv_gcm_tag_4[16] = { 0x1B, }; -static void furi_hal_crypto_ctr_setup() { +static void furi_hal_crypto_ctr_setup(void) { } -static void furi_hal_crypto_ctr_teardown() { +static void furi_hal_crypto_ctr_teardown(void) { } -static void furi_hal_crypto_gcm_setup() { +static void furi_hal_crypto_gcm_setup(void) { } -static void furi_hal_crypto_gcm_teardown() { +static void furi_hal_crypto_gcm_teardown(void) { } MU_TEST(furi_hal_crypto_ctr_1) { @@ -595,7 +595,7 @@ MU_TEST_SUITE(furi_hal_crypto_gcm_test) { MU_RUN_TEST(furi_hal_crypto_gcm_4); } -int run_minunit_test_furi_hal_crypto() { +int run_minunit_test_furi_hal_crypto(void) { MU_RUN_SUITE(furi_hal_crypto_ctr_test); MU_RUN_SUITE(furi_hal_crypto_gcm_test); return MU_EXIT_CODE; diff --git a/applications/debug/unit_tests/furi_hal/furi_hal_tests.c b/applications/debug/unit_tests/furi_hal/furi_hal_tests.c index a75615d0c..0c5cec8a6 100644 --- a/applications/debug/unit_tests/furi_hal/furi_hal_tests.c +++ b/applications/debug/unit_tests/furi_hal/furi_hal_tests.c @@ -14,19 +14,19 @@ #define EEPROM_PAGE_SIZE 16 #define EEPROM_WRITE_DELAY_MS 6 -static void furi_hal_i2c_int_setup() { +static void furi_hal_i2c_int_setup(void) { furi_hal_i2c_acquire(&furi_hal_i2c_handle_power); } -static void furi_hal_i2c_int_teardown() { +static void furi_hal_i2c_int_teardown(void) { furi_hal_i2c_release(&furi_hal_i2c_handle_power); } -static void furi_hal_i2c_ext_setup() { +static void furi_hal_i2c_ext_setup(void) { furi_hal_i2c_acquire(&furi_hal_i2c_handle_external); } -static void furi_hal_i2c_ext_teardown() { +static void furi_hal_i2c_ext_teardown(void) { furi_hal_i2c_release(&furi_hal_i2c_handle_external); } @@ -227,7 +227,7 @@ MU_TEST_SUITE(furi_hal_i2c_ext_suite) { MU_RUN_TEST(furi_hal_i2c_ext_eeprom); } -int run_minunit_test_furi_hal() { +int run_minunit_test_furi_hal(void) { MU_RUN_SUITE(furi_hal_i2c_int_suite); MU_RUN_SUITE(furi_hal_i2c_ext_suite); return MU_EXIT_CODE; diff --git a/applications/debug/unit_tests/infrared/infrared_test.c b/applications/debug/unit_tests/infrared/infrared_test.c index 294c2da9a..4442fedb3 100644 --- a/applications/debug/unit_tests/infrared/infrared_test.c +++ b/applications/debug/unit_tests/infrared/infrared_test.c @@ -17,7 +17,7 @@ typedef struct { static InfraredTest* test; -static void infrared_test_alloc() { +static void infrared_test_alloc(void) { Storage* storage = furi_record_open(RECORD_STORAGE); test = malloc(sizeof(InfraredTest)); test->decoder_handler = infrared_alloc_decoder(); @@ -26,7 +26,7 @@ static void infrared_test_alloc() { test->file_path = furi_string_alloc(); } -static void infrared_test_free() { +static void infrared_test_free(void) { furi_check(test); infrared_free_decoder(test->decoder_handler); infrared_free_encoder(test->encoder_handler); @@ -426,53 +426,53 @@ MU_TEST(infrared_test_decoder_mixed) { infrared_test_run_decoder(InfraredProtocolSIRC, 3); infrared_test_run_decoder(InfraredProtocolKaseikyo, 1); infrared_test_run_decoder(InfraredProtocolRCA, 1); + infrared_test_run_decoder(InfraredProtocolPioneer, 6); } MU_TEST(infrared_test_decoder_nec) { - infrared_test_run_decoder(InfraredProtocolNEC, 1); - infrared_test_run_decoder(InfraredProtocolNEC, 2); - infrared_test_run_decoder(InfraredProtocolNEC, 3); + for(uint32_t i = 1; i <= 3; ++i) { + infrared_test_run_decoder(InfraredProtocolNEC, i); + } } MU_TEST(infrared_test_decoder_unexpected_end_in_sequence) { - infrared_test_run_decoder(InfraredProtocolNEC, 1); - infrared_test_run_decoder(InfraredProtocolNEC, 1); - infrared_test_run_decoder(InfraredProtocolNEC, 2); - infrared_test_run_decoder(InfraredProtocolNEC, 2); + for(uint32_t i = 1; i <= 2; ++i) { + infrared_test_run_decoder(InfraredProtocolNEC, i); + infrared_test_run_decoder(InfraredProtocolNEC, i); + } } MU_TEST(infrared_test_decoder_necext1) { - infrared_test_run_decoder(InfraredProtocolNECext, 1); - infrared_test_run_decoder(InfraredProtocolNECext, 1); + for(uint32_t i = 0; i < 2; ++i) { + UNUSED(i); + infrared_test_run_decoder(InfraredProtocolNECext, 1); + } } MU_TEST(infrared_test_decoder_long_packets_with_nec_start) { - infrared_test_run_decoder(InfraredProtocolNEC42ext, 1); - infrared_test_run_decoder(InfraredProtocolNEC42ext, 2); + for(uint32_t i = 1; i <= 2; ++i) { + infrared_test_run_decoder(InfraredProtocolNEC42ext, i); + } } MU_TEST(infrared_test_encoder_sirc) { - infrared_test_run_encoder(InfraredProtocolSIRC, 1); - infrared_test_run_encoder(InfraredProtocolSIRC, 2); + for(uint32_t i = 1; i <= 2; ++i) { + infrared_test_run_encoder(InfraredProtocolSIRC, i); + } } MU_TEST(infrared_test_decoder_sirc) { - infrared_test_run_decoder(InfraredProtocolSIRC, 3); - infrared_test_run_decoder(InfraredProtocolSIRC, 1); - infrared_test_run_decoder(InfraredProtocolSIRC, 2); - infrared_test_run_decoder(InfraredProtocolSIRC, 4); - infrared_test_run_decoder(InfraredProtocolSIRC, 5); + for(uint32_t i = 1; i <= 5; ++i) { + infrared_test_run_decoder(InfraredProtocolSIRC, 5); + } } MU_TEST(infrared_test_decoder_rc5) { infrared_test_run_decoder(InfraredProtocolRC5X, 1); - infrared_test_run_decoder(InfraredProtocolRC5, 1); - infrared_test_run_decoder(InfraredProtocolRC5, 2); - infrared_test_run_decoder(InfraredProtocolRC5, 3); - infrared_test_run_decoder(InfraredProtocolRC5, 4); - infrared_test_run_decoder(InfraredProtocolRC5, 5); - infrared_test_run_decoder(InfraredProtocolRC5, 6); - infrared_test_run_decoder(InfraredProtocolRC5, 7); + + for(uint32_t i = 1; i <= 7; ++i) { + infrared_test_run_decoder(InfraredProtocolRC5, i); + } } MU_TEST(infrared_test_encoder_rc5x) { @@ -492,21 +492,21 @@ MU_TEST(infrared_test_encoder_rc6) { } MU_TEST(infrared_test_decoder_kaseikyo) { - infrared_test_run_decoder(InfraredProtocolKaseikyo, 1); - infrared_test_run_decoder(InfraredProtocolKaseikyo, 2); - infrared_test_run_decoder(InfraredProtocolKaseikyo, 3); - infrared_test_run_decoder(InfraredProtocolKaseikyo, 4); - infrared_test_run_decoder(InfraredProtocolKaseikyo, 5); - infrared_test_run_decoder(InfraredProtocolKaseikyo, 6); + for(uint32_t i = 1; i <= 6; ++i) { + infrared_test_run_decoder(InfraredProtocolKaseikyo, i); + } } MU_TEST(infrared_test_decoder_rca) { - infrared_test_run_decoder(InfraredProtocolRCA, 1); - infrared_test_run_decoder(InfraredProtocolRCA, 2); - infrared_test_run_decoder(InfraredProtocolRCA, 3); - infrared_test_run_decoder(InfraredProtocolRCA, 4); - infrared_test_run_decoder(InfraredProtocolRCA, 5); - infrared_test_run_decoder(InfraredProtocolRCA, 6); + for(uint32_t i = 1; i <= 6; ++i) { + infrared_test_run_decoder(InfraredProtocolRCA, i); + } +} + +MU_TEST(infrared_test_decoder_pioneer) { + for(uint32_t i = 1; i <= 11; ++i) { + infrared_test_run_decoder(InfraredProtocolPioneer, i); + } } MU_TEST(infrared_test_encoder_decoder_all) { @@ -520,6 +520,7 @@ MU_TEST(infrared_test_encoder_decoder_all) { infrared_test_run_encoder_decoder(InfraredProtocolSIRC, 1); infrared_test_run_encoder_decoder(InfraredProtocolKaseikyo, 1); infrared_test_run_encoder_decoder(InfraredProtocolRCA, 1); + infrared_test_run_encoder_decoder(InfraredProtocolPioneer, 1); } MU_TEST_SUITE(infrared_test) { @@ -539,11 +540,12 @@ MU_TEST_SUITE(infrared_test) { MU_RUN_TEST(infrared_test_decoder_necext1); MU_RUN_TEST(infrared_test_decoder_kaseikyo); MU_RUN_TEST(infrared_test_decoder_rca); + MU_RUN_TEST(infrared_test_decoder_pioneer); MU_RUN_TEST(infrared_test_decoder_mixed); MU_RUN_TEST(infrared_test_encoder_decoder_all); } -int run_minunit_test_infrared() { +int run_minunit_test_infrared(void) { MU_RUN_SUITE(infrared_test); return MU_EXIT_CODE; } diff --git a/applications/debug/unit_tests/lfrfid/lfrfid_protocols.c b/applications/debug/unit_tests/lfrfid/lfrfid_protocols.c index d5c2433ba..6a7dbab9c 100644 --- a/applications/debug/unit_tests/lfrfid/lfrfid_protocols.c +++ b/applications/debug/unit_tests/lfrfid/lfrfid_protocols.c @@ -547,7 +547,7 @@ MU_TEST_SUITE(test_lfrfid_protocols_suite) { MU_RUN_TEST(test_lfrfid_protocol_fdxb_emulate_simple); } -int run_minunit_test_lfrfid_protocols() { +int run_minunit_test_lfrfid_protocols(void) { MU_RUN_SUITE(test_lfrfid_protocols_suite); return MU_EXIT_CODE; } \ No newline at end of file diff --git a/applications/debug/unit_tests/manifest/manifest.c b/applications/debug/unit_tests/manifest/manifest.c index 19370b0e1..e8ac93d7c 100644 --- a/applications/debug/unit_tests/manifest/manifest.c +++ b/applications/debug/unit_tests/manifest/manifest.c @@ -69,7 +69,7 @@ MU_TEST_SUITE(manifest_suite) { MU_RUN_TEST(manifest_iteration_test); } -int run_minunit_test_manifest() { +int run_minunit_test_manifest(void) { MU_RUN_SUITE(manifest_suite); return MU_EXIT_CODE; } \ No newline at end of file diff --git a/applications/debug/unit_tests/nfc/nfc_test.c b/applications/debug/unit_tests/nfc/nfc_test.c index 29b9e80d9..c6304d53c 100644 --- a/applications/debug/unit_tests/nfc/nfc_test.c +++ b/applications/debug/unit_tests/nfc/nfc_test.c @@ -7,10 +7,13 @@ #include #include #include +#include #include #include #include #include +#include +#include #include #include @@ -22,18 +25,35 @@ #define NFC_TEST_NFC_DEV_PATH EXT_PATH("unit_tests/nfc/nfc_device_test.nfc") #define NFC_APP_MF_CLASSIC_DICT_UNIT_TEST_PATH EXT_PATH("unit_tests/mf_dict.nfc") +#define NFC_TEST_FLAG_WORKER_DONE (1) + +typedef enum { + NfcTestMfClassicSendFrameTestStateAuth, + NfcTestMfClassicSendFrameTestStateReadBlock, + + NfcTestMfClassicSendFrameTestStateFail, + NfcTestMfClassicSendFrameTestStateSuccess, +} NfcTestMfClassicSendFrameTestState; + +typedef struct { + NfcTestMfClassicSendFrameTestState state; + BitBuffer* tx_buf; + BitBuffer* rx_buf; + FuriThreadId thread_id; +} NfcTestMfClassicSendFrameTest; + typedef struct { Storage* storage; } NfcTest; static NfcTest* nfc_test = NULL; -static void nfc_test_alloc() { +static void nfc_test_alloc(void) { nfc_test = malloc(sizeof(NfcTest)); nfc_test->storage = furi_record_open(RECORD_STORAGE); } -static void nfc_test_free() { +static void nfc_test_free(void) { furi_check(nfc_test); furi_record_close(RECORD_STORAGE); @@ -292,7 +312,7 @@ MU_TEST(ntag_213_locked_reader) { nfc_free(poller); } -static void mf_ultralight_write() { +static void mf_ultralight_write(void) { Nfc* poller = nfc_alloc(); Nfc* listener = nfc_alloc(); @@ -342,7 +362,7 @@ static void mf_ultralight_write() { nfc_free(poller); } -static void mf_classic_reader() { +static void mf_classic_reader(void) { Nfc* poller = nfc_alloc(); Nfc* listener = nfc_alloc(); @@ -368,7 +388,7 @@ static void mf_classic_reader() { nfc_free(poller); } -static void mf_classic_write() { +static void mf_classic_write(void) { Nfc* poller = nfc_alloc(); Nfc* listener = nfc_alloc(); @@ -396,7 +416,7 @@ static void mf_classic_write() { nfc_free(poller); } -static void mf_classic_value_block() { +static void mf_classic_value_block(void) { Nfc* poller = nfc_alloc(); Nfc* listener = nfc_alloc(); @@ -435,6 +455,109 @@ static void mf_classic_value_block() { nfc_free(poller); } +NfcCommand mf_classic_poller_send_frame_callback(NfcGenericEventEx event, void* context) { + furi_check(event.poller); + furi_check(event.parent_event_data); + furi_check(context); + + NfcCommand command = NfcCommandContinue; + MfClassicPoller* instance = event.poller; + NfcTestMfClassicSendFrameTest* frame_test = context; + Iso14443_3aPollerEvent* iso3_event = event.parent_event_data; + + MfClassicError error = MfClassicErrorNone; + if(iso3_event->type == Iso14443_3aPollerEventTypeReady) { + if(frame_test->state == NfcTestMfClassicSendFrameTestStateAuth) { + MfClassicKey key = { + .data = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + }; + error = mf_classic_poller_auth(instance, 0, &key, MfClassicKeyTypeA, NULL); + frame_test->state = (error == MfClassicErrorNone) ? + NfcTestMfClassicSendFrameTestStateReadBlock : + NfcTestMfClassicSendFrameTestStateFail; + } else if(frame_test->state == NfcTestMfClassicSendFrameTestStateReadBlock) { + do { + const uint8_t read_block_cmd[] = { + 0x30, + 0x01, + 0x8b, + 0xb9, + }; + bit_buffer_copy_bytes(frame_test->tx_buf, read_block_cmd, sizeof(read_block_cmd)); + + error = mf_classic_poller_send_encrypted_frame( + instance, frame_test->tx_buf, frame_test->rx_buf, 200000); + if(error != MfClassicErrorNone) break; + if(bit_buffer_get_size_bytes(frame_test->rx_buf) != 18) { + error = MfClassicErrorProtocol; + break; + } + + const uint8_t* rx_data = bit_buffer_get_data(frame_test->rx_buf); + const uint8_t rx_data_ref[16] = {0}; + if(memcmp(rx_data, rx_data_ref, sizeof(rx_data_ref)) != 0) { + error = MfClassicErrorProtocol; + break; + } + } while(false); + + frame_test->state = (error == MfClassicErrorNone) ? + NfcTestMfClassicSendFrameTestStateSuccess : + NfcTestMfClassicSendFrameTestStateFail; + } else if(frame_test->state == NfcTestMfClassicSendFrameTestStateSuccess) { + command = NfcCommandStop; + } else if(frame_test->state == NfcTestMfClassicSendFrameTestStateFail) { + command = NfcCommandStop; + } + } else { + frame_test->state = NfcTestMfClassicSendFrameTestStateFail; + command = NfcCommandStop; + } + + if(command == NfcCommandStop) { + furi_thread_flags_set(frame_test->thread_id, NFC_TEST_FLAG_WORKER_DONE); + } + + return command; +} + +MU_TEST(mf_classic_send_frame_test) { + Nfc* poller = nfc_alloc(); + Nfc* listener = nfc_alloc(); + + NfcDevice* nfc_device = nfc_device_alloc(); + nfc_data_generator_fill_data(NfcDataGeneratorTypeMfClassic4k_7b, nfc_device); + NfcListener* mfc_listener = nfc_listener_alloc( + listener, NfcProtocolMfClassic, nfc_device_get_data(nfc_device, NfcProtocolMfClassic)); + nfc_listener_start(mfc_listener, NULL, NULL); + + NfcPoller* mfc_poller = nfc_poller_alloc(poller, NfcProtocolMfClassic); + NfcTestMfClassicSendFrameTest context = { + .state = NfcTestMfClassicSendFrameTestStateAuth, + .thread_id = furi_thread_get_current_id(), + .tx_buf = bit_buffer_alloc(32), + .rx_buf = bit_buffer_alloc(32), + }; + nfc_poller_start_ex(mfc_poller, mf_classic_poller_send_frame_callback, &context); + + uint32_t flag = + furi_thread_flags_wait(NFC_TEST_FLAG_WORKER_DONE, FuriFlagWaitAny, FuriWaitForever); + mu_assert(flag == NFC_TEST_FLAG_WORKER_DONE, "Wrong thread flag"); + nfc_poller_stop(mfc_poller); + nfc_poller_free(mfc_poller); + + mu_assert( + context.state == NfcTestMfClassicSendFrameTestStateSuccess, "Wrong test state at the end"); + + bit_buffer_free(context.tx_buf); + bit_buffer_free(context.rx_buf); + nfc_listener_stop(mfc_listener); + nfc_listener_free(mfc_listener); + nfc_device_free(nfc_device); + nfc_free(listener); + nfc_free(poller); +} + MU_TEST(mf_classic_dict_test) { Storage* storage = furi_record_open(RECORD_STORAGE); if(storage_common_stat(storage, NFC_APP_MF_CLASSIC_DICT_UNIT_TEST_PATH, NULL) == FSE_OK) { @@ -538,17 +661,17 @@ MU_TEST_SUITE(nfc) { MU_RUN_TEST(mf_classic_1k_7b_file_test); MU_RUN_TEST(mf_classic_4k_4b_file_test); MU_RUN_TEST(mf_classic_4k_7b_file_test); - MU_RUN_TEST(mf_classic_reader); + MU_RUN_TEST(mf_classic_reader); MU_RUN_TEST(mf_classic_write); MU_RUN_TEST(mf_classic_value_block); - + MU_RUN_TEST(mf_classic_send_frame_test); MU_RUN_TEST(mf_classic_dict_test); nfc_test_free(); } -int run_minunit_test_nfc() { +int run_minunit_test_nfc(void) { MU_RUN_SUITE(nfc); return MU_EXIT_CODE; } diff --git a/applications/debug/unit_tests/nfc/nfc_transport.c b/applications/debug/unit_tests/nfc/nfc_transport.c index e9f4e2134..6886ef66d 100644 --- a/applications/debug/unit_tests/nfc/nfc_transport.c +++ b/applications/debug/unit_tests/nfc/nfc_transport.c @@ -115,7 +115,7 @@ static void nfc_prepare_col_res_data( } } -Nfc* nfc_alloc() { +Nfc* nfc_alloc(void) { Nfc* instance = malloc(sizeof(Nfc)); return instance; diff --git a/applications/debug/unit_tests/power/power_test.c b/applications/debug/unit_tests/power/power_test.c index a9b66b221..03e0ad269 100644 --- a/applications/debug/unit_tests/power/power_test.c +++ b/applications/debug/unit_tests/power/power_test.c @@ -63,7 +63,7 @@ MU_TEST_SUITE(test_power_suite) { power_test_deinit(); } -int run_minunit_test_power() { +int run_minunit_test_power(void) { MU_RUN_SUITE(test_power_suite); return MU_EXIT_CODE; } diff --git a/applications/debug/unit_tests/protocol_dict/protocol_dict_test.c b/applications/debug/unit_tests/protocol_dict/protocol_dict_test.c index 73e77ec90..6ecaa1a52 100644 --- a/applications/debug/unit_tests/protocol_dict/protocol_dict_test.c +++ b/applications/debug/unit_tests/protocol_dict/protocol_dict_test.c @@ -18,7 +18,7 @@ typedef struct { static const uint32_t protocol_0_decoder_result = 0xDEADBEEF; -static void* protocol_0_alloc() { +static void* protocol_0_alloc(void) { void* data = malloc(sizeof(Protocol0Data)); return data; } @@ -63,7 +63,7 @@ typedef struct { static const uint64_t protocol_1_decoder_result = 0x1234567890ABCDEF; -static void* protocol_1_alloc() { +static void* protocol_1_alloc(void) { void* data = malloc(sizeof(Protocol1Data)); return data; } @@ -216,7 +216,7 @@ MU_TEST_SUITE(test_protocol_dict_suite) { MU_RUN_TEST(test_protocol_dict); } -int run_minunit_test_protocol_dict() { +int run_minunit_test_protocol_dict(void) { MU_RUN_SUITE(test_protocol_dict_suite); return MU_EXIT_CODE; } \ No newline at end of file diff --git a/applications/debug/unit_tests/resources/unit_tests/infrared/test_pioneer.irtest b/applications/debug/unit_tests/resources/unit_tests/infrared/test_pioneer.irtest new file mode 100644 index 000000000..f05b33eec --- /dev/null +++ b/applications/debug/unit_tests/resources/unit_tests/infrared/test_pioneer.irtest @@ -0,0 +1,205 @@ +Filetype: IR tests file +Version: 1 +# +name: decoder_input1 +type: raw +data: 25557 8437 4188 571 1538 595 1514 567 1542 570 1539 573 501 565 1544 568 506 571 1539 573 501 565 509 568 508 569 506 571 1538 574 501 565 1543 569 506 571 504 573 1536 566 1544 568 506 592 1517 574 1535 567 507 570 505 572 1537 575 500 566 508 600 1509 572 503 574 501 565 1544 568 1540 593 +# +name: decoder_expected1 +type: parsed_array +count: 1 +# +protocol: Pioneer +address: AF 00 00 00 +command: 36 00 00 00 +repeat: false +# +name: decoder_input2 +type: raw +data: 25609 8444 4152 564 1568 544 1565 547 1561 541 1568 544 530 547 1536 566 510 567 1567 545 529 548 526 540 535 542 508 569 1539 573 527 539 1543 569 506 571 504 573 1561 541 508 569 507 570 1538 564 1545 567 507 570 505 572 1537 565 509 568 1541 571 1538 564 511 566 509 568 1539 573 1537 596 +# +name: decoder_expected2 +type: parsed_array +count: 1 +# +protocol: Pioneer +address: AF 00 00 00 +command: 32 00 00 00 +repeat: false +# +name: decoder_input3 +type: raw +data: 25582 8448 4176 571 1537 565 1544 568 1540 572 1537 575 500 566 1542 570 505 572 1537 575 500 566 508 569 506 571 504 573 1536 565 510 567 1542 570 504 573 1536 566 1543 569 506 571 504 573 1536 566 1543 569 506 571 504 573 502 575 500 566 1542 570 1539 573 502 575 500 566 1542 570 1540 572 +# +name: decoder_expected3 +type: parsed_array +count: 1 +# +protocol: Pioneer +address: AF 00 00 00 +command: 33 00 00 00 +repeat: false +# +name: decoder_input4 +type: raw +data: 25594 8443 4181 568 1542 570 505 572 1538 564 1545 567 508 569 1540 572 504 573 1536 566 510 567 1542 571 505 572 504 573 1562 540 510 567 1543 570 506 571 504 573 503 574 501 565 510 567 509 568 507 570 1539 573 502 565 1545 568 1542 571 1539 573 1536 566 1544 569 1541 572 503 574 1537 565 +# +name: decoder_expected4 +type: parsed_array +count: 1 +# +protocol: Pioneer +address: AD 00 00 00 +command: 40 00 00 00 +repeat: false +# +name: decoder_input5 +type: raw +data: 25556 8475 4150 597 1512 600 476 601 1509 603 1506 595 480 597 1512 600 476 601 1508 594 482 595 1515 597 478 599 477 600 1510 602 473 604 1506 595 480 597 1513 599 476 601 475 602 474 603 472 594 482 595 1514 598 477 600 476 601 1508 594 1516 596 1513 599 1510 602 1507 595 480 597 1513 599 +# +name: decoder_expected5 +type: parsed_array +count: 1 +# +protocol: Pioneer +address: AD 00 00 00 +command: 41 00 00 00 +repeat: false +# +name: decoder_input6 +type: raw +data: 25567 8471 4155 604 1506 596 480 597 1513 599 1510 603 473 594 1515 597 478 599 1511 602 474 603 1507 595 480 597 479 598 1511 602 474 603 1506 596 480 597 478 599 1511 602 474 603 472 594 481 596 479 598 1512 601 474 603 1506 596 479 598 1511 602 1508 594 1515 598 1512 600 475 602 1507 595 +# +name: decoder_expected6 +type: parsed_array +count: 1 +# +protocol: Pioneer +address: AD 00 00 00 +command: 42 00 00 00 +repeat: false +# +name: decoder_input7 +type: raw +data: 25584 8444 4180 569 1541 572 504 573 1536 566 1544 569 507 570 1539 574 501 566 1569 596 455 570 1540 573 502 575 501 565 1544 569 507 570 1565 548 503 574 1535 567 1543 570 506 571 529 548 502 565 511 566 1543 601 475 571 504 573 503 574 1536 566 1543 570 1539 574 1536 566 509 568 1541 572 +# +name: decoder_expected7 +type: parsed_array +count: 1 +# +protocol: Pioneer +address: AD 00 00 00 +command: 43 00 00 00 +repeat: false +# +name: decoder_input8 +type: raw +data: 25562 8445 4181 568 1543 570 505 572 1538 575 1535 567 508 569 1539 573 503 595 1514 567 508 600 1509 572 503 595 481 596 1513 568 507 601 1508 573 502 575 501 566 1543 570 506 571 504 573 1536 566 510 567 508 600 475 571 1539 573 502 575 1534 568 1542 571 505 572 1537 575 1534 568 1542 571 +# +name: decoder_expected8 +type: parsed_array +count: 1 +# +protocol: Pioneer +address: AD 00 00 00 +command: 12 00 00 00 +repeat: false +# +name: decoder_input9 +type: raw +data: 25558 8470 4152 597 1513 600 476 601 1508 594 1515 598 478 599 1509 593 483 594 1515 598 478 599 1510 603 474 592 482 595 1514 599 477 600 1509 593 483 594 481 596 1513 600 476 601 1508 594 1515 598 478 599 476 601 474 593 1517 596 479 598 1512 601 474 603 472 594 1515 598 1511 602 1508 594 +# +name: decoder_expected9 +type: parsed_array +count: 1 +# +protocol: Pioneer +address: AD 00 00 00 +command: 1A 00 00 00 +repeat: false +# +name: decoder_input10 +type: raw +data: 25587 8442 4179 601 1507 595 481 565 1544 600 1509 593 482 595 1513 568 507 570 1539 594 481 565 1544 600 476 570 505 593 1516 597 479 598 1511 591 484 593 481 575 1534 600 476 570 1539 595 480 597 478 599 476 570 505 593 1517 564 511 597 1511 602 474 572 1537 597 1513 600 1509 572 1537 565 +# +name: decoder_expected10 +type: parsed_array +count: 1 +# +protocol: Pioneer +address: AD 00 00 00 +command: 0A 00 00 00 +repeat: false +# +name: decoder_input11 +type: raw +data: 25554 8474 4149 600 1510 603 472 594 1515 597 1512 601 475 602 1507 595 480 597 1513 599 475 602 1508 594 481 596 479 598 1512 601 474 603 1506 596 479 598 1512 601 1508 594 481 596 1513 599 476 601 474 603 472 594 481 596 480 597 478 599 1510 603 473 593 1515 597 1512 601 1509 603 1506 596 +# +name: decoder_expected11 +type: parsed_array +count: 1 +# +protocol: Pioneer +address: AD 00 00 00 +command: 0B 00 00 00 +repeat: false +# +name: encoder_decoder_input1 +type: parsed_array +count: 11 +# +protocol: Pioneer +address: AF 00 00 00 +command: 36 00 00 00 +repeat: false +# +protocol: Pioneer +address: AF 00 00 00 +command: 32 00 00 00 +repeat: false +# +protocol: Pioneer +address: AF 00 00 00 +command: 33 00 00 00 +repeat: false +# +protocol: Pioneer +address: AD 00 00 00 +command: 40 00 00 00 +repeat: false +# +protocol: Pioneer +address: AD 00 00 00 +command: 41 00 00 00 +repeat: false +# +protocol: Pioneer +address: AD 00 00 00 +command: 42 00 00 00 +repeat: false +# +protocol: Pioneer +address: AD 00 00 00 +command: 43 00 00 00 +repeat: false +# +protocol: Pioneer +address: AD 00 00 00 +command: 12 00 00 00 +repeat: false +# +protocol: Pioneer +address: AD 00 00 00 +command: 1A 00 00 00 +repeat: false +# +protocol: Pioneer +address: AD 00 00 00 +command: 0A 00 00 00 +repeat: false +# +protocol: Pioneer +address: AD 00 00 00 +command: 0B 00 00 00 +repeat: false +# diff --git a/applications/debug/unit_tests/rpc/rpc_test.c b/applications/debug/unit_tests/rpc/rpc_test.c index 3faf61572..cd692d69d 100644 --- a/applications/debug/unit_tests/rpc/rpc_test.c +++ b/applications/debug/unit_tests/rpc/rpc_test.c @@ -1840,7 +1840,7 @@ MU_TEST_SUITE(test_rpc_session) { furi_record_close(RECORD_STORAGE); } -int run_minunit_test_rpc() { +int run_minunit_test_rpc(void) { Storage* storage = furi_record_open(RECORD_STORAGE); if(storage_sd_status(storage) != FSE_OK) { FURI_LOG_E(TAG, "SD card not mounted - skip storage tests"); diff --git a/applications/debug/unit_tests/storage/dirwalk_test.c b/applications/debug/unit_tests/storage/dirwalk_test.c index 19ac336ff..415ec7dd4 100644 --- a/applications/debug/unit_tests/storage/dirwalk_test.c +++ b/applications/debug/unit_tests/storage/dirwalk_test.c @@ -266,7 +266,7 @@ MU_TEST_SUITE(test_dirwalk_suite) { furi_record_close(RECORD_STORAGE); } -int run_minunit_test_dirwalk() { +int run_minunit_test_dirwalk(void) { MU_RUN_SUITE(test_dirwalk_suite); return MU_EXIT_CODE; } \ No newline at end of file diff --git a/applications/debug/unit_tests/storage/storage_test.c b/applications/debug/unit_tests/storage/storage_test.c index 5ea36935b..e4361f06c 100644 --- a/applications/debug/unit_tests/storage/storage_test.c +++ b/applications/debug/unit_tests/storage/storage_test.c @@ -36,7 +36,7 @@ static bool storage_file_create(Storage* storage, const char* path, const char* return result; } -static void storage_file_open_lock_setup() { +static void storage_file_open_lock_setup(void) { Storage* storage = furi_record_open(RECORD_STORAGE); File* file = storage_file_alloc(storage); storage_simply_remove(storage, STORAGE_LOCKED_FILE); @@ -47,7 +47,7 @@ static void storage_file_open_lock_setup() { furi_record_close(RECORD_STORAGE); } -static void storage_file_open_lock_teardown() { +static void storage_file_open_lock_teardown(void) { Storage* storage = furi_record_open(RECORD_STORAGE); mu_check(storage_simply_remove(storage, STORAGE_LOCKED_FILE)); furi_record_close(RECORD_STORAGE); @@ -702,7 +702,7 @@ MU_TEST_SUITE(test_md5_calc_suite) { MU_RUN_TEST(test_md5_calc); } -int run_minunit_test_storage() { +int run_minunit_test_storage(void) { MU_RUN_SUITE(storage_file); MU_RUN_SUITE(storage_file_64k); MU_RUN_SUITE(storage_dir); diff --git a/applications/debug/unit_tests/stream/stream_test.c b/applications/debug/unit_tests/stream/stream_test.c index 2fa3b21a2..3e31773b4 100644 --- a/applications/debug/unit_tests/stream/stream_test.c +++ b/applications/debug/unit_tests/stream/stream_test.c @@ -526,7 +526,7 @@ MU_TEST_SUITE(stream_suite) { MU_RUN_TEST(stream_buffered_large_file_test); } -int run_minunit_test_stream() { +int run_minunit_test_stream(void) { MU_RUN_SUITE(stream_suite); return MU_EXIT_CODE; } diff --git a/applications/debug/unit_tests/subghz/subghz_test.c b/applications/debug/unit_tests/subghz/subghz_test.c index 53894c551..a2f00885b 100644 --- a/applications/debug/unit_tests/subghz/subghz_test.c +++ b/applications/debug/unit_tests/subghz/subghz_test.c @@ -314,7 +314,7 @@ static LevelDuration subghz_hal_async_tx_test_yield(void* context) { furi_crash("Yield after reset"); } } else { - furi_crash("Programming error"); + furi_crash(); } } @@ -904,7 +904,7 @@ MU_TEST_SUITE(subghz) { subghz_test_deinit(); } -int run_minunit_test_subghz() { +int run_minunit_test_subghz(void) { MU_RUN_SUITE(subghz); return MU_EXIT_CODE; } diff --git a/applications/debug/unit_tests/test_index.c b/applications/debug/unit_tests/test_index.c index 60132a161..5d0282bd7 100644 --- a/applications/debug/unit_tests/test_index.c +++ b/applications/debug/unit_tests/test_index.c @@ -8,31 +8,31 @@ #define TAG "UnitTests" -int run_minunit_test_furi(); -int run_minunit_test_furi_hal(); -int run_minunit_test_furi_hal_crypto(); -int run_minunit_test_furi_string(); -int run_minunit_test_infrared(); -int run_minunit_test_rpc(); -int run_minunit_test_manifest(); -int run_minunit_test_flipper_format(); -int run_minunit_test_flipper_format_string(); -int run_minunit_test_stream(); -int run_minunit_test_storage(); -int run_minunit_test_subghz(); -int run_minunit_test_dirwalk(); -int run_minunit_test_power(); -int run_minunit_test_protocol_dict(); -int run_minunit_test_lfrfid_protocols(); -int run_minunit_test_nfc(); -int run_minunit_test_bit_lib(); -int run_minunit_test_datetime(); -int run_minunit_test_float_tools(); -int run_minunit_test_bt(); -int run_minunit_test_dialogs_file_browser_options(); -int run_minunit_test_expansion(); +int run_minunit_test_furi(void); +int run_minunit_test_furi_hal(void); +int run_minunit_test_furi_hal_crypto(void); +int run_minunit_test_furi_string(void); +int run_minunit_test_infrared(void); +int run_minunit_test_rpc(void); +int run_minunit_test_manifest(void); +int run_minunit_test_flipper_format(void); +int run_minunit_test_flipper_format_string(void); +int run_minunit_test_stream(void); +int run_minunit_test_storage(void); +int run_minunit_test_subghz(void); +int run_minunit_test_dirwalk(void); +int run_minunit_test_power(void); +int run_minunit_test_protocol_dict(void); +int run_minunit_test_lfrfid_protocols(void); +int run_minunit_test_nfc(void); +int run_minunit_test_bit_lib(void); +int run_minunit_test_datetime(void); +int run_minunit_test_float_tools(void); +int run_minunit_test_bt(void); +int run_minunit_test_dialogs_file_browser_options(void); +int run_minunit_test_expansion(void); -typedef int (*UnitTestEntry)(); +typedef int (*UnitTestEntry)(void); typedef struct { const char* name; @@ -66,7 +66,7 @@ const UnitTest unit_tests[] = { {.name = "expansion", .entry = run_minunit_test_expansion}, }; -void minunit_print_progress() { +void minunit_print_progress(void) { static const char progress[] = {'\\', '|', '/', '-'}; static uint8_t progress_counter = 0; static uint32_t last_tick = 0; @@ -157,7 +157,7 @@ void unit_tests_cli(Cli* cli, FuriString* args, void* context) { furi_record_close(RECORD_LOADER); } -void unit_tests_on_system_start() { +void unit_tests_on_system_start(void) { #ifdef SRV_CLI Cli* cli = furi_record_open(RECORD_CLI); diff --git a/applications/debug/unit_tests/varint/varint_test.c b/applications/debug/unit_tests/varint/varint_test.c index 8faab1368..ac444013d 100644 --- a/applications/debug/unit_tests/varint/varint_test.c +++ b/applications/debug/unit_tests/varint/varint_test.c @@ -82,7 +82,7 @@ MU_TEST_SUITE(test_varint_suite) { MU_RUN_TEST(test_varint_rand_i); } -int run_minunit_test_varint() { +int run_minunit_test_varint(void) { MU_RUN_SUITE(test_varint_suite); return MU_EXIT_CODE; } \ No newline at end of file diff --git a/applications/debug/usb_test/usb_test.c b/applications/debug/usb_test/usb_test.c index ed86c37a8..ddec9d9b0 100644 --- a/applications/debug/usb_test/usb_test.c +++ b/applications/debug/usb_test/usb_test.c @@ -55,7 +55,7 @@ uint32_t usb_test_exit(void* context) { return VIEW_NONE; } -UsbTestApp* usb_test_app_alloc() { +UsbTestApp* usb_test_app_alloc(void) { UsbTestApp* app = malloc(sizeof(UsbTestApp)); // Gui diff --git a/applications/drivers/subghz/cc1101_ext/cc1101_ext.c b/applications/drivers/subghz/cc1101_ext/cc1101_ext.c index f8ce82bf3..429a4b3a4 100644 --- a/applications/drivers/subghz/cc1101_ext/cc1101_ext.c +++ b/applications/drivers/subghz/cc1101_ext/cc1101_ext.c @@ -93,7 +93,7 @@ typedef struct { static SubGhzDeviceCC1101Ext* subghz_device_cc1101_ext = NULL; -static bool subghz_device_cc1101_ext_check_init() { +static bool subghz_device_cc1101_ext_check_init(void) { furi_assert(subghz_device_cc1101_ext->state == SubGhzDeviceCC1101ExtStateInit); subghz_device_cc1101_ext->state = SubGhzDeviceCC1101ExtStateIdle; @@ -177,6 +177,14 @@ static bool subghz_device_cc1101_ext_check_init() { furi_hal_gpio_init( subghz_device_cc1101_ext->g0_pin, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + // Reset GDO2 (!TX/RX) to floating state + cc1101_status = cc1101_write_reg( + subghz_device_cc1101_ext->spi_bus_handle, CC1101_IOCFG2, CC1101IocfgHighImpedance); + if(cc1101_status.CHIP_RDYn != 0) { + //timeout or error + break; + } + // Go to sleep cc1101_status = cc1101_shutdown(subghz_device_cc1101_ext->spi_bus_handle); if(cc1101_status.CHIP_RDYn != 0) { @@ -198,7 +206,7 @@ static bool subghz_device_cc1101_ext_check_init() { return ret; } -bool subghz_device_cc1101_ext_alloc() { +bool subghz_device_cc1101_ext_alloc(void) { furi_assert(subghz_device_cc1101_ext == NULL); subghz_device_cc1101_ext = malloc(sizeof(SubGhzDeviceCC1101Ext)); subghz_device_cc1101_ext->state = SubGhzDeviceCC1101ExtStateInit; @@ -213,7 +221,7 @@ bool subghz_device_cc1101_ext_alloc() { return subghz_device_cc1101_ext_check_init(); } -void subghz_device_cc1101_ext_free() { +void subghz_device_cc1101_ext_free(void) { furi_assert(subghz_device_cc1101_ext != NULL); furi_hal_spi_bus_handle_deinit(subghz_device_cc1101_ext->spi_bus_handle); free(subghz_device_cc1101_ext); @@ -224,11 +232,11 @@ void subghz_device_cc1101_ext_set_async_mirror_pin(const GpioPin* pin) { subghz_device_cc1101_ext->async_mirror_pin = pin; } -const GpioPin* subghz_device_cc1101_ext_get_data_gpio() { +const GpioPin* subghz_device_cc1101_ext_get_data_gpio(void) { return subghz_device_cc1101_ext->g0_pin; } -bool subghz_device_cc1101_ext_is_connect() { +bool subghz_device_cc1101_ext_is_connect(void) { bool ret = false; if(subghz_device_cc1101_ext == NULL) { // not initialized @@ -244,7 +252,7 @@ bool subghz_device_cc1101_ext_is_connect() { return ret; } -void subghz_device_cc1101_ext_sleep() { +void subghz_device_cc1101_ext_sleep(void) { furi_assert(subghz_device_cc1101_ext->state == SubGhzDeviceCC1101ExtStateIdle); furi_hal_spi_acquire(subghz_device_cc1101_ext->spi_bus_handle); @@ -259,7 +267,7 @@ void subghz_device_cc1101_ext_sleep() { furi_hal_spi_release(subghz_device_cc1101_ext->spi_bus_handle); } -void subghz_device_cc1101_ext_dump_state() { +void subghz_device_cc1101_ext_dump_state(void) { furi_hal_spi_acquire(subghz_device_cc1101_ext->spi_bus_handle); printf( "[subghz_device_cc1101_ext] cc1101 chip %d, version %d\r\n", @@ -324,19 +332,19 @@ void subghz_device_cc1101_ext_write_packet(const uint8_t* data, uint8_t size) { furi_hal_spi_release(subghz_device_cc1101_ext->spi_bus_handle); } -void subghz_device_cc1101_ext_flush_rx() { +void subghz_device_cc1101_ext_flush_rx(void) { furi_hal_spi_acquire(subghz_device_cc1101_ext->spi_bus_handle); cc1101_flush_rx(subghz_device_cc1101_ext->spi_bus_handle); furi_hal_spi_release(subghz_device_cc1101_ext->spi_bus_handle); } -void subghz_device_cc1101_ext_flush_tx() { +void subghz_device_cc1101_ext_flush_tx(void) { furi_hal_spi_acquire(subghz_device_cc1101_ext->spi_bus_handle); cc1101_flush_tx(subghz_device_cc1101_ext->spi_bus_handle); furi_hal_spi_release(subghz_device_cc1101_ext->spi_bus_handle); } -bool subghz_device_cc1101_ext_rx_pipe_not_empty() { +bool subghz_device_cc1101_ext_rx_pipe_not_empty(void) { CC1101RxBytes status[1]; furi_hal_spi_acquire(subghz_device_cc1101_ext->spi_bus_handle); cc1101_read_reg( @@ -351,7 +359,7 @@ bool subghz_device_cc1101_ext_rx_pipe_not_empty() { } } -bool subghz_device_cc1101_ext_is_rx_data_crc_valid() { +bool subghz_device_cc1101_ext_is_rx_data_crc_valid(void) { furi_hal_spi_acquire(subghz_device_cc1101_ext->spi_bus_handle); uint8_t data[1]; cc1101_read_reg( @@ -370,14 +378,14 @@ void subghz_device_cc1101_ext_read_packet(uint8_t* data, uint8_t* size) { furi_hal_spi_release(subghz_device_cc1101_ext->spi_bus_handle); } -void subghz_device_cc1101_ext_shutdown() { +void subghz_device_cc1101_ext_shutdown(void) { furi_hal_spi_acquire(subghz_device_cc1101_ext->spi_bus_handle); // Reset and shutdown cc1101_shutdown(subghz_device_cc1101_ext->spi_bus_handle); furi_hal_spi_release(subghz_device_cc1101_ext->spi_bus_handle); } -void subghz_device_cc1101_ext_reset() { +void subghz_device_cc1101_ext_reset(void) { furi_hal_spi_acquire(subghz_device_cc1101_ext->spi_bus_handle); furi_hal_gpio_init(subghz_device_cc1101_ext->g0_pin, GpioModeAnalog, GpioPullNo, GpioSpeedLow); cc1101_switch_to_idle(subghz_device_cc1101_ext->spi_bus_handle); @@ -385,39 +393,51 @@ void subghz_device_cc1101_ext_reset() { // Warning: push pull cc1101 clock output on GD0 cc1101_write_reg( subghz_device_cc1101_ext->spi_bus_handle, CC1101_IOCFG0, CC1101IocfgHighImpedance); + // Reset GDO2 (!TX/RX) to floating state + cc1101_write_reg( + subghz_device_cc1101_ext->spi_bus_handle, CC1101_IOCFG2, CC1101IocfgHighImpedance); furi_hal_spi_release(subghz_device_cc1101_ext->spi_bus_handle); } -void subghz_device_cc1101_ext_idle() { +void subghz_device_cc1101_ext_idle(void) { furi_hal_spi_acquire(subghz_device_cc1101_ext->spi_bus_handle); cc1101_switch_to_idle(subghz_device_cc1101_ext->spi_bus_handle); //waiting for the chip to switch to IDLE mode furi_check(cc1101_wait_status_state( subghz_device_cc1101_ext->spi_bus_handle, CC1101StateIDLE, 10000)); + // Reset GDO2 (!TX/RX) to floating state + cc1101_write_reg( + subghz_device_cc1101_ext->spi_bus_handle, CC1101_IOCFG2, CC1101IocfgHighImpedance); furi_hal_spi_release(subghz_device_cc1101_ext->spi_bus_handle); } -void subghz_device_cc1101_ext_rx() { +void subghz_device_cc1101_ext_rx(void) { furi_hal_spi_acquire(subghz_device_cc1101_ext->spi_bus_handle); cc1101_switch_to_rx(subghz_device_cc1101_ext->spi_bus_handle); //waiting for the chip to switch to Rx mode furi_check( cc1101_wait_status_state(subghz_device_cc1101_ext->spi_bus_handle, CC1101StateRX, 10000)); + // Go GDO2 (!TX/RX) to high (RX state) + cc1101_write_reg( + subghz_device_cc1101_ext->spi_bus_handle, CC1101_IOCFG2, CC1101IocfgHW | CC1101_IOCFG_INV); + furi_hal_spi_release(subghz_device_cc1101_ext->spi_bus_handle); } -bool subghz_device_cc1101_ext_tx() { +bool subghz_device_cc1101_ext_tx(void) { if(subghz_device_cc1101_ext->regulation != SubGhzDeviceCC1101ExtRegulationTxRx) return false; furi_hal_spi_acquire(subghz_device_cc1101_ext->spi_bus_handle); cc1101_switch_to_tx(subghz_device_cc1101_ext->spi_bus_handle); //waiting for the chip to switch to Tx mode furi_check( cc1101_wait_status_state(subghz_device_cc1101_ext->spi_bus_handle, CC1101StateTX, 10000)); + // Go GDO2 (!TX/RX) to low (TX state) + cc1101_write_reg(subghz_device_cc1101_ext->spi_bus_handle, CC1101_IOCFG2, CC1101IocfgHW); furi_hal_spi_release(subghz_device_cc1101_ext->spi_bus_handle); return true; } -float subghz_device_cc1101_ext_get_rssi() { +float subghz_device_cc1101_ext_get_rssi(void) { furi_hal_spi_acquire(subghz_device_cc1101_ext->spi_bus_handle); int32_t rssi_dec = cc1101_get_rssi(subghz_device_cc1101_ext->spi_bus_handle); furi_hal_spi_release(subghz_device_cc1101_ext->spi_bus_handle); @@ -432,7 +452,7 @@ float subghz_device_cc1101_ext_get_rssi() { return rssi; } -uint8_t subghz_device_cc1101_ext_get_lqi() { +uint8_t subghz_device_cc1101_ext_get_lqi(void) { furi_hal_spi_acquire(subghz_device_cc1101_ext->spi_bus_handle); uint8_t data[1]; cc1101_read_reg( @@ -472,7 +492,7 @@ uint32_t subghz_device_cc1101_ext_set_frequency(uint32_t value) { return real_frequency; } -static bool subghz_device_cc1101_ext_start_debug() { +static bool subghz_device_cc1101_ext_start_debug(void) { bool ret = false; if(subghz_device_cc1101_ext->async_mirror_pin != NULL) { furi_hal_gpio_init( @@ -485,7 +505,7 @@ static bool subghz_device_cc1101_ext_start_debug() { return ret; } -static bool subghz_device_cc1101_ext_stop_debug() { +static bool subghz_device_cc1101_ext_stop_debug(void) { bool ret = false; if(subghz_device_cc1101_ext->async_mirror_pin != NULL) { furi_hal_gpio_init( @@ -495,7 +515,8 @@ static bool subghz_device_cc1101_ext_stop_debug() { return ret; } -static void subghz_device_cc1101_ext_capture_ISR() { +static void subghz_device_cc1101_ext_capture_ISR(void* context) { + UNUSED(context); if(!furi_hal_gpio_read(subghz_device_cc1101_ext->g0_pin)) { if(subghz_device_cc1101_ext->async_rx.capture_callback) { if(subghz_device_cc1101_ext->async_mirror_pin != NULL) @@ -566,7 +587,7 @@ void subghz_device_cc1101_ext_start_async_rx( subghz_device_cc1101_ext->async_rx.capture_delta_duration = 0; } -void subghz_device_cc1101_ext_stop_async_rx() { +void subghz_device_cc1101_ext_stop_async_rx(void) { furi_assert(subghz_device_cc1101_ext->state == SubGhzDeviceCC1101ExtStateAsyncRx); subghz_device_cc1101_ext->state = SubGhzDeviceCC1101ExtStateIdle; @@ -674,7 +695,8 @@ static void subghz_device_cc1101_ext_async_tx_refill(uint32_t* buffer, size_t sa } } -static void subghz_device_cc1101_ext_async_tx_dma_isr() { +static void subghz_device_cc1101_ext_async_tx_dma_isr(void* context) { + UNUSED(context); furi_assert(subghz_device_cc1101_ext->state == SubGhzDeviceCC1101ExtStateAsyncTx); #if SUBGHZ_DEVICE_CC1101_EXT_DMA_CH3_CHANNEL == LL_DMA_CHANNEL_3 @@ -803,13 +825,13 @@ bool subghz_device_cc1101_ext_start_async_tx(SubGhzDeviceCC1101ExtCallback callb return true; } -bool subghz_device_cc1101_ext_is_async_tx_complete() { +bool subghz_device_cc1101_ext_is_async_tx_complete(void) { return ( (subghz_device_cc1101_ext->state == SubGhzDeviceCC1101ExtStateAsyncTx) && (LL_TIM_GetAutoReload(TIM17) == 0)); } -void subghz_device_cc1101_ext_stop_async_tx() { +void subghz_device_cc1101_ext_stop_async_tx(void) { furi_assert(subghz_device_cc1101_ext->state == SubGhzDeviceCC1101ExtStateAsyncTx); // Shutdown radio diff --git a/applications/drivers/subghz/cc1101_ext/cc1101_ext.h b/applications/drivers/subghz/cc1101_ext/cc1101_ext.h index d972fcb66..8e8e2befb 100644 --- a/applications/drivers/subghz/cc1101_ext/cc1101_ext.h +++ b/applications/drivers/subghz/cc1101_ext/cc1101_ext.h @@ -1,6 +1,6 @@ /** - * @file furi_hal_subghz.h - * SubGhz HAL API + * @file cc1101_ext.h + * @brief External CC1101 transceiver access API. */ #pragma once @@ -28,31 +28,31 @@ void subghz_device_cc1101_ext_set_async_mirror_pin(const GpioPin* pin); * * @return pointer to the gpio pin structure */ -const GpioPin* subghz_device_cc1101_ext_get_data_gpio(); +const GpioPin* subghz_device_cc1101_ext_get_data_gpio(void); /** Initialize device * * @return true if success */ -bool subghz_device_cc1101_ext_alloc(); +bool subghz_device_cc1101_ext_alloc(void); /** Deinitialize device */ -void subghz_device_cc1101_ext_free(); +void subghz_device_cc1101_ext_free(void); /** Check and switch to power save mode Used by internal API-HAL * initialization routine Can be used to reinitialize device to safe state and * send it to sleep */ -bool subghz_device_cc1101_ext_is_connect(); +bool subghz_device_cc1101_ext_is_connect(void); /** Send device to sleep mode */ -void subghz_device_cc1101_ext_sleep(); +void subghz_device_cc1101_ext_sleep(void); /** Dump info to stdout */ -void subghz_device_cc1101_ext_dump_state(); +void subghz_device_cc1101_ext_dump_state(void); /** Load custom registers from preset * @@ -83,13 +83,13 @@ void subghz_device_cc1101_ext_write_packet(const uint8_t* data, uint8_t size); * * @return true if not empty */ -bool subghz_device_cc1101_ext_rx_pipe_not_empty(); +bool subghz_device_cc1101_ext_rx_pipe_not_empty(void); /** Check if received data crc is valid * * @return true if valid */ -bool subghz_device_cc1101_ext_is_rx_data_crc_valid(); +bool subghz_device_cc1101_ext_is_rx_data_crc_valid(void); /** Read packet from FIFO * @@ -100,47 +100,47 @@ void subghz_device_cc1101_ext_read_packet(uint8_t* data, uint8_t* size); /** Flush rx FIFO buffer */ -void subghz_device_cc1101_ext_flush_rx(); +void subghz_device_cc1101_ext_flush_rx(void); /** Flush tx FIFO buffer */ -void subghz_device_cc1101_ext_flush_tx(); +void subghz_device_cc1101_ext_flush_tx(void); /** Shutdown Issue SPWD command * @warning registers content will be lost */ -void subghz_device_cc1101_ext_shutdown(); +void subghz_device_cc1101_ext_shutdown(void); /** Reset Issue reset command * @warning registers content will be lost */ -void subghz_device_cc1101_ext_reset(); +void subghz_device_cc1101_ext_reset(void); /** Switch to Idle */ -void subghz_device_cc1101_ext_idle(); +void subghz_device_cc1101_ext_idle(void); /** Switch to Receive */ -void subghz_device_cc1101_ext_rx(); +void subghz_device_cc1101_ext_rx(void); /** Switch to Transmit * * @return true if the transfer is allowed by belonging to the region */ -bool subghz_device_cc1101_ext_tx(); +bool subghz_device_cc1101_ext_tx(void); /** Get RSSI value in dBm * * @return RSSI value */ -float subghz_device_cc1101_ext_get_rssi(); +float subghz_device_cc1101_ext_get_rssi(void); /** Get LQI * * @return LQI value */ -uint8_t subghz_device_cc1101_ext_get_lqi(); +uint8_t subghz_device_cc1101_ext_get_lqi(void); /** Check if frequency is in valid range * @@ -174,7 +174,7 @@ void subghz_device_cc1101_ext_start_async_rx( /** Disable signal timings capture Resets GPIO and TIM2 */ -void subghz_device_cc1101_ext_stop_async_rx(); +void subghz_device_cc1101_ext_stop_async_rx(void); /** Async TX callback type * @param context callback context @@ -195,11 +195,11 @@ bool subghz_device_cc1101_ext_start_async_tx(SubGhzDeviceCC1101ExtCallback callb * * @return true if TX complete */ -bool subghz_device_cc1101_ext_is_async_tx_complete(); +bool subghz_device_cc1101_ext_is_async_tx_complete(void); /** Stop async transmission and cleanup resources Resets GPIO, TIM2, and DMA1 */ -void subghz_device_cc1101_ext_stop_async_tx(); +void subghz_device_cc1101_ext_stop_async_tx(void); #ifdef __cplusplus } diff --git a/applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.c b/applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.c index 1f1193154..68f2b8aff 100644 --- a/applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.c +++ b/applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.c @@ -105,6 +105,6 @@ static const FlipperAppPluginDescriptor subghz_device_cc1101_ext_descriptor = { .entry_point = &subghz_device_cc1101_ext, }; -const FlipperAppPluginDescriptor* subghz_device_cc1101_ext_ep() { +const FlipperAppPluginDescriptor* subghz_device_cc1101_ext_ep(void) { return &subghz_device_cc1101_ext_descriptor; } \ No newline at end of file diff --git a/applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h b/applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h index cf1ff3ee0..3fcee45d5 100644 --- a/applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h +++ b/applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h @@ -5,4 +5,4 @@ typedef struct SubGhzDeviceCC1101Ext SubGhzDeviceCC1101Ext; -const FlipperAppPluginDescriptor* subghz_device_cc1101_ext_ep(); +const FlipperAppPluginDescriptor* subghz_device_cc1101_ext_ep(void); diff --git a/applications/examples/example_adc/application.fam b/applications/examples/example_adc/application.fam new file mode 100644 index 000000000..68aa2ac4d --- /dev/null +++ b/applications/examples/example_adc/application.fam @@ -0,0 +1,9 @@ +App( + appid="example_adc", + name="Example: ADC", + apptype=FlipperAppType.EXTERNAL, + entry_point="example_adc_main", + requires=["gui"], + stack_size=1 * 1024, + fap_category="Examples", +) diff --git a/applications/examples/example_adc/example_adc.c b/applications/examples/example_adc/example_adc.c new file mode 100644 index 000000000..53f8d5c12 --- /dev/null +++ b/applications/examples/example_adc/example_adc.c @@ -0,0 +1,176 @@ +/** + * @file example_adc.c + * @brief ADC example. + */ +#include +#include + +#include +#include +#include + +const uint8_t font[] = + "`\2\3\2\3\4\1\2\4\5\11\0\376\6\376\7\377\1M\2\263\3\370 \6\315\364\371\6!\12\315" + "\364\201\260\35\312Q\0\42\11\315tJI\316\13\0#\14\315\264\223dP*\203R'\1$\15\315\264" + "\262A\311\266D\251l\71\0%\15\315\264\7%\61)J\42\345 \0&\14\315\264\263$\13\223\266$" + "\7\1'\10\315\364\201\60\347\10(\10\315\364\32[\313\0)\11\315\64\322b[\35\2*\12\315\264\263" + "(\222j\71\15+\11\315\364I\331\226\23\1,\10\315\364\271\205Y\10-\10\315\364\31t\26\0.\10" + "\315\364\71\346(\0/\14\315\364\221\60\13\263\60\13C\0\60\13\315\264\245Jb)E:\12\61\12\315" + "\364\201Ll\333A\0\62\12\315\264\245bV\33r\20\63\13\315\264\245Z\232D\221\216\2\64\14\315\364" + "\201LJ\242!\313v\20\65\14\315t\207$\134\223(\322Q\0\66\13\315\264\245p\252D\221\216\2\67" + "\12\315t\207\60+\326a\0\70\13\315\264\245\222T\211\42\35\5\71\13\315\264\245J\24\215\221\216\2:" + "\11\315\364i\71!G\1;\12\315\364I\71!\314B\0<\11\315\364\341\254Z\7\1=\12\315\364)" + "C<\344$\0>\11\315\364\301\264V\207\1\77\12\315\264\245Z\35\312a\0@\14\315\264\245J\242$" + "J\272\203\0A\15\315\264\245J\224\14I\224D\71\10B\13\315t\247\312T\211\222\35\5C\12\315\264" + "\245JX\212t\24D\15\315t\247J\224DI\224\354(\0E\14\315t\207$\234\302p\310A\0F" + "\12\315t\207$\234\302:\1G\14\315\264\245J\230(Q\244\243\0H\17\315t\243$J\206$J\242" + "$\312A\0I\11\315\264\267\260m\7\1J\12\315\364\221\260%\212t\24K\14\315t\243\244\244iI" + "T\7\1L\11\315t\303\216C\16\2M\17\315t\243dH\206$J\242$\312A\0N\16\315t\243" + "D\251(Q\22%Q\16\2O\15\315\264\245J\224DI\24\351(\0P\12\315t\247J\224LaN" + "Q\15\315\264\245J\224DI\42\251\61\0R\14\315t\247J\224L\225(\7\1S\13\315\264\245\222\232" + "D\221\216\2T\10\315\264\267\260;\12U\16\315t\243$J\242$J\242HG\1V\15\315t\243$" + "J\242$Jj\71\14W\17\315t\243$J\242dH\206$\312A\0X\15\315t\243$\212\64\251\22" + "\345 \0Y\13\315t\243$Jja\35\6Z\12\315t\207\60k\34r\20[\10\315\264\264\260G\31" + "\134\12\315\264\303\64L\303\64\14]\10\315t\304\276\351\0^\11\315\364\201,\311\271\1_\7\315\364y" + "\35\4`\10\315t\322\234'\0a\14\315\364IK\224$R\222\203\0b\13\315t\303p\252D\311\216" + "\2c\12\315\364IR%\335A\0d\14\315\364\221\60Z\242$\212v\20e\12\315\364I\322\220\244;" + "\10f\12\315\364\221,\333\302:\12g\14\315\364IK\224D\321\30I\0h\14\315t\303p\252DI" + "\224\203\0i\12\315\364\201\34\21k;\10j\12\315\364\201\34\21\273e\0k\13\315t\303J\244%Q" + "\35\4l\10\315\264\305n;\10m\14\315\364)CRQ\22\245\216\1n\13\315\364)%\245\224D\71" + "\10o\12\315\364IR%\212t\24p\13\315\364)S%J\246\60\4q\13\315\364IK\224D\321X" + "\1r\11\315\364)%\245\230\23s\12\315\364I\313\232\354(\0t\13\315\364\201\60\333\302\64\7\1u" + "\15\315\364)Q\22%\211\224\344 \0v\13\315\364)Q\22%\265\34\6w\13\315\364)\25%Q\272" + "\203\0x\12\315\364)Q\244Iu\20y\15\315\364)Q\22%Q\64F\22\0z\12\315\364)CV" + "\33r\20{\12\315\364\212\265\64\254&\0|\7\315\264\302~\7}\12\315t\322\260\232\205\265\14~\11" + "\315\364II;\13\0\177\6\315\364\371\6\0\0\0\4\377\377\0"; + +#define FONT_HEIGHT (8u) + +typedef float (*ValueConverter)(FuriHalAdcHandle* handle, uint16_t value); + +typedef struct { + const GpioPinRecord* pin; + float value; + ValueConverter converter; + const char* suffix; +} DataItem; + +typedef struct { + size_t count; + DataItem* items; +} Data; + +const GpioPinRecord item_vref = {.name = "VREF", .channel = FuriHalAdcChannelVREFINT}; +const GpioPinRecord item_temp = {.name = "TEMP", .channel = FuriHalAdcChannelTEMPSENSOR}; +const GpioPinRecord item_vbat = {.name = "VBAT", .channel = FuriHalAdcChannelVBAT}; + +static void app_draw_callback(Canvas* canvas, void* ctx) { + furi_assert(ctx); + Data* data = ctx; + + canvas_set_custom_u8g2_font(canvas, font); + char buffer[64]; + int32_t x = 0, y = FONT_HEIGHT; + for(size_t i = 0; i < data->count; i++) { + if(i == canvas_height(canvas) / FONT_HEIGHT) { + x = 64; + y = FONT_HEIGHT; + } + + snprintf( + buffer, + sizeof(buffer), + "%4s: %4.0f%s\n", + data->items[i].pin->name, + (double)data->items[i].value, + data->items[i].suffix); + canvas_draw_str(canvas, x, y, buffer); + y += FONT_HEIGHT; + } +} + +static void app_input_callback(InputEvent* input_event, void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; + furi_message_queue_put(event_queue, input_event, FuriWaitForever); +} + +int32_t example_adc_main(void* p) { + UNUSED(p); + + // Data + Data data = {}; + for(size_t i = 0; i < gpio_pins_count; i++) { + if(gpio_pins[i].channel != FuriHalAdcChannelNone) { + data.count++; + } + } + data.count += 3; // Special channels + data.items = malloc(data.count * sizeof(DataItem)); + size_t item_pos = 0; + for(size_t i = 0; i < gpio_pins_count; i++) { + if(gpio_pins[i].channel != FuriHalAdcChannelNone) { + furi_hal_gpio_init(gpio_pins[i].pin, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + data.items[item_pos].pin = &gpio_pins[i]; + data.items[item_pos].converter = furi_hal_adc_convert_to_voltage; + data.items[item_pos].suffix = "mV"; + item_pos++; + } + } + data.items[item_pos].pin = &item_vref; + data.items[item_pos].converter = furi_hal_adc_convert_vref; + data.items[item_pos].suffix = "mV"; + item_pos++; + data.items[item_pos].pin = &item_temp; + data.items[item_pos].converter = furi_hal_adc_convert_temp; + data.items[item_pos].suffix = "C"; + item_pos++; + data.items[item_pos].pin = &item_vbat; + data.items[item_pos].converter = furi_hal_adc_convert_vbat; + data.items[item_pos].suffix = "mV"; + item_pos++; + furi_assert(item_pos == data.count); + + // Alloc message queue + FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(InputEvent)); + + // Configure view port + ViewPort* view_port = view_port_alloc(); + view_port_draw_callback_set(view_port, app_draw_callback, &data); + view_port_input_callback_set(view_port, app_input_callback, event_queue); + + // Register view port in GUI + Gui* gui = furi_record_open(RECORD_GUI); + gui_add_view_port(gui, view_port, GuiLayerFullscreen); + + // Initialize ADC + FuriHalAdcHandle* adc_handle = furi_hal_adc_acquire(); + furi_hal_adc_configure(adc_handle); + + // Process events + InputEvent event; + bool running = true; + while(running) { + if(furi_message_queue_get(event_queue, &event, 100) == FuriStatusOk) { + if(event.type == InputTypePress && event.key == InputKeyBack) { + running = false; + } + } else { + for(size_t i = 0; i < data.count; i++) { + data.items[i].value = data.items[i].converter( + adc_handle, furi_hal_adc_read(adc_handle, data.items[i].pin->channel)); + } + view_port_update(view_port); + } + } + + furi_hal_adc_release(adc_handle); + view_port_enabled_set(view_port, false); + gui_remove_view_port(gui, view_port); + view_port_free(view_port); + furi_message_queue_free(event_queue); + furi_record_close(RECORD_GUI); + free(data.items); + + return 0; +} diff --git a/applications/examples/example_apps_assets/README.md b/applications/examples/example_apps_assets/README.md index 024c0877b..bf7e63e42 100644 --- a/applications/examples/example_apps_assets/README.md +++ b/applications/examples/example_apps_assets/README.md @@ -1,7 +1,11 @@ -# Apps Assets folder Example +# Apps Assets folder Example {#example_app_assets} This example shows how to use the Apps Assets folder to store data that is not part of the application itself, but is required for its operation, and that data is provided with the application. +## Source code + +Source code for this example can be found [here](https://github.com/flipperdevices/flipperzero-firmware/tree/dev/applications/examples/example_apps_assets). + ## What is the Apps Assets Folder? The **Apps Assets** folder is a folder where external applications unpack their assets. diff --git a/applications/examples/example_apps_assets/example_apps_assets.c b/applications/examples/example_apps_assets/example_apps_assets.c index 2c2cc8a87..dae81a8da 100644 --- a/applications/examples/example_apps_assets/example_apps_assets.c +++ b/applications/examples/example_apps_assets/example_apps_assets.c @@ -1,3 +1,7 @@ +/** + * @file example_apps_assets.c + * @brief Application assets example. + */ #include #include #include diff --git a/applications/examples/example_apps_data/README.md b/applications/examples/example_apps_data/README.md index 0e51daf18..fb7617547 100644 --- a/applications/examples/example_apps_data/README.md +++ b/applications/examples/example_apps_data/README.md @@ -1,7 +1,11 @@ -# Apps Data folder Example +# Apps Data folder Example {#example_app_data} This example demonstrates how to utilize the Apps Data folder to store data that is not part of the app itself, such as user data, configuration files, and so forth. +## Source code + +Source code for this example can be found [here](https://github.com/flipperdevices/flipperzero-firmware/tree/dev/applications/examples/example_apps_data). + ## What is the Apps Data Folder? The **Apps Data** folder is a folder used to store data for external apps that are not part of the main firmware. diff --git a/applications/examples/example_apps_data/example_apps_data.c b/applications/examples/example_apps_data/example_apps_data.c index 7a297b01c..f40d526c9 100644 --- a/applications/examples/example_apps_data/example_apps_data.c +++ b/applications/examples/example_apps_data/example_apps_data.c @@ -1,3 +1,7 @@ +/** + * @file example_apps_data.c + * @brief Application data example. + */ #include #include diff --git a/applications/examples/example_ble_beacon/ble_beacon_app.c b/applications/examples/example_ble_beacon/ble_beacon_app.c index 20e3e307a..af2133602 100644 --- a/applications/examples/example_ble_beacon/ble_beacon_app.c +++ b/applications/examples/example_ble_beacon/ble_beacon_app.c @@ -57,7 +57,7 @@ static void ble_beacon_app_restore_beacon_state(BleBeaconApp* app) { app->beacon_data_len = furi_hal_bt_extra_beacon_get_data(app->beacon_data); } -static BleBeaconApp* ble_beacon_app_alloc() { +static BleBeaconApp* ble_beacon_app_alloc(void) { BleBeaconApp* app = malloc(sizeof(BleBeaconApp)); app->gui = furi_record_open(RECORD_GUI); diff --git a/applications/examples/example_ble_beacon/ble_beacon_app.h b/applications/examples/example_ble_beacon/ble_beacon_app.h index 563bd5bed..61c8c56d1 100644 --- a/applications/examples/example_ble_beacon/ble_beacon_app.h +++ b/applications/examples/example_ble_beacon/ble_beacon_app.h @@ -1,3 +1,7 @@ +/** + * @file ble_beacon_app.h + * @brief BLE beacon example. + */ #pragma once #include "extra_beacon.h" diff --git a/applications/examples/example_custom_font/example_custom_font.c b/applications/examples/example_custom_font/example_custom_font.c index 15eeb5f02..a175838e3 100644 --- a/applications/examples/example_custom_font/example_custom_font.c +++ b/applications/examples/example_custom_font/example_custom_font.c @@ -1,3 +1,7 @@ +/** + * @file example_custom_font.c + * @brief Custom font example. + */ #include #include @@ -7,35 +11,62 @@ //This arrays contains the font itself. You can use any u8g2 font you want /* -Fontname: -Raccoon-Fixed4x6-Medium-R-Normal--6-60-75-75-P-40-ISO10646-1 -Copyright: -Glyphs: 95/203 -BBX Build Mode: 0 + Fontname: -Misc-Fixed-Medium-R-Normal--6-60-75-75-C-40-ISO10646-1 + Copyright: Public domain font. Share and enjoy. + Glyphs: 191/919 + BBX Build Mode: 0 */ -const uint8_t u8g2_font_tom_thumb_4x6_tr[725] = - "_\0\2\2\2\3\3\4\4\3\6\0\377\5\377\5\0\0\352\1\330\2\270 \5\340\315\0!\6\265\310" - "\254\0\42\6\213\313$\25#\10\227\310\244\241\206\12$\10\227\310\215\70b\2%\10\227\310d\324F\1" - "&\10\227\310(\65R\22'\5\251\313\10(\6\266\310\251\62)\10\226\310\304\224\24\0*\6\217\312\244" - "\16+\7\217\311\245\225\0,\6\212\310)\0-\5\207\312\14.\5\245\310\4/\7\227\310Ve\4\60" - "\7\227\310-k\1\61\6\226\310\255\6\62\10\227\310h\220\312\1\63\11\227\310h\220\62X\0\64\10\227" - "\310$\65b\1\65\10\227\310\214\250\301\2\66\10\227\310\315\221F\0\67\10\227\310\314TF\0\70\10\227" - "\310\214\64\324\10\71\10\227\310\214\64\342\2:\6\255\311\244\0;\7\222\310e\240\0<\10\227\310\246\32" - "d\20=\6\217\311l\60>\11\227\310d\220A*\1\77\10\227\310\314\224a\2@\10\227\310UC\3" - "\1A\10\227\310UC\251\0B\10\227\310\250\264\322\2C\7\227\310\315\32\10D\10\227\310\250d-\0" - "E\10\227\310\214\70\342\0F\10\227\310\214\70b\4G\10\227\310\315\221\222\0H\10\227\310$\65\224\12" - "I\7\227\310\254X\15J\7\227\310\226\252\2K\10\227\310$\265\222\12L\7\227\310\304\346\0M\10\227" - "\310\244\61\224\12N\10\227\310\244q\250\0O\7\227\310UV\5P\10\227\310\250\264b\4Q\10\227\310" - "Uj$\1R\10\227\310\250\64V\1S\10\227\310m\220\301\2T\7\227\310\254\330\2U\7\227\310$" - "W\22V\10\227\310$\253L\0W\10\227\310$\65\206\12X\10\227\310$\325R\1Y\10\227\310$U" - "V\0Z\7\227\310\314T\16[\7\227\310\214X\16\134\10\217\311d\220A\0]\7\227\310\314r\4^" - "\5\213\313\65_\5\207\310\14`\6\212\313\304\0a\7\223\310\310\65\2b\10\227\310D\225\324\2c\7" - "\223\310\315\14\4d\10\227\310\246\245\222\0e\6\223\310\235\2f\10\227\310\246\264b\2g\10\227\307\35" - "\61%\0h\10\227\310D\225\254\0i\6\265\310\244\1j\10\233\307f\30U\5k\10\227\310\304\264T" - "\1l\7\227\310\310\326\0m\7\223\310\11\253\310d\220A*\1\77\11\253\310h\220\62L\0@\7" + "\253\310-\33\10A\10\253\310UC\251\0B\10\253\310\250\264\322\2C\10\253\310U\62U\0D\10\253" + "\310\250d-\0E\10\253\310\214\250\342\0F\10\253\310\214\250b\4G\10\253\310\315\244\222\0H\10\253" + "\310$\65\224\12I\7\253\310\254X\15J\7\253\310\226\252\2K\10\253\310$\265\222\12L\7\253\310\304" + "\346\0M\10\253\310\244\61\224\12N\10\253\310\252\241$\0O\7\253\310UV\5P\10\253\310\250\264b" + "\4Q\10\263\307UV\15\2R\10\253\310\250\264\222\12S\10\253\310m\220\301\2T\7\253\310\254\330\2" + "U\7\253\310$\327\10V\10\253\310$k\244\4W\10\253\310$\65\206\12X\10\253\310$\325R\1Y" + "\10\253\310$UV\0Z\7\253\310\314T\16[\6\352\310\254J\134\11\253\310\304\14\62\210\1]\6\252" + "\310\250j^\5\223\313\65_\5\213\307\14`\6\322\313\304\0a\7\243\310-\225\4b\10\253\310D\225" + "\324\2c\7\243\310\315\14\4d\10\253\310\246\245\222\0e\6\243\310USf\10\253\310\246\264b\2g" + "\10\253\307\255$\27\0h\10\253\310D\225\254\0i\10\253\310e$\323\0j\10\263\307fX.\0k" + "\10\253\310\304\264\222\12l\7\253\310\310\326\0m\10\243\310\244\241T\0n\7\243\310\250d\5o\7\243" + "\310U\252\2p\10\253\307\250\264b\4q\10\253\307-\225d\0r\10\243\310\244\25#\0s\10\243\310" + "\215\14\26\0t\10\253\310\245\25\63\10u\7\243\310$+\11v\7\243\310$\253\2w\10\243\310$\65" + "T\0x\7\243\310\244\62\25y\10\253\307$\225\344\2z\7\243\310\314\224\6{\10\263\307\246$k\20" + "|\6\351\310\14\1}\11\263\307d\20UL\21~\7\224\313%\225\0\0\0\0\4\377\377\4\1\11\253" + "\310\244\261\342\0\4\2\11\253\310\214\250\222\12\4\3\10\253\310\16Y\2\4\4\11\253\310M\225\201\0\4" + "\5\11\253\310m\220\301\2\4\6\10\253\310\254X\15\4\7\11\253\310\244\221b\32\4\10\10\253\310\226\252" + "\2\4\11\11\254\310L\325Z\2\4\12\11\254\310\244\326JK\4\13\11\253\310\250\250\222\12\4\14\10\253" + "\310\312\264\12\4\16\11\263\307\244\32u\2\4\17\11\263\307$\327H\11\4\20\11\253\310UC\251\0\4" + "\21\11\253\310\214\250\322\2\4\22\11\253\310\250\264\322\2\4\23\10\253\310\214\330\4\4\24\11\263\307\254\245" + "\206\12\4\25\11\253\310\214\250\342\0\4\26\12\253\310\244\221\322H\1\4\27\12\253\310h\220\62X\0\4" + "\30\11\253\310\304\64T\14\4\31\11\263\307\315\64T\14\4\32\11\253\310$\265\222\12\4\33\10\253\310-" + "W\0\4\34\11\253\310\244\241\254\0\4\35\11\253\310$\65\224\12\4\36\10\253\310UV\5\4\37\10\253" + "\310\214\344\12\4 \11\253\310\250\264b\4\4!\11\253\310U\62U\0\4\42\10\253\310\254\330\2\4#" + "\11\263\307$\253L\21\4$\12\253\310\245\221FJ\0\4%\11\253\310$\325R\1\4&\10\253\310$" + "\327\10\4'\11\253\310$\225d\1\4(\11\253\310$\65\216\0\4)\12\264\307\244\326#\203\0\4*" + "\13\254\310h\220\201LI\1\4+\12\254\310D\271\324H\1\4,\11\253\310\304\250\322\2\4-\11\253" + "\310h\220\344\2\4.\12\254\310\244\244.\225\0\4/\11\253\310\255\264T\0\4\60\10\243\310-\225\4" + "\4\61\11\253\310\315\221*\0\4\62\11\243\310\14\225\26\0\4\63\10\243\310\214X\2\4\64\11\253\307-" + "\65T\0\4\65\7\243\310US\4\66\11\244\310$S%\1\4\67\11\243\310\254\14\26\0\4\70\11\243" + "\310\244\61T\0\4\71\11\253\310\244\326P\1\4:\10\243\310$\265\12\4;\7\243\310-+\4<\11" + "\243\310\244\241T\0\4=\11\243\310\244\241T\0\4>\10\243\310U\252\2\4\77\10\243\310\214d\5\4" + "@\11\253\307\250\264b\4\4A\10\243\310\315\14\4\4B\10\243\310\254X\1\4C\11\253\307$\225\344" + "\2\4D\12\263\307\305\224T\231\0\4E\10\243\310\244\62\25\4F\11\253\307$k\304\0\4G\11\243" + "\310$\225d\0\4H\10\243\310\244q\4\4I\11\254\307\244\364\310 \4J\12\244\310h SR\0" + "\4K\11\244\310\304\245F\12\4L\11\243\310D\225\26\0\4M\10\243\310H\271\0\4N\12\244\310\244" + "\244\226J\0\4O\10\243\310\255\264\2\4Q\10\253\310\244\326\24\4R\11\263\307D\25U\31\4S\11" + "\253\310\246\64b\4\4T\11\243\310\215\224\201\0\4U\11\243\310\215\14\26\0\4V\11\253\310e$\323" + "\0\4W\11\253\310\244\14d\32\4X\11\263\307fX.\0\4Y\10\244\310\251\326\22\4Z\11\244\310" + "\244\264\322\22\4[\11\253\310D\25U\1\4\134\10\253\310\312\264\12\4^\11\263\307\244\32u\2\4_" + "\11\253\307$k\244\4\4\220\10\253\310\16Y\2\4\221\10\243\310\16\31\1\4\222\11\253\310\251\264b\2" + "\4\223\11\243\310\251\264\22\0\0"; // Screen is 128x64 px static void app_draw_callback(Canvas* canvas, void* ctx) { @@ -43,10 +74,11 @@ static void app_draw_callback(Canvas* canvas, void* ctx) { canvas_clear(canvas); - canvas_set_custom_u8g2_font(canvas, u8g2_font_tom_thumb_4x6_tr); + canvas_set_custom_u8g2_font(canvas, u8g2_font_4x6_t_cyrillic); canvas_draw_str(canvas, 0, 6, "This is a tiny custom font"); canvas_draw_str(canvas, 0, 12, "012345.?! ,:;\"\'@#$%"); + canvas_draw_str(canvas, 0, 18, "И немного юникода"); } static void app_input_callback(InputEvent* input_event, void* ctx) { @@ -62,7 +94,7 @@ int32_t example_custom_font_main(void* p) { // Configure view port ViewPort* view_port = view_port_alloc(); - view_port_draw_callback_set(view_port, app_draw_callback, view_port); + view_port_draw_callback_set(view_port, app_draw_callback, NULL); view_port_input_callback_set(view_port, app_input_callback, event_queue); // Register view port in GUI diff --git a/applications/examples/example_images/ReadMe.md b/applications/examples/example_images/ReadMe.md index d884a0a97..bf5795008 100644 --- a/applications/examples/example_images/ReadMe.md +++ b/applications/examples/example_images/ReadMe.md @@ -1,11 +1,21 @@ -# Application icons +# Application icons {#example_app_images} + +## Source code + +Source code for this example can be found [here](https://github.com/flipperdevices/flipperzero-firmware/tree/dev/applications/examples/example_images). + +## General principle + To use icons, do the following: -* add a line to the application manifest: `fap_icon_assets="folder"`, where `folder` points to the folder where your icons are located -* add `#include "application_id_icons.h"` to the application code, where `application_id` is the appid from the manifest -* every icon in the folder will be available as a `I_icon_name` variable, where `icon_name` is the name of the icon file without the extension + +* Add a line to the application manifest: `fap_icon_assets="folder"`, where `folder` points to the folder where your icons are located +* Add `#include "application_id_icons.h"` to the application code, where `application_id` is the appid from the manifest +* Every icon in the folder will be available as a `I_icon_name` variable, where `icon_name` is the name of the icon file without the extension ## Example + We have an application with the following manifest: + ``` App( appid="example_images", @@ -17,6 +27,7 @@ App( So the icons are in the `images` folder and will be available in the generated `example_images_icons.h` file. The example code is located in `example_images_main.c` and contains the following line: + ``` #include "example_images_icons.h" ``` diff --git a/applications/examples/example_images/example_images.c b/applications/examples/example_images/example_images.c index b00818cd6..60269a81f 100644 --- a/applications/examples/example_images/example_images.c +++ b/applications/examples/example_images/example_images.c @@ -1,3 +1,7 @@ +/** + * @file example_images.c + * @brief Custom images example. + */ #include #include @@ -9,7 +13,7 @@ #include "example_images_icons.h" typedef struct { - uint8_t x, y; + int32_t x, y; } ImagePosition; static ImagePosition image_position = {.x = 0, .y = 0}; @@ -19,7 +23,7 @@ static void app_draw_callback(Canvas* canvas, void* ctx) { UNUSED(ctx); canvas_clear(canvas); - canvas_draw_icon(canvas, image_position.x % 128, image_position.y % 64, &I_dolphin_71x25); + canvas_draw_icon(canvas, image_position.x, image_position.y, &I_dolphin_71x25); } static void app_input_callback(InputEvent* input_event, void* ctx) { @@ -35,7 +39,7 @@ int32_t example_images_main(void* p) { // Configure view port ViewPort* view_port = view_port_alloc(); - view_port_draw_callback_set(view_port, app_draw_callback, view_port); + view_port_draw_callback_set(view_port, app_draw_callback, NULL); view_port_input_callback_set(view_port, app_input_callback, event_queue); // Register view port in GUI diff --git a/applications/examples/example_plugins/example_plugins.c b/applications/examples/example_plugins/example_plugins.c index 7e71e0d2e..4f2150884 100644 --- a/applications/examples/example_plugins/example_plugins.c +++ b/applications/examples/example_plugins/example_plugins.c @@ -1,5 +1,7 @@ -/* - * An example of a plugin host application. +/** + * @file example_plugins.c + * @brief Plugin host application example. + * * Loads a single plugin and calls its methods. */ diff --git a/applications/examples/example_plugins/example_plugins_multi.c b/applications/examples/example_plugins/example_plugins_multi.c index 3525b39ea..40abff561 100644 --- a/applications/examples/example_plugins/example_plugins_multi.c +++ b/applications/examples/example_plugins/example_plugins_multi.c @@ -1,5 +1,7 @@ -/* - * An example of an advanced plugin host application. +/** + * @file example_plugins_multi.c + * @brief Advanced plugin host application example. + * * It uses PluginManager to load all plugins from a directory */ diff --git a/applications/examples/example_plugins/plugin1.c b/applications/examples/example_plugins/plugin1.c index 156219353..05036d252 100644 --- a/applications/examples/example_plugins/plugin1.c +++ b/applications/examples/example_plugins/plugin1.c @@ -1,10 +1,15 @@ -/* A simple plugin implementing example_plugins application's plugin interface */ +/** + * @file plugin1.c + * @brief Plugin example 1. + * + * A simple plugin implementing example_plugins application's plugin interface + */ #include "plugin_interface.h" #include -static int example_plugin1_method1() { +static int example_plugin1_method1(void) { return 42; } @@ -27,6 +32,6 @@ static const FlipperAppPluginDescriptor example_plugin1_descriptor = { }; /* Plugin entry point - must return a pointer to const descriptor */ -const FlipperAppPluginDescriptor* example_plugin1_ep() { +const FlipperAppPluginDescriptor* example_plugin1_ep(void) { return &example_plugin1_descriptor; } diff --git a/applications/examples/example_plugins/plugin2.c b/applications/examples/example_plugins/plugin2.c index 0b774dad2..bff170dde 100644 --- a/applications/examples/example_plugins/plugin2.c +++ b/applications/examples/example_plugins/plugin2.c @@ -1,10 +1,15 @@ -/* Second plugin implementing example_plugins application's plugin interface */ +/** + * @file plugin2.c + * @brief Plugin example 2. + * + * Second plugin implementing example_plugins application's plugin interface + */ #include "plugin_interface.h" #include -static int example_plugin2_method1() { +static int example_plugin2_method1(void) { return 1337; } @@ -27,6 +32,6 @@ static const FlipperAppPluginDescriptor example_plugin2_descriptor = { }; /* Plugin entry point - must return a pointer to const descriptor */ -const FlipperAppPluginDescriptor* example_plugin2_ep() { +const FlipperAppPluginDescriptor* example_plugin2_ep(void) { return &example_plugin2_descriptor; } diff --git a/applications/examples/example_plugins/plugin_interface.h b/applications/examples/example_plugins/plugin_interface.h index 25d95d294..fadb9089f 100644 --- a/applications/examples/example_plugins/plugin_interface.h +++ b/applications/examples/example_plugins/plugin_interface.h @@ -1,12 +1,16 @@ +/** + * @file plugin_interface.h + * @brief Example plugin interface. + * + * Common interface between a plugin and host application + */ #pragma once -/* Common interface between a plugin and host application */ - #define PLUGIN_APP_ID "example_plugins" #define PLUGIN_API_VERSION 1 typedef struct { const char* name; - int (*method1)(); + int (*method1)(void); int (*method2)(int, int); } ExamplePlugin; diff --git a/applications/examples/example_plugins_advanced/app_api.c b/applications/examples/example_plugins_advanced/app_api.c index 42b3a1860..4f314f4ce 100644 --- a/applications/examples/example_plugins_advanced/app_api.c +++ b/applications/examples/example_plugins_advanced/app_api.c @@ -8,7 +8,7 @@ void app_api_accumulator_set(uint32_t value) { accumulator = value; } -uint32_t app_api_accumulator_get() { +uint32_t app_api_accumulator_get(void) { return accumulator; } diff --git a/applications/examples/example_plugins_advanced/app_api.h b/applications/examples/example_plugins_advanced/app_api.h index 7035b79f5..df80455d7 100644 --- a/applications/examples/example_plugins_advanced/app_api.h +++ b/applications/examples/example_plugins_advanced/app_api.h @@ -1,9 +1,12 @@ -#pragma once - -/* +/** + * @file app_api.h + * @brief Application API example. + * * This file contains an API that is internally implemented by the application * It is also exposed to plugins to allow them to use the application's API. */ +#pragma once + #include #ifdef __cplusplus @@ -12,7 +15,7 @@ extern "C" { void app_api_accumulator_set(uint32_t value); -uint32_t app_api_accumulator_get(); +uint32_t app_api_accumulator_get(void); void app_api_accumulator_add(uint32_t value); diff --git a/applications/examples/example_plugins_advanced/app_api_table.cpp b/applications/examples/example_plugins_advanced/app_api_table.cpp index aacfb8c18..db15c84d1 100644 --- a/applications/examples/example_plugins_advanced/app_api_table.cpp +++ b/applications/examples/example_plugins_advanced/app_api_table.cpp @@ -18,8 +18,8 @@ constexpr HashtableApiInterface applicaton_hashtable_api_interface{ .resolver_callback = &elf_resolve_from_hashtable, }, /* pointers to application's API table boundaries */ - .table_cbegin = app_api_table.cbegin(), - .table_cend = app_api_table.cend(), + app_api_table.cbegin(), + app_api_table.cend(), }; /* Casting to generic resolver to use in Composite API resolver */ diff --git a/applications/examples/example_plugins_advanced/plugin1.c b/applications/examples/example_plugins_advanced/plugin1.c index bf0ab50b4..e45122d95 100644 --- a/applications/examples/example_plugins_advanced/plugin1.c +++ b/applications/examples/example_plugins_advanced/plugin1.c @@ -1,4 +1,7 @@ -/* +/** + * @file plugin1.c + * @brief Plugin example 1. + * * This plugin uses both firmware's API interface and private application headers. * It can be loaded by a plugin manager that uses CompoundApiInterface, * which combines both interfaces. @@ -15,7 +18,7 @@ static void advanced_plugin1_method1(int arg1) { app_api_accumulator_add(arg1); } -static void advanced_plugin1_method2() { +static void advanced_plugin1_method2(void) { /* Accumulator value is stored inside host application */ FURI_LOG_I("TEST", "Plugin 1, accumulator: %lu", app_api_accumulator_get()); } @@ -35,6 +38,6 @@ static const FlipperAppPluginDescriptor advanced_plugin1_descriptor = { }; /* Plugin entry point - must return a pointer to const descriptor */ -const FlipperAppPluginDescriptor* advanced_plugin1_ep() { +const FlipperAppPluginDescriptor* advanced_plugin1_ep(void) { return &advanced_plugin1_descriptor; } diff --git a/applications/examples/example_plugins_advanced/plugin2.c b/applications/examples/example_plugins_advanced/plugin2.c index f0b2f726d..efc8db478 100644 --- a/applications/examples/example_plugins_advanced/plugin2.c +++ b/applications/examples/example_plugins_advanced/plugin2.c @@ -1,4 +1,7 @@ -/* +/** + * @file plugin2.c + * @brief Plugin example 2. + * * This plugin uses both firmware's API interface and private application headers. * It can be loaded by a plugin manager that uses CompoundApiInterface, * which combines both interfaces. @@ -15,7 +18,7 @@ static void advanced_plugin2_method1(int arg1) { app_api_accumulator_mul(arg1); } -static void advanced_plugin2_method2() { +static void advanced_plugin2_method2(void) { /* Accumulator value is stored inside host application */ FURI_LOG_I("TEST", "Plugin 2, accumulator: %lu", app_api_accumulator_get()); } @@ -35,6 +38,6 @@ static const FlipperAppPluginDescriptor advanced_plugin2_descriptor = { }; /* Plugin entry point - must return a pointer to const descriptor */ -const FlipperAppPluginDescriptor* advanced_plugin2_ep() { +const FlipperAppPluginDescriptor* advanced_plugin2_ep(void) { return &advanced_plugin2_descriptor; } diff --git a/applications/examples/example_plugins_advanced/plugin_interface.h b/applications/examples/example_plugins_advanced/plugin_interface.h index d99b335ff..4cef7567b 100644 --- a/applications/examples/example_plugins_advanced/plugin_interface.h +++ b/applications/examples/example_plugins_advanced/plugin_interface.h @@ -1,12 +1,16 @@ +/** + * @file plugin_interface.h + * @brief Example plugin interface. + * + * Common interface between a plugin and host application + */ #pragma once -/* Common interface between a plugin and host application */ - #define PLUGIN_APP_ID "example_plugins_advanced" #define PLUGIN_API_VERSION 1 typedef struct { const char* name; void (*method1)(int); - void (*method2)(); + void (*method2)(void); } AdvancedPlugin; diff --git a/applications/examples/example_thermo/README.md b/applications/examples/example_thermo/README.md index d298de643..4af2e6043 100644 --- a/applications/examples/example_thermo/README.md +++ b/applications/examples/example_thermo/README.md @@ -1,8 +1,14 @@ -# 1-Wire Thermometer +# 1-Wire Thermometer {#example_thermo} + This example application demonstrates the use of the 1-Wire library with a DS18B20 thermometer. It also covers basic GUI, input handling, threads and localisation. +## Source code + +Source code for this example can be found [here](https://github.com/flipperdevices/flipperzero-firmware/tree/dev/applications/examples/example_thermo). + ## Electrical connections + Before launching the application, connect the sensor to Flipper's external GPIO according to the table below: | DS18B20 | Flipper | | :-----: | :-----: | @@ -15,12 +21,14 @@ Before launching the application, connect the sensor to Flipper's external GPIO *NOTE 2*: For any other pin than 17, connect an external 4.7k pull-up resistor to pin 9. ## Launching the application + In order to launch this demo, follow the steps below: 1. Make sure your Flipper has an SD card installed. 2. Connect your Flipper to the computer via a USB cable. 3. Run `./fbt launch APPSRC=example_thermo` in your terminal emulator of choice. ## Changing the data pin + It is possible to use other GPIO pin as a 1-Wire data pin. In order to change it, set the `THERMO_GPIO_PIN` macro to any of the options listed below: ```c diff --git a/applications/examples/example_thermo/example_thermo.c b/applications/examples/example_thermo/example_thermo.c index 5abd963a1..dafe56886 100644 --- a/applications/examples/example_thermo/example_thermo.c +++ b/applications/examples/example_thermo/example_thermo.c @@ -1,4 +1,7 @@ -/* +/** + * @file example_thermo.c + * @brief 1-Wire thermometer example. + * * This file contains an example application that reads and displays * the temperature from a DS18B20 1-wire thermometer. * @@ -312,7 +315,7 @@ static void example_thermo_run(ExampleThermoContext* context) { /******************** Initialisation & startup *****************************/ /* Allocate the memory and initialise the variables */ -static ExampleThermoContext* example_thermo_context_alloc() { +static ExampleThermoContext* example_thermo_context_alloc(void) { ExampleThermoContext* context = malloc(sizeof(ExampleThermoContext)); context->view_port = view_port_alloc(); diff --git a/applications/main/archive/archive.c b/applications/main/archive/archive.c index b8609cf2d..8dd934cc7 100644 --- a/applications/main/archive/archive.c +++ b/applications/main/archive/archive.c @@ -12,7 +12,7 @@ bool archive_back_event_callback(void* context) { return scene_manager_handle_back_event(archive->scene_manager); } -ArchiveApp* archive_alloc() { +ArchiveApp* archive_alloc(void) { ArchiveApp* archive = malloc(sizeof(ArchiveApp)); archive->gui = furi_record_open(RECORD_GUI); diff --git a/applications/main/archive/helpers/archive_favorites.c b/applications/main/archive/helpers/archive_favorites.c index 682aa6b38..351d68c1d 100644 --- a/applications/main/archive/helpers/archive_favorites.c +++ b/applications/main/archive/helpers/archive_favorites.c @@ -79,7 +79,7 @@ uint16_t archive_favorites_count(void* context) { return lines; } -static bool archive_favourites_rescan() { +static bool archive_favourites_rescan(void) { FuriString* buffer; buffer = furi_string_alloc(); Storage* storage = furi_record_open(RECORD_STORAGE); diff --git a/applications/main/archive/scenes/archive_scene_browser.c b/applications/main/archive/scenes/archive_scene_browser.c index d156d171d..284e534ab 100644 --- a/applications/main/archive/scenes/archive_scene_browser.c +++ b/applications/main/archive/scenes/archive_scene_browser.c @@ -157,6 +157,7 @@ bool archive_scene_browser_on_event(void* context, SceneManagerEvent event) { break; case ArchiveBrowserEventFileMenuDelete: if(archive_get_tab(browser) != ArchiveTabFavorites) { + archive_show_file_menu(browser, false); scene_manager_set_scene_state( archive->scene_manager, ArchiveAppSceneBrowser, SCENE_STATE_NEED_REFRESH); scene_manager_next_scene(archive->scene_manager, ArchiveAppSceneDelete); diff --git a/applications/main/archive/scenes/archive_scene_delete.c b/applications/main/archive/scenes/archive_scene_delete.c index d3964d0fe..45d5b47cc 100644 --- a/applications/main/archive/scenes/archive_scene_delete.c +++ b/applications/main/archive/scenes/archive_scene_delete.c @@ -29,6 +29,12 @@ void archive_scene_delete_on_enter(void* context) { filename = furi_string_alloc(); ArchiveFile_t* current = archive_get_current_file(app->browser); + + FuriString* filename_no_ext = furi_string_alloc(); + path_extract_filename(current->path, filename_no_ext, true); + strlcpy(app->text_store, furi_string_get_cstr(filename_no_ext), MAX_NAME_LEN); + furi_string_free(filename_no_ext); + path_extract_filename(current->path, filename, false); char delete_str[64]; diff --git a/applications/main/archive/views/archive_browser_view.c b/applications/main/archive/views/archive_browser_view.c index 447941504..6cdf12c62 100644 --- a/applications/main/archive/views/archive_browser_view.c +++ b/applications/main/archive/views/archive_browser_view.c @@ -436,7 +436,7 @@ static void browser_view_exit(void* context) { furi_timer_stop(browser->scroll_timer); } -ArchiveBrowserView* browser_alloc() { +ArchiveBrowserView* browser_alloc(void) { ArchiveBrowserView* browser = malloc(sizeof(ArchiveBrowserView)); browser->view = view_alloc(); view_allocate_model(browser->view, ViewModelTypeLocking, sizeof(ArchiveBrowserViewModel)); diff --git a/applications/main/archive/views/archive_browser_view.h b/applications/main/archive/views/archive_browser_view.h index 25490aedd..5fbdaf973 100644 --- a/applications/main/archive/views/archive_browser_view.h +++ b/applications/main/archive/views/archive_browser_view.h @@ -111,5 +111,5 @@ void archive_browser_set_callback( View* archive_browser_get_view(ArchiveBrowserView* browser); -ArchiveBrowserView* browser_alloc(); +ArchiveBrowserView* browser_alloc(void); void browser_free(ArchiveBrowserView* browser); diff --git a/applications/main/bad_usb/application.fam b/applications/main/bad_usb/application.fam index 9844e248d..8d3909fcc 100644 --- a/applications/main/bad_usb/application.fam +++ b/applications/main/bad_usb/application.fam @@ -7,7 +7,7 @@ App( icon="A_BadUsb_14", order=70, resources="resources", - fap_libs=["assets"], + fap_libs=["assets", "ble_profile"], fap_icon="icon.png", fap_category="USB", ) diff --git a/applications/main/bad_usb/bad_usb_app.c b/applications/main/bad_usb/bad_usb_app.c index ea97c4487..0cf7f1924 100644 --- a/applications/main/bad_usb/bad_usb_app.c +++ b/applications/main/bad_usb/bad_usb_app.c @@ -1,11 +1,14 @@ #include "bad_usb_app_i.h" -#include "bad_usb_settings_filename.h" #include #include #include #include +#include -#define BAD_USB_SETTINGS_PATH BAD_USB_APP_BASE_FOLDER "/" BAD_USB_SETTINGS_FILE_NAME +#define BAD_USB_SETTINGS_PATH BAD_USB_APP_BASE_FOLDER "/.badusb.settings" +#define BAD_USB_SETTINGS_FILE_TYPE "Flipper BadUSB Settings File" +#define BAD_USB_SETTINGS_VERSION 1 +#define BAD_USB_SETTINGS_DEFAULT_LAYOUT BAD_USB_APP_PATH_LAYOUT_FOLDER "/en-US.kl" static bool bad_usb_app_custom_event_callback(void* context, uint32_t event) { furi_assert(context); @@ -26,46 +29,69 @@ static void bad_usb_app_tick_event_callback(void* context) { } static void bad_usb_load_settings(BadUsbApp* app) { - File* settings_file = storage_file_alloc(furi_record_open(RECORD_STORAGE)); - if(storage_file_open(settings_file, BAD_USB_SETTINGS_PATH, FSAM_READ, FSOM_OPEN_EXISTING)) { - char chr; - while((storage_file_read(settings_file, &chr, 1) == 1) && - !storage_file_eof(settings_file) && !isspace(chr)) { - furi_string_push_back(app->keyboard_layout, chr); - } - } else { - furi_string_reset(app->keyboard_layout); - } - storage_file_close(settings_file); - storage_file_free(settings_file); + Storage* storage = furi_record_open(RECORD_STORAGE); + FlipperFormat* fff = flipper_format_file_alloc(storage); + bool state = false; + + FuriString* temp_str = furi_string_alloc(); + uint32_t version = 0; + uint32_t interface = 0; + + if(flipper_format_file_open_existing(fff, BAD_USB_SETTINGS_PATH)) { + do { + if(!flipper_format_read_header(fff, temp_str, &version)) break; + if((strcmp(furi_string_get_cstr(temp_str), BAD_USB_SETTINGS_FILE_TYPE) != 0) || + (version != BAD_USB_SETTINGS_VERSION)) + break; + + if(!flipper_format_read_string(fff, "layout", temp_str)) break; + if(!flipper_format_read_uint32(fff, "interface", &interface, 1)) break; + if(interface > BadUsbHidInterfaceBle) break; + + state = true; + } while(0); + } + flipper_format_free(fff); + furi_record_close(RECORD_STORAGE); + + if(state) { + furi_string_set(app->keyboard_layout, temp_str); + app->interface = interface; - if(!furi_string_empty(app->keyboard_layout)) { Storage* fs_api = furi_record_open(RECORD_STORAGE); FileInfo layout_file_info; FS_Error file_check_err = storage_common_stat( fs_api, furi_string_get_cstr(app->keyboard_layout), &layout_file_info); furi_record_close(RECORD_STORAGE); - if(file_check_err != FSE_OK) { - furi_string_reset(app->keyboard_layout); - return; - } - if(layout_file_info.size != 256) { - furi_string_reset(app->keyboard_layout); + if((file_check_err != FSE_OK) || (layout_file_info.size != 256)) { + furi_string_set(app->keyboard_layout, BAD_USB_SETTINGS_DEFAULT_LAYOUT); } + } else { + furi_string_set(app->keyboard_layout, BAD_USB_SETTINGS_DEFAULT_LAYOUT); + app->interface = BadUsbHidInterfaceUsb; } + + furi_string_free(temp_str); } static void bad_usb_save_settings(BadUsbApp* app) { - File* settings_file = storage_file_alloc(furi_record_open(RECORD_STORAGE)); - if(storage_file_open(settings_file, BAD_USB_SETTINGS_PATH, FSAM_WRITE, FSOM_OPEN_ALWAYS)) { - storage_file_write( - settings_file, - furi_string_get_cstr(app->keyboard_layout), - furi_string_size(app->keyboard_layout)); - storage_file_write(settings_file, "\n", 1); + Storage* storage = furi_record_open(RECORD_STORAGE); + FlipperFormat* fff = flipper_format_file_alloc(storage); + + if(flipper_format_file_open_always(fff, BAD_USB_SETTINGS_PATH)) { + do { + if(!flipper_format_write_header_cstr( + fff, BAD_USB_SETTINGS_FILE_TYPE, BAD_USB_SETTINGS_VERSION)) + break; + if(!flipper_format_write_string(fff, "layout", app->keyboard_layout)) break; + uint32_t interface_id = app->interface; + if(!flipper_format_write_uint32(fff, "interface", (const uint32_t*)&interface_id, 1)) + break; + } while(0); } - storage_file_close(settings_file); - storage_file_free(settings_file); + + flipper_format_free(fff); + furi_record_close(RECORD_STORAGE); } BadUsbApp* bad_usb_app_alloc(char* arg) { @@ -103,13 +129,15 @@ BadUsbApp* bad_usb_app_alloc(char* arg) { view_dispatcher_add_view( app->view_dispatcher, BadUsbAppViewError, widget_get_view(app->widget)); - app->submenu = submenu_alloc(); + app->var_item_list = variable_item_list_alloc(); view_dispatcher_add_view( - app->view_dispatcher, BadUsbAppViewConfig, submenu_get_view(app->submenu)); + app->view_dispatcher, + BadUsbAppViewConfig, + variable_item_list_get_view(app->var_item_list)); - app->bad_usb_view = bad_usb_alloc(); + app->bad_usb_view = bad_usb_view_alloc(); view_dispatcher_add_view( - app->view_dispatcher, BadUsbAppViewWork, bad_usb_get_view(app->bad_usb_view)); + app->view_dispatcher, BadUsbAppViewWork, bad_usb_view_get_view(app->bad_usb_view)); view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen); @@ -122,8 +150,6 @@ BadUsbApp* bad_usb_app_alloc(char* arg) { furi_check(furi_hal_usb_set_config(NULL, NULL)); if(!furi_string_empty(app->file_path)) { - app->bad_usb_script = bad_usb_script_open(app->file_path); - bad_usb_script_set_keyboard_layout(app->bad_usb_script, app->keyboard_layout); scene_manager_next_scene(app->scene_manager, BadUsbSceneWork); } else { furi_string_set(app->file_path, BAD_USB_APP_BASE_FOLDER); @@ -144,15 +170,15 @@ void bad_usb_app_free(BadUsbApp* app) { // Views view_dispatcher_remove_view(app->view_dispatcher, BadUsbAppViewWork); - bad_usb_free(app->bad_usb_view); + bad_usb_view_free(app->bad_usb_view); // Custom Widget view_dispatcher_remove_view(app->view_dispatcher, BadUsbAppViewError); widget_free(app->widget); - // Submenu + // Config menu view_dispatcher_remove_view(app->view_dispatcher, BadUsbAppViewConfig); - submenu_free(app->submenu); + variable_item_list_free(app->var_item_list); // View dispatcher view_dispatcher_free(app->view_dispatcher); diff --git a/applications/main/bad_usb/bad_usb_app_i.h b/applications/main/bad_usb/bad_usb_app_i.h index cf1c02ebc..c12f9ac75 100644 --- a/applications/main/bad_usb/bad_usb_app_i.h +++ b/applications/main/bad_usb/bad_usb_app_i.h @@ -3,12 +3,12 @@ #include "bad_usb_app.h" #include "scenes/bad_usb_scene.h" #include "helpers/ducky_script.h" +#include "helpers/bad_usb_hid.h" #include #include #include #include -#include #include #include #include @@ -33,7 +33,7 @@ struct BadUsbApp { NotificationApp* notifications; DialogsApp* dialogs; Widget* widget; - Submenu* submenu; + VariableItemList* var_item_list; BadUsbAppError error; FuriString* file_path; @@ -41,6 +41,7 @@ struct BadUsbApp { BadUsb* bad_usb_view; BadUsbScript* bad_usb_script; + BadUsbHidInterface interface; FuriHalUsbInterface* usb_if_prev; }; diff --git a/applications/main/bad_usb/bad_usb_settings_filename.h b/applications/main/bad_usb/bad_usb_settings_filename.h deleted file mode 100644 index 12ba8f31c..000000000 --- a/applications/main/bad_usb/bad_usb_settings_filename.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -#define BAD_USB_SETTINGS_FILE_NAME ".badusb.settings" diff --git a/applications/main/bad_usb/helpers/bad_usb_hid.c b/applications/main/bad_usb/helpers/bad_usb_hid.c new file mode 100644 index 000000000..289e3ae8c --- /dev/null +++ b/applications/main/bad_usb/helpers/bad_usb_hid.c @@ -0,0 +1,226 @@ +#include "bad_usb_hid.h" +#include +#include +#include + +#define TAG "BadUSB HID" + +#define HID_BT_KEYS_STORAGE_NAME ".bt_hid.keys" + +void* hid_usb_init(FuriHalUsbHidConfig* hid_cfg) { + furi_check(furi_hal_usb_set_config(&usb_hid, hid_cfg)); + return NULL; +} + +void hid_usb_deinit(void* inst) { + UNUSED(inst); + furi_check(furi_hal_usb_set_config(NULL, NULL)); +} + +void hid_usb_set_state_callback(void* inst, HidStateCallback cb, void* context) { + UNUSED(inst); + furi_hal_hid_set_state_callback(cb, context); +} + +bool hid_usb_is_connected(void* inst) { + UNUSED(inst); + return furi_hal_hid_is_connected(); +} + +bool hid_usb_kb_press(void* inst, uint16_t button) { + UNUSED(inst); + return furi_hal_hid_kb_press(button); +} + +bool hid_usb_kb_release(void* inst, uint16_t button) { + UNUSED(inst); + return furi_hal_hid_kb_release(button); +} + +bool hid_usb_consumer_press(void* inst, uint16_t button) { + UNUSED(inst); + return furi_hal_hid_consumer_key_press(button); +} + +bool hid_usb_consumer_release(void* inst, uint16_t button) { + UNUSED(inst); + return furi_hal_hid_consumer_key_release(button); +} + +bool hid_usb_release_all(void* inst) { + UNUSED(inst); + bool state = furi_hal_hid_kb_release_all(); + state &= furi_hal_hid_consumer_key_release_all(); + return state; +} + +uint8_t hid_usb_get_led_state(void* inst) { + UNUSED(inst); + return furi_hal_hid_get_led_state(); +} + +static const BadUsbHidApi hid_api_usb = { + .init = hid_usb_init, + .deinit = hid_usb_deinit, + .set_state_callback = hid_usb_set_state_callback, + .is_connected = hid_usb_is_connected, + + .kb_press = hid_usb_kb_press, + .kb_release = hid_usb_kb_release, + .consumer_press = hid_usb_consumer_press, + .consumer_release = hid_usb_consumer_release, + .release_all = hid_usb_release_all, + .get_led_state = hid_usb_get_led_state, +}; + +typedef struct { + Bt* bt; + FuriHalBleProfileBase* profile; + HidStateCallback state_callback; + void* callback_context; + bool is_connected; +} BleHidInstance; + +static const BleProfileHidParams ble_hid_params = { + .device_name_prefix = "BadUSB", + .mac_xor = 0x0002, +}; + +static void hid_ble_connection_status_callback(BtStatus status, void* context) { + furi_assert(context); + BleHidInstance* ble_hid = context; + ble_hid->is_connected = (status == BtStatusConnected); + if(ble_hid->state_callback) { + ble_hid->state_callback(ble_hid->is_connected, ble_hid->callback_context); + } +} + +void* hid_ble_init(FuriHalUsbHidConfig* hid_cfg) { + UNUSED(hid_cfg); + BleHidInstance* ble_hid = malloc(sizeof(BleHidInstance)); + ble_hid->bt = furi_record_open(RECORD_BT); + bt_disconnect(ble_hid->bt); + + // Wait 2nd core to update nvm storage + furi_delay_ms(200); + + bt_keys_storage_set_storage_path(ble_hid->bt, APP_DATA_PATH(HID_BT_KEYS_STORAGE_NAME)); + + ble_hid->profile = bt_profile_start(ble_hid->bt, ble_profile_hid, (void*)&ble_hid_params); + furi_check(ble_hid->profile); + + furi_hal_bt_start_advertising(); + + bt_set_status_changed_callback(ble_hid->bt, hid_ble_connection_status_callback, ble_hid); + + return ble_hid; +} + +void hid_ble_deinit(void* inst) { + BleHidInstance* ble_hid = inst; + furi_assert(ble_hid); + + bt_set_status_changed_callback(ble_hid->bt, NULL, NULL); + bt_disconnect(ble_hid->bt); + + // Wait 2nd core to update nvm storage + furi_delay_ms(200); + bt_keys_storage_set_default_path(ble_hid->bt); + + furi_check(bt_profile_restore_default(ble_hid->bt)); + furi_record_close(RECORD_BT); + free(ble_hid); +} + +void hid_ble_set_state_callback(void* inst, HidStateCallback cb, void* context) { + BleHidInstance* ble_hid = inst; + furi_assert(ble_hid); + ble_hid->state_callback = cb; + ble_hid->callback_context = context; +} + +bool hid_ble_is_connected(void* inst) { + BleHidInstance* ble_hid = inst; + furi_assert(ble_hid); + return ble_hid->is_connected; +} + +bool hid_ble_kb_press(void* inst, uint16_t button) { + BleHidInstance* ble_hid = inst; + furi_assert(ble_hid); + return ble_profile_hid_kb_press(ble_hid->profile, button); +} + +bool hid_ble_kb_release(void* inst, uint16_t button) { + BleHidInstance* ble_hid = inst; + furi_assert(ble_hid); + return ble_profile_hid_kb_release(ble_hid->profile, button); +} + +bool hid_ble_consumer_press(void* inst, uint16_t button) { + BleHidInstance* ble_hid = inst; + furi_assert(ble_hid); + return ble_profile_hid_consumer_key_press(ble_hid->profile, button); +} + +bool hid_ble_consumer_release(void* inst, uint16_t button) { + BleHidInstance* ble_hid = inst; + furi_assert(ble_hid); + return ble_profile_hid_consumer_key_release(ble_hid->profile, button); +} + +bool hid_ble_release_all(void* inst) { + BleHidInstance* ble_hid = inst; + furi_assert(ble_hid); + bool state = ble_profile_hid_kb_release_all(ble_hid->profile); + state &= ble_profile_hid_consumer_key_release_all(ble_hid->profile); + return state; +} + +uint8_t hid_ble_get_led_state(void* inst) { + UNUSED(inst); + FURI_LOG_W(TAG, "hid_ble_get_led_state not implemented"); + return 0; +} + +static const BadUsbHidApi hid_api_ble = { + .init = hid_ble_init, + .deinit = hid_ble_deinit, + .set_state_callback = hid_ble_set_state_callback, + .is_connected = hid_ble_is_connected, + + .kb_press = hid_ble_kb_press, + .kb_release = hid_ble_kb_release, + .consumer_press = hid_ble_consumer_press, + .consumer_release = hid_ble_consumer_release, + .release_all = hid_ble_release_all, + .get_led_state = hid_ble_get_led_state, +}; + +const BadUsbHidApi* bad_usb_hid_get_interface(BadUsbHidInterface interface) { + if(interface == BadUsbHidInterfaceUsb) { + return &hid_api_usb; + } else { + return &hid_api_ble; + } +} + +void bad_usb_hid_ble_remove_pairing(void) { + Bt* bt = furi_record_open(RECORD_BT); + bt_disconnect(bt); + + // Wait 2nd core to update nvm storage + furi_delay_ms(200); + + furi_hal_bt_stop_advertising(); + + bt_keys_storage_set_storage_path(bt, APP_DATA_PATH(HID_BT_KEYS_STORAGE_NAME)); + bt_forget_bonded_devices(bt); + + // Wait 2nd core to update nvm storage + furi_delay_ms(200); + bt_keys_storage_set_default_path(bt); + + furi_check(bt_profile_restore_default(bt)); + furi_record_close(RECORD_BT); +} \ No newline at end of file diff --git a/applications/main/bad_usb/helpers/bad_usb_hid.h b/applications/main/bad_usb/helpers/bad_usb_hid.h new file mode 100644 index 000000000..71d3a58e7 --- /dev/null +++ b/applications/main/bad_usb/helpers/bad_usb_hid.h @@ -0,0 +1,35 @@ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +typedef enum { + BadUsbHidInterfaceUsb, + BadUsbHidInterfaceBle, +} BadUsbHidInterface; + +typedef struct { + void* (*init)(FuriHalUsbHidConfig* hid_cfg); + void (*deinit)(void* inst); + void (*set_state_callback)(void* inst, HidStateCallback cb, void* context); + bool (*is_connected)(void* inst); + + bool (*kb_press)(void* inst, uint16_t button); + bool (*kb_release)(void* inst, uint16_t button); + bool (*consumer_press)(void* inst, uint16_t button); + bool (*consumer_release)(void* inst, uint16_t button); + bool (*release_all)(void* inst); + uint8_t (*get_led_state)(void* inst); +} BadUsbHidApi; + +const BadUsbHidApi* bad_usb_hid_get_interface(BadUsbHidInterface interface); + +void bad_usb_hid_ble_remove_pairing(void); + +#ifdef __cplusplus +} +#endif diff --git a/applications/main/bad_usb/helpers/ducky_script.c b/applications/main/bad_usb/helpers/ducky_script.c index c4aa91062..077b1c37b 100644 --- a/applications/main/bad_usb/helpers/ducky_script.c +++ b/applications/main/bad_usb/helpers/ducky_script.c @@ -3,7 +3,6 @@ #include #include #include -#include #include #include "ducky_script.h" #include "ducky_script_i.h" @@ -71,39 +70,40 @@ bool ducky_get_number(const char* param, uint32_t* val) { return false; } -void ducky_numlock_on() { - if((furi_hal_hid_get_led_state() & HID_KB_LED_NUM) == 0) { - furi_hal_hid_kb_press(HID_KEYBOARD_LOCK_NUM_LOCK); - furi_hal_hid_kb_release(HID_KEYBOARD_LOCK_NUM_LOCK); +void ducky_numlock_on(BadUsbScript* bad_usb) { + if((bad_usb->hid->get_led_state(bad_usb->hid_inst) & HID_KB_LED_NUM) == 0) { + bad_usb->hid->kb_press(bad_usb->hid_inst, HID_KEYBOARD_LOCK_NUM_LOCK); + bad_usb->hid->kb_release(bad_usb->hid_inst, HID_KEYBOARD_LOCK_NUM_LOCK); } } -bool ducky_numpad_press(const char num) { + +bool ducky_numpad_press(BadUsbScript* bad_usb, const char num) { if((num < '0') || (num > '9')) return false; uint16_t key = numpad_keys[num - '0']; - furi_hal_hid_kb_press(key); - furi_hal_hid_kb_release(key); + bad_usb->hid->kb_press(bad_usb->hid_inst, key); + bad_usb->hid->kb_release(bad_usb->hid_inst, key); return true; } -bool ducky_altchar(const char* charcode) { +bool ducky_altchar(BadUsbScript* bad_usb, const char* charcode) { uint8_t i = 0; bool state = false; - furi_hal_hid_kb_press(KEY_MOD_LEFT_ALT); + bad_usb->hid->kb_press(bad_usb->hid_inst, KEY_MOD_LEFT_ALT); while(!ducky_is_line_end(charcode[i])) { - state = ducky_numpad_press(charcode[i]); + state = ducky_numpad_press(bad_usb, charcode[i]); if(state == false) break; i++; } - furi_hal_hid_kb_release(KEY_MOD_LEFT_ALT); + bad_usb->hid->kb_release(bad_usb->hid_inst, KEY_MOD_LEFT_ALT); return state; } -bool ducky_altstring(const char* param) { +bool ducky_altstring(BadUsbScript* bad_usb, const char* param) { uint32_t i = 0; bool state = false; @@ -116,7 +116,7 @@ bool ducky_altstring(const char* param) { char temp_str[4]; snprintf(temp_str, 4, "%u", param[i]); - state = ducky_altchar(temp_str); + state = ducky_altchar(bad_usb, temp_str); if(state == false) break; i++; } @@ -140,12 +140,12 @@ bool ducky_string(BadUsbScript* bad_usb, const char* param) { if(param[i] != '\n') { uint16_t keycode = BADUSB_ASCII_TO_KEY(bad_usb, param[i]); if(keycode != HID_KEYBOARD_NONE) { - furi_hal_hid_kb_press(keycode); - furi_hal_hid_kb_release(keycode); + bad_usb->hid->kb_press(bad_usb->hid_inst, keycode); + bad_usb->hid->kb_release(bad_usb->hid_inst, keycode); } } else { - furi_hal_hid_kb_press(HID_KEYBOARD_RETURN); - furi_hal_hid_kb_release(HID_KEYBOARD_RETURN); + bad_usb->hid->kb_press(bad_usb->hid_inst, HID_KEYBOARD_RETURN); + bad_usb->hid->kb_release(bad_usb->hid_inst, HID_KEYBOARD_RETURN); } i++; } @@ -163,12 +163,12 @@ static bool ducky_string_next(BadUsbScript* bad_usb) { if(print_char != '\n') { uint16_t keycode = BADUSB_ASCII_TO_KEY(bad_usb, print_char); if(keycode != HID_KEYBOARD_NONE) { - furi_hal_hid_kb_press(keycode); - furi_hal_hid_kb_release(keycode); + bad_usb->hid->kb_press(bad_usb->hid_inst, keycode); + bad_usb->hid->kb_release(bad_usb->hid_inst, keycode); } } else { - furi_hal_hid_kb_press(HID_KEYBOARD_RETURN); - furi_hal_hid_kb_release(HID_KEYBOARD_RETURN); + bad_usb->hid->kb_press(bad_usb->hid_inst, HID_KEYBOARD_RETURN); + bad_usb->hid->kb_release(bad_usb->hid_inst, HID_KEYBOARD_RETURN); } bad_usb->string_print_pos++; @@ -201,8 +201,8 @@ static int32_t ducky_parse_line(BadUsbScript* bad_usb, FuriString* line) { line_tmp = &line_tmp[ducky_get_command_len(line_tmp) + 1]; key |= ducky_get_keycode(bad_usb, line_tmp, true); } - furi_hal_hid_kb_press(key); - furi_hal_hid_kb_release(key); + bad_usb->hid->kb_press(bad_usb->hid_inst, key); + bad_usb->hid->kb_release(bad_usb->hid_inst, key); return 0; } @@ -231,6 +231,17 @@ static bool ducky_set_usb_id(BadUsbScript* bad_usb, const char* line) { return false; } +static void bad_usb_hid_state_callback(bool state, void* context) { + furi_assert(context); + BadUsbScript* bad_usb = context; + + if(state == true) { + furi_thread_flags_set(furi_thread_get_id(bad_usb->thread), WorkerEvtConnect); + } else { + furi_thread_flags_set(furi_thread_get_id(bad_usb->thread), WorkerEvtDisconnect); + } +} + static bool ducky_script_preload(BadUsbScript* bad_usb, File* script_file) { uint8_t ret = 0; uint32_t line_len = 0; @@ -265,10 +276,11 @@ static bool ducky_script_preload(BadUsbScript* bad_usb, File* script_file) { } if(id_set) { - furi_check(furi_hal_usb_set_config(&usb_hid, &bad_usb->hid_cfg)); + bad_usb->hid_inst = bad_usb->hid->init(&bad_usb->hid_cfg); } else { - furi_check(furi_hal_usb_set_config(&usb_hid, NULL)); + bad_usb->hid_inst = bad_usb->hid->init(NULL); } + bad_usb->hid->set_state_callback(bad_usb->hid_inst, bad_usb_hid_state_callback, bad_usb); storage_file_seek(script_file, 0, true); furi_string_reset(bad_usb->line); @@ -345,17 +357,6 @@ static int32_t ducky_script_execute_next(BadUsbScript* bad_usb, File* script_fil return 0; } -static void bad_usb_hid_state_callback(bool state, void* context) { - furi_assert(context); - BadUsbScript* bad_usb = context; - - if(state == true) { - furi_thread_flags_set(furi_thread_get_id(bad_usb->thread), WorkerEvtConnect); - } else { - furi_thread_flags_set(furi_thread_get_id(bad_usb->thread), WorkerEvtDisconnect); - } -} - static uint32_t bad_usb_flags_get(uint32_t flags_mask, uint32_t timeout) { uint32_t flags = furi_thread_flags_get(); furi_check((flags & FuriFlagError) == 0); @@ -382,8 +383,6 @@ static int32_t bad_usb_worker(void* context) { bad_usb->line_prev = furi_string_alloc(); bad_usb->string_print = furi_string_alloc(); - furi_hal_hid_set_state_callback(bad_usb_hid_state_callback, bad_usb); - while(1) { if(worker_state == BadUsbStateInit) { // State: initialization if(storage_file_open( @@ -392,7 +391,7 @@ static int32_t bad_usb_worker(void* context) { FSAM_READ, FSOM_OPEN_EXISTING)) { if((ducky_script_preload(bad_usb, script_file)) && (bad_usb->st.line_nb > 0)) { - if(furi_hal_hid_is_connected()) { + if(bad_usb->hid->is_connected(bad_usb->hid_inst)) { worker_state = BadUsbStateIdle; // Ready to run } else { worker_state = BadUsbStateNotConnected; // USB not connected @@ -408,7 +407,8 @@ static int32_t bad_usb_worker(void* context) { } else if(worker_state == BadUsbStateNotConnected) { // State: USB not connected uint32_t flags = bad_usb_flags_get( - WorkerEvtEnd | WorkerEvtConnect | WorkerEvtStartStop, FuriWaitForever); + WorkerEvtEnd | WorkerEvtConnect | WorkerEvtDisconnect | WorkerEvtStartStop, + FuriWaitForever); if(flags & WorkerEvtEnd) { break; @@ -432,6 +432,7 @@ static int32_t bad_usb_worker(void* context) { bad_usb->st.line_cur = 0; bad_usb->defdelay = 0; bad_usb->stringdelay = 0; + bad_usb->defstringdelay = 0; bad_usb->repeat_cnt = 0; bad_usb->key_hold_nb = 0; bad_usb->file_end = false; @@ -455,6 +456,7 @@ static int32_t bad_usb_worker(void* context) { bad_usb->st.line_cur = 0; bad_usb->defdelay = 0; bad_usb->stringdelay = 0; + bad_usb->defstringdelay = 0; bad_usb->repeat_cnt = 0; bad_usb->file_end = false; storage_file_seek(script_file, 0, true); @@ -488,10 +490,10 @@ static int32_t bad_usb_worker(void* context) { break; } else if(flags & WorkerEvtStartStop) { worker_state = BadUsbStateIdle; // Stop executing script - furi_hal_hid_kb_release_all(); + bad_usb->hid->release_all(bad_usb->hid_inst); } else if(flags & WorkerEvtDisconnect) { worker_state = BadUsbStateNotConnected; // USB disconnected - furi_hal_hid_kb_release_all(); + bad_usb->hid->release_all(bad_usb->hid_inst); } else if(flags & WorkerEvtPauseResume) { pause_state = BadUsbStateRunning; worker_state = BadUsbStatePaused; // Pause @@ -511,12 +513,12 @@ static int32_t bad_usb_worker(void* context) { delay_val = 0; worker_state = BadUsbStateScriptError; bad_usb->st.state = worker_state; - furi_hal_hid_kb_release_all(); + bad_usb->hid->release_all(bad_usb->hid_inst); } else if(delay_val == SCRIPT_STATE_END) { // End of script delay_val = 0; worker_state = BadUsbStateIdle; bad_usb->st.state = BadUsbStateDone; - furi_hal_hid_kb_release_all(); + bad_usb->hid->release_all(bad_usb->hid_inst); continue; } else if(delay_val == SCRIPT_STATE_STRING_START) { // Start printing string with delays delay_val = bad_usb->defdelay; @@ -544,7 +546,7 @@ static int32_t bad_usb_worker(void* context) { worker_state = BadUsbStateRunning; } else if(flags & WorkerEvtDisconnect) { worker_state = BadUsbStateNotConnected; // USB disconnected - furi_hal_hid_kb_release_all(); + bad_usb->hid->release_all(bad_usb->hid_inst); } bad_usb->st.state = worker_state; continue; @@ -559,11 +561,11 @@ static int32_t bad_usb_worker(void* context) { } else if(flags & WorkerEvtStartStop) { worker_state = BadUsbStateIdle; // Stop executing script bad_usb->st.state = worker_state; - furi_hal_hid_kb_release_all(); + bad_usb->hid->release_all(bad_usb->hid_inst); } else if(flags & WorkerEvtDisconnect) { worker_state = BadUsbStateNotConnected; // USB disconnected bad_usb->st.state = worker_state; - furi_hal_hid_kb_release_all(); + bad_usb->hid->release_all(bad_usb->hid_inst); } else if(flags & WorkerEvtPauseResume) { if(pause_state == BadUsbStateRunning) { if(delay_val > 0) { @@ -582,19 +584,21 @@ static int32_t bad_usb_worker(void* context) { continue; } } else if(worker_state == BadUsbStateStringDelay) { // State: print string with delays + uint32_t delay = (bad_usb->stringdelay == 0) ? bad_usb->defstringdelay : + bad_usb->stringdelay; uint32_t flags = bad_usb_flags_get( WorkerEvtEnd | WorkerEvtStartStop | WorkerEvtPauseResume | WorkerEvtDisconnect, - bad_usb->stringdelay); + delay); if(!(flags & FuriFlagError)) { if(flags & WorkerEvtEnd) { break; } else if(flags & WorkerEvtStartStop) { worker_state = BadUsbStateIdle; // Stop executing script - furi_hal_hid_kb_release_all(); + bad_usb->hid->release_all(bad_usb->hid_inst); } else if(flags & WorkerEvtDisconnect) { worker_state = BadUsbStateNotConnected; // USB disconnected - furi_hal_hid_kb_release_all(); + bad_usb->hid->release_all(bad_usb->hid_inst); } else if(flags & WorkerEvtPauseResume) { pause_state = BadUsbStateStringDelay; worker_state = BadUsbStatePaused; // Pause @@ -624,7 +628,8 @@ static int32_t bad_usb_worker(void* context) { } } - furi_hal_hid_set_state_callback(NULL, NULL); + bad_usb->hid->set_state_callback(bad_usb->hid_inst, NULL, NULL); + bad_usb->hid->deinit(bad_usb->hid_inst); storage_file_close(script_file); storage_file_free(script_file); @@ -643,7 +648,7 @@ static void bad_usb_script_set_default_keyboard_layout(BadUsbScript* bad_usb) { memcpy(bad_usb->layout, hid_asciimap, MIN(sizeof(hid_asciimap), sizeof(bad_usb->layout))); } -BadUsbScript* bad_usb_script_open(FuriString* file_path) { +BadUsbScript* bad_usb_script_open(FuriString* file_path, BadUsbHidInterface interface) { furi_assert(file_path); BadUsbScript* bad_usb = malloc(sizeof(BadUsbScript)); @@ -653,6 +658,7 @@ BadUsbScript* bad_usb_script_open(FuriString* file_path) { bad_usb->st.state = BadUsbStateInit; bad_usb->st.error[0] = '\0'; + bad_usb->hid = bad_usb_hid_get_interface(interface); bad_usb->thread = furi_thread_alloc_ex("BadUsbWorker", 2048, bad_usb_worker, bad_usb); furi_thread_start(bad_usb->thread); diff --git a/applications/main/bad_usb/helpers/ducky_script.h b/applications/main/bad_usb/helpers/ducky_script.h index dca61ed4e..9519623f6 100644 --- a/applications/main/bad_usb/helpers/ducky_script.h +++ b/applications/main/bad_usb/helpers/ducky_script.h @@ -6,6 +6,7 @@ extern "C" { #include #include +#include "bad_usb_hid.h" typedef enum { BadUsbStateInit, @@ -33,7 +34,7 @@ typedef struct { typedef struct BadUsbScript BadUsbScript; -BadUsbScript* bad_usb_script_open(FuriString* file_path); +BadUsbScript* bad_usb_script_open(FuriString* file_path, BadUsbHidInterface interface); void bad_usb_script_close(BadUsbScript* bad_usb); diff --git a/applications/main/bad_usb/helpers/ducky_script_commands.c b/applications/main/bad_usb/helpers/ducky_script_commands.c index a5bc7c8cf..7f9a48fb2 100644 --- a/applications/main/bad_usb/helpers/ducky_script_commands.c +++ b/applications/main/bad_usb/helpers/ducky_script_commands.c @@ -1,5 +1,4 @@ #include -#include #include "ducky_script.h" #include "ducky_script_i.h" @@ -46,6 +45,17 @@ static int32_t ducky_fnc_strdelay(BadUsbScript* bad_usb, const char* line, int32 return 0; } +static int32_t ducky_fnc_defstrdelay(BadUsbScript* bad_usb, const char* line, int32_t param) { + UNUSED(param); + + line = &line[ducky_get_command_len(line) + 1]; + bool state = ducky_get_number(line, &bad_usb->defstringdelay); + if(!state) { + return ducky_error(bad_usb, "Invalid number %s", line); + } + return 0; +} + static int32_t ducky_fnc_string(BadUsbScript* bad_usb, const char* line, int32_t param) { line = &line[ducky_get_command_len(line) + 1]; furi_string_set_str(bad_usb->string_print, line); @@ -53,7 +63,8 @@ static int32_t ducky_fnc_string(BadUsbScript* bad_usb, const char* line, int32_t furi_string_cat(bad_usb->string_print, "\n"); } - if(bad_usb->stringdelay == 0) { // stringdelay not set - run command immediately + if(bad_usb->stringdelay == 0 && + bad_usb->defstringdelay == 0) { // stringdelay not set - run command immediately bool state = ducky_string(bad_usb, furi_string_get_cstr(bad_usb->string_print)); if(!state) { return ducky_error(bad_usb, "Invalid string %s", line); @@ -81,9 +92,9 @@ static int32_t ducky_fnc_sysrq(BadUsbScript* bad_usb, const char* line, int32_t line = &line[ducky_get_command_len(line) + 1]; uint16_t key = ducky_get_keycode(bad_usb, line, true); - furi_hal_hid_kb_press(KEY_MOD_LEFT_ALT | HID_KEYBOARD_PRINT_SCREEN); - furi_hal_hid_kb_press(key); - furi_hal_hid_kb_release_all(); + bad_usb->hid->kb_press(bad_usb->hid_inst, KEY_MOD_LEFT_ALT | HID_KEYBOARD_PRINT_SCREEN); + bad_usb->hid->kb_press(bad_usb->hid_inst, key); + bad_usb->hid->release_all(bad_usb->hid_inst); return 0; } @@ -91,8 +102,8 @@ static int32_t ducky_fnc_altchar(BadUsbScript* bad_usb, const char* line, int32_ UNUSED(param); line = &line[ducky_get_command_len(line) + 1]; - ducky_numlock_on(); - bool state = ducky_altchar(line); + ducky_numlock_on(bad_usb); + bool state = ducky_altchar(bad_usb, line); if(!state) { return ducky_error(bad_usb, "Invalid altchar %s", line); } @@ -103,8 +114,8 @@ static int32_t ducky_fnc_altstring(BadUsbScript* bad_usb, const char* line, int3 UNUSED(param); line = &line[ducky_get_command_len(line) + 1]; - ducky_numlock_on(); - bool state = ducky_altstring(line); + ducky_numlock_on(bad_usb); + bool state = ducky_altstring(bad_usb, line); if(!state) { return ducky_error(bad_usb, "Invalid altstring %s", line); } @@ -123,7 +134,7 @@ static int32_t ducky_fnc_hold(BadUsbScript* bad_usb, const char* line, int32_t p if(bad_usb->key_hold_nb > (HID_KB_MAX_KEYS - 1)) { return ducky_error(bad_usb, "Too many keys are hold"); } - furi_hal_hid_kb_press(key); + bad_usb->hid->kb_press(bad_usb->hid_inst, key); return 0; } @@ -139,7 +150,36 @@ static int32_t ducky_fnc_release(BadUsbScript* bad_usb, const char* line, int32_ return ducky_error(bad_usb, "No keys are hold"); } bad_usb->key_hold_nb--; - furi_hal_hid_kb_release(key); + bad_usb->hid->kb_release(bad_usb->hid_inst, key); + return 0; +} + +static int32_t ducky_fnc_media(BadUsbScript* bad_usb, const char* line, int32_t param) { + UNUSED(param); + + line = &line[ducky_get_command_len(line) + 1]; + uint16_t key = ducky_get_media_keycode_by_name(line); + if(key == HID_CONSUMER_UNASSIGNED) { + return ducky_error(bad_usb, "No keycode defined for %s", line); + } + bad_usb->hid->consumer_press(bad_usb->hid_inst, key); + bad_usb->hid->consumer_release(bad_usb->hid_inst, key); + return 0; +} + +static int32_t ducky_fnc_globe(BadUsbScript* bad_usb, const char* line, int32_t param) { + UNUSED(param); + + line = &line[ducky_get_command_len(line) + 1]; + uint16_t key = ducky_get_keycode(bad_usb, line, true); + if(key == HID_KEYBOARD_NONE) { + return ducky_error(bad_usb, "No keycode defined for %s", line); + } + + bad_usb->hid->consumer_press(bad_usb->hid_inst, HID_CONSUMER_FN_GLOBE); + bad_usb->hid->kb_press(bad_usb->hid_inst, key); + bad_usb->hid->kb_release(bad_usb->hid_inst, key); + bad_usb->hid->consumer_release(bad_usb->hid_inst, HID_CONSUMER_FN_GLOBE); return 0; } @@ -161,6 +201,8 @@ static const DuckyCmd ducky_commands[] = { {"DEFAULTDELAY", ducky_fnc_defdelay, -1}, {"STRINGDELAY", ducky_fnc_strdelay, -1}, {"STRING_DELAY", ducky_fnc_strdelay, -1}, + {"DEFAULT_STRING_DELAY", ducky_fnc_defstrdelay, -1}, + {"DEFAULTSTRINGDELAY", ducky_fnc_defstrdelay, -1}, {"REPEAT", ducky_fnc_repeat, -1}, {"SYSRQ", ducky_fnc_sysrq, -1}, {"ALTCHAR", ducky_fnc_altchar, -1}, @@ -169,6 +211,8 @@ static const DuckyCmd ducky_commands[] = { {"HOLD", ducky_fnc_hold, -1}, {"RELEASE", ducky_fnc_release, -1}, {"WAIT_FOR_BUTTON_PRESS", ducky_fnc_waitforbutton, -1}, + {"MEDIA", ducky_fnc_media, -1}, + {"GLOBE", ducky_fnc_globe, -1}, }; #define TAG "BadUsb" diff --git a/applications/main/bad_usb/helpers/ducky_script_i.h b/applications/main/bad_usb/helpers/ducky_script_i.h index 84c7ef9de..bbafdccb6 100644 --- a/applications/main/bad_usb/helpers/ducky_script_i.h +++ b/applications/main/bad_usb/helpers/ducky_script_i.h @@ -7,6 +7,7 @@ extern "C" { #include #include #include "ducky_script.h" +#include "bad_usb_hid.h" #define SCRIPT_STATE_ERROR (-1) #define SCRIPT_STATE_END (-2) @@ -19,6 +20,8 @@ extern "C" { struct BadUsbScript { FuriHalUsbHidConfig hid_cfg; + const BadUsbHidApi* hid; + void* hid_inst; FuriThread* thread; BadUsbState st; @@ -30,6 +33,7 @@ struct BadUsbScript { uint32_t defdelay; uint32_t stringdelay; + uint32_t defstringdelay; uint16_t layout[128]; FuriString* line; @@ -49,15 +53,17 @@ bool ducky_is_line_end(const char chr); uint16_t ducky_get_keycode_by_name(const char* param); +uint16_t ducky_get_media_keycode_by_name(const char* param); + bool ducky_get_number(const char* param, uint32_t* val); -void ducky_numlock_on(void); +void ducky_numlock_on(BadUsbScript* bad_usb); -bool ducky_numpad_press(const char num); +bool ducky_numpad_press(BadUsbScript* bad_usb, const char num); -bool ducky_altchar(const char* charcode); +bool ducky_altchar(BadUsbScript* bad_usb, const char* charcode); -bool ducky_altstring(const char* param); +bool ducky_altstring(BadUsbScript* bad_usb, const char* param); bool ducky_string(BadUsbScript* bad_usb, const char* param); diff --git a/applications/main/bad_usb/helpers/ducky_script_keycodes.c b/applications/main/bad_usb/helpers/ducky_script_keycodes.c index da2fc22f7..290618c13 100644 --- a/applications/main/bad_usb/helpers/ducky_script_keycodes.c +++ b/applications/main/bad_usb/helpers/ducky_script_keycodes.c @@ -1,5 +1,4 @@ #include -#include #include "ducky_script_i.h" typedef struct { @@ -64,6 +63,49 @@ static const DuckyKey ducky_keys[] = { {"F10", HID_KEYBOARD_F10}, {"F11", HID_KEYBOARD_F11}, {"F12", HID_KEYBOARD_F12}, + {"F13", HID_KEYBOARD_F13}, + {"F14", HID_KEYBOARD_F14}, + {"F15", HID_KEYBOARD_F15}, + {"F16", HID_KEYBOARD_F16}, + {"F17", HID_KEYBOARD_F17}, + {"F18", HID_KEYBOARD_F18}, + {"F19", HID_KEYBOARD_F19}, + {"F20", HID_KEYBOARD_F20}, + {"F21", HID_KEYBOARD_F21}, + {"F22", HID_KEYBOARD_F22}, + {"F23", HID_KEYBOARD_F23}, + {"F24", HID_KEYBOARD_F24}, +}; + +static const DuckyKey ducky_media_keys[] = { + {"POWER", HID_CONSUMER_POWER}, + {"REBOOT", HID_CONSUMER_RESET}, + {"SLEEP", HID_CONSUMER_SLEEP}, + {"LOGOFF", HID_CONSUMER_AL_LOGOFF}, + + {"EXIT", HID_CONSUMER_AC_EXIT}, + {"HOME", HID_CONSUMER_AC_HOME}, + {"BACK", HID_CONSUMER_AC_BACK}, + {"FORWARD", HID_CONSUMER_AC_FORWARD}, + {"REFRESH", HID_CONSUMER_AC_REFRESH}, + + {"SNAPSHOT", HID_CONSUMER_SNAPSHOT}, + + {"PLAY", HID_CONSUMER_PLAY}, + {"PAUSE", HID_CONSUMER_PAUSE}, + {"PLAY_PAUSE", HID_CONSUMER_PLAY_PAUSE}, + {"NEXT_TRACK", HID_CONSUMER_SCAN_NEXT_TRACK}, + {"PREV_TRACK", HID_CONSUMER_SCAN_PREVIOUS_TRACK}, + {"STOP", HID_CONSUMER_STOP}, + {"EJECT", HID_CONSUMER_EJECT}, + + {"MUTE", HID_CONSUMER_MUTE}, + {"VOLUME_UP", HID_CONSUMER_VOLUME_INCREMENT}, + {"VOLUME_DOWN", HID_CONSUMER_VOLUME_DECREMENT}, + + {"FN", HID_CONSUMER_FN_GLOBE}, + {"BRIGHT_UP", HID_CONSUMER_BRIGHTNESS_INCREMENT}, + {"BRIGHT_DOWN", HID_CONSUMER_BRIGHTNESS_DECREMENT}, }; uint16_t ducky_get_keycode_by_name(const char* param) { @@ -77,3 +119,15 @@ uint16_t ducky_get_keycode_by_name(const char* param) { return HID_KEYBOARD_NONE; } + +uint16_t ducky_get_media_keycode_by_name(const char* param) { + for(size_t i = 0; i < COUNT_OF(ducky_media_keys); i++) { + size_t key_cmd_len = strlen(ducky_media_keys[i].name); + if((strncmp(param, ducky_media_keys[i].name, key_cmd_len) == 0) && + (ducky_is_line_end(param[key_cmd_len]))) { + return ducky_media_keys[i].keycode; + } + } + + return HID_CONSUMER_UNASSIGNED; +} diff --git a/applications/main/bad_usb/resources/badusb/assets/layouts/it-IT-mac.kl b/applications/main/bad_usb/resources/badusb/assets/layouts/it-IT-mac.kl new file mode 100644 index 000000000..6c10e4266 Binary files /dev/null and b/applications/main/bad_usb/resources/badusb/assets/layouts/it-IT-mac.kl differ diff --git a/applications/main/bad_usb/resources/badusb/demo_chromeos.txt b/applications/main/bad_usb/resources/badusb/demo_chromeos.txt new file mode 100644 index 000000000..c5f675fb3 --- /dev/null +++ b/applications/main/bad_usb/resources/badusb/demo_chromeos.txt @@ -0,0 +1,80 @@ +REM This is BadUSB demo script for ChromeOS by kowalski7cc + +REM Open a new tab +CTRL t +REM wait for some slower chromebooks +DELAY 1000 +REM Open an empty editable page +DEFAULT_DELAY 50 +STRING data:text/html,