pzrnqt1vrss 2 лет назад
Родитель
Сommit
224e1149f9
100 измененных файлов с 0 добавлено и 8448 удалено
  1. 0 191
      .clang-format
  2. 0 13
      .editorconfig
  3. 0 49
      .pvsconfig
  4. 0 1
      .pvsoptions
  5. 0 128
      CODE_OF_CONDUCT.md
  6. 0 101
      CODING_STYLE.md
  7. 0 72
      CONTRIBUTING.md
  8. 0 674
      LICENSE
  9. 0 337
      SConstruct
  10. 0 94
      applications/ReadMe.md
  11. 0 11
      applications/debug/accessor/accessor.cpp
  12. 0 141
      applications/debug/accessor/accessor_app.cpp
  13. 0 54
      applications/debug/accessor/accessor_app.h
  14. 0 19
      applications/debug/accessor/accessor_event.h
  15. 0 80
      applications/debug/accessor/accessor_view_manager.cpp
  16. 0 39
      applications/debug/accessor/accessor_view_manager.h
  17. 0 12
      applications/debug/accessor/application.fam
  18. 0 221
      applications/debug/accessor/helpers/wiegand.cpp
  19. 0 30
      applications/debug/accessor/helpers/wiegand.h
  20. 0 13
      applications/debug/accessor/scene/accessor_scene_generic.h
  21. 0 88
      applications/debug/accessor/scene/accessor_scene_start.cpp
  22. 0 9
      applications/debug/accessor/scene/accessor_scene_start.h
  23. 0 16
      applications/debug/application.fam
  24. 0 15
      applications/debug/battery_test_app/application.fam
  25. 0 101
      applications/debug/battery_test_app/battery_test_app.c
  26. 0 25
      applications/debug/battery_test_app/battery_test_app.h
  27. 0 148
      applications/debug/battery_test_app/views/battery_info.c
  28. 0 23
      applications/debug/battery_test_app/views/battery_info.h
  29. 0 11
      applications/debug/blink_test/application.fam
  30. 0 126
      applications/debug/blink_test/blink_test.c
  31. 0 18
      applications/debug/bt_debug_app/application.fam
  32. 0 118
      applications/debug/bt_debug_app/bt_debug_app.c
  33. 0 26
      applications/debug/bt_debug_app/bt_debug_app.h
  34. 0 188
      applications/debug/bt_debug_app/views/bt_carrier_test.c
  35. 0 10
      applications/debug/bt_debug_app/views/bt_carrier_test.h
  36. 0 155
      applications/debug/bt_debug_app/views/bt_packet_test.c
  37. 0 10
      applications/debug/bt_debug_app/views/bt_packet_test.h
  38. 0 434
      applications/debug/bt_debug_app/views/bt_test.c
  39. 0 46
      applications/debug/bt_debug_app/views/bt_test.h
  40. 0 30
      applications/debug/bt_debug_app/views/bt_test_types.h
  41. 0 10
      applications/debug/direct_draw/application.fam
  42. 0 112
      applications/debug/direct_draw/direct_draw.c
  43. 0 12
      applications/debug/display_test/application.fam
  44. 0 231
      applications/debug/display_test/display_test.c
  45. 0 1
      applications/debug/display_test/display_test.h
  46. 0 185
      applications/debug/display_test/view_display_test.c
  47. 0 12
      applications/debug/display_test/view_display_test.h
  48. 0 9
      applications/debug/example_custom_font/application.fam
  49. 0 98
      applications/debug/example_custom_font/example_custom_font.c
  50. 0 12
      applications/debug/file_browser_test/application.fam
  51. 0 99
      applications/debug/file_browser_test/file_browser_app.c
  52. 0 32
      applications/debug/file_browser_test/file_browser_app_i.h
  53. BIN
      applications/debug/file_browser_test/icons/badusb_10px.png
  54. 0 30
      applications/debug/file_browser_test/scenes/file_browser_scene.c
  55. 0 29
      applications/debug/file_browser_test/scenes/file_browser_scene.h
  56. 0 40
      applications/debug/file_browser_test/scenes/file_browser_scene_browser.c
  57. 0 3
      applications/debug/file_browser_test/scenes/file_browser_scene_config.h
  58. 0 41
      applications/debug/file_browser_test/scenes/file_browser_scene_result.c
  59. 0 46
      applications/debug/file_browser_test/scenes/file_browser_scene_start.c
  60. 0 11
      applications/debug/keypad_test/application.fam
  61. 0 157
      applications/debug/keypad_test/keypad_test.c
  62. 0 16
      applications/debug/lfrfid_debug/application.fam
  63. 0 81
      applications/debug/lfrfid_debug/lfrfid_debug.c
  64. 0 30
      applications/debug/lfrfid_debug/lfrfid_debug_i.h
  65. 0 44
      applications/debug/lfrfid_debug/scenes/lfrfid_debug_app_scene_start.c
  66. 0 48
      applications/debug/lfrfid_debug/scenes/lfrfid_debug_app_scene_tune.c
  67. 0 30
      applications/debug/lfrfid_debug/scenes/lfrfid_debug_scene.c
  68. 0 29
      applications/debug/lfrfid_debug/scenes/lfrfid_debug_scene.h
  69. 0 2
      applications/debug/lfrfid_debug/scenes/lfrfid_debug_scene_config.h
  70. 0 234
      applications/debug/lfrfid_debug/views/lfrfid_debug_view_tune.c
  71. 0 18
      applications/debug/lfrfid_debug/views/lfrfid_debug_view_tune.h
  72. 0 11
      applications/debug/locale_test/application.fam
  73. 0 102
      applications/debug/locale_test/locale_test.c
  74. 0 10
      applications/debug/rpc_debug_app/application.fam
  75. 0 138
      applications/debug/rpc_debug_app/rpc_debug_app.c
  76. 0 54
      applications/debug/rpc_debug_app/rpc_debug_app.h
  77. 0 30
      applications/debug/rpc_debug_app/scenes/rpc_debug_app_scene.c
  78. 0 29
      applications/debug/rpc_debug_app/scenes/rpc_debug_app_scene.h
  79. 0 8
      applications/debug/rpc_debug_app/scenes/rpc_debug_app_scene_config.h
  80. 0 40
      applications/debug/rpc_debug_app/scenes/rpc_debug_app_scene_input_data_exchange.c
  81. 0 64
      applications/debug/rpc_debug_app/scenes/rpc_debug_app_scene_input_error_code.c
  82. 0 40
      applications/debug/rpc_debug_app/scenes/rpc_debug_app_scene_input_error_text.c
  83. 0 70
      applications/debug/rpc_debug_app/scenes/rpc_debug_app_scene_receive_data_exchange.c
  84. 0 57
      applications/debug/rpc_debug_app/scenes/rpc_debug_app_scene_start.c
  85. 0 30
      applications/debug/rpc_debug_app/scenes/rpc_debug_app_scene_start_dummy.c
  86. 0 57
      applications/debug/rpc_debug_app/scenes/rpc_debug_app_scene_test_app_error.c
  87. 0 58
      applications/debug/rpc_debug_app/scenes/rpc_debug_app_scene_test_data_exchange.c
  88. 0 11
      applications/debug/text_box_test/application.fam
  89. 0 129
      applications/debug/text_box_test/text_box_test.c
  90. 0 11
      applications/debug/uart_echo/application.fam
  91. 0 271
      applications/debug/uart_echo/uart_echo.c
  92. 0 18
      applications/debug/unit_tests/application.fam
  93. 0 110
      applications/debug/unit_tests/bt/bt_test.c
  94. 0 337
      applications/debug/unit_tests/flipper_format/flipper_format_string_test.c
  95. 0 551
      applications/debug/unit_tests/flipper_format/flipper_format_test.c
  96. 0 60
      applications/debug/unit_tests/float_tools/float_tools_test.c
  97. 0 39
      applications/debug/unit_tests/furi/furi_memmgr_test.c
  98. 0 45
      applications/debug/unit_tests/furi/furi_pubsub_test.c
  99. 0 20
      applications/debug/unit_tests/furi/furi_record_test.c
  100. 0 469
      applications/debug/unit_tests/furi/furi_string_test.c

+ 0 - 191
.clang-format

@@ -1,191 +0,0 @@
----
-Language:        Cpp
-AccessModifierOffset: -4
-AlignAfterOpenBracket: AlwaysBreak
-AlignArrayOfStructures: None
-AlignConsecutiveMacros: None
-AlignConsecutiveAssignments: None
-AlignConsecutiveBitFields: None
-AlignConsecutiveDeclarations: None
-AlignEscapedNewlines: Left
-AlignOperands:   Align
-AlignTrailingComments: false
-AllowAllArgumentsOnNextLine: true
-AllowAllParametersOfDeclarationOnNextLine: false
-AllowShortEnumsOnASingleLine: true
-AllowShortBlocksOnASingleLine: Never
-AllowShortCaseLabelsOnASingleLine: false
-AllowShortFunctionsOnASingleLine: None
-AllowShortLambdasOnASingleLine: All
-AllowShortIfStatementsOnASingleLine: WithoutElse
-AllowShortLoopsOnASingleLine: true
-AlwaysBreakAfterDefinitionReturnType: None
-AlwaysBreakAfterReturnType: None
-AlwaysBreakBeforeMultilineStrings: false
-AlwaysBreakTemplateDeclarations: Yes
-AttributeMacros:
-  - __capability
-BinPackArguments: false
-BinPackParameters: false
-BraceWrapping:
-  AfterCaseLabel:  false
-  AfterClass:      false
-  AfterControlStatement: Never
-  AfterEnum:       false
-  AfterFunction:   false
-  AfterNamespace:  false
-  AfterObjCDeclaration: false
-  AfterStruct:     false
-  AfterUnion:      false
-  AfterExternBlock: false
-  BeforeCatch:     false
-  BeforeElse:      false
-  BeforeLambdaBody: false
-  BeforeWhile:     false
-  IndentBraces:    false
-  SplitEmptyFunction: true
-  SplitEmptyRecord: true
-  SplitEmptyNamespace: true
-BreakBeforeBinaryOperators: None
-BreakBeforeConceptDeclarations: true
-BreakBeforeBraces: Attach
-BreakBeforeInheritanceComma: false
-BreakInheritanceList: BeforeColon
-BreakBeforeTernaryOperators: false
-BreakConstructorInitializersBeforeComma: false
-BreakConstructorInitializers: BeforeComma
-BreakAfterJavaFieldAnnotations: false
-BreakStringLiterals: false
-ColumnLimit:     99
-CommentPragmas:  '^ IWYU pragma:'
-QualifierAlignment: Leave
-CompactNamespaces: false
-ConstructorInitializerIndentWidth: 4
-ContinuationIndentWidth: 4
-Cpp11BracedListStyle: true
-DeriveLineEnding: true
-DerivePointerAlignment: false
-DisableFormat:   false
-EmptyLineAfterAccessModifier: Never
-EmptyLineBeforeAccessModifier: LogicalBlock
-ExperimentalAutoDetectBinPacking: false
-PackConstructorInitializers: BinPack
-BasedOnStyle:    ''
-ConstructorInitializerAllOnOneLineOrOnePerLine: false
-AllowAllConstructorInitializersOnNextLine: true
-FixNamespaceComments: false
-ForEachMacros:
-  - foreach
-  - Q_FOREACH
-  - BOOST_FOREACH
-IfMacros:
-  - KJ_IF_MAYBE
-IncludeBlocks:   Preserve
-IncludeCategories:
-  - Regex:           '.*'
-    Priority:        1
-    SortPriority:    0
-    CaseSensitive:   false
-  - Regex:           '^(<|"(gtest|gmock|isl|json)/)'
-    Priority:        3
-    SortPriority:    0
-    CaseSensitive:   false
-  - Regex:           '.*'
-    Priority:        1
-    SortPriority:    0
-    CaseSensitive:   false
-IncludeIsMainRegex: '(Test)?$'
-IncludeIsMainSourceRegex: ''
-IndentAccessModifiers: false
-IndentCaseLabels: false
-IndentCaseBlocks: false
-IndentGotoLabels: true
-IndentPPDirectives: None
-IndentExternBlock: AfterExternBlock
-IndentRequires:  false
-IndentWidth:     4
-IndentWrappedFunctionNames: true
-InsertTrailingCommas: None
-JavaScriptQuotes: Leave
-JavaScriptWrapImports: true
-KeepEmptyLinesAtTheStartOfBlocks: false
-LambdaBodyIndentation: Signature
-MacroBlockBegin: ''
-MacroBlockEnd:   ''
-MaxEmptyLinesToKeep: 1
-NamespaceIndentation: None
-ObjCBinPackProtocolList: Auto
-ObjCBlockIndentWidth: 4
-ObjCBreakBeforeNestedBlockParam: true
-ObjCSpaceAfterProperty: true
-ObjCSpaceBeforeProtocolList: true
-PenaltyBreakAssignment: 10
-PenaltyBreakBeforeFirstCallParameter: 30
-PenaltyBreakComment: 10
-PenaltyBreakFirstLessLess: 0
-PenaltyBreakOpenParenthesis: 0
-PenaltyBreakString: 10
-PenaltyBreakTemplateDeclaration: 10
-PenaltyExcessCharacter: 100
-PenaltyReturnTypeOnItsOwnLine: 60
-PenaltyIndentedWhitespace: 0
-PointerAlignment: Left
-PPIndentWidth:   -1
-ReferenceAlignment: Pointer
-ReflowComments:  false
-RemoveBracesLLVM: false
-SeparateDefinitionBlocks: Leave
-ShortNamespaceLines: 1
-SortIncludes:    Never
-SortJavaStaticImport: Before
-SortUsingDeclarations: false
-SpaceAfterCStyleCast: false
-SpaceAfterLogicalNot: false
-SpaceAfterTemplateKeyword: true
-SpaceBeforeAssignmentOperators: true
-SpaceBeforeCaseColon: false
-SpaceBeforeCpp11BracedList: false
-SpaceBeforeCtorInitializerColon: true
-SpaceBeforeInheritanceColon: true
-SpaceBeforeParens: Never
-SpaceBeforeParensOptions:
-  AfterControlStatements: false
-  AfterForeachMacros: false
-  AfterFunctionDefinitionName: false
-  AfterFunctionDeclarationName: false
-  AfterIfMacros:   false
-  AfterOverloadedOperator: false
-  BeforeNonEmptyParentheses: false
-SpaceAroundPointerQualifiers: Default
-SpaceBeforeRangeBasedForLoopColon: true
-SpaceInEmptyBlock: false
-SpaceInEmptyParentheses: false
-SpacesBeforeTrailingComments: 1
-SpacesInAngles:  Never
-SpacesInConditionalStatement: false
-SpacesInContainerLiterals: false
-SpacesInCStyleCastParentheses: false
-SpacesInLineCommentPrefix:
-  Minimum:         1
-  Maximum:         -1
-SpacesInParentheses: false
-SpacesInSquareBrackets: false
-SpaceBeforeSquareBrackets: false
-BitFieldColonSpacing: Both
-Standard:        c++03
-StatementAttributeLikeMacros:
-  - Q_EMIT
-StatementMacros:
-  - Q_UNUSED
-  - QT_REQUIRE_VERSION
-TabWidth:        4
-UseCRLF:         false
-UseTab:          Never
-WhitespaceSensitiveMacros:
-  - STRINGIZE
-  - PP_STRINGIZE
-  - BOOST_PP_STRINGIZE
-  - NS_SWIFT_NAME
-  - CF_SWIFT_NAME
-...
-

+ 0 - 13
.editorconfig

@@ -1,13 +0,0 @@
-root = true
-
-[*]
-end_of_line = lf
-insert_final_newline = true
-charset = utf-8
-
-[*.{cpp,h,c,py,sh}]
-indent_style = space
-indent_size = 4
-
-[{Makefile,*.mk}]
-indent_size = tab

+ 0 - 49
.pvsconfig

@@ -1,49 +0,0 @@
-# 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:BPTREE_DEF2:779,1086,557,773,512
-//-V:DICT_DEF2:779,524,776,760,1044,1001,729,590,568,747,685
-//-V:ALGO_DEF:1048,747,1044
-//-V:TUPLE_DEF2:524,590,1001,760
-
-# Non-severe malloc/null pointer deref warnings
-//-V::522:2,3
-
-# Warning about headers with copyleft license
-//-V::1042
-
-# Potentially null argument warnings
-//-V:memset:575
-//-V:memcpy:575
-//-V:memcmp:575
-//-V:strlen:575
-//-V:strcpy:575
-//-V:strncpy:575
-//-V:strchr:575
-
-# For loop warning on M_FOREACH
-//-V:for:1044
-
-# Bitwise OR
-//-V:bit:792
-
-# Do not complain about similar code
-//-V::525
-
-# Common embedded development pointer operations
-//-V::566
-//-V::1032
-
-# Warnings about length mismatch
-//-V:property_value_out:666
-
-# 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/

+ 0 - 1
.pvsoptions

@@ -1 +0,0 @@
---ignore-ccache -C gccarm --rules-config .pvsconfig -e lib/fatfs -e lib/fnv1a-hash -e lib/FreeRTOS-Kernel -e lib/heatshrink -e lib/libusb_stm32 -e lib/littlefs -e lib/mbedtls -e lib/micro-ecc -e lib/microtar -e lib/mlib -e lib/qrcode -e lib/ST25RFAL002 -e lib/STM32CubeWB -e lib/u8g2 -e lib/nanopb -e */arm-none-eabi/* -e applications/external/dap_link/lib/free-dap

+ 0 - 128
CODE_OF_CONDUCT.md

@@ -1,128 +0,0 @@
-# Contributor Covenant Code of Conduct
-
-## Our Pledge
-
-We as members, contributors, and leaders pledge to make participation in our
-community a harassment-free experience for everyone, regardless of age, body
-size, visible or invisible disability, ethnicity, sex characteristics, gender
-identity and expression, level of experience, education, socio-economic status,
-nationality, personal appearance, race, religion, or sexual identity
-and orientation.
-
-We pledge to act and interact in ways that contribute to an open, welcoming,
-diverse, inclusive, and healthy community.
-
-## Our Standards
-
-Examples of behavior that contributes to a positive environment for our
-community include:
-
-* Demonstrating empathy and kindness toward other people
-* Being respectful of differing opinions, viewpoints, and experiences
-* Giving and gracefully accepting constructive feedback
-* Accepting responsibility and apologizing to those affected by our mistakes,
-  and learning from the experience
-* Focusing on what is best not just for us as individuals, but for the
-  overall community
-
-Examples of unacceptable behavior include:
-
-* The use of sexualized language or imagery, and sexual attention or
-  advances of any kind
-* Trolling, insulting or derogatory comments, and personal or political attacks
-* Public or private harassment
-* Publishing others' private information, such as a physical or email
-  address, without their explicit permission
-* Other conduct which could reasonably be considered inappropriate in a
-  professional setting
-
-## Enforcement Responsibilities
-
-Community leaders are responsible for clarifying and enforcing our standards of
-acceptable behavior and will take appropriate and fair corrective action in
-response to any behavior that they deem inappropriate, threatening, offensive,
-or harmful.
-
-Community leaders have the right and responsibility to remove, edit, or reject
-comments, commits, code, wiki edits, issues, and other contributions that are
-not aligned to this Code of Conduct, and will communicate reasons for moderation
-decisions when appropriate.
-
-## Scope
-
-This Code of Conduct applies within all community spaces, and also applies when
-an individual is officially representing the community in public spaces.
-Examples of representing our community include using an official e-mail address,
-posting via an official social media account, or acting as an appointed
-representative at an online or offline event.
-
-## Enforcement
-
-Instances of abusive, harassing, or otherwise unacceptable behavior may be
-reported to the community leaders responsible for enforcement at
-hello@flipperdevices.com.
-All complaints will be reviewed and investigated promptly and fairly.
-
-All community leaders are obligated to respect the privacy and security of the
-reporter of any incident.
-
-## Enforcement Guidelines
-
-Community leaders will follow these Community Impact Guidelines in determining
-the consequences for any action they deem in violation of this Code of Conduct:
-
-### 1. Correction
-
-**Community Impact**: Use of inappropriate language or other behavior deemed
-unprofessional or unwelcome in the community.
-
-**Consequence**: A private, written warning from community leaders, providing
-clarity around the nature of the violation and an explanation of why the
-behavior was inappropriate. A public apology may be requested.
-
-### 2. Warning
-
-**Community Impact**: A violation through a single incident or series
-of actions.
-
-**Consequence**: A warning with consequences for continued behavior. No
-interaction with the people involved, including unsolicited interaction with
-those enforcing the Code of Conduct, for a specified period of time. This
-includes avoiding interactions in community spaces as well as external channels
-like social media. Violating these terms may lead to a temporary or
-permanent ban.
-
-### 3. Temporary Ban
-
-**Community Impact**: A serious violation of community standards, including
-sustained inappropriate behavior.
-
-**Consequence**: A temporary ban from any sort of interaction or public
-communication with the community for a specified period of time. No public or
-private interaction with the people involved, including unsolicited interaction
-with those enforcing the Code of Conduct, is allowed during this period.
-Violating these terms may lead to a permanent ban.
-
-### 4. Permanent Ban
-
-**Community Impact**: Demonstrating a pattern of violation of community
-standards, including sustained inappropriate behavior,  harassment of an
-individual, or aggression toward or disparagement of classes of individuals.
-
-**Consequence**: A permanent ban from any sort of public interaction within
-the community.
-
-## Attribution
-
-This Code of Conduct is adapted from the [Contributor Covenant][homepage],
-version 2.0, available at
-https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
-
-Community Impact Guidelines were inspired by [Mozilla's code of conduct
-enforcement ladder](https://github.com/mozilla/diversity).
-
-[homepage]: https://www.contributor-covenant.org
-
-For answers to common questions about this code of conduct, see the FAQ at
-https://www.contributor-covenant.org/faq. Translations are available at
-https://www.contributor-covenant.org/translations.

+ 0 - 101
CODING_STYLE.md

@@ -1,101 +0,0 @@
-# Intro
-
-Nice to see you reading this document, we really appreciate it.
-
-As all documents of this kind it's unable to cover everything.
-But it will cover general rules that we are enforcing on PR review.
-
-Also, we already have automatic rules checking and formatting,
-but it got its limitations and this guide is still mandatory.
-
-Some part of this project do have its own naming and coding guides.
-For example: assets. Take a look into `ReadMe.md` in assets folder for more details.
-
-Also, 3rd party libraries are none of our concern.
-
-And yes, this set is not final and we are open to discussion.
-If you want to add/remove/change something here please feel free to open new ticket.
-
-# Inspiration
-
-Our guide is inspired by, but not claiming to be compatible with:
-
-- https://www.kernel.org/doc/html/v4.10/process/coding-style.html
-- https://docs.unrealengine.com/en-US/Programming/Development/CodingStandard
-- https://webkit.org/code-style-guidelines/
-
-# General rules
-
-## Readability and Simplicity first
-
-Code we write is intended to be public.
-Avoid one-liners from hell and keep code complexity under control.
-Try to make code self-explanatory and add comments if needed.
-Leave references to standards that you are implementing.
-Use project wiki to document new/reverse engineered standards.
-
-## Variable and function names must clearly define what it's doing
-
-It's ok if it will be long, but it should clearly state what it's doing, without need to dive into code.
-This also applies to function/method's code.
-Try to avoid one letter variables.
-
-## Encapsulation
-
-Don't expose raw data, provide methods to work with it.
-Almost everything in flipper firmware is built around this concept.
-
-# C coding style
-
-- Tab is 4 spaces
-- Use `fbt format` to reformat source code and check style guide before commit
-
-## Naming
-
-### Type names are PascalCase
-
-Examples:
-
-	FuriHalUsb
-	Gui
-	SubGhzKeystore
-
-
-### Functions are snake_case
-
-	furi_hal_usb_init
-	gui_add_view_port
-	subghz_keystore_read
-
-### File and Package name is a prefix for it's content
-
-This rule makes easier to locate types, functions and sources.
-
-For example:
-
-We have abstraction that we call `SubGhz Keystore`, so there will be:
-file `subghz_keystore.h` we have type `SubGhzKeystore` and function `subghz_keystore_read`.
-
-### File names
-
-- Directories: `^[0-9A-Za-z_]+$`
-- File names: `^[0-9A-Za-z_]+\.[a-z]+$`
-- File extensions: `[ ".h", ".c", ".cpp", ".cxx", ".hpp" ]`
-
-Enforced by linter.
-
-### Standard function/method names
-
-Suffixes:
-
-- `alloc` - allocate and init instance. C style constructor. Returns pointer to instance.
-- `free` - de-init and release instance. C style destructor. Takes pointer to instance.
-
-# C++ coding style
-
-Work In Progress. Use C style guide as a base.
-
-# Python coding style
-
-- Tab is 4 spaces
-- Use [black](https://pypi.org/project/black/) to reformat source code before commit

+ 0 - 72
CONTRIBUTING.md

@@ -1,72 +0,0 @@
-# Welcome to FlipperZero contributing guide <!-- omit in toc -->
-
-Thank you for investing your time in contributing to our project! 
-
-Read our [Code of Conduct](CODE_OF_CONDUCT.md) to keep our community approachable and respectable.
-
-In this guide you will get an overview of the contribution workflow from opening an issue, creating a PR, reviewing, and merging the PR.
-
-## New contributor guide
-
-See the [ReadMe](ReadMe.md) to get an overview of the project. Here are some helpful resources to get you comfortable with open source contribution:
-
-- [Finding ways to contribute to open source on GitHub](https://docs.github.com/en/get-started/exploring-projects-on-github/finding-ways-to-contribute-to-open-source-on-github)
-- [Set up Git](https://docs.github.com/en/get-started/quickstart/set-up-git)
-- [GitHub flow](https://docs.github.com/en/get-started/quickstart/github-flow)
-- [Collaborating with pull requests](https://docs.github.com/en/github/collaborating-with-pull-requests)
-
-## Getting started
-
-Before writing code and creating PR make sure that it aligns with our mission and guidelines:
-
-- All our devices are intended for research and education.
-- PR that contains code intended to commit crimes is not going to be accepted.
-- Your PR must comply with our [Coding Style](CODING_STYLE.md)
-- Your PR must contain code compatible with project [LICENSE](LICENSE).
-- PR will only be merged if it passes CI/CD.
-- PR will only be merged if it passes review by code owner.
-
-Feel free to ask questions in issues if you're not sure.
-
-### Issues
-
-#### Create a new issue
-
-If you found a problem, [search if an issue already exists](https://docs.github.com/en/github/searching-for-information-on-github/searching-on-github/searching-issues-and-pull-requests#search-by-the-title-body-or-comments). If a related issue doesn't exist, you can open a new issue using a relevant [issue form](https://github.com/flipperdevices/flipperzero-firmware/issues/new/choose). 
-
-#### Solve an issue
-
-Scan through our [existing issues](https://github.com/flipperdevices/flipperzero-firmware/issues) to find one that interests you.
-
-### Make Changes
-
-1. Fork the repository.
-- Using GitHub Desktop:
-  - [Getting started with GitHub Desktop](https://docs.github.com/en/desktop/installing-and-configuring-github-desktop/getting-started-with-github-desktop) will guide you through setting up Desktop.
-  - Once Desktop is set up, you can use it to [fork the repo](https://docs.github.com/en/desktop/contributing-and-collaborating-using-github-desktop/cloning-and-forking-repositories-from-github-desktop)!
-
-- Using the command line:
-  - [Fork the repo](https://docs.github.com/en/github/getting-started-with-github/fork-a-repo#fork-an-example-repository) so that you can make your changes without affecting the original project until you're ready to merge them.
-
-2. Install build requirements
-
-3. Create a working branch and start with your changes!
-
-### Commit your update
-
-Commit the changes once you are happy with them. Make sure that code compilation is not broken and passes tests. Check syntax and formatting.
-
-### Pull Request
-
-When you're done making the changes, open a pull request, often referred to as a PR. 
-- Fill out the "Ready for review" template, so we can review your PR. This template helps reviewers understand your changes and the purpose of your pull request. 
-- Don't forget to [link PR to issue](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue) if you are solving one.
-- Enable the checkbox to [allow maintainer edits](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/allowing-changes-to-a-pull-request-branch-created-from-a-fork) so the branch can be updated for a merge.
-Once you submit your PR, a Docs team member will review your proposal. We may ask questions or request for additional information.
-- We may ask for changes to be made before a PR can be merged, either using [suggested changes](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/incorporating-feedback-in-your-pull-request) or pull request comments. You can apply suggested changes directly through the UI. You can make any other changes in your fork, then commit them to your branch.
-- As you update your PR and apply changes, mark each conversation as [resolved](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/commenting-on-a-pull-request#resolving-conversations).
-- If you run into any merge issues, checkout this [git tutorial](https://lab.github.com/githubtraining/managing-merge-conflicts) to help you resolve merge conflicts and other issues.
-
-### Your PR is merged!
-
-Congratulations :tada::tada: The FlipperDevices team thanks you :sparkles:.

+ 0 - 674
LICENSE

@@ -1,674 +0,0 @@
-                    GNU GENERAL PUBLIC LICENSE
-                       Version 3, 29 June 2007
-
- Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-                            Preamble
-
-  The GNU General Public License is a free, copyleft license for
-software and other kinds of works.
-
-  The licenses for most software and other practical works are designed
-to take away your freedom to share and change the works.  By contrast,
-the GNU General Public License is intended to guarantee your freedom to
-share and change all versions of a program--to make sure it remains free
-software for all its users.  We, the Free Software Foundation, use the
-GNU General Public License for most of our software; it applies also to
-any other work released this way by its authors.  You can apply it to
-your programs, too.
-
-  When we speak of free software, we are referring to freedom, not
-price.  Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-them if you wish), that you receive source code or can get it if you
-want it, that you can change the software or use pieces of it in new
-free programs, and that you know you can do these things.
-
-  To protect your rights, we need to prevent others from denying you
-these rights or asking you to surrender the rights.  Therefore, you have
-certain responsibilities if you distribute copies of the software, or if
-you modify it: responsibilities to respect the freedom of others.
-
-  For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must pass on to the recipients the same
-freedoms that you received.  You must make sure that they, too, receive
-or can get the source code.  And you must show them these terms so they
-know their rights.
-
-  Developers that use the GNU GPL protect your rights with two steps:
-(1) assert copyright on the software, and (2) offer you this License
-giving you legal permission to copy, distribute and/or modify it.
-
-  For the developers' and authors' protection, the GPL clearly explains
-that there is no warranty for this free software.  For both users' and
-authors' sake, the GPL requires that modified versions be marked as
-changed, so that their problems will not be attributed erroneously to
-authors of previous versions.
-
-  Some devices are designed to deny users access to install or run
-modified versions of the software inside them, although the manufacturer
-can do so.  This is fundamentally incompatible with the aim of
-protecting users' freedom to change the software.  The systematic
-pattern of such abuse occurs in the area of products for individuals to
-use, which is precisely where it is most unacceptable.  Therefore, we
-have designed this version of the GPL to prohibit the practice for those
-products.  If such problems arise substantially in other domains, we
-stand ready to extend this provision to those domains in future versions
-of the GPL, as needed to protect the freedom of users.
-
-  Finally, every program is threatened constantly by software patents.
-States should not allow patents to restrict development and use of
-software on general-purpose computers, but in those that do, we wish to
-avoid the special danger that patents applied to a free program could
-make it effectively proprietary.  To prevent this, the GPL assures that
-patents cannot be used to render the program non-free.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.
-
-                       TERMS AND CONDITIONS
-
-  0. Definitions.
-
-  "This License" refers to version 3 of the GNU General Public License.
-
-  "Copyright" also means copyright-like laws that apply to other kinds of
-works, such as semiconductor masks.
-
-  "The Program" refers to any copyrightable work licensed under this
-License.  Each licensee is addressed as "you".  "Licensees" and
-"recipients" may be individuals or organizations.
-
-  To "modify" a work means to copy from or adapt all or part of the work
-in a fashion requiring copyright permission, other than the making of an
-exact copy.  The resulting work is called a "modified version" of the
-earlier work or a work "based on" the earlier work.
-
-  A "covered work" means either the unmodified Program or a work based
-on the Program.
-
-  To "propagate" a work means to do anything with it that, without
-permission, would make you directly or secondarily liable for
-infringement under applicable copyright law, except executing it on a
-computer or modifying a private copy.  Propagation includes copying,
-distribution (with or without modification), making available to the
-public, and in some countries other activities as well.
-
-  To "convey" a work means any kind of propagation that enables other
-parties to make or receive copies.  Mere interaction with a user through
-a computer network, with no transfer of a copy, is not conveying.
-
-  An interactive user interface displays "Appropriate Legal Notices"
-to the extent that it includes a convenient and prominently visible
-feature that (1) displays an appropriate copyright notice, and (2)
-tells the user that there is no warranty for the work (except to the
-extent that warranties are provided), that licensees may convey the
-work under this License, and how to view a copy of this License.  If
-the interface presents a list of user commands or options, such as a
-menu, a prominent item in the list meets this criterion.
-
-  1. Source Code.
-
-  The "source code" for a work means the preferred form of the work
-for making modifications to it.  "Object code" means any non-source
-form of a work.
-
-  A "Standard Interface" means an interface that either is an official
-standard defined by a recognized standards body, or, in the case of
-interfaces specified for a particular programming language, one that
-is widely used among developers working in that language.
-
-  The "System Libraries" of an executable work include anything, other
-than the work as a whole, that (a) is included in the normal form of
-packaging a Major Component, but which is not part of that Major
-Component, and (b) serves only to enable use of the work with that
-Major Component, or to implement a Standard Interface for which an
-implementation is available to the public in source code form.  A
-"Major Component", in this context, means a major essential component
-(kernel, window system, and so on) of the specific operating system
-(if any) on which the executable work runs, or a compiler used to
-produce the work, or an object code interpreter used to run it.
-
-  The "Corresponding Source" for a work in object code form means all
-the source code needed to generate, install, and (for an executable
-work) run the object code and to modify the work, including scripts to
-control those activities.  However, it does not include the work's
-System Libraries, or general-purpose tools or generally available free
-programs which are used unmodified in performing those activities but
-which are not part of the work.  For example, Corresponding Source
-includes interface definition files associated with source files for
-the work, and the source code for shared libraries and dynamically
-linked subprograms that the work is specifically designed to require,
-such as by intimate data communication or control flow between those
-subprograms and other parts of the work.
-
-  The Corresponding Source need not include anything that users
-can regenerate automatically from other parts of the Corresponding
-Source.
-
-  The Corresponding Source for a work in source code form is that
-same work.
-
-  2. Basic Permissions.
-
-  All rights granted under this License are granted for the term of
-copyright on the Program, and are irrevocable provided the stated
-conditions are met.  This License explicitly affirms your unlimited
-permission to run the unmodified Program.  The output from running a
-covered work is covered by this License only if the output, given its
-content, constitutes a covered work.  This License acknowledges your
-rights of fair use or other equivalent, as provided by copyright law.
-
-  You may make, run and propagate covered works that you do not
-convey, without conditions so long as your license otherwise remains
-in force.  You may convey covered works to others for the sole purpose
-of having them make modifications exclusively for you, or provide you
-with facilities for running those works, provided that you comply with
-the terms of this License in conveying all material for which you do
-not control copyright.  Those thus making or running the covered works
-for you must do so exclusively on your behalf, under your direction
-and control, on terms that prohibit them from making any copies of
-your copyrighted material outside their relationship with you.
-
-  Conveying under any other circumstances is permitted solely under
-the conditions stated below.  Sublicensing is not allowed; section 10
-makes it unnecessary.
-
-  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
-
-  No covered work shall be deemed part of an effective technological
-measure under any applicable law fulfilling obligations under article
-11 of the WIPO copyright treaty adopted on 20 December 1996, or
-similar laws prohibiting or restricting circumvention of such
-measures.
-
-  When you convey a covered work, you waive any legal power to forbid
-circumvention of technological measures to the extent such circumvention
-is effected by exercising rights under this License with respect to
-the covered work, and you disclaim any intention to limit operation or
-modification of the work as a means of enforcing, against the work's
-users, your or third parties' legal rights to forbid circumvention of
-technological measures.
-
-  4. Conveying Verbatim Copies.
-
-  You may convey verbatim copies of the Program's source code as you
-receive it, in any medium, provided that you conspicuously and
-appropriately publish on each copy an appropriate copyright notice;
-keep intact all notices stating that this License and any
-non-permissive terms added in accord with section 7 apply to the code;
-keep intact all notices of the absence of any warranty; and give all
-recipients a copy of this License along with the Program.
-
-  You may charge any price or no price for each copy that you convey,
-and you may offer support or warranty protection for a fee.
-
-  5. Conveying Modified Source Versions.
-
-  You may convey a work based on the Program, or the modifications to
-produce it from the Program, in the form of source code under the
-terms of section 4, provided that you also meet all of these conditions:
-
-    a) The work must carry prominent notices stating that you modified
-    it, and giving a relevant date.
-
-    b) The work must carry prominent notices stating that it is
-    released under this License and any conditions added under section
-    7.  This requirement modifies the requirement in section 4 to
-    "keep intact all notices".
-
-    c) You must license the entire work, as a whole, under this
-    License to anyone who comes into possession of a copy.  This
-    License will therefore apply, along with any applicable section 7
-    additional terms, to the whole of the work, and all its parts,
-    regardless of how they are packaged.  This License gives no
-    permission to license the work in any other way, but it does not
-    invalidate such permission if you have separately received it.
-
-    d) If the work has interactive user interfaces, each must display
-    Appropriate Legal Notices; however, if the Program has interactive
-    interfaces that do not display Appropriate Legal Notices, your
-    work need not make them do so.
-
-  A compilation of a covered work with other separate and independent
-works, which are not by their nature extensions of the covered work,
-and which are not combined with it such as to form a larger program,
-in or on a volume of a storage or distribution medium, is called an
-"aggregate" if the compilation and its resulting copyright are not
-used to limit the access or legal rights of the compilation's users
-beyond what the individual works permit.  Inclusion of a covered work
-in an aggregate does not cause this License to apply to the other
-parts of the aggregate.
-
-  6. Conveying Non-Source Forms.
-
-  You may convey a covered work in object code form under the terms
-of sections 4 and 5, provided that you also convey the
-machine-readable Corresponding Source under the terms of this License,
-in one of these ways:
-
-    a) Convey the object code in, or embodied in, a physical product
-    (including a physical distribution medium), accompanied by the
-    Corresponding Source fixed on a durable physical medium
-    customarily used for software interchange.
-
-    b) Convey the object code in, or embodied in, a physical product
-    (including a physical distribution medium), accompanied by a
-    written offer, valid for at least three years and valid for as
-    long as you offer spare parts or customer support for that product
-    model, to give anyone who possesses the object code either (1) a
-    copy of the Corresponding Source for all the software in the
-    product that is covered by this License, on a durable physical
-    medium customarily used for software interchange, for a price no
-    more than your reasonable cost of physically performing this
-    conveying of source, or (2) access to copy the
-    Corresponding Source from a network server at no charge.
-
-    c) Convey individual copies of the object code with a copy of the
-    written offer to provide the Corresponding Source.  This
-    alternative is allowed only occasionally and noncommercially, and
-    only if you received the object code with such an offer, in accord
-    with subsection 6b.
-
-    d) Convey the object code by offering access from a designated
-    place (gratis or for a charge), and offer equivalent access to the
-    Corresponding Source in the same way through the same place at no
-    further charge.  You need not require recipients to copy the
-    Corresponding Source along with the object code.  If the place to
-    copy the object code is a network server, the Corresponding Source
-    may be on a different server (operated by you or a third party)
-    that supports equivalent copying facilities, provided you maintain
-    clear directions next to the object code saying where to find the
-    Corresponding Source.  Regardless of what server hosts the
-    Corresponding Source, you remain obligated to ensure that it is
-    available for as long as needed to satisfy these requirements.
-
-    e) Convey the object code using peer-to-peer transmission, provided
-    you inform other peers where the object code and Corresponding
-    Source of the work are being offered to the general public at no
-    charge under subsection 6d.
-
-  A separable portion of the object code, whose source code is excluded
-from the Corresponding Source as a System Library, need not be
-included in conveying the object code work.
-
-  A "User Product" is either (1) a "consumer product", which means any
-tangible personal property which is normally used for personal, family,
-or household purposes, or (2) anything designed or sold for incorporation
-into a dwelling.  In determining whether a product is a consumer product,
-doubtful cases shall be resolved in favor of coverage.  For a particular
-product received by a particular user, "normally used" refers to a
-typical or common use of that class of product, regardless of the status
-of the particular user or of the way in which the particular user
-actually uses, or expects or is expected to use, the product.  A product
-is a consumer product regardless of whether the product has substantial
-commercial, industrial or non-consumer uses, unless such uses represent
-the only significant mode of use of the product.
-
-  "Installation Information" for a User Product means any methods,
-procedures, authorization keys, or other information required to install
-and execute modified versions of a covered work in that User Product from
-a modified version of its Corresponding Source.  The information must
-suffice to ensure that the continued functioning of the modified object
-code is in no case prevented or interfered with solely because
-modification has been made.
-
-  If you convey an object code work under this section in, or with, or
-specifically for use in, a User Product, and the conveying occurs as
-part of a transaction in which the right of possession and use of the
-User Product is transferred to the recipient in perpetuity or for a
-fixed term (regardless of how the transaction is characterized), the
-Corresponding Source conveyed under this section must be accompanied
-by the Installation Information.  But this requirement does not apply
-if neither you nor any third party retains the ability to install
-modified object code on the User Product (for example, the work has
-been installed in ROM).
-
-  The requirement to provide Installation Information does not include a
-requirement to continue to provide support service, warranty, or updates
-for a work that has been modified or installed by the recipient, or for
-the User Product in which it has been modified or installed.  Access to a
-network may be denied when the modification itself materially and
-adversely affects the operation of the network or violates the rules and
-protocols for communication across the network.
-
-  Corresponding Source conveyed, and Installation Information provided,
-in accord with this section must be in a format that is publicly
-documented (and with an implementation available to the public in
-source code form), and must require no special password or key for
-unpacking, reading or copying.
-
-  7. Additional Terms.
-
-  "Additional permissions" are terms that supplement the terms of this
-License by making exceptions from one or more of its conditions.
-Additional permissions that are applicable to the entire Program shall
-be treated as though they were included in this License, to the extent
-that they are valid under applicable law.  If additional permissions
-apply only to part of the Program, that part may be used separately
-under those permissions, but the entire Program remains governed by
-this License without regard to the additional permissions.
-
-  When you convey a copy of a covered work, you may at your option
-remove any additional permissions from that copy, or from any part of
-it.  (Additional permissions may be written to require their own
-removal in certain cases when you modify the work.)  You may place
-additional permissions on material, added by you to a covered work,
-for which you have or can give appropriate copyright permission.
-
-  Notwithstanding any other provision of this License, for material you
-add to a covered work, you may (if authorized by the copyright holders of
-that material) supplement the terms of this License with terms:
-
-    a) Disclaiming warranty or limiting liability differently from the
-    terms of sections 15 and 16 of this License; or
-
-    b) Requiring preservation of specified reasonable legal notices or
-    author attributions in that material or in the Appropriate Legal
-    Notices displayed by works containing it; or
-
-    c) Prohibiting misrepresentation of the origin of that material, or
-    requiring that modified versions of such material be marked in
-    reasonable ways as different from the original version; or
-
-    d) Limiting the use for publicity purposes of names of licensors or
-    authors of the material; or
-
-    e) Declining to grant rights under trademark law for use of some
-    trade names, trademarks, or service marks; or
-
-    f) Requiring indemnification of licensors and authors of that
-    material by anyone who conveys the material (or modified versions of
-    it) with contractual assumptions of liability to the recipient, for
-    any liability that these contractual assumptions directly impose on
-    those licensors and authors.
-
-  All other non-permissive additional terms are considered "further
-restrictions" within the meaning of section 10.  If the Program as you
-received it, or any part of it, contains a notice stating that it is
-governed by this License along with a term that is a further
-restriction, you may remove that term.  If a license document contains
-a further restriction but permits relicensing or conveying under this
-License, you may add to a covered work material governed by the terms
-of that license document, provided that the further restriction does
-not survive such relicensing or conveying.
-
-  If you add terms to a covered work in accord with this section, you
-must place, in the relevant source files, a statement of the
-additional terms that apply to those files, or a notice indicating
-where to find the applicable terms.
-
-  Additional terms, permissive or non-permissive, may be stated in the
-form of a separately written license, or stated as exceptions;
-the above requirements apply either way.
-
-  8. Termination.
-
-  You may not propagate or modify a covered work except as expressly
-provided under this License.  Any attempt otherwise to propagate or
-modify it is void, and will automatically terminate your rights under
-this License (including any patent licenses granted under the third
-paragraph of section 11).
-
-  However, if you cease all violation of this License, then your
-license from a particular copyright holder is reinstated (a)
-provisionally, unless and until the copyright holder explicitly and
-finally terminates your license, and (b) permanently, if the copyright
-holder fails to notify you of the violation by some reasonable means
-prior to 60 days after the cessation.
-
-  Moreover, your license from a particular copyright holder is
-reinstated permanently if the copyright holder notifies you of the
-violation by some reasonable means, this is the first time you have
-received notice of violation of this License (for any work) from that
-copyright holder, and you cure the violation prior to 30 days after
-your receipt of the notice.
-
-  Termination of your rights under this section does not terminate the
-licenses of parties who have received copies or rights from you under
-this License.  If your rights have been terminated and not permanently
-reinstated, you do not qualify to receive new licenses for the same
-material under section 10.
-
-  9. Acceptance Not Required for Having Copies.
-
-  You are not required to accept this License in order to receive or
-run a copy of the Program.  Ancillary propagation of a covered work
-occurring solely as a consequence of using peer-to-peer transmission
-to receive a copy likewise does not require acceptance.  However,
-nothing other than this License grants you permission to propagate or
-modify any covered work.  These actions infringe copyright if you do
-not accept this License.  Therefore, by modifying or propagating a
-covered work, you indicate your acceptance of this License to do so.
-
-  10. Automatic Licensing of Downstream Recipients.
-
-  Each time you convey a covered work, the recipient automatically
-receives a license from the original licensors, to run, modify and
-propagate that work, subject to this License.  You are not responsible
-for enforcing compliance by third parties with this License.
-
-  An "entity transaction" is a transaction transferring control of an
-organization, or substantially all assets of one, or subdividing an
-organization, or merging organizations.  If propagation of a covered
-work results from an entity transaction, each party to that
-transaction who receives a copy of the work also receives whatever
-licenses to the work the party's predecessor in interest had or could
-give under the previous paragraph, plus a right to possession of the
-Corresponding Source of the work from the predecessor in interest, if
-the predecessor has it or can get it with reasonable efforts.
-
-  You may not impose any further restrictions on the exercise of the
-rights granted or affirmed under this License.  For example, you may
-not impose a license fee, royalty, or other charge for exercise of
-rights granted under this License, and you may not initiate litigation
-(including a cross-claim or counterclaim in a lawsuit) alleging that
-any patent claim is infringed by making, using, selling, offering for
-sale, or importing the Program or any portion of it.
-
-  11. Patents.
-
-  A "contributor" is a copyright holder who authorizes use under this
-License of the Program or a work on which the Program is based.  The
-work thus licensed is called the contributor's "contributor version".
-
-  A contributor's "essential patent claims" are all patent claims
-owned or controlled by the contributor, whether already acquired or
-hereafter acquired, that would be infringed by some manner, permitted
-by this License, of making, using, or selling its contributor version,
-but do not include claims that would be infringed only as a
-consequence of further modification of the contributor version.  For
-purposes of this definition, "control" includes the right to grant
-patent sublicenses in a manner consistent with the requirements of
-this License.
-
-  Each contributor grants you a non-exclusive, worldwide, royalty-free
-patent license under the contributor's essential patent claims, to
-make, use, sell, offer for sale, import and otherwise run, modify and
-propagate the contents of its contributor version.
-
-  In the following three paragraphs, a "patent license" is any express
-agreement or commitment, however denominated, not to enforce a patent
-(such as an express permission to practice a patent or covenant not to
-sue for patent infringement).  To "grant" such a patent license to a
-party means to make such an agreement or commitment not to enforce a
-patent against the party.
-
-  If you convey a covered work, knowingly relying on a patent license,
-and the Corresponding Source of the work is not available for anyone
-to copy, free of charge and under the terms of this License, through a
-publicly available network server or other readily accessible means,
-then you must either (1) cause the Corresponding Source to be so
-available, or (2) arrange to deprive yourself of the benefit of the
-patent license for this particular work, or (3) arrange, in a manner
-consistent with the requirements of this License, to extend the patent
-license to downstream recipients.  "Knowingly relying" means you have
-actual knowledge that, but for the patent license, your conveying the
-covered work in a country, or your recipient's use of the covered work
-in a country, would infringe one or more identifiable patents in that
-country that you have reason to believe are valid.
-
-  If, pursuant to or in connection with a single transaction or
-arrangement, you convey, or propagate by procuring conveyance of, a
-covered work, and grant a patent license to some of the parties
-receiving the covered work authorizing them to use, propagate, modify
-or convey a specific copy of the covered work, then the patent license
-you grant is automatically extended to all recipients of the covered
-work and works based on it.
-
-  A patent license is "discriminatory" if it does not include within
-the scope of its coverage, prohibits the exercise of, or is
-conditioned on the non-exercise of one or more of the rights that are
-specifically granted under this License.  You may not convey a covered
-work if you are a party to an arrangement with a third party that is
-in the business of distributing software, under which you make payment
-to the third party based on the extent of your activity of conveying
-the work, and under which the third party grants, to any of the
-parties who would receive the covered work from you, a discriminatory
-patent license (a) in connection with copies of the covered work
-conveyed by you (or copies made from those copies), or (b) primarily
-for and in connection with specific products or compilations that
-contain the covered work, unless you entered into that arrangement,
-or that patent license was granted, prior to 28 March 2007.
-
-  Nothing in this License shall be construed as excluding or limiting
-any implied license or other defenses to infringement that may
-otherwise be available to you under applicable patent law.
-
-  12. No Surrender of Others' Freedom.
-
-  If conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot convey a
-covered work so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you may
-not convey it at all.  For example, if you agree to terms that obligate you
-to collect a royalty for further conveying from those to whom you convey
-the Program, the only way you could satisfy both those terms and this
-License would be to refrain entirely from conveying the Program.
-
-  13. Use with the GNU Affero General Public License.
-
-  Notwithstanding any other provision of this License, you have
-permission to link or combine any covered work with a work licensed
-under version 3 of the GNU Affero General Public License into a single
-combined work, and to convey the resulting work.  The terms of this
-License will continue to apply to the part which is the covered work,
-but the special requirements of the GNU Affero General Public License,
-section 13, concerning interaction through a network will apply to the
-combination as such.
-
-  14. Revised Versions of this License.
-
-  The Free Software Foundation may publish revised and/or new versions of
-the GNU General Public License from time to time.  Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-  Each version is given a distinguishing version number.  If the
-Program specifies that a certain numbered version of the GNU General
-Public License "or any later version" applies to it, you have the
-option of following the terms and conditions either of that numbered
-version or of any later version published by the Free Software
-Foundation.  If the Program does not specify a version number of the
-GNU General Public License, you may choose any version ever published
-by the Free Software Foundation.
-
-  If the Program specifies that a proxy can decide which future
-versions of the GNU General Public License can be used, that proxy's
-public statement of acceptance of a version permanently authorizes you
-to choose that version for the Program.
-
-  Later license versions may give you additional or different
-permissions.  However, no additional obligations are imposed on any
-author or copyright holder as a result of your choosing to follow a
-later version.
-
-  15. Disclaimer of Warranty.
-
-  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
-APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
-HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
-OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
-THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
-IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
-ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
-  16. Limitation of Liability.
-
-  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
-THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
-GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
-USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
-DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
-PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
-EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGES.
-
-  17. Interpretation of Sections 15 and 16.
-
-  If the disclaimer of warranty and limitation of liability provided
-above cannot be given local legal effect according to their terms,
-reviewing courts shall apply local law that most closely approximates
-an absolute waiver of all civil liability in connection with the
-Program, unless a warranty or assumption of liability accompanies a
-copy of the Program in return for a fee.
-
-                     END OF TERMS AND CONDITIONS
-
-            How to Apply These Terms to Your New Programs
-
-  If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
-  To do so, attach the following notices to the program.  It is safest
-to attach them to the start of each source file to most effectively
-state the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-    <one line to give the program's name and a brief idea of what it does.>
-    Copyright (C) <year>  <name of author>
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-Also add information on how to contact you by electronic and paper mail.
-
-  If the program does terminal interaction, make it output a short
-notice like this when it starts in an interactive mode:
-
-    <program>  Copyright (C) <year>  <name of author>
-    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
-    This is free software, and you are welcome to redistribute it
-    under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License.  Of course, your program's commands
-might be different; for a GUI interface, you would use an "about box".
-
-  You should also get your employer (if you work as a programmer) or school,
-if any, to sign a "copyright disclaimer" for the program, if necessary.
-For more information on this, and how to apply and follow the GNU GPL, see
-<https://www.gnu.org/licenses/>.
-
-  The GNU General Public License does not permit incorporating your program
-into proprietary programs.  If your program is a subroutine library, you
-may consider it more useful to permit linking proprietary applications with
-the library.  If this is what you want to do, use the GNU Lesser General
-Public License instead of this License.  But first, please read
-<https://www.gnu.org/licenses/why-not-lgpl.html>.

+ 0 - 337
SConstruct

@@ -1,337 +0,0 @@
-#
-# Main Flipper Build System entry point
-#
-# This file is evaluated by scons (the build system) every time fbt is invoked.
-# Scons constructs all referenced environments & their targets' dependency
-# trees on startup. So, to keep startup time as low as possible, we're hiding
-# construction of certain targets behind command-line options.
-
-import os
-from fbt.util import path_as_posix
-
-DefaultEnvironment(tools=[])
-
-EnsurePythonVersion(3, 8)
-
-# Progress(["OwO\r", "owo\r", "uwu\r", "owo\r"], interval=15)
-
-# This environment is created only for loading options & validating file/dir existence
-fbt_variables = SConscript("site_scons/commandline.scons")
-cmd_environment = Environment(
-    toolpath=["#/scripts/fbt_tools"],
-    tools=[
-        ("fbt_help", {"vars": fbt_variables}),
-    ],
-    variables=fbt_variables,
-)
-
-# Building basic environment - tools, utility methods, cross-compilation
-# settings, gcc flags for Cortex-M4, basic builders and more
-coreenv = SConscript(
-    "site_scons/environ.scons",
-    exports={"VAR_ENV": cmd_environment},
-    toolpath=["#/scripts/fbt_tools"],
-)
-SConscript("site_scons/cc.scons", exports={"ENV": coreenv})
-
-# Create a separate "dist" environment and add construction envs to it
-distenv = coreenv.Clone(
-    tools=[
-        "fbt_dist",
-        "fbt_debugopts",
-        "openocd",
-        "blackmagic",
-        "jflash",
-    ],
-    ENV=os.environ,
-    UPDATE_BUNDLE_DIR="dist/${DIST_DIR}/f${TARGET_HW}-update-${DIST_SUFFIX}",
-)
-
-firmware_env = distenv.AddFwProject(
-    base_env=coreenv,
-    fw_type="firmware",
-    fw_env_key="FW_ENV",
-)
-
-# If enabled, initialize updater-related targets
-if GetOption("fullenv") or any(
-    filter(lambda target: "updater" in target or "flash_usb" in target, BUILD_TARGETS)
-):
-    updater_env = distenv.AddFwProject(
-        base_env=coreenv,
-        fw_type="updater",
-        fw_env_key="UPD_ENV",
-    )
-
-    # Target for self-update package
-    dist_basic_arguments = [
-        "--bundlever",
-        '"${UPDATE_VERSION_STRING}"',
-    ]
-    dist_radio_arguments = [
-        "--radio",
-        '"${ROOT_DIR.abspath}/${COPRO_STACK_BIN_DIR}/${COPRO_STACK_BIN}"',
-        "--radiotype",
-        "${COPRO_STACK_TYPE}",
-        "${COPRO_DISCLAIMER}",
-        "--obdata",
-        '"${ROOT_DIR.abspath}/${COPRO_OB_DATA}"',
-    ]
-    dist_resource_arguments = [
-        "-r",
-        '"${ROOT_DIR.abspath}/assets/resources"',
-    ]
-    dist_splash_arguments = (
-        [
-            "--splash",
-            distenv.subst("assets/slideshow/$UPDATE_SPLASH"),
-        ]
-        if distenv["UPDATE_SPLASH"]
-        else []
-    )
-
-    selfupdate_dist = distenv.DistCommand(
-        "updater_package",
-        (distenv["DIST_DEPENDS"], firmware_env["FW_RESOURCES"]),
-        DIST_EXTRA=[
-            *dist_basic_arguments,
-            *dist_radio_arguments,
-            *dist_resource_arguments,
-            *dist_splash_arguments,
-        ],
-    )
-
-    selfupdate_min_dist = distenv.DistCommand(
-        "updater_minpackage",
-        distenv["DIST_DEPENDS"],
-        DIST_EXTRA=dist_basic_arguments,
-    )
-
-    # Updater debug
-    distenv.PhonyTarget(
-        "updater_debug",
-        "${GDBPYCOM}",
-        source=updater_env["FW_ELF"],
-        GDBREMOTE="${OPENOCD_GDB_PIPE}",
-    )
-
-    distenv.PhonyTarget(
-        "updater_blackmagic",
-        "${GDBPYCOM}",
-        source=updater_env["FW_ELF"],
-        GDBOPTS=distenv.subst("$GDBOPTS_BLACKMAGIC"),
-        GDBREMOTE="${BLACKMAGIC_ADDR}",
-    )
-
-    # Installation over USB & CLI
-    usb_update_package = distenv.AddUsbFlashTarget(
-        "#build/usbinstall.flag", (firmware_env["FW_RESOURCES"], selfupdate_dist)
-    )
-    distenv.Alias("flash_usb_full", usb_update_package)
-
-    usb_minupdate_package = distenv.AddUsbFlashTarget(
-        "#build/minusbinstall.flag", (selfupdate_min_dist,)
-    )
-    distenv.Alias("flash_usb", usb_minupdate_package)
-
-
-# Target for copying & renaming binaries to dist folder
-basic_dist = distenv.DistCommand("fw_dist", distenv["DIST_DEPENDS"])
-distenv.Default(basic_dist)
-
-dist_dir_name = distenv.GetProjetDirName()
-dist_dir = distenv.Dir(f"#/dist/{dist_dir_name}")
-external_apps_artifacts = firmware_env["FW_EXTAPPS"]
-external_app_list = external_apps_artifacts.application_map.values()
-
-fap_dist = [
-    distenv.Install(
-        dist_dir.Dir("debug_elf"),
-        list(app_artifact.debug for app_artifact in external_app_list),
-    ),
-    *(
-        distenv.Install(
-            dist_dir.File(dist_entry[1]).dir,
-            app_artifact.compact,
-        )
-        for app_artifact in external_app_list
-        for dist_entry in app_artifact.dist_entries
-    ),
-]
-Depends(
-    fap_dist,
-    list(app_artifact.validator for app_artifact in external_app_list),
-)
-Alias("fap_dist", fap_dist)
-# distenv.Default(fap_dist)
-
-distenv.Depends(firmware_env["FW_RESOURCES"], external_apps_artifacts.resources_dist)
-
-# Copy all faps to device
-
-fap_deploy = distenv.PhonyTarget(
-    "fap_deploy",
-    "${PYTHON3} ${ROOT_DIR}/scripts/storage.py send ${SOURCE} /ext/apps",
-    source=Dir("#/assets/resources/apps"),
-)
-
-
-# Target for bundling core2 package for qFlipper
-copro_dist = distenv.CoproBuilder(
-    "#/build/core2_firmware.tgz",
-    [],
-)
-distenv.AlwaysBuild(copro_dist)
-distenv.Alias("copro_dist", copro_dist)
-
-firmware_flash = distenv.AddOpenOCDFlashTarget(firmware_env)
-distenv.Alias("flash", firmware_flash)
-
-firmware_jflash = distenv.AddJFlashTarget(firmware_env)
-distenv.Alias("jflash", firmware_jflash)
-
-firmware_bm_flash = distenv.PhonyTarget(
-    "flash_blackmagic",
-    "$GDB $GDBOPTS $SOURCES $GDBFLASH",
-    source=firmware_env["FW_ELF"],
-    GDBOPTS="${GDBOPTS_BASE} ${GDBOPTS_BLACKMAGIC}",
-    GDBREMOTE="${BLACKMAGIC_ADDR}",
-    GDBFLASH=[
-        "-ex",
-        "load",
-        "-ex",
-        "quit",
-    ],
-)
-
-gdb_backtrace_all_threads = distenv.PhonyTarget(
-    "gdb_trace_all",
-    "$GDB $GDBOPTS $SOURCES $GDBFLASH",
-    source=firmware_env["FW_ELF"],
-    GDBOPTS="${GDBOPTS_BASE}",
-    GDBREMOTE="${OPENOCD_GDB_PIPE}",
-    GDBFLASH=[
-        "-ex",
-        "thread apply all bt",
-        "-ex",
-        "quit",
-    ],
-)
-
-# Debugging firmware
-firmware_debug = distenv.PhonyTarget(
-    "debug",
-    "${GDBPYCOM}",
-    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")),
-)
-distenv.Depends(firmware_debug, firmware_flash)
-
-distenv.PhonyTarget(
-    "blackmagic",
-    "${GDBPYCOM}",
-    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")),
-)
-
-# Debug alien elf
-distenv.PhonyTarget(
-    "debug_other",
-    "${GDBPYCOM}",
-    GDBOPTS="${GDBOPTS_BASE}",
-    GDBREMOTE="${OPENOCD_GDB_PIPE}",
-    GDBPYOPTS='-ex "source ${FBT_DEBUG_DIR}/PyCortexMDebug/PyCortexMDebug.py" ',
-)
-
-distenv.PhonyTarget(
-    "debug_other_blackmagic",
-    "${GDBPYCOM}",
-    GDBOPTS="${GDBOPTS_BASE}  ${GDBOPTS_BLACKMAGIC}",
-    GDBREMOTE="$${BLACKMAGIC_ADDR}",
-)
-
-
-# Just start OpenOCD
-distenv.PhonyTarget(
-    "openocd",
-    "${OPENOCDCOM}",
-)
-
-# Linter
-distenv.PhonyTarget(
-    "lint",
-    "${PYTHON3} ${FBT_SCRIPT_DIR}/lint.py check ${LINT_SOURCES}",
-    LINT_SOURCES=[n.srcnode() for n in firmware_env["LINT_SOURCES"]],
-)
-
-distenv.PhonyTarget(
-    "format",
-    "${PYTHON3} ${FBT_SCRIPT_DIR}/lint.py format ${LINT_SOURCES}",
-    LINT_SOURCES=[n.srcnode() for n in firmware_env["LINT_SOURCES"]],
-)
-
-# PY_LINT_SOURCES contains recursively-built modules' SConscript files + application manifests
-# Here we add additional Python files residing in repo root
-firmware_env.Append(
-    PY_LINT_SOURCES=[
-        # Py code folders
-        "site_scons",
-        "scripts",
-        # Extra files
-        "SConstruct",
-        "firmware.scons",
-        "fbt_options.py",
-    ]
-)
-
-
-black_commandline = "@${PYTHON3} -m black ${PY_BLACK_ARGS} ${PY_LINT_SOURCES}"
-black_base_args = ["--include", '"\\.scons|\\.py|SConscript|SConstruct"']
-
-distenv.PhonyTarget(
-    "lint_py",
-    black_commandline,
-    PY_BLACK_ARGS=[
-        "--check",
-        "--diff",
-        *black_base_args,
-    ],
-    PY_LINT_SOURCES=firmware_env["PY_LINT_SOURCES"],
-)
-
-distenv.PhonyTarget(
-    "format_py",
-    black_commandline,
-    PY_BLACK_ARGS=black_base_args,
-    PY_LINT_SOURCES=firmware_env["PY_LINT_SOURCES"],
-)
-
-# Start Flipper CLI via PySerial's miniterm
-distenv.PhonyTarget("cli", "${PYTHON3} ${FBT_SCRIPT_DIR}/serial_cli.py")
-
-
-# Find blackmagic probe
-distenv.PhonyTarget(
-    "get_blackmagic",
-    "@echo $( ${BLACKMAGIC_ADDR} $)",
-)
-
-
-# Find STLink probe ids
-distenv.PhonyTarget(
-    "get_stlink",
-    distenv.Action(
-        lambda **kw: distenv.GetDevices(),
-        None,
-    ),
-)
-
-# Prepare vscode environment
-vscode_dist = distenv.Install("#.vscode", distenv.Glob("#.vscode/example/*"))
-distenv.Precious(vscode_dist)
-distenv.NoClean(vscode_dist)
-distenv.Alias("vscode_dist", vscode_dist)

+ 0 - 94
applications/ReadMe.md

@@ -1,94 +0,0 @@
-# Structure
-
-## debug 
-
-Applications for factory testing the Flipper.
-
-- `accessor`            - Wiegand server 
-- `battery_test_app`    - Battery debug app
-- `blink_test`          - LED blinker   
-- `bt_debug_app`        - BT test app. Requires full BT stack installed
-- `display_test`        - Various display tests & tweaks
-- `file_browser_test`   - Test UI for file picker
-- `keypad_test`         - Keypad test
-- `lfrfid_debug`        - LF RFID debug tool
-- `text_box_test`       - UI tests
-- `uart_echo`           - UART mode test 
-- `unit_tests`          - Unit tests
-- `usb_mouse`           - USB HID test
-- `usb_test`            - Other USB tests
-- `vibro_test`          - Vibro test
-
-
-## main
-
-Applications for main Flipper menu.
-
-- `archive`             - Archive and file manager 
-- `bad_usb`             - Bad USB application
-- `fap_loader`          - External applications loader
-- `gpio`                - GPIO application: includes USART bridge and GPIO control
-- `ibutton`             - iButton application, onewire keys and more
-- `infrared`            - Infrared application, controls your IR devices
-- `lfrfid`              - LF RFID application
-- `nfc`                 - NFC application, HF rfid, EMV and etc
-- `subghz`              - SubGhz application, 433 fobs and etc
-- `u2f`                 - U2F Application
-
-
-## External
-
-External applications deployed to SD Card
-
-- `clock`               - Clock application
-- `dap_link`            - DAP Link OnChip debugger
-- `hid_app`             - USB/BT Remote controller
-- `music_player`        - Music player app (demo)
-- `nfc_magic`           - NFC MFC Magic card application
-- `picopass`            - Picopass reader / writer
-- `signal_generator`    - Signal generator app: PWM and clock generator
-- `snake_game`          - Snake game application
-- `spi_mem_manager`     - SPI Memory reader / flasher
-- `weather_station`     - SubGHz weather station
-
-## services
-
-Background services providing system APIs to applications.
-
-- `applications.h`      - Firmware application list header
-
-- `bt`                  - BLE service and application
-- `cli`                 - Console service and API
-- `crypto`              - Crypto cli tools
-- `desktop`             - Desktop service
-- `dialogs`             - Dialogs service: GUI Dialogs for your app
-- `dolphin`             - Dolphin service and supplementary apps
-- `gui`                 - GUI service and API
-- `input`               - Input service
-- `loader`              - Application loader service
-- `notification`        - Notification service 
-- `power`               - Power service
-- `rpc`                 - RPC service and API
-- `storage`             - Storage service, internal + sdcard
-
-
-## settings
-
-Small applications providing configuration for basic firmware and its services.
-
-- `about`               - Small About application that shows flipper info
-- `bt_settings_app`     - Bluetooth options
-- `desktop_settings`    - Desktop configuration
-- `dolphin_passport`    - Dolphin passport app
-- `notification_settings` - LCD brightness, sound volume, etc configuration
-- `power_settings_app`  - Basic power options
-- `storage_settings`    - Storage settings app
-- `system`              - System settings
-
-
-## system
-
-Utility apps not visible in other menus.
-
-- `storage_move_to_sd`  - Data migration tool for internal storage
-- `updater`             - Update service & application

+ 0 - 11
applications/debug/accessor/accessor.cpp

@@ -1,11 +0,0 @@
-#include "accessor_app.h"
-
-// app enter function
-extern "C" int32_t accessor_app(void* p) {
-    UNUSED(p);
-    AccessorApp* app = new AccessorApp();
-    app->run();
-    delete app;
-
-    return 255;
-}

+ 0 - 141
applications/debug/accessor/accessor_app.cpp

@@ -1,141 +0,0 @@
-#include "accessor_app.h"
-#include <furi.h>
-#include <furi_hal.h>
-#include <stdarg.h>
-
-void AccessorApp::run(void) {
-    AccessorEvent event;
-    bool consumed;
-    bool exit = false;
-
-    wiegand.begin();
-    onewire_host_start(onewire_host);
-
-    scenes[current_scene]->on_enter(this);
-
-    while(!exit) {
-        view.receive_event(&event);
-
-        consumed = scenes[current_scene]->on_event(this, &event);
-
-        if(!consumed) {
-            if(event.type == AccessorEvent::Type::Back) {
-                exit = switch_to_previous_scene();
-            }
-        }
-    };
-
-    scenes[current_scene]->on_exit(this);
-
-    wiegand.end();
-    onewire_host_stop(onewire_host);
-}
-
-AccessorApp::AccessorApp()
-    : text_store{0} {
-    notification = static_cast<NotificationApp*>(furi_record_open(RECORD_NOTIFICATION));
-    onewire_host = onewire_host_alloc(&gpio_ibutton);
-    furi_hal_power_enable_otg();
-}
-
-AccessorApp::~AccessorApp() {
-    furi_hal_power_disable_otg();
-    furi_record_close(RECORD_NOTIFICATION);
-    onewire_host_free(onewire_host);
-}
-
-AccessorAppViewManager* AccessorApp::get_view_manager() {
-    return &view;
-}
-
-void AccessorApp::switch_to_next_scene(Scene next_scene) {
-    previous_scenes_list.push_front(current_scene);
-
-    if(next_scene != Scene::Exit) {
-        scenes[current_scene]->on_exit(this);
-        current_scene = next_scene;
-        scenes[current_scene]->on_enter(this);
-    }
-}
-
-void AccessorApp::search_and_switch_to_previous_scene(std::initializer_list<Scene> scenes_list) {
-    Scene previous_scene = Scene::Start;
-    bool scene_found = false;
-
-    while(!scene_found) {
-        previous_scene = get_previous_scene();
-        for(Scene element : scenes_list) {
-            if(previous_scene == element || previous_scene == Scene::Start) {
-                scene_found = true;
-                break;
-            }
-        }
-    }
-
-    scenes[current_scene]->on_exit(this);
-    current_scene = previous_scene;
-    scenes[current_scene]->on_enter(this);
-}
-
-bool AccessorApp::switch_to_previous_scene(uint8_t count) {
-    Scene previous_scene = Scene::Start;
-
-    for(uint8_t i = 0; i < count; i++) {
-        previous_scene = get_previous_scene();
-        if(previous_scene == Scene::Exit) break;
-    }
-
-    if(previous_scene == Scene::Exit) {
-        return true;
-    } else {
-        scenes[current_scene]->on_exit(this);
-        current_scene = previous_scene;
-        scenes[current_scene]->on_enter(this);
-        return false;
-    }
-}
-
-AccessorApp::Scene AccessorApp::get_previous_scene() {
-    Scene scene = previous_scenes_list.front();
-    previous_scenes_list.pop_front();
-    return scene;
-}
-
-/***************************** NOTIFY *******************************/
-
-void AccessorApp::notify_green_blink() {
-    notification_message(notification, &sequence_blink_green_10);
-}
-
-void AccessorApp::notify_success() {
-    notification_message(notification, &sequence_success);
-}
-
-/*************************** TEXT STORE *****************************/
-
-char* AccessorApp::get_text_store() {
-    return text_store;
-}
-
-uint8_t AccessorApp::get_text_store_size() {
-    return text_store_size;
-}
-
-void AccessorApp::set_text_store(const char* text...) {
-    va_list args;
-    va_start(args, text);
-
-    vsnprintf(text_store, text_store_size, text, args);
-
-    va_end(args);
-}
-
-/*************************** APP RESOURCES *****************************/
-
-WIEGAND* AccessorApp::get_wiegand() {
-    return &wiegand;
-}
-
-OneWireHost* AccessorApp::get_one_wire() {
-    return onewire_host;
-}

+ 0 - 54
applications/debug/accessor/accessor_app.h

@@ -1,54 +0,0 @@
-#pragma once
-#include <map>
-#include <list>
-#include "accessor_view_manager.h"
-#include "scene/accessor_scene_start.h"
-#include "helpers/wiegand.h"
-#include <one_wire/one_wire_host.h>
-#include <notification/notification_messages.h>
-
-class AccessorApp {
-public:
-    void run(void);
-
-    AccessorApp();
-    ~AccessorApp();
-
-    enum class Scene : uint8_t {
-        Exit,
-        Start,
-    };
-
-    AccessorAppViewManager* get_view_manager();
-    void switch_to_next_scene(Scene index);
-    void search_and_switch_to_previous_scene(std::initializer_list<Scene> scenes_list);
-    bool switch_to_previous_scene(uint8_t count = 1);
-    Scene get_previous_scene();
-
-    void notify_green_blink();
-    void notify_success();
-
-    char* get_text_store();
-    uint8_t get_text_store_size();
-    void set_text_store(const char* text...);
-
-    WIEGAND* get_wiegand();
-    OneWireHost* get_one_wire();
-
-private:
-    std::list<Scene> previous_scenes_list = {Scene::Exit};
-    Scene current_scene = Scene::Start;
-    AccessorAppViewManager view;
-
-    std::map<Scene, AccessorScene*> scenes = {
-        {Scene::Start, new AccessorSceneStart()},
-    };
-
-    static const uint8_t text_store_size = 128;
-    char text_store[text_store_size + 1];
-
-    WIEGAND wiegand;
-    OneWireHost* onewire_host;
-
-    NotificationApp* notification;
-};

+ 0 - 19
applications/debug/accessor/accessor_event.h

@@ -1,19 +0,0 @@
-#pragma once
-#include <stdint.h>
-
-class AccessorEvent {
-public:
-    // events enum
-    enum class Type : uint8_t {
-        Tick,
-        Back,
-    };
-
-    // payload
-    union {
-        uint32_t menu_index;
-    } payload;
-
-    // event type
-    Type type;
-};

+ 0 - 80
applications/debug/accessor/accessor_view_manager.cpp

@@ -1,80 +0,0 @@
-#include "accessor_view_manager.h"
-#include "accessor_event.h"
-#include <callback-connector.h>
-
-AccessorAppViewManager::AccessorAppViewManager() {
-    event_queue = furi_message_queue_alloc(10, sizeof(AccessorEvent));
-
-    view_dispatcher = view_dispatcher_alloc();
-    auto callback = cbc::obtain_connector(this, &AccessorAppViewManager::previous_view_callback);
-
-    // allocate views
-    submenu = submenu_alloc();
-    add_view(ViewType::Submenu, submenu_get_view(submenu));
-
-    popup = popup_alloc();
-    add_view(ViewType::Popup, popup_get_view(popup));
-
-    gui = static_cast<Gui*>(furi_record_open(RECORD_GUI));
-    view_dispatcher_attach_to_gui(view_dispatcher, gui, ViewDispatcherTypeFullscreen);
-
-    // set previous view callback for all views
-    view_set_previous_callback(submenu_get_view(submenu), callback);
-    view_set_previous_callback(popup_get_view(popup), callback);
-}
-
-AccessorAppViewManager::~AccessorAppViewManager() {
-    // remove views
-    view_dispatcher_remove_view(
-        view_dispatcher, static_cast<uint32_t>(AccessorAppViewManager::ViewType::Submenu));
-    view_dispatcher_remove_view(
-        view_dispatcher, static_cast<uint32_t>(AccessorAppViewManager::ViewType::Popup));
-
-    // free view modules
-    furi_record_close(RECORD_GUI);
-    submenu_free(submenu);
-    popup_free(popup);
-
-    // free dispatcher
-    view_dispatcher_free(view_dispatcher);
-
-    // free event queue
-    furi_message_queue_free(event_queue);
-}
-
-void AccessorAppViewManager::switch_to(ViewType type) {
-    view_dispatcher_switch_to_view(view_dispatcher, static_cast<uint32_t>(type));
-}
-
-Submenu* AccessorAppViewManager::get_submenu() {
-    return submenu;
-}
-
-Popup* AccessorAppViewManager::get_popup() {
-    return popup;
-}
-
-void AccessorAppViewManager::receive_event(AccessorEvent* event) {
-    if(furi_message_queue_get(event_queue, event, 100) != FuriStatusOk) {
-        event->type = AccessorEvent::Type::Tick;
-    }
-}
-
-void AccessorAppViewManager::send_event(AccessorEvent* event) {
-    FuriStatus result = furi_message_queue_put(event_queue, event, 0);
-    furi_check(result == FuriStatusOk);
-}
-
-uint32_t AccessorAppViewManager::previous_view_callback(void*) {
-    if(event_queue != NULL) {
-        AccessorEvent event;
-        event.type = AccessorEvent::Type::Back;
-        send_event(&event);
-    }
-
-    return VIEW_IGNORE;
-}
-
-void AccessorAppViewManager::add_view(ViewType view_type, View* view) {
-    view_dispatcher_add_view(view_dispatcher, static_cast<uint32_t>(view_type), view);
-}

+ 0 - 39
applications/debug/accessor/accessor_view_manager.h

@@ -1,39 +0,0 @@
-#pragma once
-#include <furi.h>
-#include <gui/view_dispatcher.h>
-#include <gui/modules/submenu.h>
-#include <gui/modules/popup.h>
-#include "accessor_event.h"
-
-class AccessorAppViewManager {
-public:
-    enum class ViewType : uint8_t {
-        Submenu,
-        Popup,
-        Tune,
-    };
-
-    FuriMessageQueue* event_queue;
-
-    AccessorAppViewManager();
-    ~AccessorAppViewManager();
-
-    void switch_to(ViewType type);
-
-    void receive_event(AccessorEvent* event);
-    void send_event(AccessorEvent* event);
-
-    Submenu* get_submenu();
-    Popup* get_popup();
-
-private:
-    ViewDispatcher* view_dispatcher;
-    Gui* gui;
-
-    uint32_t previous_view_callback(void* context);
-    void add_view(ViewType view_type, View* view);
-
-    // view elements
-    Submenu* submenu;
-    Popup* popup;
-};

+ 0 - 12
applications/debug/accessor/application.fam

@@ -1,12 +0,0 @@
-App(
-    appid="accessor",
-    name="Accessor",
-    apptype=FlipperAppType.DEBUG,
-    targets=["f7"],
-    entry_point="accessor_app",
-    cdefines=["APP_ACCESSOR"],
-    requires=["gui"],
-    stack_size=4 * 1024,
-    order=40,
-    fap_category="Debug",
-)

+ 0 - 221
applications/debug/accessor/helpers/wiegand.cpp

@@ -1,221 +0,0 @@
-#include "wiegand.h"
-#include <furi.h>
-#include <furi_hal.h>
-
-volatile unsigned long WIEGAND::_cardTempHigh = 0;
-volatile unsigned long WIEGAND::_cardTemp = 0;
-volatile unsigned long WIEGAND::_lastWiegand = 0;
-unsigned long WIEGAND::_code = 0;
-unsigned long WIEGAND::_codeHigh = 0;
-volatile int WIEGAND::_bitCount = 0;
-int WIEGAND::_wiegandType = 0;
-
-constexpr uint32_t clocks_in_ms = 64 * 1000;
-const GpioPin* const pinD0 = &gpio_ext_pa4;
-const GpioPin* const pinD1 = &gpio_ext_pa7;
-
-WIEGAND::WIEGAND() {
-}
-
-unsigned long WIEGAND::getCode() {
-    return _code;
-}
-
-unsigned long WIEGAND::getCodeHigh() {
-    return _codeHigh;
-}
-
-int WIEGAND::getWiegandType() {
-    return _wiegandType;
-}
-
-bool WIEGAND::available() {
-    bool ret;
-    FURI_CRITICAL_ENTER();
-    ret = DoWiegandConversion();
-    FURI_CRITICAL_EXIT();
-    return ret;
-}
-
-static void input_isr_d0(void* _ctx) {
-    WIEGAND* _this = static_cast<WIEGAND*>(_ctx);
-    _this->ReadD0();
-}
-
-static void input_isr_d1(void* _ctx) {
-    WIEGAND* _this = static_cast<WIEGAND*>(_ctx);
-    _this->ReadD1();
-}
-
-void WIEGAND::begin() {
-    _lastWiegand = 0;
-    _cardTempHigh = 0;
-    _cardTemp = 0;
-    _code = 0;
-    _wiegandType = 0;
-    _bitCount = 0;
-
-    furi_hal_gpio_init_simple(pinD0, GpioModeInterruptFall); // Set D0 pin as input
-    furi_hal_gpio_init_simple(pinD1, GpioModeInterruptFall); // Set D1 pin as input
-
-    furi_hal_gpio_add_int_callback(pinD0, input_isr_d0, this);
-    furi_hal_gpio_add_int_callback(pinD1, input_isr_d1, this);
-}
-
-void WIEGAND::end() {
-    furi_hal_gpio_remove_int_callback(pinD0);
-    furi_hal_gpio_remove_int_callback(pinD1);
-
-    furi_hal_gpio_init_simple(pinD0, GpioModeAnalog);
-    furi_hal_gpio_init_simple(pinD1, GpioModeAnalog);
-}
-
-void WIEGAND::ReadD0() {
-    _bitCount++; // Increment bit count for Interrupt connected to D0
-    if(_bitCount > 31) // If bit count more than 31, process high bits
-    {
-        _cardTempHigh |= ((0x80000000 & _cardTemp) >> 31); //	shift value to high bits
-        _cardTempHigh <<= 1;
-        _cardTemp <<= 1;
-    } else {
-        _cardTemp <<= 1; // D0 represent binary 0, so just left shift card data
-    }
-    _lastWiegand = DWT->CYCCNT; // Keep track of last wiegand bit received
-}
-
-void WIEGAND::ReadD1() {
-    _bitCount++; // Increment bit count for Interrupt connected to D1
-    if(_bitCount > 31) // If bit count more than 31, process high bits
-    {
-        _cardTempHigh |= ((0x80000000 & _cardTemp) >> 31); // shift value to high bits
-        _cardTempHigh <<= 1;
-        _cardTemp |= 1;
-        _cardTemp <<= 1;
-    } else {
-        _cardTemp |= 1; // D1 represent binary 1, so OR card data with 1 then
-        _cardTemp <<= 1; // left shift card data
-    }
-    _lastWiegand = DWT->CYCCNT; // Keep track of last wiegand bit received
-}
-
-unsigned long WIEGAND::GetCardId(
-    volatile unsigned long* codehigh,
-    volatile unsigned long* codelow,
-    char bitlength) {
-    if(bitlength == 26) // EM tag
-        return (*codelow & 0x1FFFFFE) >> 1;
-
-    if(bitlength == 24) return (*codelow & 0x7FFFFE) >> 1;
-
-    if(bitlength == 34) // Mifare
-    {
-        *codehigh = *codehigh & 0x03; // only need the 2 LSB of the codehigh
-        *codehigh <<= 30; // shift 2 LSB to MSB
-        *codelow >>= 1;
-        return *codehigh | *codelow;
-    }
-
-    if(bitlength == 32) {
-        return (*codelow & 0x7FFFFFFE) >> 1;
-    }
-
-    return *codelow; // EM tag or Mifare without parity bits
-}
-
-char translateEnterEscapeKeyPress(char originalKeyPress) {
-    switch(originalKeyPress) {
-    case 0x0b: // 11 or * key
-        return 0x0d; // 13 or ASCII ENTER
-
-    case 0x0a: // 10 or # key
-        return 0x1b; // 27 or ASCII ESCAPE
-
-    default:
-        return originalKeyPress;
-    }
-}
-
-bool WIEGAND::DoWiegandConversion() {
-    unsigned long cardID;
-    unsigned long sysTick = DWT->CYCCNT;
-
-    if((sysTick - _lastWiegand) >
-       (25 * clocks_in_ms)) // if no more signal coming through after 25ms
-    {
-        if((_bitCount == 24) || (_bitCount == 26) || (_bitCount == 32) || (_bitCount == 34) ||
-           (_bitCount == 37) || (_bitCount == 40) || (_bitCount == 8) ||
-           (_bitCount ==
-            4)) // bitCount for keypress=4 or 8, Wiegand 26=24 or 26, Wiegand 34=32 or 34
-        {
-            _codeHigh = 0;
-            // shift right 1 bit to get back the real value - interrupt done 1 left shift in advance
-            _cardTemp >>= 1;
-            // bit count more than 32 bits, shift high bits right to make adjustment
-            if(_bitCount > 32) _cardTempHigh >>= 1;
-
-            if(_bitCount == 8) // keypress wiegand with integrity
-            {
-                // 8-bit Wiegand keyboard data, high nibble is the "NOT" of low nibble
-                // eg if key 1 pressed, data=E1 in binary 11100001 , high nibble=1110 , low nibble = 0001
-                char highNibble = (_cardTemp & 0xf0) >> 4;
-                char lowNibble = (_cardTemp & 0x0f);
-                _wiegandType = _bitCount;
-                _bitCount = 0;
-                _cardTemp = 0;
-                _cardTempHigh = 0;
-
-                if(lowNibble ==
-                   (~highNibble & 0x0f)) // check if low nibble matches the "NOT" of high nibble.
-                {
-                    _code = (int)translateEnterEscapeKeyPress(lowNibble);
-                    return true;
-                } else {
-                    _lastWiegand = sysTick;
-                    return false;
-                }
-
-                // TODO: Handle validation failure case!
-            } else if(4 == _bitCount) {
-                // 4-bit Wiegand codes have no data integrity check so we just
-                // read the LOW nibble.
-                _code = (int)translateEnterEscapeKeyPress(_cardTemp & 0x0000000F);
-
-                _wiegandType = _bitCount;
-                _bitCount = 0;
-                _cardTemp = 0;
-                _cardTempHigh = 0;
-
-                return true;
-            } else if(40 == _bitCount) {
-                _cardTempHigh >>= 1;
-
-                _code = _cardTemp;
-                _codeHigh = _cardTempHigh;
-
-                _wiegandType = _bitCount;
-                _bitCount = 0;
-                _cardTemp = 0;
-                _cardTempHigh = 0;
-
-                return true;
-            } else {
-                // wiegand 26 or wiegand 34
-                cardID = GetCardId(&_cardTempHigh, &_cardTemp, _bitCount);
-                _wiegandType = _bitCount;
-                _bitCount = 0;
-                _cardTemp = 0;
-                _cardTempHigh = 0;
-                _code = cardID;
-                return true;
-            }
-        } else {
-            // well time over 25 ms and bitCount !=8 , !=26, !=34 , must be noise or nothing then.
-            _lastWiegand = sysTick;
-            _bitCount = 0;
-            _cardTemp = 0;
-            _cardTempHigh = 0;
-            return false;
-        }
-    } else
-        return false;
-}

+ 0 - 30
applications/debug/accessor/helpers/wiegand.h

@@ -1,30 +0,0 @@
-#pragma once
-
-class WIEGAND {
-public:
-    WIEGAND();
-    void begin();
-    void end();
-    bool available();
-    unsigned long getCode();
-    unsigned long getCodeHigh();
-    int getWiegandType();
-
-    static void ReadD0();
-    static void ReadD1();
-
-private:
-    static bool DoWiegandConversion();
-    static unsigned long GetCardId(
-        volatile unsigned long* codehigh,
-        volatile 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 int _wiegandType;
-    static unsigned long _code;
-    static unsigned long _codeHigh;
-};

+ 0 - 13
applications/debug/accessor/scene/accessor_scene_generic.h

@@ -1,13 +0,0 @@
-#pragma once
-#include "../accessor_app.h"
-
-class AccessorApp;
-
-class AccessorScene {
-public:
-    virtual void on_enter(AccessorApp* app) = 0;
-    virtual bool on_event(AccessorApp* app, AccessorEvent* event) = 0;
-    virtual void on_exit(AccessorApp* app) = 0;
-
-private:
-};

+ 0 - 88
applications/debug/accessor/scene/accessor_scene_start.cpp

@@ -1,88 +0,0 @@
-#include "../accessor_app.h"
-#include "../accessor_view_manager.h"
-#include "../accessor_event.h"
-#include <callback-connector.h>
-#include "accessor_scene_start.h"
-
-void AccessorSceneStart::on_enter(AccessorApp* app) {
-    AccessorAppViewManager* view_manager = app->get_view_manager();
-    Popup* popup = view_manager->get_popup();
-
-    popup_set_header(popup, "Accessor App", 64, 16, AlignCenter, AlignBottom);
-    app->set_text_store("[??????]");
-    popup_set_text(popup, app->get_text_store(), 64, 22, AlignCenter, AlignTop);
-
-    view_manager->switch_to(AccessorAppViewManager::ViewType::Popup);
-}
-
-bool AccessorSceneStart::on_event(AccessorApp* app, AccessorEvent* event) {
-    bool consumed = false;
-
-    if(event->type == AccessorEvent::Type::Tick) {
-        WIEGAND* wiegand = app->get_wiegand();
-        Popup* popup = app->get_view_manager()->get_popup();
-        OneWireHost* onewire_host = app->get_one_wire();
-
-        uint8_t data[8] = {0, 0, 0, 0, 0, 0, 0, 0};
-        uint8_t type = 0;
-
-        if(wiegand->available()) {
-            type = wiegand->getWiegandType();
-
-            for(uint8_t i = 0; i < 4; i++) {
-                data[i] = wiegand->getCode() >> (i * 8);
-            }
-
-            for(uint8_t i = 4; i < 8; i++) {
-                data[i] = wiegand->getCodeHigh() >> ((i - 4) * 8);
-            }
-        } else {
-            FURI_CRITICAL_ENTER();
-            if(onewire_host_reset(onewire_host)) {
-                type = 255;
-                onewire_host_write(onewire_host, 0x33);
-                for(uint8_t i = 0; i < 8; i++) {
-                    data[i] = onewire_host_read(onewire_host);
-                }
-
-                for(uint8_t i = 0; i < 7; i++) {
-                    data[i] = data[i + 1];
-                }
-            }
-            FURI_CRITICAL_EXIT();
-        }
-
-        if(type > 0) {
-            if(type == 255) {
-                app->set_text_store(
-                    "[%02X %02X %02X %02X %02X %02X DS]",
-                    data[5],
-                    data[4],
-                    data[3],
-                    data[2],
-                    data[1],
-                    data[0]);
-            } else {
-                app->set_text_store(
-                    "[%02X %02X %02X %02X %02X %02X W%u]",
-                    data[5],
-                    data[4],
-                    data[3],
-                    data[2],
-                    data[1],
-                    data[0],
-                    type);
-            }
-            popup_set_text(popup, app->get_text_store(), 64, 22, AlignCenter, AlignTop);
-            app->notify_success();
-        }
-    }
-
-    return consumed;
-}
-
-void AccessorSceneStart::on_exit(AccessorApp* app) {
-    Popup* popup = app->get_view_manager()->get_popup();
-    popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom);
-    popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop);
-}

+ 0 - 9
applications/debug/accessor/scene/accessor_scene_start.h

@@ -1,9 +0,0 @@
-#pragma once
-#include "accessor_scene_generic.h"
-
-class AccessorSceneStart : public AccessorScene {
-public:
-    void on_enter(AccessorApp* app) final;
-    bool on_event(AccessorApp* app, AccessorEvent* event) final;
-    void on_exit(AccessorApp* app) final;
-};

+ 0 - 16
applications/debug/application.fam

@@ -1,16 +0,0 @@
-App(
-    appid="debug_apps",
-    name="Basic debug apps bundle",
-    apptype=FlipperAppType.METAPACKAGE,
-    provides=[
-        "blink_test",
-        "vibro_test",
-        "keypad_test",
-        "usb_test",
-        "usb_mouse",
-        "uart_echo",
-        "display_test",
-        "text_box_test",
-        "file_browser_test",
-    ],
-)

+ 0 - 15
applications/debug/battery_test_app/application.fam

@@ -1,15 +0,0 @@
-App(
-    appid="battery_test",
-    name="Battery Test",
-    apptype=FlipperAppType.DEBUG,
-    entry_point="battery_test_app",
-    cdefines=["APP_BATTERY_TEST"],
-    requires=[
-        "gui",
-        "power",
-    ],
-    stack_size=1 * 1024,
-    order=130,
-    fap_category="Debug",
-    fap_libs=["assets"],
-)

+ 0 - 101
applications/debug/battery_test_app/battery_test_app.c

@@ -1,101 +0,0 @@
-#include "battery_test_app.h"
-
-#include <notification/notification_messages.h>
-
-void battery_test_dialog_callback(DialogExResult result, void* context) {
-    furi_assert(context);
-    BatteryTestApp* app = context;
-    if(result == DialogExResultLeft) {
-        view_dispatcher_stop(app->view_dispatcher);
-    } else if(result == DialogExResultRight) {
-        view_dispatcher_switch_to_view(app->view_dispatcher, BatteryTestAppViewBatteryInfo);
-    }
-}
-
-uint32_t battery_test_exit_confirm_view() {
-    return BatteryTestAppViewExitDialog;
-}
-
-static void battery_test_battery_info_update_model(void* context) {
-    BatteryTestApp* app = context;
-    power_get_info(app->power, &app->info);
-    BatteryInfoModel battery_info_data = {
-        .vbus_voltage = app->info.voltage_vbus,
-        .gauge_voltage = app->info.voltage_gauge,
-        .gauge_current = app->info.current_gauge,
-        .gauge_temperature = app->info.temperature_gauge,
-        .charge = app->info.charge,
-        .health = app->info.health,
-    };
-    battery_info_set_data(app->battery_info, &battery_info_data);
-    notification_message(app->notifications, &sequence_display_backlight_on);
-}
-
-BatteryTestApp* battery_test_alloc() {
-    BatteryTestApp* app = malloc(sizeof(BatteryTestApp));
-
-    // Records
-    app->gui = furi_record_open(RECORD_GUI);
-    app->power = furi_record_open(RECORD_POWER);
-    app->notifications = furi_record_open(RECORD_NOTIFICATION);
-
-    // View dispatcher
-    app->view_dispatcher = view_dispatcher_alloc();
-    view_dispatcher_enable_queue(app->view_dispatcher);
-    view_dispatcher_set_event_callback_context(app->view_dispatcher, app);
-    view_dispatcher_set_tick_event_callback(
-        app->view_dispatcher, battery_test_battery_info_update_model, 500);
-    view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen);
-
-    // Views
-    app->battery_info = battery_info_alloc();
-    view_set_previous_callback(
-        battery_info_get_view(app->battery_info), battery_test_exit_confirm_view);
-    view_dispatcher_add_view(
-        app->view_dispatcher,
-        BatteryTestAppViewBatteryInfo,
-        battery_info_get_view(app->battery_info));
-
-    app->dialog = dialog_ex_alloc();
-    dialog_ex_set_header(app->dialog, "Close Battery Test?", 64, 12, AlignCenter, AlignTop);
-    dialog_ex_set_left_button_text(app->dialog, "Exit");
-    dialog_ex_set_right_button_text(app->dialog, "Stay");
-    dialog_ex_set_result_callback(app->dialog, battery_test_dialog_callback);
-    dialog_ex_set_context(app->dialog, app);
-
-    view_dispatcher_add_view(
-        app->view_dispatcher, BatteryTestAppViewExitDialog, dialog_ex_get_view(app->dialog));
-
-    battery_test_battery_info_update_model(app);
-    view_dispatcher_switch_to_view(app->view_dispatcher, BatteryTestAppViewBatteryInfo);
-    return app;
-}
-
-void battery_test_free(BatteryTestApp* app) {
-    furi_assert(app);
-
-    // Views
-    view_dispatcher_remove_view(app->view_dispatcher, BatteryTestAppViewBatteryInfo);
-    battery_info_free(app->battery_info);
-    view_dispatcher_remove_view(app->view_dispatcher, BatteryTestAppViewExitDialog);
-    dialog_ex_free(app->dialog);
-    // View dispatcher
-    view_dispatcher_free(app->view_dispatcher);
-    // Records
-    furi_record_close(RECORD_POWER);
-    furi_record_close(RECORD_GUI);
-    furi_record_close(RECORD_NOTIFICATION);
-    free(app);
-}
-
-int32_t battery_test_app(void* p) {
-    UNUSED(p);
-    BatteryTestApp* app = battery_test_alloc();
-    // Disable battery low level notification
-    power_enable_low_battery_level_notification(app->power, false);
-
-    view_dispatcher_run(app->view_dispatcher);
-    power_enable_low_battery_level_notification(app->power, true);
-    battery_test_free(app);
-    return 0;
-}

+ 0 - 25
applications/debug/battery_test_app/battery_test_app.h

@@ -1,25 +0,0 @@
-#include <furi.h>
-#include <power/power_service/power.h>
-#include <gui/gui.h>
-#include <gui/view.h>
-#include <gui/view_dispatcher.h>
-#include <notification/notification.h>
-
-#include <gui/modules/dialog_ex.h>
-// FIXME
-#include "../settings/power_settings_app/views/battery_info.h"
-
-typedef struct {
-    Power* power;
-    Gui* gui;
-    NotificationApp* notifications;
-    ViewDispatcher* view_dispatcher;
-    BatteryInfo* battery_info;
-    DialogEx* dialog;
-    PowerInfo info;
-} BatteryTestApp;
-
-typedef enum {
-    BatteryTestAppViewBatteryInfo,
-    BatteryTestAppViewExitDialog,
-} BatteryTestAppView;

+ 0 - 148
applications/debug/battery_test_app/views/battery_info.c

@@ -1,148 +0,0 @@
-#include "battery_info.h"
-#include <furi.h>
-#include <gui/elements.h>
-#include <assets_icons.h>
-
-#define LOW_CHARGE_THRESHOLD 10
-#define HIGH_DRAIN_CURRENT_THRESHOLD 100
-
-struct BatteryInfo {
-    View* view;
-};
-
-static void draw_stat(Canvas* canvas, int x, int y, const Icon* icon, char* val) {
-    canvas_draw_frame(canvas, x - 7, y + 7, 30, 13);
-    canvas_draw_icon(canvas, x, y, icon);
-    canvas_set_color(canvas, ColorWhite);
-    canvas_draw_box(canvas, x - 4, y + 16, 24, 6);
-    canvas_set_color(canvas, ColorBlack);
-    canvas_draw_str_aligned(canvas, x + 8, y + 22, AlignCenter, AlignBottom, val);
-};
-
-static void draw_battery(Canvas* canvas, BatteryInfoModel* data, int x, int y) {
-    char emote[20] = {};
-    char header[20] = {};
-    char value[20] = {};
-
-    int32_t drain_current = data->gauge_current * (-1000);
-    uint32_t charge_current = data->gauge_current * 1000;
-
-    // Draw battery
-    canvas_draw_icon(canvas, x, y, &I_BatteryBody_52x28);
-    if(charge_current > 0) {
-        canvas_draw_icon(canvas, x + 16, y + 7, &I_FaceCharging_29x14);
-    } else if(drain_current > HIGH_DRAIN_CURRENT_THRESHOLD) {
-        canvas_draw_icon(canvas, x + 16, y + 7, &I_FaceConfused_29x14);
-    } else if(data->charge < LOW_CHARGE_THRESHOLD) {
-        canvas_draw_icon(canvas, x + 16, y + 7, &I_FaceNopower_29x14);
-    } else {
-        canvas_draw_icon(canvas, x + 16, y + 7, &I_FaceNormal_29x14);
-    }
-
-    // Draw bubble
-    elements_bubble(canvas, 53, 0, 71, 39);
-
-    // Set text
-    if(charge_current > 0) {
-        snprintf(emote, sizeof(emote), "%s", "Yummy!");
-        snprintf(header, sizeof(header), "%s", "Charging at");
-        snprintf(
-            value,
-            sizeof(value),
-            "%lu.%luV   %lumA",
-            (uint32_t)(data->vbus_voltage),
-            (uint32_t)(data->vbus_voltage * 10) % 10,
-            charge_current);
-    } else if(drain_current > 0) {
-        snprintf(
-            emote,
-            sizeof(emote),
-            "%s",
-            drain_current > HIGH_DRAIN_CURRENT_THRESHOLD ? "Oh no!" : "Om-nom-nom!");
-        snprintf(header, sizeof(header), "%s", "Consumption is");
-        snprintf(
-            value,
-            sizeof(value),
-            "%ld %s",
-            drain_current,
-            drain_current > HIGH_DRAIN_CURRENT_THRESHOLD ? "mA!" : "mA");
-    } else if(drain_current != 0) {
-        snprintf(header, 20, "...");
-    } else if(data->charging_voltage < 4.2) {
-        // Non-default battery charging limit, mention it
-        snprintf(emote, sizeof(emote), "Charged!");
-        snprintf(header, sizeof(header), "Limited to");
-        snprintf(
-            value,
-            sizeof(value),
-            "%lu.%luV",
-            (uint32_t)(data->charging_voltage),
-            (uint32_t)(data->charging_voltage * 10) % 10);
-    } else {
-        snprintf(header, sizeof(header), "Charged!");
-    }
-
-    canvas_draw_str_aligned(canvas, 92, y + 3, AlignCenter, AlignCenter, emote);
-    canvas_draw_str_aligned(canvas, 92, y + 15, AlignCenter, AlignCenter, header);
-    canvas_draw_str_aligned(canvas, 92, y + 27, AlignCenter, AlignCenter, value);
-};
-
-static void battery_info_draw_callback(Canvas* canvas, void* context) {
-    furi_assert(context);
-    BatteryInfoModel* model = context;
-
-    canvas_clear(canvas);
-    canvas_set_color(canvas, ColorBlack);
-    draw_battery(canvas, model, 0, 5);
-
-    char batt_level[10];
-    char temperature[10];
-    char voltage[10];
-    char health[10];
-
-    snprintf(batt_level, sizeof(batt_level), "%lu%%", (uint32_t)model->charge);
-    snprintf(temperature, sizeof(temperature), "%lu C", (uint32_t)model->gauge_temperature);
-    snprintf(
-        voltage,
-        sizeof(voltage),
-        "%lu.%01lu V",
-        (uint32_t)model->gauge_voltage,
-        (uint32_t)(model->gauge_voltage * 10) % 10UL);
-    snprintf(health, sizeof(health), "%d%%", model->health);
-
-    draw_stat(canvas, 8, 42, &I_Battery_16x16, batt_level);
-    draw_stat(canvas, 40, 42, &I_Temperature_16x16, temperature);
-    draw_stat(canvas, 72, 42, &I_Voltage_16x16, voltage);
-    draw_stat(canvas, 104, 42, &I_Health_16x16, health);
-}
-
-BatteryInfo* battery_info_alloc() {
-    BatteryInfo* battery_info = malloc(sizeof(BatteryInfo));
-    battery_info->view = view_alloc();
-    view_set_context(battery_info->view, battery_info);
-    view_allocate_model(battery_info->view, ViewModelTypeLocking, sizeof(BatteryInfoModel));
-    view_set_draw_callback(battery_info->view, battery_info_draw_callback);
-
-    return battery_info;
-}
-
-void battery_info_free(BatteryInfo* battery_info) {
-    furi_assert(battery_info);
-    view_free(battery_info->view);
-    free(battery_info);
-}
-
-View* battery_info_get_view(BatteryInfo* battery_info) {
-    furi_assert(battery_info);
-    return battery_info->view;
-}
-
-void battery_info_set_data(BatteryInfo* battery_info, BatteryInfoModel* data) {
-    furi_assert(battery_info);
-    furi_assert(data);
-    with_view_model(
-        battery_info->view,
-        BatteryInfoModel * model,
-        { memcpy(model, data, sizeof(BatteryInfoModel)); },
-        true);
-}

+ 0 - 23
applications/debug/battery_test_app/views/battery_info.h

@@ -1,23 +0,0 @@
-#pragma once
-
-#include <gui/view.h>
-
-typedef struct BatteryInfo BatteryInfo;
-
-typedef struct {
-    float vbus_voltage;
-    float gauge_voltage;
-    float gauge_current;
-    float gauge_temperature;
-    float charging_voltage;
-    uint8_t charge;
-    uint8_t health;
-} BatteryInfoModel;
-
-BatteryInfo* battery_info_alloc();
-
-void battery_info_free(BatteryInfo* battery_info);
-
-View* battery_info_get_view(BatteryInfo* battery_info);
-
-void battery_info_set_data(BatteryInfo* battery_info, BatteryInfoModel* data);

+ 0 - 11
applications/debug/blink_test/application.fam

@@ -1,11 +0,0 @@
-App(
-    appid="blink_test",
-    name="Blink Test",
-    apptype=FlipperAppType.DEBUG,
-    entry_point="blink_test_app",
-    cdefines=["APP_BLINK"],
-    requires=["gui"],
-    stack_size=1 * 1024,
-    order=10,
-    fap_category="Debug",
-)

+ 0 - 126
applications/debug/blink_test/blink_test.c

@@ -1,126 +0,0 @@
-#include <core/common_defines.h>
-#include <furi.h>
-#include <furi_hal.h>
-
-#include <gui/gui.h>
-#include <input/input.h>
-
-#include <notification/notification_messages.h>
-
-typedef enum {
-    BlinkEventTypeTick,
-    BlinkEventTypeInput,
-} BlinkEventType;
-
-typedef struct {
-    BlinkEventType type;
-    InputEvent input;
-} BlinkEvent;
-
-static const NotificationSequence blink_test_sequence_hw_blink_start_red = {
-    &message_blink_start_10,
-    &message_blink_set_color_red,
-    &message_do_not_reset,
-    NULL,
-};
-
-static const NotificationSequence blink_test_sequence_hw_blink_green = {
-    &message_blink_set_color_green,
-    NULL,
-};
-
-static const NotificationSequence blink_test_sequence_hw_blink_blue = {
-    &message_blink_set_color_blue,
-    NULL,
-};
-
-static const NotificationSequence blink_test_sequence_hw_blink_stop = {
-    &message_blink_stop,
-    NULL,
-};
-
-static const NotificationSequence* blink_test_colors[] = {
-    &sequence_blink_red_100,
-    &sequence_blink_green_100,
-    &sequence_blink_blue_100,
-    &sequence_blink_yellow_100,
-    &sequence_blink_cyan_100,
-    &sequence_blink_magenta_100,
-    &sequence_blink_white_100,
-    &blink_test_sequence_hw_blink_start_red,
-    &blink_test_sequence_hw_blink_green,
-    &blink_test_sequence_hw_blink_blue,
-    &blink_test_sequence_hw_blink_stop,
-};
-
-static void blink_test_update(void* ctx) {
-    furi_assert(ctx);
-    FuriMessageQueue* event_queue = ctx;
-    BlinkEvent event = {.type = BlinkEventTypeTick};
-    // It's OK to loose this event if system overloaded
-    furi_message_queue_put(event_queue, &event, 0);
-}
-
-static void blink_test_draw_callback(Canvas* canvas, void* ctx) {
-    UNUSED(ctx);
-    canvas_clear(canvas);
-    canvas_set_font(canvas, FontPrimary);
-    canvas_draw_str(canvas, 2, 10, "Blink application");
-}
-
-static void blink_test_input_callback(InputEvent* input_event, void* ctx) {
-    furi_assert(ctx);
-    FuriMessageQueue* event_queue = ctx;
-
-    BlinkEvent event = {.type = BlinkEventTypeInput, .input = *input_event};
-    furi_message_queue_put(event_queue, &event, FuriWaitForever);
-}
-
-int32_t blink_test_app(void* p) {
-    UNUSED(p);
-    FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(BlinkEvent));
-
-    // Configure view port
-    ViewPort* view_port = view_port_alloc();
-    view_port_draw_callback_set(view_port, blink_test_draw_callback, NULL);
-    view_port_input_callback_set(view_port, blink_test_input_callback, event_queue);
-    FuriTimer* timer = furi_timer_alloc(blink_test_update, FuriTimerTypePeriodic, event_queue);
-    furi_timer_start(timer, furi_kernel_get_tick_frequency());
-
-    // Register view port in GUI
-    Gui* gui = furi_record_open(RECORD_GUI);
-    gui_add_view_port(gui, view_port, GuiLayerFullscreen);
-
-    NotificationApp* notifications = furi_record_open(RECORD_NOTIFICATION);
-
-    uint8_t state = 0;
-    BlinkEvent event;
-
-    while(1) {
-        furi_check(furi_message_queue_get(event_queue, &event, FuriWaitForever) == FuriStatusOk);
-        if(event.type == BlinkEventTypeInput) {
-            if((event.input.type == InputTypeShort) && (event.input.key == InputKeyBack)) {
-                break;
-            }
-        } else {
-            notification_message(notifications, blink_test_colors[state]);
-            state++;
-            if(state >= COUNT_OF(blink_test_colors)) {
-                state = 0;
-            }
-        }
-    }
-
-    notification_message(notifications, &blink_test_sequence_hw_blink_stop);
-
-    furi_timer_free(timer);
-
-    gui_remove_view_port(gui, view_port);
-    view_port_free(view_port);
-    furi_message_queue_free(event_queue);
-
-    furi_record_close(RECORD_NOTIFICATION);
-    furi_record_close(RECORD_GUI);
-
-    return 0;
-}

+ 0 - 18
applications/debug/bt_debug_app/application.fam

@@ -1,18 +0,0 @@
-App(
-    appid="bt_debug",
-    name="Bluetooth Debug",
-    apptype=FlipperAppType.DEBUG,
-    entry_point="bt_debug_app",
-    cdefines=["SRV_BT"],
-    requires=[
-        "bt",
-        "gui",
-        "dialogs",
-    ],
-    provides=[
-        "bt_debug",
-    ],
-    stack_size=1 * 1024,
-    order=110,
-    fap_category="Debug",
-)

+ 0 - 118
applications/debug/bt_debug_app/bt_debug_app.c

@@ -1,118 +0,0 @@
-#include "bt_debug_app.h"
-#include <furi_hal_bt.h>
-
-#define TAG "BtDebugApp"
-
-enum BtDebugSubmenuIndex {
-    BtDebugSubmenuIndexCarrierTest,
-    BtDebugSubmenuIndexPacketTest,
-};
-
-void bt_debug_submenu_callback(void* context, uint32_t index) {
-    furi_assert(context);
-    BtDebugApp* app = context;
-    if(index == BtDebugSubmenuIndexCarrierTest) {
-        view_dispatcher_switch_to_view(app->view_dispatcher, BtDebugAppViewCarrierTest);
-    } else if(index == BtDebugSubmenuIndexPacketTest) {
-        view_dispatcher_switch_to_view(app->view_dispatcher, BtDebugAppViewPacketTest);
-    }
-}
-
-uint32_t bt_debug_exit(void* context) {
-    UNUSED(context);
-    return VIEW_NONE;
-}
-
-uint32_t bt_debug_start_view(void* context) {
-    UNUSED(context);
-    return BtDebugAppViewSubmenu;
-}
-
-BtDebugApp* bt_debug_app_alloc() {
-    BtDebugApp* app = malloc(sizeof(BtDebugApp));
-
-    // Gui
-    app->gui = furi_record_open(RECORD_GUI);
-
-    // View dispatcher
-    app->view_dispatcher = view_dispatcher_alloc();
-    view_dispatcher_enable_queue(app->view_dispatcher);
-    view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen);
-
-    // Views
-    app->submenu = submenu_alloc();
-    submenu_add_item(
-        app->submenu,
-        "Carrier test",
-        BtDebugSubmenuIndexCarrierTest,
-        bt_debug_submenu_callback,
-        app);
-    submenu_add_item(
-        app->submenu, "Packet test", BtDebugSubmenuIndexPacketTest, bt_debug_submenu_callback, app);
-    view_set_previous_callback(submenu_get_view(app->submenu), bt_debug_exit);
-    view_dispatcher_add_view(
-        app->view_dispatcher, BtDebugAppViewSubmenu, submenu_get_view(app->submenu));
-    app->bt_carrier_test = bt_carrier_test_alloc();
-    view_set_previous_callback(
-        bt_carrier_test_get_view(app->bt_carrier_test), bt_debug_start_view);
-    view_dispatcher_add_view(
-        app->view_dispatcher,
-        BtDebugAppViewCarrierTest,
-        bt_carrier_test_get_view(app->bt_carrier_test));
-    app->bt_packet_test = bt_packet_test_alloc();
-    view_set_previous_callback(bt_packet_test_get_view(app->bt_packet_test), bt_debug_start_view);
-    view_dispatcher_add_view(
-        app->view_dispatcher,
-        BtDebugAppViewPacketTest,
-        bt_packet_test_get_view(app->bt_packet_test));
-
-    // Switch to menu
-    view_dispatcher_switch_to_view(app->view_dispatcher, BtDebugAppViewSubmenu);
-
-    return app;
-}
-
-void bt_debug_app_free(BtDebugApp* app) {
-    furi_assert(app);
-
-    // Free views
-    view_dispatcher_remove_view(app->view_dispatcher, BtDebugAppViewSubmenu);
-    submenu_free(app->submenu);
-    view_dispatcher_remove_view(app->view_dispatcher, BtDebugAppViewCarrierTest);
-    bt_carrier_test_free(app->bt_carrier_test);
-    view_dispatcher_remove_view(app->view_dispatcher, BtDebugAppViewPacketTest);
-    bt_packet_test_free(app->bt_packet_test);
-    view_dispatcher_free(app->view_dispatcher);
-
-    // Close gui record
-    furi_record_close(RECORD_GUI);
-    app->gui = NULL;
-
-    // Free rest
-    free(app);
-}
-
-int32_t bt_debug_app(void* p) {
-    UNUSED(p);
-    if(!furi_hal_bt_is_testing_supported()) {
-        FURI_LOG_E(TAG, "Incorrect radio stack: radio testing features are absent.");
-        DialogsApp* dialogs = furi_record_open(RECORD_DIALOGS);
-        dialog_message_show_storage_error(dialogs, "Incorrect\nRadioStack");
-        return 255;
-    }
-
-    BtDebugApp* app = bt_debug_app_alloc();
-    // Was bt active?
-    const bool was_active = furi_hal_bt_is_active();
-    // Stop advertising
-    furi_hal_bt_stop_advertising();
-
-    view_dispatcher_run(app->view_dispatcher);
-
-    // Restart advertising
-    if(was_active) {
-        furi_hal_bt_start_advertising();
-    }
-    bt_debug_app_free(app);
-    return 0;
-}

+ 0 - 26
applications/debug/bt_debug_app/bt_debug_app.h

@@ -1,26 +0,0 @@
-#pragma once
-
-#include <furi.h>
-#include <gui/gui.h>
-#include <gui/view.h>
-#include <gui/view_dispatcher.h>
-#include <gui/modules/submenu.h>
-
-#include <dialogs/dialogs.h>
-
-#include "views/bt_carrier_test.h"
-#include "views/bt_packet_test.h"
-
-typedef struct {
-    Gui* gui;
-    ViewDispatcher* view_dispatcher;
-    Submenu* submenu;
-    BtCarrierTest* bt_carrier_test;
-    BtPacketTest* bt_packet_test;
-} BtDebugApp;
-
-typedef enum {
-    BtDebugAppViewSubmenu,
-    BtDebugAppViewCarrierTest,
-    BtDebugAppViewPacketTest,
-} BtDebugAppView;

+ 0 - 188
applications/debug/bt_debug_app/views/bt_carrier_test.c

@@ -1,188 +0,0 @@
-#include "bt_carrier_test.h"
-#include "bt_test.h"
-#include "bt_test_types.h"
-#include <furi_hal_bt.h>
-
-struct BtCarrierTest {
-    BtTest* bt_test;
-    BtTestParam* bt_param_channel;
-    BtTestMode mode;
-    BtTestChannel channel;
-    BtTestPower power;
-    FuriTimer* timer;
-};
-
-static BtTestParamValue bt_param_mode[] = {
-    {.value = BtTestModeRx, .str = "Rx"},
-    {.value = BtTestModeTx, .str = "Tx"},
-    {.value = BtTestModeTxHopping, .str = "Hopping Tx"},
-};
-
-static BtTestParamValue bt_param_channel[] = {
-    {.value = BtTestChannel2402, .str = "2402 MHz"},
-    {.value = BtTestChannel2440, .str = "2440 MHz"},
-    {.value = BtTestChannel2480, .str = "2480 MHz"},
-};
-
-static BtTestParamValue bt_param_power[] = {
-    {.value = BtPower0dB, .str = "0 dB"},
-    {.value = BtPower2dB, .str = "2 dB"},
-    {.value = BtPower4dB, .str = "4 dB"},
-    {.value = BtPower6dB, .str = "6 dB"},
-};
-
-static void bt_carrier_test_start(BtCarrierTest* bt_carrier_test) {
-    furi_assert(bt_carrier_test);
-    if(bt_carrier_test->mode == BtTestModeRx) {
-        furi_hal_bt_start_packet_rx(bt_carrier_test->channel, 1);
-        furi_timer_start(bt_carrier_test->timer, furi_kernel_get_tick_frequency() / 4);
-    } else if(bt_carrier_test->mode == BtTestModeTxHopping) {
-        furi_hal_bt_start_tone_tx(bt_carrier_test->channel, bt_carrier_test->power);
-        furi_timer_start(bt_carrier_test->timer, furi_kernel_get_tick_frequency() * 2);
-    } else if(bt_carrier_test->mode == BtTestModeTx) {
-        furi_hal_bt_start_tone_tx(bt_carrier_test->channel, bt_carrier_test->power);
-    }
-}
-
-static void bt_carrier_test_switch_channel(BtCarrierTest* bt_carrier_test) {
-    furi_assert(bt_carrier_test);
-    furi_hal_bt_stop_tone_tx();
-    uint8_t channel_i = 0;
-    if(bt_carrier_test->channel == BtTestChannel2402) {
-        bt_carrier_test->channel = BtTestChannel2440;
-        channel_i = 1;
-    } else if(bt_carrier_test->channel == BtTestChannel2440) {
-        bt_carrier_test->channel = BtTestChannel2480;
-        channel_i = 2;
-    } else if(bt_carrier_test->channel == BtTestChannel2480) {
-        bt_carrier_test->channel = BtTestChannel2402;
-        channel_i = 0;
-    }
-    furi_hal_bt_start_tone_tx(bt_carrier_test->channel, bt_carrier_test->power);
-    bt_test_set_current_value_index(bt_carrier_test->bt_param_channel, channel_i);
-    bt_test_set_current_value_text(
-        bt_carrier_test->bt_param_channel, bt_param_channel[channel_i].str);
-}
-
-static void bt_carrier_test_stop(BtCarrierTest* bt_carrier_test) {
-    furi_assert(bt_carrier_test);
-    if(bt_carrier_test->mode == BtTestModeTxHopping) {
-        furi_hal_bt_stop_tone_tx();
-        furi_timer_stop(bt_carrier_test->timer);
-    } else if(bt_carrier_test->mode == BtTestModeTx) {
-        furi_hal_bt_stop_tone_tx();
-    } else if(bt_carrier_test->mode == BtTestModeRx) {
-        furi_hal_bt_stop_packet_test();
-        furi_timer_stop(bt_carrier_test->timer);
-    }
-}
-
-static uint32_t bt_carrier_test_param_changed(BtTestParam* param, BtTestParamValue* param_val) {
-    furi_assert(param);
-    uint8_t index = bt_test_get_current_value_index(param);
-    bt_test_set_current_value_text(param, param_val[index].str);
-    return param_val[index].value;
-}
-
-static void bt_carrier_test_mode_changed(BtTestParam* param) {
-    BtCarrierTest* bt_carrier_test = bt_test_get_context(param);
-    bt_carrier_test_stop(bt_carrier_test);
-    bt_carrier_test->mode = bt_carrier_test_param_changed(param, bt_param_mode);
-}
-
-static void bt_carrier_test_channel_changed(BtTestParam* param) {
-    BtCarrierTest* bt_carrier_test = bt_test_get_context(param);
-    bt_carrier_test_stop(bt_carrier_test);
-    bt_carrier_test->channel = bt_carrier_test_param_changed(param, bt_param_channel);
-}
-
-static void bt_carrier_test_param_channel(BtTestParam* param) {
-    BtCarrierTest* bt_carrier_test = bt_test_get_context(param);
-    bt_carrier_test_stop(bt_carrier_test);
-    bt_carrier_test->power = bt_carrier_test_param_changed(param, bt_param_power);
-}
-
-static void bt_carrier_test_change_state_callback(BtTestState state, void* context) {
-    furi_assert(context);
-    BtCarrierTest* bt_carrier_test = context;
-    furi_hal_bt_stop_tone_tx();
-    if(state == BtTestStateStarted) {
-        bt_carrier_test_start(bt_carrier_test);
-    } else if(state == BtTestStateStopped) {
-        bt_carrier_test_stop(bt_carrier_test);
-    }
-}
-
-static void bt_carrier_test_exit_callback(void* context) {
-    furi_assert(context);
-    BtCarrierTest* bt_carrier_test = context;
-    bt_carrier_test_stop(bt_carrier_test);
-}
-
-static void bt_test_carrier_timer_callback(void* context) {
-    furi_assert(context);
-    BtCarrierTest* bt_carrier_test = context;
-    if(bt_carrier_test->mode == BtTestModeRx) {
-        bt_test_set_rssi(bt_carrier_test->bt_test, furi_hal_bt_get_rssi());
-    } else if(bt_carrier_test->mode == BtTestModeTxHopping) {
-        bt_carrier_test_switch_channel(bt_carrier_test);
-    }
-}
-
-BtCarrierTest* bt_carrier_test_alloc() {
-    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);
-    bt_test_set_change_state_callback(
-        bt_carrier_test->bt_test, bt_carrier_test_change_state_callback);
-    bt_test_set_back_callback(bt_carrier_test->bt_test, bt_carrier_test_exit_callback);
-
-    BtTestParam* param;
-    param = bt_test_param_add(
-        bt_carrier_test->bt_test,
-        "Mode",
-        COUNT_OF(bt_param_mode),
-        bt_carrier_test_mode_changed,
-        bt_carrier_test);
-    bt_test_set_current_value_index(param, 0);
-    bt_test_set_current_value_text(param, bt_param_mode[0].str);
-    bt_carrier_test->mode = BtTestModeRx;
-
-    param = bt_test_param_add(
-        bt_carrier_test->bt_test,
-        "Channel",
-        COUNT_OF(bt_param_channel),
-        bt_carrier_test_channel_changed,
-        bt_carrier_test);
-    bt_test_set_current_value_index(param, 0);
-    bt_test_set_current_value_text(param, bt_param_channel[0].str);
-    bt_carrier_test->channel = BtTestChannel2402;
-    bt_carrier_test->bt_param_channel = param;
-
-    param = bt_test_param_add(
-        bt_carrier_test->bt_test,
-        "Power",
-        COUNT_OF(bt_param_power),
-        bt_carrier_test_param_channel,
-        bt_carrier_test);
-    bt_test_set_current_value_index(param, 0);
-    bt_test_set_current_value_text(param, bt_param_power[0].str);
-    bt_carrier_test->power = BtPower0dB;
-
-    bt_carrier_test->timer =
-        furi_timer_alloc(bt_test_carrier_timer_callback, FuriTimerTypePeriodic, bt_carrier_test);
-
-    return bt_carrier_test;
-}
-
-void bt_carrier_test_free(BtCarrierTest* bt_carrier_test) {
-    furi_assert(bt_carrier_test);
-    bt_test_free(bt_carrier_test->bt_test);
-    furi_timer_free(bt_carrier_test->timer);
-    free(bt_carrier_test);
-}
-
-View* bt_carrier_test_get_view(BtCarrierTest* bt_carrier_test) {
-    furi_assert(bt_carrier_test);
-    return bt_test_get_view(bt_carrier_test->bt_test);
-}

+ 0 - 10
applications/debug/bt_debug_app/views/bt_carrier_test.h

@@ -1,10 +0,0 @@
-#pragma once
-#include <gui/view.h>
-
-typedef struct BtCarrierTest BtCarrierTest;
-
-BtCarrierTest* bt_carrier_test_alloc();
-
-void bt_carrier_test_free(BtCarrierTest* bt_carrier_test);
-
-View* bt_carrier_test_get_view(BtCarrierTest* bt_carrier_test);

+ 0 - 155
applications/debug/bt_debug_app/views/bt_packet_test.c

@@ -1,155 +0,0 @@
-#include "bt_packet_test.h"
-#include "bt_test.h"
-#include "bt_test_types.h"
-#include <furi_hal_bt.h>
-
-struct BtPacketTest {
-    BtTest* bt_test;
-    BtTestMode mode;
-    BtTestChannel channel;
-    BtTestDataRate data_rate;
-    FuriTimer* timer;
-};
-
-static BtTestParamValue bt_param_mode[] = {
-    {.value = BtTestModeRx, .str = "Rx"},
-    {.value = BtTestModeTx, .str = "Tx"},
-};
-
-static BtTestParamValue bt_param_channel[] = {
-    {.value = BtTestChannel2402, .str = "2402 MHz"},
-    {.value = BtTestChannel2440, .str = "2440 MHz"},
-    {.value = BtTestChannel2480, .str = "2480 MHz"},
-};
-
-static BtTestParamValue bt_param_data_rate[] = {
-    {.value = BtDataRate1M, .str = "1 Mbps"},
-    {.value = BtDataRate2M, .str = "2 Mbps"},
-};
-
-static void bt_packet_test_start(BtPacketTest* bt_packet_test) {
-    furi_assert(bt_packet_test);
-    if(bt_packet_test->mode == BtTestModeRx) {
-        furi_hal_bt_start_packet_rx(bt_packet_test->channel, bt_packet_test->data_rate);
-        furi_timer_start(bt_packet_test->timer, furi_kernel_get_tick_frequency() / 4);
-    } else if(bt_packet_test->mode == BtTestModeTx) {
-        furi_hal_bt_start_packet_tx(bt_packet_test->channel, 1, bt_packet_test->data_rate);
-    }
-}
-
-static void bt_packet_test_stop(BtPacketTest* bt_packet_test) {
-    furi_assert(bt_packet_test);
-    if(bt_packet_test->mode == BtTestModeTx) {
-        furi_hal_bt_stop_packet_test();
-        bt_test_set_packets_tx(bt_packet_test->bt_test, furi_hal_bt_get_transmitted_packets());
-    } else if(bt_packet_test->mode == BtTestModeRx) {
-        bt_test_set_packets_rx(bt_packet_test->bt_test, furi_hal_bt_stop_packet_test());
-        furi_timer_stop(bt_packet_test->timer);
-    }
-}
-
-static uint32_t bt_packet_test_param_changed(BtTestParam* param, BtTestParamValue* param_val) {
-    furi_assert(param);
-    uint8_t index = bt_test_get_current_value_index(param);
-    bt_test_set_current_value_text(param, param_val[index].str);
-    return param_val[index].value;
-}
-
-static void bt_packet_test_mode_changed(BtTestParam* param) {
-    BtPacketTest* bt_packet_test = bt_test_get_context(param);
-    bt_packet_test_stop(bt_packet_test);
-    bt_packet_test->mode = bt_packet_test_param_changed(param, bt_param_mode);
-}
-
-static void bt_packet_test_channel_changed(BtTestParam* param) {
-    BtPacketTest* bt_packet_test = bt_test_get_context(param);
-    bt_packet_test_stop(bt_packet_test);
-    bt_packet_test->channel = bt_packet_test_param_changed(param, bt_param_channel);
-}
-
-static void bt_packet_test_param_channel(BtTestParam* param) {
-    BtPacketTest* bt_packet_test = bt_test_get_context(param);
-    bt_packet_test_stop(bt_packet_test);
-    bt_packet_test->data_rate = bt_packet_test_param_changed(param, bt_param_data_rate);
-}
-
-static void bt_packet_test_change_state_callback(BtTestState state, void* context) {
-    furi_assert(context);
-    BtPacketTest* bt_packet_test = context;
-    if(state == BtTestStateStarted) {
-        bt_packet_test_start(bt_packet_test);
-    } else if(state == BtTestStateStopped) {
-        bt_packet_test_stop(bt_packet_test);
-    }
-}
-
-static void bt_packet_test_exit_callback(void* context) {
-    furi_assert(context);
-    BtPacketTest* bt_packet_test = context;
-    bt_packet_test_stop(bt_packet_test);
-}
-
-static void bt_test_packet_timer_callback(void* context) {
-    furi_assert(context);
-    BtPacketTest* bt_packet_test = context;
-    if(bt_packet_test->mode == BtTestModeRx) {
-        bt_test_set_rssi(bt_packet_test->bt_test, furi_hal_bt_get_rssi());
-    }
-}
-
-BtPacketTest* bt_packet_test_alloc() {
-    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);
-    bt_test_set_change_state_callback(
-        bt_packet_test->bt_test, bt_packet_test_change_state_callback);
-    bt_test_set_back_callback(bt_packet_test->bt_test, bt_packet_test_exit_callback);
-
-    BtTestParam* param;
-    param = bt_test_param_add(
-        bt_packet_test->bt_test,
-        "Mode",
-        COUNT_OF(bt_param_mode),
-        bt_packet_test_mode_changed,
-        bt_packet_test);
-    bt_test_set_current_value_index(param, 0);
-    bt_test_set_current_value_text(param, bt_param_mode[0].str);
-    bt_packet_test->mode = BtTestModeRx;
-
-    param = bt_test_param_add(
-        bt_packet_test->bt_test,
-        "Channel",
-        COUNT_OF(bt_param_channel),
-        bt_packet_test_channel_changed,
-        bt_packet_test);
-    bt_test_set_current_value_index(param, 0);
-    bt_test_set_current_value_text(param, bt_param_channel[0].str);
-    bt_packet_test->channel = BtTestChannel2402;
-
-    param = bt_test_param_add(
-        bt_packet_test->bt_test,
-        "Data rate",
-        COUNT_OF(bt_param_data_rate),
-        bt_packet_test_param_channel,
-        bt_packet_test);
-    bt_test_set_current_value_index(param, 0);
-    bt_test_set_current_value_text(param, bt_param_data_rate[0].str);
-    bt_packet_test->data_rate = BtDataRate1M;
-
-    bt_packet_test->timer =
-        furi_timer_alloc(bt_test_packet_timer_callback, FuriTimerTypePeriodic, bt_packet_test);
-
-    return bt_packet_test;
-}
-
-void bt_packet_test_free(BtPacketTest* bt_packet_test) {
-    furi_assert(bt_packet_test);
-    bt_test_free(bt_packet_test->bt_test);
-    furi_timer_free(bt_packet_test->timer);
-    free(bt_packet_test);
-}
-
-View* bt_packet_test_get_view(BtPacketTest* bt_packet_test) {
-    furi_assert(bt_packet_test);
-    return bt_test_get_view(bt_packet_test->bt_test);
-}

+ 0 - 10
applications/debug/bt_debug_app/views/bt_packet_test.h

@@ -1,10 +0,0 @@
-#pragma once
-#include <gui/view.h>
-
-typedef struct BtPacketTest BtPacketTest;
-
-BtPacketTest* bt_packet_test_alloc();
-
-void bt_packet_test_free(BtPacketTest* bt_packet_test);
-
-View* bt_packet_test_get_view(BtPacketTest* bt_packet_test);

+ 0 - 434
applications/debug/bt_debug_app/views/bt_test.c

@@ -1,434 +0,0 @@
-#include "bt_test.h"
-
-#include <gui/canvas.h>
-#include <gui/elements.h>
-
-#include <lib/toolbox/float_tools.h>
-#include <m-array.h>
-#include <furi.h>
-#include <inttypes.h>
-#include <stdint.h>
-
-struct BtTestParam {
-    const char* label;
-    uint8_t current_value_index;
-    FuriString* current_value_text;
-    uint8_t values_count;
-    BtTestParamChangeCallback change_callback;
-    void* context;
-};
-
-ARRAY_DEF(BtTestParamArray, BtTestParam, M_POD_OPLIST);
-
-struct BtTest {
-    View* view;
-    BtTestChangeStateCallback change_state_callback;
-    BtTestBackCallback back_callback;
-    void* context;
-};
-
-typedef struct {
-    BtTestState state;
-    BtTestParamArray_t params;
-    uint8_t position;
-    uint8_t window_position;
-    const char* message;
-    float rssi;
-    uint32_t packets_num_rx;
-    uint32_t packets_num_tx;
-} BtTestModel;
-
-#define BT_TEST_START_MESSAGE "Ok - Start"
-#define BT_TEST_STOP_MESSAGE "Ok - Stop"
-
-static void bt_test_process_up(BtTest* bt_test);
-static void bt_test_process_down(BtTest* bt_test);
-static void bt_test_process_left(BtTest* bt_test);
-static void bt_test_process_right(BtTest* bt_test);
-static void bt_test_process_ok(BtTest* bt_test);
-static void bt_test_process_back(BtTest* bt_test);
-
-static void bt_test_draw_callback(Canvas* canvas, void* _model) {
-    BtTestModel* model = _model;
-    char info_str[32];
-
-    const uint8_t param_height = 16;
-    const uint8_t param_width = 123;
-
-    canvas_clear(canvas);
-
-    uint8_t position = 0;
-    BtTestParamArray_it_t it;
-
-    canvas_set_font(canvas, FontSecondary);
-    for(BtTestParamArray_it(it, model->params); !BtTestParamArray_end_p(it);
-        BtTestParamArray_next(it)) {
-        uint8_t param_position = position - model->window_position;
-        uint8_t params_on_screen = 3;
-        uint8_t y_offset = 0;
-
-        if(param_position < params_on_screen) {
-            const BtTestParam* param = BtTestParamArray_cref(it);
-            uint8_t param_y = y_offset + (param_position * param_height);
-            uint8_t param_text_y = param_y + param_height - 4;
-
-            if(position == model->position) {
-                canvas_set_color(canvas, ColorBlack);
-                elements_slightly_rounded_box(
-                    canvas, 0, param_y + 1, param_width, param_height - 2);
-                canvas_set_color(canvas, ColorWhite);
-            } else {
-                canvas_set_color(canvas, ColorBlack);
-            }
-
-            canvas_draw_str(canvas, 6, param_text_y, param->label);
-
-            if(param->current_value_index > 0) {
-                canvas_draw_str(canvas, 50, param_text_y, "<");
-            }
-
-            canvas_draw_str(
-                canvas, 61, param_text_y, furi_string_get_cstr(param->current_value_text));
-
-            if(param->current_value_index < (param->values_count - 1)) {
-                canvas_draw_str(canvas, 113, param_text_y, ">");
-            }
-        }
-
-        position++;
-    }
-
-    elements_scrollbar(canvas, model->position, BtTestParamArray_size(model->params));
-    canvas_draw_str(canvas, 6, 60, model->message);
-    if(model->state == BtTestStateStarted) {
-        if(!float_is_equal(model->rssi, 0.0f)) {
-            snprintf(info_str, sizeof(info_str), "RSSI:%3.1f dB", (double)model->rssi);
-            canvas_draw_str_aligned(canvas, 124, 60, AlignRight, AlignBottom, info_str);
-        }
-    } else if(model->state == BtTestStateStopped) {
-        if(model->packets_num_rx) {
-            snprintf(info_str, sizeof(info_str), "%" PRIu32 " pack rcv", model->packets_num_rx);
-            canvas_draw_str_aligned(canvas, 124, 60, AlignRight, AlignBottom, info_str);
-        } else if(model->packets_num_tx) {
-            snprintf(info_str, sizeof(info_str), "%" PRIu32 " pack sent", model->packets_num_tx);
-            canvas_draw_str_aligned(canvas, 124, 60, AlignRight, AlignBottom, info_str);
-        }
-    }
-}
-
-static bool bt_test_input_callback(InputEvent* event, void* context) {
-    BtTest* bt_test = context;
-    furi_assert(bt_test);
-    bool consumed = false;
-
-    if(event->type == InputTypeShort) {
-        switch(event->key) {
-        case InputKeyUp:
-            consumed = true;
-            bt_test_process_up(bt_test);
-            break;
-        case InputKeyDown:
-            consumed = true;
-            bt_test_process_down(bt_test);
-            break;
-        case InputKeyLeft:
-            consumed = true;
-            bt_test_process_left(bt_test);
-            break;
-        case InputKeyRight:
-            consumed = true;
-            bt_test_process_right(bt_test);
-            break;
-        case InputKeyOk:
-            consumed = true;
-            bt_test_process_ok(bt_test);
-            break;
-        case InputKeyBack:
-            consumed = false;
-            bt_test_process_back(bt_test);
-            break;
-        default:
-            break;
-        }
-    }
-
-    return consumed;
-}
-
-void bt_test_process_up(BtTest* bt_test) {
-    with_view_model( // -V658
-        bt_test->view,
-        BtTestModel * model,
-        {
-            uint8_t params_on_screen = 3;
-            if(model->position > 0) {
-                model->position--;
-                if(((model->position - model->window_position) < 1) &&
-                   model->window_position > 0) {
-                    model->window_position--;
-                }
-            } else {
-                model->position = BtTestParamArray_size(model->params) - 1;
-                if(model->position > (params_on_screen - 1)) {
-                    model->window_position = model->position - (params_on_screen - 1);
-                }
-            }
-        },
-        true);
-}
-
-void bt_test_process_down(BtTest* bt_test) {
-    with_view_model(
-        bt_test->view,
-        BtTestModel * model,
-        {
-            uint8_t params_on_screen = 3;
-            if(model->position < (BtTestParamArray_size(model->params) - 1)) {
-                model->position++;
-                if((model->position - model->window_position) > (params_on_screen - 2) &&
-                   model->window_position <
-                       (BtTestParamArray_size(model->params) - params_on_screen)) {
-                    model->window_position++;
-                }
-            } else {
-                model->position = 0;
-                model->window_position = 0;
-            }
-        },
-        true);
-}
-
-BtTestParam* bt_test_get_selected_param(BtTestModel* model) {
-    BtTestParam* param = NULL;
-
-    BtTestParamArray_it_t it;
-    uint8_t position = 0;
-    for(BtTestParamArray_it(it, model->params); !BtTestParamArray_end_p(it);
-        BtTestParamArray_next(it)) {
-        if(position == model->position) {
-            break;
-        }
-        position++;
-    }
-
-    param = BtTestParamArray_ref(it);
-
-    furi_assert(param);
-    return param;
-}
-
-void bt_test_process_left(BtTest* bt_test) {
-    BtTestParam* param;
-    with_view_model(
-        bt_test->view,
-        BtTestModel * model,
-        {
-            param = bt_test_get_selected_param(model);
-            if(param->current_value_index > 0) {
-                param->current_value_index--;
-                if(param->change_callback) {
-                    model->state = BtTestStateStopped;
-                    model->message = BT_TEST_START_MESSAGE;
-                    model->rssi = 0.0f;
-                    model->packets_num_rx = 0;
-                    model->packets_num_tx = 0;
-                }
-            }
-        },
-        true);
-    if(param->change_callback) {
-        param->change_callback(param);
-    }
-}
-
-void bt_test_process_right(BtTest* bt_test) {
-    BtTestParam* param;
-    with_view_model(
-        bt_test->view,
-        BtTestModel * model,
-        {
-            param = bt_test_get_selected_param(model);
-            if(param->current_value_index < (param->values_count - 1)) {
-                param->current_value_index++;
-                if(param->change_callback) {
-                    model->state = BtTestStateStopped;
-                    model->message = BT_TEST_START_MESSAGE;
-                    model->rssi = 0.0f;
-                    model->packets_num_rx = 0;
-                    model->packets_num_tx = 0;
-                }
-            }
-        },
-        true);
-    if(param->change_callback) {
-        param->change_callback(param);
-    }
-}
-
-void bt_test_process_ok(BtTest* bt_test) {
-    BtTestState state;
-    with_view_model(
-        bt_test->view,
-        BtTestModel * model,
-        {
-            if(model->state == BtTestStateStarted) {
-                model->state = BtTestStateStopped;
-                model->message = BT_TEST_START_MESSAGE;
-                model->rssi = 0.0f;
-                model->packets_num_rx = 0;
-                model->packets_num_tx = 0;
-            } else if(model->state == BtTestStateStopped) {
-                model->state = BtTestStateStarted;
-                model->message = BT_TEST_STOP_MESSAGE;
-            }
-            state = model->state;
-        },
-        true);
-    if(bt_test->change_state_callback) {
-        bt_test->change_state_callback(state, bt_test->context);
-    }
-}
-
-void bt_test_process_back(BtTest* bt_test) {
-    with_view_model(
-        bt_test->view,
-        BtTestModel * model,
-        {
-            model->state = BtTestStateStopped;
-            model->rssi = 0.0f;
-            model->packets_num_rx = 0;
-            model->packets_num_tx = 0;
-        },
-        false);
-    if(bt_test->back_callback) {
-        bt_test->back_callback(bt_test->context);
-    }
-}
-
-BtTest* bt_test_alloc() {
-    BtTest* bt_test = malloc(sizeof(BtTest));
-    bt_test->view = view_alloc();
-    view_set_context(bt_test->view, bt_test);
-    view_allocate_model(bt_test->view, ViewModelTypeLocking, sizeof(BtTestModel));
-    view_set_draw_callback(bt_test->view, bt_test_draw_callback);
-    view_set_input_callback(bt_test->view, bt_test_input_callback);
-
-    with_view_model(
-        bt_test->view,
-        BtTestModel * model,
-        {
-            model->state = BtTestStateStopped;
-            model->message = "Ok - Start";
-            BtTestParamArray_init(model->params);
-            model->position = 0;
-            model->window_position = 0;
-            model->rssi = 0.0f;
-            model->packets_num_tx = 0;
-            model->packets_num_rx = 0;
-        },
-        true);
-
-    return bt_test;
-}
-
-void bt_test_free(BtTest* bt_test) {
-    furi_assert(bt_test);
-
-    with_view_model(
-        bt_test->view,
-        BtTestModel * model,
-        {
-            BtTestParamArray_it_t it;
-            for(BtTestParamArray_it(it, model->params); !BtTestParamArray_end_p(it);
-                BtTestParamArray_next(it)) {
-                furi_string_free(BtTestParamArray_ref(it)->current_value_text);
-            }
-            BtTestParamArray_clear(model->params);
-        },
-        false);
-    view_free(bt_test->view);
-    free(bt_test);
-}
-
-View* bt_test_get_view(BtTest* bt_test) {
-    furi_assert(bt_test);
-    return bt_test->view;
-}
-
-BtTestParam* bt_test_param_add(
-    BtTest* bt_test,
-    const char* label,
-    uint8_t values_count,
-    BtTestParamChangeCallback change_callback,
-    void* context) {
-    BtTestParam* param = NULL;
-    furi_assert(label);
-    furi_assert(bt_test);
-
-    with_view_model(
-        bt_test->view,
-        BtTestModel * model,
-        {
-            param = BtTestParamArray_push_new(model->params);
-            param->label = label;
-            param->values_count = values_count;
-            param->change_callback = change_callback;
-            param->context = context;
-            param->current_value_index = 0;
-            param->current_value_text = furi_string_alloc();
-        },
-        true);
-
-    return param;
-}
-
-void bt_test_set_rssi(BtTest* bt_test, float rssi) {
-    furi_assert(bt_test);
-    with_view_model(
-        bt_test->view, BtTestModel * model, { model->rssi = rssi; }, true);
-}
-
-void bt_test_set_packets_tx(BtTest* bt_test, uint32_t packets_num) {
-    furi_assert(bt_test);
-    with_view_model(
-        bt_test->view, BtTestModel * model, { model->packets_num_tx = packets_num; }, true);
-}
-
-void bt_test_set_packets_rx(BtTest* bt_test, uint32_t packets_num) {
-    furi_assert(bt_test);
-    with_view_model(
-        bt_test->view, BtTestModel * model, { model->packets_num_rx = packets_num; }, true);
-}
-
-void bt_test_set_change_state_callback(BtTest* bt_test, BtTestChangeStateCallback callback) {
-    furi_assert(bt_test);
-    furi_assert(callback);
-    bt_test->change_state_callback = callback;
-}
-
-void bt_test_set_back_callback(BtTest* bt_test, BtTestBackCallback callback) {
-    furi_assert(bt_test);
-    furi_assert(callback);
-    bt_test->back_callback = callback;
-}
-
-void bt_test_set_context(BtTest* bt_test, void* context) {
-    furi_assert(bt_test);
-    bt_test->context = context;
-}
-
-void bt_test_set_current_value_index(BtTestParam* param, uint8_t current_value_index) {
-    param->current_value_index = current_value_index;
-}
-
-void bt_test_set_current_value_text(BtTestParam* param, const char* current_value_text) {
-    furi_string_set(param->current_value_text, current_value_text);
-}
-
-uint8_t bt_test_get_current_value_index(BtTestParam* param) {
-    return param->current_value_index;
-}
-
-void* bt_test_get_context(BtTestParam* param) {
-    return param->context;
-}

+ 0 - 46
applications/debug/bt_debug_app/views/bt_test.h

@@ -1,46 +0,0 @@
-#pragma once
-#include <gui/view.h>
-
-typedef enum {
-    BtTestStateStarted,
-    BtTestStateStopped,
-} BtTestState;
-
-typedef struct BtTest BtTest;
-typedef void (*BtTestChangeStateCallback)(BtTestState state, void* context);
-typedef void (*BtTestBackCallback)(void* context);
-typedef struct BtTestParam BtTestParam;
-typedef void (*BtTestParamChangeCallback)(BtTestParam* param);
-
-BtTest* bt_test_alloc();
-
-void bt_test_free(BtTest* bt_test);
-
-View* bt_test_get_view(BtTest* bt_test);
-
-BtTestParam* bt_test_param_add(
-    BtTest* bt_test,
-    const char* label,
-    uint8_t values_count,
-    BtTestParamChangeCallback change_callback,
-    void* context);
-
-void bt_test_set_change_state_callback(BtTest* bt_test, BtTestChangeStateCallback callback);
-
-void bt_test_set_back_callback(BtTest* bt_test, BtTestBackCallback callback);
-
-void bt_test_set_context(BtTest* bt_test, void* context);
-
-void bt_test_set_rssi(BtTest* bt_test, float rssi);
-
-void bt_test_set_packets_tx(BtTest* bt_test, uint32_t packets_num);
-
-void bt_test_set_packets_rx(BtTest* bt_test, uint32_t packets_num);
-
-void bt_test_set_current_value_index(BtTestParam* param, uint8_t current_value_index);
-
-void bt_test_set_current_value_text(BtTestParam* param, const char* current_value_text);
-
-uint8_t bt_test_get_current_value_index(BtTestParam* param);
-
-void* bt_test_get_context(BtTestParam* param);

+ 0 - 30
applications/debug/bt_debug_app/views/bt_test_types.h

@@ -1,30 +0,0 @@
-#pragma once
-
-typedef enum {
-    BtTestModeRx,
-    BtTestModeTx,
-    BtTestModeTxHopping,
-} BtTestMode;
-
-typedef enum {
-    BtTestChannel2402 = 0,
-    BtTestChannel2440 = 19,
-    BtTestChannel2480 = 39,
-} BtTestChannel;
-
-typedef enum {
-    BtPower0dB = 0x19,
-    BtPower2dB = 0x1B,
-    BtPower4dB = 0x1D,
-    BtPower6dB = 0x1F,
-} BtTestPower;
-
-typedef enum {
-    BtDataRate1M = 1,
-    BtDataRate2M = 2,
-} BtTestDataRate;
-
-typedef struct {
-    uint32_t value;
-    const char* str;
-} BtTestParamValue;

+ 0 - 10
applications/debug/direct_draw/application.fam

@@ -1,10 +0,0 @@
-App(
-    appid="direct_draw",
-    name="Direct Draw",
-    apptype=FlipperAppType.DEBUG,
-    entry_point="direct_draw_app",
-    requires=["gui", "input"],
-    stack_size=2 * 1024,
-    order=70,
-    fap_category="Debug",
-)

+ 0 - 112
applications/debug/direct_draw/direct_draw.c

@@ -1,112 +0,0 @@
-#include <furi.h>
-#include <gui/gui.h>
-#include <gui/canvas_i.h>
-#include <input/input.h>
-
-#define BUFFER_SIZE (32U)
-
-typedef struct {
-    FuriPubSub* input;
-    FuriPubSubSubscription* input_subscription;
-    Gui* gui;
-    Canvas* canvas;
-    bool stop;
-    uint32_t counter;
-} DirectDraw;
-
-static void gui_input_events_callback(const void* value, void* ctx) {
-    furi_assert(value);
-    furi_assert(ctx);
-
-    DirectDraw* instance = ctx;
-    const InputEvent* event = value;
-
-    if(event->key == InputKeyBack && event->type == InputTypeShort) {
-        instance->stop = true;
-    }
-}
-
-static DirectDraw* direct_draw_alloc() {
-    DirectDraw* instance = malloc(sizeof(DirectDraw));
-
-    instance->input = furi_record_open(RECORD_INPUT_EVENTS);
-    instance->gui = furi_record_open(RECORD_GUI);
-    instance->canvas = gui_direct_draw_acquire(instance->gui);
-
-    instance->input_subscription =
-        furi_pubsub_subscribe(instance->input, gui_input_events_callback, instance);
-
-    return instance;
-}
-
-static void direct_draw_free(DirectDraw* instance) {
-    furi_pubsub_unsubscribe(instance->input, instance->input_subscription);
-
-    instance->canvas = NULL;
-    gui_direct_draw_release(instance->gui);
-    furi_record_close(RECORD_GUI);
-    furi_record_close(RECORD_INPUT_EVENTS);
-}
-
-static void direct_draw_block(Canvas* canvas, uint32_t size, uint32_t counter) {
-    size += 16;
-    uint8_t width = canvas_width(canvas) - size;
-    uint8_t height = canvas_height(canvas) - size;
-
-    uint8_t x = counter % width;
-    if((counter / width) % 2) {
-        x = width - x;
-    }
-
-    uint8_t y = counter % height;
-    if((counter / height) % 2) {
-        y = height - y;
-    }
-
-    canvas_draw_box(canvas, x, y, size, size);
-}
-
-static void direct_draw_run(DirectDraw* instance) {
-    size_t start = DWT->CYCCNT;
-    size_t counter = 0;
-    float fps = 0;
-
-    vTaskPrioritySet(furi_thread_get_current_id(), FuriThreadPriorityIdle);
-
-    do {
-        size_t elapsed = DWT->CYCCNT - start;
-        char buffer[BUFFER_SIZE] = {0};
-
-        if(elapsed >= 64000000) {
-            fps = (float)counter / ((float)elapsed / 64000000.0f);
-
-            start = DWT->CYCCNT;
-            counter = 0;
-        }
-        snprintf(buffer, BUFFER_SIZE, "FPS: %.1f", (double)fps);
-
-        canvas_reset(instance->canvas);
-        canvas_set_color(instance->canvas, ColorXOR);
-        direct_draw_block(instance->canvas, instance->counter % 16, instance->counter);
-        direct_draw_block(instance->canvas, instance->counter * 2 % 16, instance->counter * 2);
-        direct_draw_block(instance->canvas, instance->counter * 3 % 16, instance->counter * 3);
-        direct_draw_block(instance->canvas, instance->counter * 4 % 16, instance->counter * 4);
-        direct_draw_block(instance->canvas, instance->counter * 5 % 16, instance->counter * 5);
-        canvas_draw_str(instance->canvas, 10, 10, buffer);
-        canvas_commit(instance->canvas);
-
-        counter++;
-        instance->counter++;
-        furi_thread_yield();
-    } while(!instance->stop);
-}
-
-int32_t direct_draw_app(void* p) {
-    UNUSED(p);
-
-    DirectDraw* instance = direct_draw_alloc();
-    direct_draw_run(instance);
-    direct_draw_free(instance);
-
-    return 0;
-}

+ 0 - 12
applications/debug/display_test/application.fam

@@ -1,12 +0,0 @@
-App(
-    appid="display_test",
-    name="Display Test",
-    apptype=FlipperAppType.DEBUG,
-    entry_point="display_test_app",
-    cdefines=["APP_DISPLAY_TEST"],
-    requires=["gui"],
-    fap_libs=["misc"],
-    stack_size=1 * 1024,
-    order=120,
-    fap_category="Debug",
-)

+ 0 - 231
applications/debug/display_test/display_test.c

@@ -1,231 +0,0 @@
-#include "display_test.h"
-
-#include <furi_hal.h>
-#include <furi.h>
-
-// Need access to u8g2
-#include <gui/gui_i.h>
-#include <gui/canvas_i.h>
-#include <u8g2_glue.h>
-
-#include <gui/view_dispatcher.h>
-#include <gui/modules/submenu.h>
-#include <gui/modules/variable_item_list.h>
-
-#include "view_display_test.h"
-
-#define TAG "DisplayTest"
-
-typedef struct {
-    Gui* gui;
-    ViewDispatcher* view_dispatcher;
-    ViewDisplayTest* view_display_test;
-    VariableItemList* variable_item_list;
-    Submenu* submenu;
-
-    bool config_bias;
-    uint8_t config_contrast;
-    uint8_t config_regulation_ratio;
-} DisplayTest;
-
-typedef enum {
-    DisplayTestViewSubmenu,
-    DisplayTestViewConfigure,
-    DisplayTestViewDisplayTest,
-} DisplayTestView;
-
-const bool config_bias_value[] = {
-    true,
-    false,
-};
-const char* const config_bias_text[] = {
-    "1/7",
-    "1/9",
-};
-
-const uint8_t config_regulation_ratio_value[] = {
-    0b000,
-    0b001,
-    0b010,
-    0b011,
-    0b100,
-    0b101,
-    0b110,
-    0b111,
-};
-const char* const config_regulation_ratio_text[] = {
-    "3.0",
-    "3.5",
-    "4.0",
-    "4.5",
-    "5.0",
-    "5.5",
-    "6.0",
-    "6.5",
-};
-
-static void display_test_submenu_callback(void* context, uint32_t index) {
-    DisplayTest* instance = (DisplayTest*)context;
-    view_dispatcher_switch_to_view(instance->view_dispatcher, index);
-}
-
-static uint32_t display_test_previous_callback(void* context) {
-    UNUSED(context);
-    return DisplayTestViewSubmenu;
-}
-
-static uint32_t display_test_exit_callback(void* context) {
-    UNUSED(context);
-    return VIEW_NONE;
-}
-
-static void display_test_reload_config(DisplayTest* instance) {
-    FURI_LOG_I(
-        TAG,
-        "contrast: %d, regulation_ratio: %d, bias: %d",
-        instance->config_contrast,
-        instance->config_regulation_ratio,
-        instance->config_bias);
-    u8x8_d_st756x_init(
-        &instance->gui->canvas->fb.u8x8,
-        instance->config_contrast,
-        instance->config_regulation_ratio,
-        instance->config_bias);
-}
-
-static void display_config_set_bias(VariableItem* item) {
-    DisplayTest* instance = variable_item_get_context(item);
-    uint8_t index = variable_item_get_current_value_index(item);
-    variable_item_set_current_value_text(item, config_bias_text[index]);
-    instance->config_bias = config_bias_value[index];
-    display_test_reload_config(instance);
-}
-
-static void display_config_set_regulation_ratio(VariableItem* item) {
-    DisplayTest* instance = variable_item_get_context(item);
-    uint8_t index = variable_item_get_current_value_index(item);
-    variable_item_set_current_value_text(item, config_regulation_ratio_text[index]);
-    instance->config_regulation_ratio = config_regulation_ratio_value[index];
-    display_test_reload_config(instance);
-}
-
-static void display_config_set_contrast(VariableItem* item) {
-    DisplayTest* instance = variable_item_get_context(item);
-    uint8_t index = variable_item_get_current_value_index(item);
-    FuriString* temp;
-    temp = furi_string_alloc();
-    furi_string_cat_printf(temp, "%d", index);
-    variable_item_set_current_value_text(item, furi_string_get_cstr(temp));
-    furi_string_free(temp);
-    instance->config_contrast = index;
-    display_test_reload_config(instance);
-}
-
-DisplayTest* display_test_alloc() {
-    DisplayTest* instance = malloc(sizeof(DisplayTest));
-
-    View* view = NULL;
-
-    instance->gui = furi_record_open(RECORD_GUI);
-    instance->view_dispatcher = view_dispatcher_alloc();
-    view_dispatcher_enable_queue(instance->view_dispatcher);
-    view_dispatcher_attach_to_gui(
-        instance->view_dispatcher, instance->gui, ViewDispatcherTypeFullscreen);
-
-    // Test
-    instance->view_display_test = view_display_test_alloc();
-    view = view_display_test_get_view(instance->view_display_test);
-    view_set_previous_callback(view, display_test_previous_callback);
-    view_dispatcher_add_view(instance->view_dispatcher, DisplayTestViewDisplayTest, view);
-
-    // Configure
-    instance->variable_item_list = variable_item_list_alloc();
-    view = variable_item_list_get_view(instance->variable_item_list);
-    view_set_previous_callback(view, display_test_previous_callback);
-    view_dispatcher_add_view(instance->view_dispatcher, DisplayTestViewConfigure, view);
-
-    // Configuration items
-    VariableItem* item;
-    instance->config_bias = false;
-    instance->config_contrast = 32;
-    instance->config_regulation_ratio = 0b101;
-    // Bias
-    item = variable_item_list_add(
-        instance->variable_item_list,
-        "Bias:",
-        COUNT_OF(config_bias_value),
-        display_config_set_bias,
-        instance);
-    variable_item_set_current_value_index(item, 1);
-    variable_item_set_current_value_text(item, config_bias_text[1]);
-    // Regulation Ratio
-    item = variable_item_list_add(
-        instance->variable_item_list,
-        "Reg Ratio:",
-        COUNT_OF(config_regulation_ratio_value),
-        display_config_set_regulation_ratio,
-        instance);
-    variable_item_set_current_value_index(item, 5);
-    variable_item_set_current_value_text(item, config_regulation_ratio_text[5]);
-    // Contrast
-    item = variable_item_list_add(
-        instance->variable_item_list, "Contrast:", 64, display_config_set_contrast, instance);
-    variable_item_set_current_value_index(item, 32);
-    variable_item_set_current_value_text(item, "32");
-
-    // Menu
-    instance->submenu = submenu_alloc();
-    view = submenu_get_view(instance->submenu);
-    view_set_previous_callback(view, display_test_exit_callback);
-    view_dispatcher_add_view(instance->view_dispatcher, DisplayTestViewSubmenu, view);
-    submenu_add_item(
-        instance->submenu,
-        "Test",
-        DisplayTestViewDisplayTest,
-        display_test_submenu_callback,
-        instance);
-    submenu_add_item(
-        instance->submenu,
-        "Configure",
-        DisplayTestViewConfigure,
-        display_test_submenu_callback,
-        instance);
-
-    return instance;
-}
-
-void display_test_free(DisplayTest* instance) {
-    view_dispatcher_remove_view(instance->view_dispatcher, DisplayTestViewSubmenu);
-    submenu_free(instance->submenu);
-
-    view_dispatcher_remove_view(instance->view_dispatcher, DisplayTestViewConfigure);
-    variable_item_list_free(instance->variable_item_list);
-
-    view_dispatcher_remove_view(instance->view_dispatcher, DisplayTestViewDisplayTest);
-    view_display_test_free(instance->view_display_test);
-
-    view_dispatcher_free(instance->view_dispatcher);
-    furi_record_close(RECORD_GUI);
-
-    free(instance);
-}
-
-int32_t display_test_run(DisplayTest* instance) {
-    UNUSED(instance);
-    view_dispatcher_switch_to_view(instance->view_dispatcher, DisplayTestViewSubmenu);
-    view_dispatcher_run(instance->view_dispatcher);
-
-    return 0;
-}
-
-int32_t display_test_app(void* p) {
-    UNUSED(p);
-
-    DisplayTest* instance = display_test_alloc();
-
-    int32_t ret = display_test_run(instance);
-
-    display_test_free(instance);
-
-    return ret;
-}

+ 0 - 1
applications/debug/display_test/display_test.h

@@ -1 +0,0 @@
-#pragma once

+ 0 - 185
applications/debug/display_test/view_display_test.c

@@ -1,185 +0,0 @@
-#include "view_display_test.h"
-
-typedef struct {
-    uint32_t test;
-    uint32_t size;
-    uint32_t counter;
-    bool flip_flop;
-} ViewDisplayTestModel;
-
-struct ViewDisplayTest {
-    View* view;
-    FuriTimer* timer;
-};
-
-static void view_display_test_draw_callback_intro(Canvas* canvas, void* _model) {
-    UNUSED(_model);
-    canvas_draw_str(canvas, 12, 24, "Use < and > to switch tests");
-    canvas_draw_str(canvas, 12, 36, "Use ^ and v to switch size");
-    canvas_draw_str(canvas, 32, 48, "Use (o) to flip");
-}
-
-static void view_display_test_draw_callback_fill(Canvas* canvas, void* _model) {
-    ViewDisplayTestModel* model = _model;
-    if(model->flip_flop) {
-        uint8_t width = canvas_width(canvas);
-        uint8_t height = canvas_height(canvas);
-        canvas_draw_box(canvas, 0, 0, width, height);
-    }
-}
-
-static void view_display_test_draw_callback_hstripe(Canvas* canvas, void* _model) {
-    ViewDisplayTestModel* model = _model;
-    uint8_t block = 1 + model->size;
-    uint8_t width = canvas_width(canvas);
-    uint8_t height = canvas_height(canvas);
-
-    for(uint8_t y = model->flip_flop * block; y < height; y += 2 * block) {
-        canvas_draw_box(canvas, 0, y, width, block);
-    }
-}
-
-static void view_display_test_draw_callback_vstripe(Canvas* canvas, void* _model) {
-    ViewDisplayTestModel* model = _model;
-    uint8_t block = 1 + model->size;
-    uint8_t width = canvas_width(canvas);
-    uint8_t height = canvas_height(canvas);
-
-    for(uint8_t x = model->flip_flop * block; x < width; x += 2 * block) {
-        canvas_draw_box(canvas, x, 0, block, height);
-    }
-}
-
-static void view_display_test_draw_callback_check(Canvas* canvas, void* _model) {
-    ViewDisplayTestModel* model = _model;
-    uint8_t block = 1 + model->size;
-    uint8_t width = canvas_width(canvas);
-    uint8_t height = canvas_height(canvas);
-
-    bool flip_flop = model->flip_flop;
-    for(uint8_t x = 0; x < width; x += block) {
-        bool last_flip_flop = flip_flop;
-        for(uint8_t y = 0; y < height; y += block) {
-            if(flip_flop) {
-                canvas_draw_box(canvas, x, y, block, block);
-            }
-            flip_flop = !flip_flop;
-        }
-        if(last_flip_flop == flip_flop) {
-            flip_flop = !flip_flop;
-        }
-    }
-}
-
-static void view_display_test_draw_callback_move(Canvas* canvas, void* _model) {
-    ViewDisplayTestModel* model = _model;
-    uint8_t block = 1 + model->size;
-    uint8_t width = canvas_width(canvas) - block;
-    uint8_t height = canvas_height(canvas) - block;
-
-    uint8_t x = model->counter % width;
-    if((model->counter / width) % 2) {
-        x = width - x;
-    }
-
-    uint8_t y = model->counter % height;
-    if((model->counter / height) % 2) {
-        y = height - y;
-    }
-
-    canvas_draw_box(canvas, x, y, block, block);
-}
-
-const ViewDrawCallback view_display_test_tests[] = {
-    view_display_test_draw_callback_intro,
-    view_display_test_draw_callback_fill,
-    view_display_test_draw_callback_hstripe,
-    view_display_test_draw_callback_vstripe,
-    view_display_test_draw_callback_check,
-    view_display_test_draw_callback_move,
-};
-
-static void view_display_test_draw_callback(Canvas* canvas, void* _model) {
-    ViewDisplayTestModel* model = _model;
-    view_display_test_tests[model->test](canvas, _model);
-}
-
-static bool view_display_test_input_callback(InputEvent* event, void* context) {
-    ViewDisplayTest* instance = context;
-
-    bool consumed = false;
-    if(event->type == InputTypeShort || event->type == InputTypeRepeat) {
-        with_view_model(
-            instance->view,
-            ViewDisplayTestModel * model,
-            {
-                if(event->key == InputKeyLeft && model->test > 0) {
-                    model->test--;
-                    consumed = true;
-                } else if(
-                    event->key == InputKeyRight &&
-                    model->test < (COUNT_OF(view_display_test_tests) - 1)) {
-                    model->test++;
-                    consumed = true;
-                } else if(event->key == InputKeyDown && model->size > 0) {
-                    model->size--;
-                    consumed = true;
-                } else if(event->key == InputKeyUp && model->size < 24) {
-                    model->size++;
-                    consumed = true;
-                } else if(event->key == InputKeyOk) {
-                    model->flip_flop = !model->flip_flop;
-                    consumed = true;
-                }
-            },
-            consumed);
-    }
-
-    return consumed;
-}
-
-static void view_display_test_enter(void* context) {
-    ViewDisplayTest* instance = context;
-    furi_timer_start(instance->timer, furi_kernel_get_tick_frequency() / 32);
-}
-
-static void view_display_test_exit(void* context) {
-    ViewDisplayTest* instance = context;
-    furi_timer_stop(instance->timer);
-}
-
-static void view_display_test_timer_callback(void* context) {
-    ViewDisplayTest* instance = context;
-    with_view_model(
-        instance->view, ViewDisplayTestModel * model, { model->counter++; }, true);
-}
-
-ViewDisplayTest* view_display_test_alloc() {
-    ViewDisplayTest* instance = malloc(sizeof(ViewDisplayTest));
-
-    instance->view = view_alloc();
-    view_set_context(instance->view, instance);
-    view_allocate_model(instance->view, ViewModelTypeLockFree, sizeof(ViewDisplayTestModel));
-    view_set_draw_callback(instance->view, view_display_test_draw_callback);
-    view_set_input_callback(instance->view, view_display_test_input_callback);
-    view_set_enter_callback(instance->view, view_display_test_enter);
-    view_set_exit_callback(instance->view, view_display_test_exit);
-
-    instance->timer =
-        furi_timer_alloc(view_display_test_timer_callback, FuriTimerTypePeriodic, instance);
-
-    return instance;
-}
-
-void view_display_test_free(ViewDisplayTest* instance) {
-    furi_assert(instance);
-
-    furi_timer_free(instance->timer);
-    view_free(instance->view);
-    free(instance);
-}
-
-View* view_display_test_get_view(ViewDisplayTest* instance) {
-    furi_assert(instance);
-    return instance->view;
-}

+ 0 - 12
applications/debug/display_test/view_display_test.h

@@ -1,12 +0,0 @@
-#pragma once
-
-#include <stdint.h>
-#include <gui/view.h>
-
-typedef struct ViewDisplayTest ViewDisplayTest;
-
-ViewDisplayTest* view_display_test_alloc();
-
-void view_display_test_free(ViewDisplayTest* instance);
-
-View* view_display_test_get_view(ViewDisplayTest* instance);

+ 0 - 9
applications/debug/example_custom_font/application.fam

@@ -1,9 +0,0 @@
-App(
-    appid="example_custom_font",
-    name="Example: custom font",
-    apptype=FlipperAppType.DEBUG,
-    entry_point="example_custom_font_main",
-    requires=["gui"],
-    stack_size=1 * 1024,
-    fap_category="Debug",
-)

+ 0 - 98
applications/debug/example_custom_font/example_custom_font.c

@@ -1,98 +0,0 @@
-#include <furi.h>
-#include <furi_hal.h>
-
-#include <gui/gui.h>
-#include <input/input.h>
-
-//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
-*/
-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<R\0n\7\223\310\250d\5o\7\223\310U\252\2p\10\227"
-    "\307\250\244V\4q\10\227\307-\225d\0r\6\223\310\315\22s\10\223\310\215\70\22\0t\10\227\310\245"
-    "\25\243\0u\7\223\310$+\11v\10\223\310$\65R\2w\7\223\310\244q\4x\7\223\310\244\62\25"
-    "y\11\227\307$\225dJ\0z\7\223\310\254\221\6{\10\227\310\251\32D\1|\6\265\310(\1}\11"
-    "\227\310\310\14RR\0~\6\213\313\215\4\0\0\0\4\377\377\0";
-
-// Screen is 128x64 px
-static void app_draw_callback(Canvas* canvas, void* ctx) {
-    UNUSED(ctx);
-
-    canvas_clear(canvas);
-
-    canvas_set_custom_u8g2_font(canvas, u8g2_font_tom_thumb_4x6_tr);
-
-    canvas_draw_str(canvas, 0, 6, "This is a tiny custom font");
-    canvas_draw_str(canvas, 0, 12, "012345.?! ,:;\"\'@#$%");
-}
-
-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_custom_font_main(void* p) {
-    UNUSED(p);
-    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, view_port);
-    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);
-
-    InputEvent event;
-
-    bool running = true;
-
-    while(running) {
-        if(furi_message_queue_get(event_queue, &event, 100) == FuriStatusOk) {
-            if((event.type == InputTypePress) || (event.type == InputTypeRepeat)) {
-                switch(event.key) {
-                case InputKeyBack:
-                    running = false;
-                    break;
-                default:
-                    break;
-                }
-            }
-        }
-    }
-
-    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);
-
-    return 0;
-}

+ 0 - 12
applications/debug/file_browser_test/application.fam

@@ -1,12 +0,0 @@
-App(
-    appid="file_browser_test",
-    name="File Browser Test",
-    apptype=FlipperAppType.DEBUG,
-    entry_point="file_browser_app",
-    cdefines=["APP_FILE_BROWSER_TEST"],
-    requires=["gui"],
-    stack_size=2 * 1024,
-    order=150,
-    fap_category="Debug",
-    fap_icon_assets="icons",
-)

+ 0 - 99
applications/debug/file_browser_test/file_browser_app.c

@@ -1,99 +0,0 @@
-#include "file_browser_app_i.h"
-#include <file_browser_test_icons.h>
-
-#include <gui/modules/file_browser.h>
-#include <storage/storage.h>
-#include <lib/toolbox/path.h>
-#include <furi.h>
-#include <furi_hal.h>
-
-static bool file_browser_app_custom_event_callback(void* context, uint32_t event) {
-    furi_assert(context);
-    FileBrowserApp* app = context;
-    return scene_manager_handle_custom_event(app->scene_manager, event);
-}
-
-static bool file_browser_app_back_event_callback(void* context) {
-    furi_assert(context);
-    FileBrowserApp* app = context;
-    return scene_manager_handle_back_event(app->scene_manager);
-}
-
-static void file_browser_app_tick_event_callback(void* context) {
-    furi_assert(context);
-    FileBrowserApp* app = context;
-    scene_manager_handle_tick_event(app->scene_manager);
-}
-
-FileBrowserApp* file_browser_app_alloc(char* arg) {
-    UNUSED(arg);
-    FileBrowserApp* app = malloc(sizeof(FileBrowserApp));
-
-    app->gui = furi_record_open(RECORD_GUI);
-    app->dialogs = furi_record_open(RECORD_DIALOGS);
-
-    app->view_dispatcher = view_dispatcher_alloc();
-    view_dispatcher_enable_queue(app->view_dispatcher);
-
-    app->scene_manager = scene_manager_alloc(&file_browser_scene_handlers, app);
-
-    view_dispatcher_set_event_callback_context(app->view_dispatcher, app);
-    view_dispatcher_set_tick_event_callback(
-        app->view_dispatcher, file_browser_app_tick_event_callback, 500);
-    view_dispatcher_set_custom_event_callback(
-        app->view_dispatcher, file_browser_app_custom_event_callback);
-    view_dispatcher_set_navigation_event_callback(
-        app->view_dispatcher, file_browser_app_back_event_callback);
-
-    app->widget = widget_alloc();
-
-    app->file_path = furi_string_alloc();
-    app->file_browser = file_browser_alloc(app->file_path);
-    file_browser_configure(app->file_browser, "*", NULL, true, false, &I_badusb_10px, true);
-
-    view_dispatcher_add_view(
-        app->view_dispatcher, FileBrowserAppViewStart, widget_get_view(app->widget));
-    view_dispatcher_add_view(
-        app->view_dispatcher, FileBrowserAppViewResult, widget_get_view(app->widget));
-    view_dispatcher_add_view(
-        app->view_dispatcher, FileBrowserAppViewBrowser, file_browser_get_view(app->file_browser));
-
-    view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen);
-
-    scene_manager_next_scene(app->scene_manager, FileBrowserSceneStart);
-
-    return app;
-}
-
-void file_browser_app_free(FileBrowserApp* app) {
-    furi_assert(app);
-
-    // Views
-    view_dispatcher_remove_view(app->view_dispatcher, FileBrowserAppViewStart);
-    view_dispatcher_remove_view(app->view_dispatcher, FileBrowserAppViewResult);
-    view_dispatcher_remove_view(app->view_dispatcher, FileBrowserAppViewBrowser);
-    widget_free(app->widget);
-    file_browser_free(app->file_browser);
-
-    // View dispatcher
-    view_dispatcher_free(app->view_dispatcher);
-    scene_manager_free(app->scene_manager);
-
-    // Close records
-    furi_record_close(RECORD_GUI);
-    furi_record_close(RECORD_NOTIFICATION);
-    furi_record_close(RECORD_DIALOGS);
-
-    furi_string_free(app->file_path);
-
-    free(app);
-}
-
-int32_t file_browser_app(void* p) {
-    FileBrowserApp* file_browser_app = file_browser_app_alloc((char*)p);
-
-    view_dispatcher_run(file_browser_app->view_dispatcher);
-
-    file_browser_app_free(file_browser_app);
-    return 0;
-}

+ 0 - 32
applications/debug/file_browser_test/file_browser_app_i.h

@@ -1,32 +0,0 @@
-#pragma once
-
-#include "scenes/file_browser_scene.h"
-
-#include <gui/gui.h>
-#include <gui/view_dispatcher.h>
-#include <gui/scene_manager.h>
-#include <gui/modules/submenu.h>
-#include <gui/modules/file_browser.h>
-#include <dialogs/dialogs.h>
-#include <notification/notification_messages.h>
-#include <gui/modules/variable_item_list.h>
-#include <gui/modules/widget.h>
-
-typedef struct FileBrowserApp FileBrowserApp;
-
-struct FileBrowserApp {
-    Gui* gui;
-    ViewDispatcher* view_dispatcher;
-    SceneManager* scene_manager;
-    DialogsApp* dialogs;
-    Widget* widget;
-    FileBrowser* file_browser;
-
-    FuriString* file_path;
-};
-
-typedef enum {
-    FileBrowserAppViewStart,
-    FileBrowserAppViewBrowser,
-    FileBrowserAppViewResult,
-} FileBrowserAppView;

BIN
applications/debug/file_browser_test/icons/badusb_10px.png


+ 0 - 30
applications/debug/file_browser_test/scenes/file_browser_scene.c

@@ -1,30 +0,0 @@
-#include "file_browser_scene.h"
-
-// Generate scene on_enter handlers array
-#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_enter,
-void (*const file_browser_scene_on_enter_handlers[])(void*) = {
-#include "file_browser_scene_config.h"
-};
-#undef ADD_SCENE
-
-// Generate scene on_event handlers array
-#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_event,
-bool (*const file_browser_scene_on_event_handlers[])(void* context, SceneManagerEvent event) = {
-#include "file_browser_scene_config.h"
-};
-#undef ADD_SCENE
-
-// Generate scene on_exit handlers array
-#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_exit,
-void (*const file_browser_scene_on_exit_handlers[])(void* context) = {
-#include "file_browser_scene_config.h"
-};
-#undef ADD_SCENE
-
-// Initialize scene handlers configuration structure
-const SceneManagerHandlers file_browser_scene_handlers = {
-    .on_enter_handlers = file_browser_scene_on_enter_handlers,
-    .on_event_handlers = file_browser_scene_on_event_handlers,
-    .on_exit_handlers = file_browser_scene_on_exit_handlers,
-    .scene_num = FileBrowserSceneNum,
-};

+ 0 - 29
applications/debug/file_browser_test/scenes/file_browser_scene.h

@@ -1,29 +0,0 @@
-#pragma once
-
-#include <gui/scene_manager.h>
-
-// Generate scene id and total number
-#define ADD_SCENE(prefix, name, id) FileBrowserScene##id,
-typedef enum {
-#include "file_browser_scene_config.h"
-    FileBrowserSceneNum,
-} FileBrowserScene;
-#undef ADD_SCENE
-
-extern const SceneManagerHandlers file_browser_scene_handlers;
-
-// Generate scene on_enter handlers declaration
-#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_enter(void*);
-#include "file_browser_scene_config.h"
-#undef ADD_SCENE
-
-// Generate scene on_event handlers declaration
-#define ADD_SCENE(prefix, name, id) \
-    bool prefix##_scene_##name##_on_event(void* context, SceneManagerEvent event);
-#include "file_browser_scene_config.h"
-#undef ADD_SCENE
-
-// Generate scene on_exit handlers declaration
-#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_exit(void* context);
-#include "file_browser_scene_config.h"
-#undef ADD_SCENE

+ 0 - 40
applications/debug/file_browser_test/scenes/file_browser_scene_browser.c

@@ -1,40 +0,0 @@
-#include "../file_browser_app_i.h"
-#include <furi.h>
-
-#define DEFAULT_PATH "/"
-#define EXTENSION "*"
-
-bool file_browser_scene_browser_on_event(void* context, SceneManagerEvent event) {
-    UNUSED(context);
-    FileBrowserApp* app = context;
-    bool consumed = false;
-
-    if(event.type == SceneManagerEventTypeCustom) {
-        scene_manager_next_scene(app->scene_manager, FileBrowserSceneResult);
-        consumed = true;
-    } else if(event.type == SceneManagerEventTypeTick) {
-    }
-    return consumed;
-}
-
-static void file_browser_callback(void* context) {
-    FileBrowserApp* app = context;
-    furi_assert(app);
-    view_dispatcher_send_custom_event(app->view_dispatcher, SceneManagerEventTypeCustom);
-}
-
-void file_browser_scene_browser_on_enter(void* context) {
-    FileBrowserApp* app = context;
-
-    file_browser_set_callback(app->file_browser, file_browser_callback, app);
-
-    file_browser_start(app->file_browser, app->file_path);
-
-    view_dispatcher_switch_to_view(app->view_dispatcher, FileBrowserAppViewBrowser);
-}
-
-void file_browser_scene_browser_on_exit(void* context) {
-    FileBrowserApp* app = context;
-
-    file_browser_stop(app->file_browser);
-}

+ 0 - 3
applications/debug/file_browser_test/scenes/file_browser_scene_config.h

@@ -1,3 +0,0 @@
-ADD_SCENE(file_browser, start, Start)
-ADD_SCENE(file_browser, browser, Browser)
-ADD_SCENE(file_browser, result, Result)

+ 0 - 41
applications/debug/file_browser_test/scenes/file_browser_scene_result.c

@@ -1,41 +0,0 @@
-#include "../file_browser_app_i.h"
-#include <furi.h>
-
-void file_browser_scene_result_ok_callback(InputType type, void* context) {
-    furi_assert(context);
-    FileBrowserApp* app = context;
-    view_dispatcher_send_custom_event(app->view_dispatcher, type);
-}
-
-bool file_browser_scene_result_on_event(void* context, SceneManagerEvent event) {
-    UNUSED(context);
-    //FileBrowserApp* app = context;
-    bool consumed = false;
-
-    if(event.type == SceneManagerEventTypeCustom) {
-        consumed = true;
-    } else if(event.type == SceneManagerEventTypeTick) {
-    }
-    return consumed;
-}
-
-void file_browser_scene_result_on_enter(void* context) {
-    FileBrowserApp* app = context;
-
-    widget_add_string_multiline_element(
-        app->widget,
-        64,
-        10,
-        AlignCenter,
-        AlignTop,
-        FontSecondary,
-        furi_string_get_cstr(app->file_path));
-
-    view_dispatcher_switch_to_view(app->view_dispatcher, FileBrowserAppViewResult);
-}
-
-void file_browser_scene_result_on_exit(void* context) {
-    UNUSED(context);
-    FileBrowserApp* app = context;
-    widget_reset(app->widget);
-}

+ 0 - 46
applications/debug/file_browser_test/scenes/file_browser_scene_start.c

@@ -1,46 +0,0 @@
-#include "../file_browser_app_i.h"
-
-#include <furi_hal.h>
-#include <gui/modules/widget_elements/widget_element_i.h>
-#include <storage/storage.h>
-
-static void
-    file_browser_scene_start_ok_callback(GuiButtonType result, InputType type, void* context) {
-    UNUSED(result);
-    furi_assert(context);
-    FileBrowserApp* app = context;
-    if(type == InputTypeShort) {
-        view_dispatcher_send_custom_event(app->view_dispatcher, type);
-    }
-}
-
-bool file_browser_scene_start_on_event(void* context, SceneManagerEvent event) {
-    FileBrowserApp* app = context;
-    bool consumed = false;
-
-    if(event.type == SceneManagerEventTypeCustom) {
-        furi_string_set(app->file_path, ANY_PATH("badusb/demo_windows.txt"));
-        scene_manager_next_scene(app->scene_manager, FileBrowserSceneBrowser);
-        consumed = true;
-    } else if(event.type == SceneManagerEventTypeTick) {
-    }
-    return consumed;
-}
-
-void file_browser_scene_start_on_enter(void* context) {
-    FileBrowserApp* app = context;
-
-    widget_add_string_multiline_element(
-        app->widget, 64, 20, AlignCenter, AlignTop, FontSecondary, "Press OK to start");
-
-    widget_add_button_element(
-        app->widget, GuiButtonTypeCenter, "Ok", file_browser_scene_start_ok_callback, app);
-
-    view_dispatcher_switch_to_view(app->view_dispatcher, FileBrowserAppViewStart);
-}
-
-void file_browser_scene_start_on_exit(void* context) {
-    UNUSED(context);
-    FileBrowserApp* app = context;
-    widget_reset(app->widget);
-}

+ 0 - 11
applications/debug/keypad_test/application.fam

@@ -1,11 +0,0 @@
-App(
-    appid="keypad_test",
-    name="Keypad Test",
-    apptype=FlipperAppType.DEBUG,
-    entry_point="keypad_test_app",
-    cdefines=["APP_KEYPAD_TEST"],
-    requires=["gui"],
-    stack_size=1 * 1024,
-    order=30,
-    fap_category="Debug",
-)

+ 0 - 157
applications/debug/keypad_test/keypad_test.c

@@ -1,157 +0,0 @@
-#include <furi.h>
-#include <gui/gui.h>
-#include <input/input.h>
-
-#define TAG "KeypadTest"
-
-typedef struct {
-    bool press[5];
-    uint16_t up;
-    uint16_t down;
-    uint16_t left;
-    uint16_t right;
-    uint16_t ok;
-    FuriMutex* mutex;
-} KeypadTestState;
-
-static void keypad_test_reset_state(KeypadTestState* state) {
-    state->left = 0;
-    state->right = 0;
-    state->up = 0;
-    state->down = 0;
-    state->ok = 0;
-}
-
-static void keypad_test_render_callback(Canvas* canvas, void* ctx) {
-    KeypadTestState* state = ctx;
-    furi_mutex_acquire(state->mutex, FuriWaitForever);
-    canvas_clear(canvas);
-    char strings[5][20];
-
-    snprintf(strings[0], 20, "Ok: %d", state->ok);
-    snprintf(strings[1], 20, "L: %d", state->left);
-    snprintf(strings[2], 20, "R: %d", state->right);
-    snprintf(strings[3], 20, "U: %d", state->up);
-    snprintf(strings[4], 20, "D: %d", state->down);
-
-    canvas_set_font(canvas, FontPrimary);
-    canvas_draw_str(canvas, 0, 10, "Keypad test");
-
-    canvas_set_font(canvas, FontSecondary);
-    canvas_draw_str(canvas, 0, 24, strings[1]);
-    canvas_draw_str(canvas, 35, 24, strings[2]);
-    canvas_draw_str(canvas, 0, 36, strings[3]);
-    canvas_draw_str(canvas, 35, 36, strings[4]);
-    canvas_draw_str(canvas, 0, 48, strings[0]);
-    canvas_draw_circle(canvas, 100, 26, 25);
-
-    if(state->press[0]) canvas_draw_disc(canvas, 118, 26, 5);
-    if(state->press[1]) canvas_draw_disc(canvas, 82, 26, 5);
-    if(state->press[2]) canvas_draw_disc(canvas, 100, 8, 5);
-    if(state->press[3]) canvas_draw_disc(canvas, 100, 44, 5);
-    if(state->press[4]) canvas_draw_disc(canvas, 100, 26, 5);
-
-    canvas_draw_str(canvas, 10, 63, "[back] - reset, hold to exit");
-
-    furi_mutex_release(state->mutex);
-}
-
-static void keypad_test_input_callback(InputEvent* input_event, void* ctx) {
-    FuriMessageQueue* event_queue = ctx;
-    furi_message_queue_put(event_queue, input_event, FuriWaitForever);
-}
-
-int32_t keypad_test_app(void* p) {
-    UNUSED(p);
-    FuriMessageQueue* event_queue = furi_message_queue_alloc(32, sizeof(InputEvent));
-    furi_check(event_queue);
-
-    KeypadTestState state = {{false, false, false, false, false}, 0, 0, 0, 0, 0, NULL};
-    state.mutex = furi_mutex_alloc(FuriMutexTypeNormal);
-
-    if(!state.mutex) {
-        FURI_LOG_E(TAG, "cannot create mutex");
-        return 0;
-    }
-
-    ViewPort* view_port = view_port_alloc();
-
-    view_port_draw_callback_set(view_port, keypad_test_render_callback, &state);
-    view_port_input_callback_set(view_port, keypad_test_input_callback, event_queue);
-
-    // Open GUI and register view_port
-    Gui* gui = furi_record_open(RECORD_GUI);
-    gui_add_view_port(gui, view_port, GuiLayerFullscreen);
-
-    InputEvent event;
-    while(furi_message_queue_get(event_queue, &event, FuriWaitForever) == FuriStatusOk) {
-        furi_mutex_acquire(state.mutex, FuriWaitForever);
-        FURI_LOG_I(
-            TAG,
-            "key: %s type: %s",
-            input_get_key_name(event.key),
-            input_get_type_name(event.type));
-
-        if(event.key == InputKeyRight) {
-            if(event.type == InputTypePress) {
-                state.press[0] = true;
-            } else if(event.type == InputTypeRelease) {
-                state.press[0] = false;
-            } else if(event.type == InputTypeShort) {
-                ++state.right;
-            }
-        } else if(event.key == InputKeyLeft) {
-            if(event.type == InputTypePress) {
-                state.press[1] = true;
-            } else if(event.type == InputTypeRelease) {
-                state.press[1] = false;
-            } else if(event.type == InputTypeShort) {
-                ++state.left;
-            }
-        } else if(event.key == InputKeyUp) {
-            if(event.type == InputTypePress) {
-                state.press[2] = true;
-            } else if(event.type == InputTypeRelease) {
-                state.press[2] = false;
-            } else if(event.type == InputTypeShort) {
-                ++state.up;
-            }
-        } else if(event.key == InputKeyDown) {
-            if(event.type == InputTypePress) {
-                state.press[3] = true;
-            } else if(event.type == InputTypeRelease) {
-                state.press[3] = false;
-            } else if(event.type == InputTypeShort) {
-                ++state.down;
-            }
-        } else if(event.key == InputKeyOk) {
-            if(event.type == InputTypePress) {
-                state.press[4] = true;
-            } else if(event.type == InputTypeRelease) {
-                state.press[4] = false;
-            } else if(event.type == InputTypeShort) {
-                ++state.ok;
-            }
-        } else if(event.key == InputKeyBack) {
-            if(event.type == InputTypeLong) {
-                furi_mutex_release(state.mutex);
-                break;
-            } else if(event.type == InputTypeShort) {
-                keypad_test_reset_state(&state);
-            }
-        }
-
-        furi_mutex_release(state.mutex);
-        view_port_update(view_port);
-    }
-
-    // remove & free all stuff created by app
-    gui_remove_view_port(gui, view_port);
-    view_port_free(view_port);
-    furi_message_queue_free(event_queue);
-    furi_mutex_free(state.mutex);
-
-    furi_record_close(RECORD_GUI);
-
-    return 0;
-}

+ 0 - 16
applications/debug/lfrfid_debug/application.fam

@@ -1,16 +0,0 @@
-App(
-    appid="lfrfid_debug",
-    name="LF-RFID Debug",
-    apptype=FlipperAppType.DEBUG,
-    targets=["f7"],
-    entry_point="lfrfid_debug_app",
-    requires=[
-        "gui",
-    ],
-    provides=[
-        "lfrfid_debug",
-    ],
-    stack_size=1 * 1024,
-    order=100,
-    fap_category="Debug",
-)

+ 0 - 81
applications/debug/lfrfid_debug/lfrfid_debug.c

@@ -1,81 +0,0 @@
-#include "lfrfid_debug_i.h"
-
-static bool lfrfid_debug_custom_event_callback(void* context, uint32_t event) {
-    furi_assert(context);
-    LfRfidDebug* app = context;
-    return scene_manager_handle_custom_event(app->scene_manager, event);
-}
-
-static bool lfrfid_debug_back_event_callback(void* context) {
-    furi_assert(context);
-    LfRfidDebug* app = context;
-    return scene_manager_handle_back_event(app->scene_manager);
-}
-
-static LfRfidDebug* lfrfid_debug_alloc() {
-    LfRfidDebug* app = malloc(sizeof(LfRfidDebug));
-
-    app->view_dispatcher = view_dispatcher_alloc();
-    app->scene_manager = scene_manager_alloc(&lfrfid_debug_scene_handlers, app);
-    view_dispatcher_enable_queue(app->view_dispatcher);
-    view_dispatcher_set_event_callback_context(app->view_dispatcher, app);
-    view_dispatcher_set_custom_event_callback(
-        app->view_dispatcher, lfrfid_debug_custom_event_callback);
-    view_dispatcher_set_navigation_event_callback(
-        app->view_dispatcher, lfrfid_debug_back_event_callback);
-
-    // Open GUI record
-    app->gui = furi_record_open(RECORD_GUI);
-    view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen);
-
-    // Submenu
-    app->submenu = submenu_alloc();
-    view_dispatcher_add_view(
-        app->view_dispatcher, LfRfidDebugViewSubmenu, submenu_get_view(app->submenu));
-
-    // Tune view
-    app->tune_view = lfrfid_debug_view_tune_alloc();
-    view_dispatcher_add_view(
-        app->view_dispatcher,
-        LfRfidDebugViewTune,
-        lfrfid_debug_view_tune_get_view(app->tune_view));
-
-    return app;
-}
-
-static void lfrfid_debug_free(LfRfidDebug* app) {
-    furi_assert(app);
-
-    // Submenu
-    view_dispatcher_remove_view(app->view_dispatcher, LfRfidDebugViewSubmenu);
-    submenu_free(app->submenu);
-
-    // Tune view
-    view_dispatcher_remove_view(app->view_dispatcher, LfRfidDebugViewTune);
-    lfrfid_debug_view_tune_free(app->tune_view);
-
-    // View Dispatcher
-    view_dispatcher_free(app->view_dispatcher);
-
-    // Scene Manager
-    scene_manager_free(app->scene_manager);
-
-    // GUI
-    furi_record_close(RECORD_GUI);
-    app->gui = NULL;
-
-    free(app);
-}
-
-int32_t lfrfid_debug_app(void* p) {
-    UNUSED(p);
-    LfRfidDebug* app = lfrfid_debug_alloc();
-
-    scene_manager_next_scene(app->scene_manager, LfRfidDebugSceneStart);
-
-    view_dispatcher_run(app->view_dispatcher);
-
-    lfrfid_debug_free(app);
-
-    return 0;
-}

+ 0 - 30
applications/debug/lfrfid_debug/lfrfid_debug_i.h

@@ -1,30 +0,0 @@
-#pragma once
-#include <furi.h>
-#include <furi_hal.h>
-
-#include <gui/gui.h>
-#include <gui/view.h>
-#include <gui/view_dispatcher.h>
-#include <gui/scene_manager.h>
-
-#include <gui/modules/submenu.h>
-
-#include "views/lfrfid_debug_view_tune.h"
-#include "scenes/lfrfid_debug_scene.h"
-
-typedef struct LfRfidDebug LfRfidDebug;
-
-struct LfRfidDebug {
-    Gui* gui;
-    ViewDispatcher* view_dispatcher;
-    SceneManager* scene_manager;
-
-    // Common Views
-    Submenu* submenu;
-    LfRfidTuneView* tune_view;
-};
-
-typedef enum {
-    LfRfidDebugViewSubmenu,
-    LfRfidDebugViewTune,
-} LfRfidDebugView;

+ 0 - 44
applications/debug/lfrfid_debug/scenes/lfrfid_debug_app_scene_start.c

@@ -1,44 +0,0 @@
-#include "../lfrfid_debug_i.h"
-
-typedef enum {
-    SubmenuIndexTune,
-} SubmenuIndex;
-
-static void lfrfid_debug_scene_start_submenu_callback(void* context, uint32_t index) {
-    LfRfidDebug* app = context;
-
-    view_dispatcher_send_custom_event(app->view_dispatcher, index);
-}
-
-void lfrfid_debug_scene_start_on_enter(void* context) {
-    LfRfidDebug* app = context;
-    Submenu* submenu = app->submenu;
-
-    submenu_add_item(
-        submenu, "Tune", SubmenuIndexTune, lfrfid_debug_scene_start_submenu_callback, app);
-
-    submenu_set_selected_item(
-        submenu, scene_manager_get_scene_state(app->scene_manager, LfRfidDebugSceneStart));
-
-    view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidDebugViewSubmenu);
-}
-
-bool lfrfid_debug_scene_start_on_event(void* context, SceneManagerEvent event) {
-    LfRfidDebug* app = context;
-    bool consumed = false;
-
-    if(event.type == SceneManagerEventTypeCustom) {
-        if(event.event == SubmenuIndexTune) {
-            scene_manager_next_scene(app->scene_manager, LfRfidDebugSceneTune);
-            consumed = true;
-        }
-    }
-
-    return consumed;
-}
-
-void lfrfid_debug_scene_start_on_exit(void* context) {
-    LfRfidDebug* app = context;
-
-    submenu_reset(app->submenu);
-}

+ 0 - 48
applications/debug/lfrfid_debug/scenes/lfrfid_debug_app_scene_tune.c

@@ -1,48 +0,0 @@
-#include "../lfrfid_debug_i.h"
-#include <furi_hal.h>
-
-static void comparator_trigger_callback(bool level, void* comp_ctx) {
-    UNUSED(comp_ctx);
-    furi_hal_gpio_write(&gpio_ext_pa7, !level);
-}
-
-void lfrfid_debug_scene_tune_on_enter(void* context) {
-    LfRfidDebug* app = context;
-
-    furi_hal_gpio_init_simple(&gpio_ext_pa7, GpioModeOutputPushPull);
-
-    furi_hal_rfid_comp_set_callback(comparator_trigger_callback, app);
-    furi_hal_rfid_comp_start();
-
-    furi_hal_rfid_pins_read();
-    furi_hal_rfid_tim_read(125000, 0.5);
-    furi_hal_rfid_tim_read_start();
-
-    view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidDebugViewTune);
-}
-
-bool lfrfid_debug_scene_tune_on_event(void* context, SceneManagerEvent event) {
-    UNUSED(event);
-
-    LfRfidDebug* app = context;
-    bool consumed = false;
-
-    if(lfrfid_debug_view_tune_is_dirty(app->tune_view)) {
-        furi_hal_rfid_set_read_period(lfrfid_debug_view_tune_get_arr(app->tune_view));
-        furi_hal_rfid_set_read_pulse(lfrfid_debug_view_tune_get_ccr(app->tune_view));
-    }
-
-    return consumed;
-}
-
-void lfrfid_debug_scene_tune_on_exit(void* context) {
-    UNUSED(context);
-
-    furi_hal_rfid_comp_stop();
-    furi_hal_rfid_comp_set_callback(NULL, NULL);
-
-    furi_hal_gpio_init_simple(&gpio_ext_pa7, GpioModeAnalog);
-    furi_hal_rfid_tim_read_stop();
-    furi_hal_rfid_tim_reset();
-    furi_hal_rfid_pins_reset();
-}

+ 0 - 30
applications/debug/lfrfid_debug/scenes/lfrfid_debug_scene.c

@@ -1,30 +0,0 @@
-#include "lfrfid_debug_scene.h"
-
-// Generate scene on_enter handlers array
-#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_enter,
-void (*const lfrfid_debug_on_enter_handlers[])(void*) = {
-#include "lfrfid_debug_scene_config.h"
-};
-#undef ADD_SCENE
-
-// Generate scene on_event handlers array
-#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_event,
-bool (*const lfrfid_debug_on_event_handlers[])(void* context, SceneManagerEvent event) = {
-#include "lfrfid_debug_scene_config.h"
-};
-#undef ADD_SCENE
-
-// Generate scene on_exit handlers array
-#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_exit,
-void (*const lfrfid_debug_on_exit_handlers[])(void* context) = {
-#include "lfrfid_debug_scene_config.h"
-};
-#undef ADD_SCENE
-
-// Initialize scene handlers configuration structure
-const SceneManagerHandlers lfrfid_debug_scene_handlers = {
-    .on_enter_handlers = lfrfid_debug_on_enter_handlers,
-    .on_event_handlers = lfrfid_debug_on_event_handlers,
-    .on_exit_handlers = lfrfid_debug_on_exit_handlers,
-    .scene_num = LfRfidDebugSceneNum,
-};

+ 0 - 29
applications/debug/lfrfid_debug/scenes/lfrfid_debug_scene.h

@@ -1,29 +0,0 @@
-#pragma once
-
-#include <gui/scene_manager.h>
-
-// Generate scene id and total number
-#define ADD_SCENE(prefix, name, id) LfRfidDebugScene##id,
-typedef enum {
-#include "lfrfid_debug_scene_config.h"
-    LfRfidDebugSceneNum,
-} LfRfidDebugScene;
-#undef ADD_SCENE
-
-extern const SceneManagerHandlers lfrfid_debug_scene_handlers;
-
-// Generate scene on_enter handlers declaration
-#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_enter(void*);
-#include "lfrfid_debug_scene_config.h"
-#undef ADD_SCENE
-
-// Generate scene on_event handlers declaration
-#define ADD_SCENE(prefix, name, id) \
-    bool prefix##_scene_##name##_on_event(void* context, SceneManagerEvent event);
-#include "lfrfid_debug_scene_config.h"
-#undef ADD_SCENE
-
-// Generate scene on_exit handlers declaration
-#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_exit(void* context);
-#include "lfrfid_debug_scene_config.h"
-#undef ADD_SCENE

+ 0 - 2
applications/debug/lfrfid_debug/scenes/lfrfid_debug_scene_config.h

@@ -1,2 +0,0 @@
-ADD_SCENE(lfrfid_debug, start, Start)
-ADD_SCENE(lfrfid_debug, tune, Tune)

+ 0 - 234
applications/debug/lfrfid_debug/views/lfrfid_debug_view_tune.c

@@ -1,234 +0,0 @@
-#include "lfrfid_debug_view_tune.h"
-#include <gui/elements.h>
-
-#define TEMP_STR_LEN 128
-
-struct LfRfidTuneView {
-    View* view;
-};
-
-typedef struct {
-    bool dirty;
-    bool fine;
-    uint32_t ARR;
-    uint32_t CCR;
-    int pos;
-} LfRfidTuneViewModel;
-
-static void lfrfid_debug_view_tune_draw_callback(Canvas* canvas, void* _model) {
-    LfRfidTuneViewModel* model = _model;
-    canvas_set_color(canvas, ColorBlack);
-
-    if(model->fine) {
-        canvas_draw_box(
-            canvas,
-            128 - canvas_string_width(canvas, "Fine") - 4,
-            0,
-            canvas_string_width(canvas, "Fine") + 4,
-            canvas_current_font_height(canvas) + 1);
-        canvas_set_color(canvas, ColorWhite);
-    }
-    canvas_draw_str_aligned(canvas, 128 - 2, 2, AlignRight, AlignTop, "Fine");
-    canvas_set_color(canvas, ColorBlack);
-
-    char buffer[TEMP_STR_LEN + 1];
-    double freq = ((float)SystemCoreClock / ((float)model->ARR + 1));
-    double duty = ((float)model->CCR + 1) / ((float)model->ARR + 1) * 100.0f;
-    snprintf(
-        buffer,
-        TEMP_STR_LEN,
-        "%sARR: %lu\n"
-        "freq = %.4f\n"
-        "%sCCR: %lu\n"
-        "duty = %.4f",
-        model->pos == 0 ? ">" : "",
-        model->ARR,
-        freq,
-        model->pos == 1 ? ">" : "",
-        model->CCR,
-        duty);
-    elements_multiline_text_aligned(canvas, 2, 2, AlignLeft, AlignTop, buffer);
-}
-
-static void lfrfid_debug_view_tune_button_up(LfRfidTuneView* tune_view) {
-    with_view_model(
-        tune_view->view,
-        LfRfidTuneViewModel * model,
-        {
-            if(model->pos > 0) model->pos--;
-        },
-        true);
-}
-
-static void lfrfid_debug_view_tune_button_down(LfRfidTuneView* tune_view) {
-    with_view_model(
-        tune_view->view,
-        LfRfidTuneViewModel * model,
-        {
-            if(model->pos < 1) model->pos++;
-        },
-        true);
-}
-
-static void lfrfid_debug_view_tune_button_left(LfRfidTuneView* tune_view) {
-    with_view_model(
-        tune_view->view,
-        LfRfidTuneViewModel * model,
-        {
-            if(model->pos == 0) {
-                if(model->fine) {
-                    model->ARR -= 1;
-                } else {
-                    model->ARR -= 10;
-                }
-            } else if(model->pos == 1) {
-                if(model->fine) {
-                    model->CCR -= 1;
-                } else {
-                    model->CCR -= 10;
-                }
-            }
-
-            model->dirty = true;
-        },
-        true);
-}
-
-static void lfrfid_debug_view_tune_button_right(LfRfidTuneView* tune_view) {
-    with_view_model(
-        tune_view->view,
-        LfRfidTuneViewModel * model,
-        {
-            if(model->pos == 0) {
-                if(model->fine) {
-                    model->ARR += 1;
-                } else {
-                    model->ARR += 10;
-                }
-            } else if(model->pos == 1) {
-                if(model->fine) {
-                    model->CCR += 1;
-                } else {
-                    model->CCR += 10;
-                }
-            }
-
-            model->dirty = true;
-        },
-        true);
-}
-
-static void lfrfid_debug_view_tune_button_ok(LfRfidTuneView* tune_view) {
-    with_view_model(
-        tune_view->view, LfRfidTuneViewModel * model, { model->fine = !model->fine; }, true);
-}
-
-static bool lfrfid_debug_view_tune_input_callback(InputEvent* event, void* context) {
-    LfRfidTuneView* tune_view = context;
-    bool consumed = false;
-
-    // Process key presses only
-    if(event->type == InputTypeShort || event->type == InputTypeRepeat) {
-        consumed = true;
-
-        switch(event->key) {
-        case InputKeyLeft:
-            lfrfid_debug_view_tune_button_left(tune_view);
-            break;
-        case InputKeyRight:
-            lfrfid_debug_view_tune_button_right(tune_view);
-            break;
-        case InputKeyUp:
-            lfrfid_debug_view_tune_button_up(tune_view);
-            break;
-        case InputKeyDown:
-            lfrfid_debug_view_tune_button_down(tune_view);
-            break;
-        case InputKeyOk:
-            lfrfid_debug_view_tune_button_ok(tune_view);
-            break;
-        default:
-            consumed = false;
-            break;
-        }
-    }
-
-    return consumed;
-}
-
-LfRfidTuneView* lfrfid_debug_view_tune_alloc() {
-    LfRfidTuneView* tune_view = malloc(sizeof(LfRfidTuneView));
-    tune_view->view = view_alloc();
-    view_set_context(tune_view->view, tune_view);
-    view_allocate_model(tune_view->view, ViewModelTypeLocking, sizeof(LfRfidTuneViewModel));
-
-    with_view_model(
-        tune_view->view,
-        LfRfidTuneViewModel * model,
-        {
-            model->dirty = true;
-            model->fine = false;
-            model->ARR = 511;
-            model->CCR = 255;
-            model->pos = 0;
-        },
-        true);
-
-    view_set_draw_callback(tune_view->view, lfrfid_debug_view_tune_draw_callback);
-    view_set_input_callback(tune_view->view, lfrfid_debug_view_tune_input_callback);
-
-    return tune_view;
-}
-
-void lfrfid_debug_view_tune_free(LfRfidTuneView* tune_view) {
-    view_free(tune_view->view);
-    free(tune_view);
-}
-
-View* lfrfid_debug_view_tune_get_view(LfRfidTuneView* tune_view) {
-    return tune_view->view;
-}
-
-void lfrfid_debug_view_tune_clean(LfRfidTuneView* tune_view) {
-    with_view_model(
-        tune_view->view,
-        LfRfidTuneViewModel * model,
-        {
-            model->dirty = true;
-            model->fine = false;
-            model->ARR = 511;
-            model->CCR = 255;
-            model->pos = 0;
-        },
-        true);
-}
-
-bool lfrfid_debug_view_tune_is_dirty(LfRfidTuneView* tune_view) {
-    bool result = false;
-    with_view_model(
-        tune_view->view,
-        LfRfidTuneViewModel * model,
-        {
-            result = model->dirty;
-            model->dirty = false;
-        },
-        false);
-
-    return result;
-}
-
-uint32_t lfrfid_debug_view_tune_get_arr(LfRfidTuneView* tune_view) {
-    uint32_t result = false;
-    with_view_model(
-        tune_view->view, LfRfidTuneViewModel * model, { result = model->ARR; }, false);
-
-    return result;
-}
-
-uint32_t lfrfid_debug_view_tune_get_ccr(LfRfidTuneView* tune_view) {
-    uint32_t result = false;
-    with_view_model(
-        tune_view->view, LfRfidTuneViewModel * model, { result = model->CCR; }, false);
-
-    return result;
-}

+ 0 - 18
applications/debug/lfrfid_debug/views/lfrfid_debug_view_tune.h

@@ -1,18 +0,0 @@
-#pragma once
-#include <gui/view.h>
-
-typedef struct LfRfidTuneView LfRfidTuneView;
-
-LfRfidTuneView* lfrfid_debug_view_tune_alloc();
-
-void lfrfid_debug_view_tune_free(LfRfidTuneView* tune_view);
-
-View* lfrfid_debug_view_tune_get_view(LfRfidTuneView* tune_view);
-
-void lfrfid_debug_view_tune_clean(LfRfidTuneView* tune_view);
-
-bool lfrfid_debug_view_tune_is_dirty(LfRfidTuneView* tune_view);
-
-uint32_t lfrfid_debug_view_tune_get_arr(LfRfidTuneView* tune_view);
-
-uint32_t lfrfid_debug_view_tune_get_ccr(LfRfidTuneView* tune_view);

+ 0 - 11
applications/debug/locale_test/application.fam

@@ -1,11 +0,0 @@
-App(
-    appid="locale_test",
-    name="Locale Test",
-    apptype=FlipperAppType.DEBUG,
-    entry_point="locale_test_app",
-    cdefines=["APP_LOCALE"],
-    requires=["gui", "locale"],
-    stack_size=2 * 1024,
-    order=70,
-    fap_category="Debug",
-)

+ 0 - 102
applications/debug/locale_test/locale_test.c

@@ -1,102 +0,0 @@
-#include <furi.h>
-#include <gui/gui.h>
-#include <gui/elements.h>
-#include <gui/view_dispatcher.h>
-#include <gui/modules/dialog_ex.h>
-#include <locale/locale.h>
-
-typedef struct {
-    Gui* gui;
-    ViewDispatcher* view_dispatcher;
-    View* view;
-} LocaleTestApp;
-
-static void locale_test_view_draw_callback(Canvas* canvas, void* _model) {
-    UNUSED(_model);
-
-    // Prepare canvas
-    canvas_set_color(canvas, ColorBlack);
-    canvas_set_font(canvas, FontSecondary);
-
-    FuriString* tmp_string = furi_string_alloc();
-
-    float temp = 25.3f;
-    LocaleMeasurementUnits units = locale_get_measurement_unit();
-    if(units == LocaleMeasurementUnitsMetric) {
-        furi_string_printf(tmp_string, "Temp: %5.1fC", (double)temp);
-    } else {
-        temp = locale_celsius_to_fahrenheit(temp);
-        furi_string_printf(tmp_string, "Temp: %5.1fF", (double)temp);
-    }
-    canvas_draw_str(canvas, 0, 10, furi_string_get_cstr(tmp_string));
-
-    FuriHalRtcDateTime datetime;
-    furi_hal_rtc_get_datetime(&datetime);
-
-    locale_format_time(tmp_string, &datetime, locale_get_time_format(), false);
-    canvas_draw_str(canvas, 0, 25, furi_string_get_cstr(tmp_string));
-
-    locale_format_date(tmp_string, &datetime, locale_get_date_format(), "/");
-    canvas_draw_str(canvas, 0, 40, furi_string_get_cstr(tmp_string));
-
-    furi_string_free(tmp_string);
-}
-
-static bool locale_test_view_input_callback(InputEvent* event, void* context) {
-    UNUSED(event);
-    UNUSED(context);
-    return false;
-}
-
-static uint32_t locale_test_exit(void* context) {
-    UNUSED(context);
-    return VIEW_NONE;
-}
-
-static LocaleTestApp* locale_test_alloc() {
-    LocaleTestApp* app = malloc(sizeof(LocaleTestApp));
-
-    // Gui
-    app->gui = furi_record_open(RECORD_GUI);
-
-    // View dispatcher
-    app->view_dispatcher = view_dispatcher_alloc();
-    view_dispatcher_enable_queue(app->view_dispatcher);
-    view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen);
-
-    // Views
-    app->view = view_alloc();
-    view_set_draw_callback(app->view, locale_test_view_draw_callback);
-    view_set_input_callback(app->view, locale_test_view_input_callback);
-
-    view_set_previous_callback(app->view, locale_test_exit);
-    view_dispatcher_add_view(app->view_dispatcher, 0, app->view);
-    view_dispatcher_switch_to_view(app->view_dispatcher, 0);
-
-    return app;
-}
-
-static void locale_test_free(LocaleTestApp* app) {
-    furi_assert(app);
-
-    // Free views
-    view_dispatcher_remove_view(app->view_dispatcher, 0);
-
-    view_free(app->view);
-    view_dispatcher_free(app->view_dispatcher);
-
-    // Close gui record
-    furi_record_close(RECORD_GUI);
-    app->gui = NULL;
-
-    // Free rest
-    free(app);
-}
-
-int32_t locale_test_app(void* p) {
-    UNUSED(p);
-    LocaleTestApp* app = locale_test_alloc();
-    view_dispatcher_run(app->view_dispatcher);
-    locale_test_free(app);
-    return 0;
-}

+ 0 - 10
applications/debug/rpc_debug_app/application.fam

@@ -1,10 +0,0 @@
-App(
-    appid="rpc_debug",
-    name="RPC Debug",
-    apptype=FlipperAppType.DEBUG,
-    entry_point="rpc_debug_app",
-    requires=["gui", "rpc_start", "notification"],
-    stack_size=2 * 1024,
-    order=10,
-    fap_category="Debug",
-)

+ 0 - 138
applications/debug/rpc_debug_app/rpc_debug_app.c

@@ -1,138 +0,0 @@
-#include "rpc_debug_app.h"
-#include <core/log.h>
-
-#include <string.h>
-
-static bool rpc_debug_app_custom_event_callback(void* context, uint32_t event) {
-    furi_assert(context);
-    RpcDebugApp* app = context;
-    return scene_manager_handle_custom_event(app->scene_manager, event);
-}
-
-static bool rpc_debug_app_back_event_callback(void* context) {
-    furi_assert(context);
-    RpcDebugApp* app = context;
-    return scene_manager_handle_back_event(app->scene_manager);
-}
-
-static void rpc_debug_app_tick_event_callback(void* context) {
-    furi_assert(context);
-    RpcDebugApp* app = context;
-    scene_manager_handle_tick_event(app->scene_manager);
-}
-
-static void rpc_debug_app_rpc_command_callback(RpcAppSystemEvent event, void* context) {
-    furi_assert(context);
-    RpcDebugApp* app = context;
-    furi_assert(app->rpc);
-
-    if(event == RpcAppEventSessionClose) {
-        scene_manager_stop(app->scene_manager);
-        view_dispatcher_stop(app->view_dispatcher);
-        rpc_system_app_set_callback(app->rpc, NULL, NULL);
-        app->rpc = NULL;
-    } else if(event == RpcAppEventAppExit) {
-        scene_manager_stop(app->scene_manager);
-        view_dispatcher_stop(app->view_dispatcher);
-        rpc_system_app_confirm(app->rpc, RpcAppEventAppExit, true);
-    } else {
-        rpc_system_app_confirm(app->rpc, event, false);
-    }
-}
-
-static bool rpc_debug_app_rpc_init_rpc(RpcDebugApp* app, const char* args) {
-    bool ret = false;
-    if(args && strlen(args)) {
-        uint32_t rpc = 0;
-        if(sscanf(args, "RPC %lX", &rpc) == 1) {
-            app->rpc = (RpcAppSystem*)rpc;
-            rpc_system_app_set_callback(app->rpc, rpc_debug_app_rpc_command_callback, app);
-            rpc_system_app_send_started(app->rpc);
-            ret = true;
-        }
-    }
-    return ret;
-}
-
-static RpcDebugApp* rpc_debug_app_alloc() {
-    RpcDebugApp* app = malloc(sizeof(RpcDebugApp));
-
-    app->gui = furi_record_open(RECORD_GUI);
-    app->notifications = furi_record_open(RECORD_NOTIFICATION);
-    app->scene_manager = scene_manager_alloc(&rpc_debug_app_scene_handlers, app);
-    app->view_dispatcher = view_dispatcher_alloc();
-
-    view_dispatcher_set_event_callback_context(app->view_dispatcher, app);
-    view_dispatcher_set_custom_event_callback(
-        app->view_dispatcher, rpc_debug_app_custom_event_callback);
-    view_dispatcher_set_navigation_event_callback(
-        app->view_dispatcher, rpc_debug_app_back_event_callback);
-    view_dispatcher_set_tick_event_callback(
-        app->view_dispatcher, rpc_debug_app_tick_event_callback, 100);
-    view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen);
-    view_dispatcher_enable_queue(app->view_dispatcher);
-
-    app->widget = widget_alloc();
-    view_dispatcher_add_view(
-        app->view_dispatcher, RpcDebugAppViewWidget, widget_get_view(app->widget));
-    app->submenu = submenu_alloc();
-    view_dispatcher_add_view(
-        app->view_dispatcher, RpcDebugAppViewSubmenu, submenu_get_view(app->submenu));
-    app->text_box = text_box_alloc();
-    view_dispatcher_add_view(
-        app->view_dispatcher, RpcDebugAppViewTextBox, text_box_get_view(app->text_box));
-    app->text_input = text_input_alloc();
-    view_dispatcher_add_view(
-        app->view_dispatcher, RpcDebugAppViewTextInput, text_input_get_view(app->text_input));
-    app->byte_input = byte_input_alloc();
-    view_dispatcher_add_view(
-        app->view_dispatcher, RpcDebugAppViewByteInput, byte_input_get_view(app->byte_input));
-
-    return app;
-}
-
-static void rpc_debug_app_free(RpcDebugApp* app) {
-    view_dispatcher_remove_view(app->view_dispatcher, RpcDebugAppViewByteInput);
-    view_dispatcher_remove_view(app->view_dispatcher, RpcDebugAppViewTextInput);
-    view_dispatcher_remove_view(app->view_dispatcher, RpcDebugAppViewTextBox);
-    view_dispatcher_remove_view(app->view_dispatcher, RpcDebugAppViewSubmenu);
-    view_dispatcher_remove_view(app->view_dispatcher, RpcDebugAppViewWidget);
-
-    free(app->byte_input);
-    free(app->text_input);
-    free(app->text_box);
-    free(app->submenu);
-    free(app->widget);
-
-    free(app->scene_manager);
-    free(app->view_dispatcher);
-
-    furi_record_close(RECORD_NOTIFICATION);
-    app->notifications = NULL;
-    furi_record_close(RECORD_GUI);
-    app->gui = NULL;
-
-    if(app->rpc) {
-        rpc_system_app_set_callback(app->rpc, NULL, NULL);
-        rpc_system_app_send_exited(app->rpc);
-        app->rpc = NULL;
-    }
-
-    free(app);
-}
-
-int32_t rpc_debug_app(void* args) {
-    RpcDebugApp* app = rpc_debug_app_alloc();
-
-    if(rpc_debug_app_rpc_init_rpc(app, args)) {
-        notification_message(app->notifications, &sequence_display_backlight_on);
-        scene_manager_next_scene(app->scene_manager, RpcDebugAppSceneStart);
-    } else {
-        scene_manager_next_scene(app->scene_manager, RpcDebugAppSceneStartDummy);
-    }
-
-    view_dispatcher_run(app->view_dispatcher);
-
-    rpc_debug_app_free(app);
-    return 0;
-}

+ 0 - 54
applications/debug/rpc_debug_app/rpc_debug_app.h

@@ -1,54 +0,0 @@
-#pragma once
-
-#include <furi.h>
-#include <gui/gui.h>
-#include <gui/view.h>
-#include <gui/scene_manager.h>
-#include <gui/view_dispatcher.h>
-
-#include <gui/modules/widget.h>
-#include <gui/modules/submenu.h>
-#include <gui/modules/text_box.h>
-#include <gui/modules/text_input.h>
-#include <gui/modules/byte_input.h>
-
-#include <rpc/rpc_app.h>
-#include <notification/notification_messages.h>
-
-#include "scenes/rpc_debug_app_scene.h"
-
-#define DATA_STORE_SIZE 64U
-#define TEXT_STORE_SIZE 64U
-
-typedef struct {
-    Gui* gui;
-    RpcAppSystem* rpc;
-    SceneManager* scene_manager;
-    ViewDispatcher* view_dispatcher;
-    NotificationApp* notifications;
-
-    Widget* widget;
-    Submenu* submenu;
-    TextBox* text_box;
-    TextInput* text_input;
-    ByteInput* byte_input;
-
-    char text_store[TEXT_STORE_SIZE];
-    uint8_t data_store[DATA_STORE_SIZE];
-} RpcDebugApp;
-
-typedef enum {
-    RpcDebugAppViewWidget,
-    RpcDebugAppViewSubmenu,
-    RpcDebugAppViewTextBox,
-    RpcDebugAppViewTextInput,
-    RpcDebugAppViewByteInput,
-} RpcDebugAppView;
-
-typedef enum {
-    // Reserve first 100 events for button types and indexes, starting from 0
-    RpcDebugAppCustomEventInputErrorCode = 100,
-    RpcDebugAppCustomEventInputErrorText,
-    RpcDebugAppCustomEventInputDataExchange,
-    RpcDebugAppCustomEventRpcDataExchange,
-} RpcDebugAppCustomEvent;

+ 0 - 30
applications/debug/rpc_debug_app/scenes/rpc_debug_app_scene.c

@@ -1,30 +0,0 @@
-#include "rpc_debug_app_scene.h"
-
-// Generate scene on_enter handlers array
-#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_enter,
-void (*const rpc_debug_app_on_enter_handlers[])(void*) = {
-#include "rpc_debug_app_scene_config.h"
-};
-#undef ADD_SCENE
-
-// Generate scene on_event handlers array
-#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_event,
-bool (*const rpc_debug_app_on_event_handlers[])(void* context, SceneManagerEvent event) = {
-#include "rpc_debug_app_scene_config.h"
-};
-#undef ADD_SCENE
-
-// Generate scene on_exit handlers array
-#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_exit,
-void (*const rpc_debug_app_on_exit_handlers[])(void* context) = {
-#include "rpc_debug_app_scene_config.h"
-};
-#undef ADD_SCENE
-
-// Initialize scene handlers configuration structure
-const SceneManagerHandlers rpc_debug_app_scene_handlers = {
-    .on_enter_handlers = rpc_debug_app_on_enter_handlers,
-    .on_event_handlers = rpc_debug_app_on_event_handlers,
-    .on_exit_handlers = rpc_debug_app_on_exit_handlers,
-    .scene_num = RpcDebugAppSceneNum,
-};

+ 0 - 29
applications/debug/rpc_debug_app/scenes/rpc_debug_app_scene.h

@@ -1,29 +0,0 @@
-#pragma once
-
-#include <gui/scene_manager.h>
-
-// Generate scene id and total number
-#define ADD_SCENE(prefix, name, id) RpcDebugAppScene##id,
-typedef enum {
-#include "rpc_debug_app_scene_config.h"
-    RpcDebugAppSceneNum,
-} RpcDebugAppScene;
-#undef ADD_SCENE
-
-extern const SceneManagerHandlers rpc_debug_app_scene_handlers;
-
-// Generate scene on_enter handlers declaration
-#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_enter(void*);
-#include "rpc_debug_app_scene_config.h"
-#undef ADD_SCENE
-
-// Generate scene on_event handlers declaration
-#define ADD_SCENE(prefix, name, id) \
-    bool prefix##_scene_##name##_on_event(void* context, SceneManagerEvent event);
-#include "rpc_debug_app_scene_config.h"
-#undef ADD_SCENE
-
-// Generate scene on_exit handlers declaration
-#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_exit(void* context);
-#include "rpc_debug_app_scene_config.h"
-#undef ADD_SCENE

+ 0 - 8
applications/debug/rpc_debug_app/scenes/rpc_debug_app_scene_config.h

@@ -1,8 +0,0 @@
-ADD_SCENE(rpc_debug_app, start, Start)
-ADD_SCENE(rpc_debug_app, start_dummy, StartDummy)
-ADD_SCENE(rpc_debug_app, test_app_error, TestAppError)
-ADD_SCENE(rpc_debug_app, test_data_exchange, TestDataExchange)
-ADD_SCENE(rpc_debug_app, input_error_code, InputErrorCode)
-ADD_SCENE(rpc_debug_app, input_error_text, InputErrorText)
-ADD_SCENE(rpc_debug_app, input_data_exchange, InputDataExchange)
-ADD_SCENE(rpc_debug_app, receive_data_exchange, ReceiveDataExchange)

+ 0 - 40
applications/debug/rpc_debug_app/scenes/rpc_debug_app_scene_input_data_exchange.c

@@ -1,40 +0,0 @@
-#include "../rpc_debug_app.h"
-
-static void rpc_debug_app_scene_input_data_exchange_result_callback(void* context) {
-    RpcDebugApp* app = context;
-    view_dispatcher_send_custom_event(
-        app->view_dispatcher, RpcDebugAppCustomEventInputDataExchange);
-}
-
-void rpc_debug_app_scene_input_data_exchange_on_enter(void* context) {
-    RpcDebugApp* app = context;
-    byte_input_set_header_text(app->byte_input, "Enter data to exchange");
-    byte_input_set_result_callback(
-        app->byte_input,
-        rpc_debug_app_scene_input_data_exchange_result_callback,
-        NULL,
-        app,
-        app->data_store,
-        DATA_STORE_SIZE);
-    view_dispatcher_switch_to_view(app->view_dispatcher, RpcDebugAppViewByteInput);
-}
-
-bool rpc_debug_app_scene_input_data_exchange_on_event(void* context, SceneManagerEvent event) {
-    RpcDebugApp* app = context;
-    bool consumed = false;
-
-    if(event.type == SceneManagerEventTypeCustom) {
-        if(event.event == RpcDebugAppCustomEventInputDataExchange) {
-            rpc_system_app_exchange_data(app->rpc, app->data_store, DATA_STORE_SIZE);
-            scene_manager_previous_scene(app->scene_manager);
-            consumed = true;
-        }
-    }
-
-    return consumed;
-}
-
-void rpc_debug_app_scene_input_data_exchange_on_exit(void* context) {
-    RpcDebugApp* app = context;
-    UNUSED(app);
-}

+ 0 - 64
applications/debug/rpc_debug_app/scenes/rpc_debug_app_scene_input_error_code.c

@@ -1,64 +0,0 @@
-#include "../rpc_debug_app.h"
-
-static bool rpc_debug_app_scene_input_error_code_validator_callback(
-    const char* text,
-    FuriString* error,
-    void* context) {
-    UNUSED(context);
-
-    for(; *text; ++text) {
-        const char c = *text;
-        if(c < '0' || c > '9') {
-            furi_string_printf(error, "%s", "Please enter\na number!");
-            return false;
-        }
-    }
-
-    return true;
-}
-
-static void rpc_debug_app_scene_input_error_code_result_callback(void* context) {
-    RpcDebugApp* app = context;
-    view_dispatcher_send_custom_event(app->view_dispatcher, RpcDebugAppCustomEventInputErrorCode);
-}
-
-void rpc_debug_app_scene_input_error_code_on_enter(void* context) {
-    RpcDebugApp* app = context;
-    strncpy(app->text_store, "666", TEXT_STORE_SIZE);
-    text_input_set_header_text(app->text_input, "Enter error code");
-    text_input_set_validator(
-        app->text_input, rpc_debug_app_scene_input_error_code_validator_callback, NULL);
-    text_input_set_result_callback(
-        app->text_input,
-        rpc_debug_app_scene_input_error_code_result_callback,
-        app,
-        app->text_store,
-        TEXT_STORE_SIZE,
-        true);
-    view_dispatcher_switch_to_view(app->view_dispatcher, RpcDebugAppViewTextInput);
-}
-
-bool rpc_debug_app_scene_input_error_code_on_event(void* context, SceneManagerEvent event) {
-    RpcDebugApp* app = context;
-    bool consumed = false;
-
-    if(event.type == SceneManagerEventTypeCustom) {
-        if(event.event == RpcDebugAppCustomEventInputErrorCode) {
-            char* end;
-            int error_code = strtol(app->text_store, &end, 10);
-            if(!*end) {
-                rpc_system_app_set_error_code(app->rpc, error_code);
-            }
-            scene_manager_previous_scene(app->scene_manager);
-            consumed = true;
-        }
-    }
-
-    return consumed;
-}
-
-void rpc_debug_app_scene_input_error_code_on_exit(void* context) {
-    RpcDebugApp* app = context;
-    text_input_reset(app->text_input);
-    text_input_set_validator(app->text_input, NULL, NULL);
-}

+ 0 - 40
applications/debug/rpc_debug_app/scenes/rpc_debug_app_scene_input_error_text.c

@@ -1,40 +0,0 @@
-#include "../rpc_debug_app.h"
-
-static void rpc_debug_app_scene_input_error_text_result_callback(void* context) {
-    RpcDebugApp* app = context;
-    view_dispatcher_send_custom_event(app->view_dispatcher, RpcDebugAppCustomEventInputErrorText);
-}
-
-void rpc_debug_app_scene_input_error_text_on_enter(void* context) {
-    RpcDebugApp* app = context;
-    strncpy(app->text_store, "I'm a scary error message!", TEXT_STORE_SIZE);
-    text_input_set_header_text(app->text_input, "Enter error text");
-    text_input_set_result_callback(
-        app->text_input,
-        rpc_debug_app_scene_input_error_text_result_callback,
-        app,
-        app->text_store,
-        TEXT_STORE_SIZE,
-        true);
-    view_dispatcher_switch_to_view(app->view_dispatcher, RpcDebugAppViewTextInput);
-}
-
-bool rpc_debug_app_scene_input_error_text_on_event(void* context, SceneManagerEvent event) {
-    RpcDebugApp* app = context;
-    bool consumed = false;
-
-    if(event.type == SceneManagerEventTypeCustom) {
-        if(event.event == RpcDebugAppCustomEventInputErrorText) {
-            rpc_system_app_set_error_text(app->rpc, app->text_store);
-            scene_manager_previous_scene(app->scene_manager);
-            consumed = true;
-        }
-    }
-
-    return consumed;
-}
-
-void rpc_debug_app_scene_input_error_text_on_exit(void* context) {
-    RpcDebugApp* app = context;
-    text_input_reset(app->text_input);
-}

+ 0 - 70
applications/debug/rpc_debug_app/scenes/rpc_debug_app_scene_receive_data_exchange.c

@@ -1,70 +0,0 @@
-#include "../rpc_debug_app.h"
-
-static void rpc_debug_app_scene_start_format_hex(
-    const uint8_t* data,
-    size_t data_size,
-    char* buf,
-    size_t buf_size) {
-    furi_assert(data);
-    furi_assert(buf);
-
-    const size_t byte_width = 3;
-    const size_t line_width = 7;
-
-    data_size = MIN(data_size, buf_size / (byte_width + 1));
-
-    for(size_t i = 0; i < data_size; ++i) {
-        char* p = buf + (i * byte_width);
-        char sep = !((i + 1) % line_width) ? '\n' : ' ';
-        snprintf(p, byte_width + 1, "%02X%c", data[i], sep);
-    }
-
-    buf[buf_size - 1] = '\0';
-}
-
-static void rpc_debug_app_scene_receive_data_exchange_callback(
-    const uint8_t* data,
-    size_t data_size,
-    void* context) {
-    RpcDebugApp* app = context;
-    if(data) {
-        rpc_debug_app_scene_start_format_hex(data, data_size, app->text_store, TEXT_STORE_SIZE);
-    } else {
-        strncpy(app->text_store, "<Data empty>", TEXT_STORE_SIZE);
-    }
-    view_dispatcher_send_custom_event(app->view_dispatcher, RpcDebugAppCustomEventRpcDataExchange);
-}
-
-void rpc_debug_app_scene_receive_data_exchange_on_enter(void* context) {
-    RpcDebugApp* app = context;
-    strncpy(app->text_store, "Received data will appear here...", TEXT_STORE_SIZE);
-
-    text_box_set_text(app->text_box, app->text_store);
-    text_box_set_font(app->text_box, TextBoxFontHex);
-
-    rpc_system_app_set_data_exchange_callback(
-        app->rpc, rpc_debug_app_scene_receive_data_exchange_callback, app);
-    view_dispatcher_switch_to_view(app->view_dispatcher, RpcDebugAppViewTextBox);
-}
-
-bool rpc_debug_app_scene_receive_data_exchange_on_event(void* context, SceneManagerEvent event) {
-    RpcDebugApp* app = context;
-    bool consumed = false;
-
-    if(event.type == SceneManagerEventTypeCustom) {
-        if(event.event == RpcDebugAppCustomEventRpcDataExchange) {
-            notification_message(app->notifications, &sequence_blink_cyan_100);
-            notification_message(app->notifications, &sequence_display_backlight_on);
-            text_box_set_text(app->text_box, app->text_store);
-            consumed = true;
-        }
-    }
-
-    return consumed;
-}
-
-void rpc_debug_app_scene_receive_data_exchange_on_exit(void* context) {
-    RpcDebugApp* app = context;
-    text_box_reset(app->text_box);
-    rpc_system_app_set_data_exchange_callback(app->rpc, NULL, NULL);
-}

+ 0 - 57
applications/debug/rpc_debug_app/scenes/rpc_debug_app_scene_start.c

@@ -1,57 +0,0 @@
-#include "../rpc_debug_app.h"
-
-enum SubmenuIndex {
-    SubmenuIndexTestAppError,
-    SubmenuIndexTestDataExchange,
-};
-
-static void rpc_debug_app_scene_start_submenu_callback(void* context, uint32_t index) {
-    RpcDebugApp* app = context;
-    view_dispatcher_send_custom_event(app->view_dispatcher, index);
-}
-
-void rpc_debug_app_scene_start_on_enter(void* context) {
-    RpcDebugApp* app = context;
-    Submenu* submenu = app->submenu;
-
-    submenu_add_item(
-        submenu,
-        "Test App Error",
-        SubmenuIndexTestAppError,
-        rpc_debug_app_scene_start_submenu_callback,
-        app);
-    submenu_add_item(
-        submenu,
-        "Test Data Exchange",
-        SubmenuIndexTestDataExchange,
-        rpc_debug_app_scene_start_submenu_callback,
-        app);
-
-    submenu_set_selected_item(submenu, SubmenuIndexTestAppError);
-    view_dispatcher_switch_to_view(app->view_dispatcher, RpcDebugAppViewSubmenu);
-}
-
-bool rpc_debug_app_scene_start_on_event(void* context, SceneManagerEvent event) {
-    RpcDebugApp* app = context;
-    SceneManager* scene_manager = app->scene_manager;
-
-    bool consumed = false;
-
-    if(event.type == SceneManagerEventTypeCustom) {
-        const uint32_t submenu_index = event.event;
-        if(submenu_index == SubmenuIndexTestAppError) {
-            scene_manager_next_scene(scene_manager, RpcDebugAppSceneTestAppError);
-            consumed = true;
-        } else if(submenu_index == SubmenuIndexTestDataExchange) {
-            scene_manager_next_scene(scene_manager, RpcDebugAppSceneTestDataExchange);
-            consumed = true;
-        }
-    }
-
-    return consumed;
-}
-
-void rpc_debug_app_scene_start_on_exit(void* context) {
-    RpcDebugApp* app = context;
-    submenu_reset(app->submenu);
-}

+ 0 - 30
applications/debug/rpc_debug_app/scenes/rpc_debug_app_scene_start_dummy.c

@@ -1,30 +0,0 @@
-#include "../rpc_debug_app.h"
-
-void rpc_debug_app_scene_start_dummy_on_enter(void* context) {
-    RpcDebugApp* app = context;
-    widget_add_text_box_element(
-        app->widget,
-        0,
-        0,
-        128,
-        64,
-        AlignCenter,
-        AlignCenter,
-        "This application\nis meant to be run\nin \e#RPC\e# mode.",
-        false);
-    view_dispatcher_switch_to_view(app->view_dispatcher, RpcDebugAppViewWidget);
-}
-
-bool rpc_debug_app_scene_start_dummy_on_event(void* context, SceneManagerEvent event) {
-    RpcDebugApp* app = context;
-    UNUSED(app);
-    UNUSED(event);
-
-    bool consumed = false;
-    return consumed;
-}
-
-void rpc_debug_app_scene_start_dummy_on_exit(void* context) {
-    RpcDebugApp* app = context;
-    widget_reset(app->widget);
-}

+ 0 - 57
applications/debug/rpc_debug_app/scenes/rpc_debug_app_scene_test_app_error.c

@@ -1,57 +0,0 @@
-#include "../rpc_debug_app.h"
-
-typedef enum {
-    SubmenuIndexSetErrorCode,
-    SubmenuIndexSetErrorText,
-} SubmenuIndex;
-
-static void rpc_debug_app_scene_test_app_error_submenu_callback(void* context, uint32_t index) {
-    RpcDebugApp* app = context;
-    view_dispatcher_send_custom_event(app->view_dispatcher, index);
-}
-
-void rpc_debug_app_scene_test_app_error_on_enter(void* context) {
-    RpcDebugApp* app = context;
-    Submenu* submenu = app->submenu;
-
-    submenu_add_item(
-        submenu,
-        "Set Error Code",
-        SubmenuIndexSetErrorCode,
-        rpc_debug_app_scene_test_app_error_submenu_callback,
-        app);
-    submenu_add_item(
-        submenu,
-        "Set Error Text",
-        SubmenuIndexSetErrorText,
-        rpc_debug_app_scene_test_app_error_submenu_callback,
-        app);
-
-    submenu_set_selected_item(submenu, SubmenuIndexSetErrorCode);
-    view_dispatcher_switch_to_view(app->view_dispatcher, RpcDebugAppViewSubmenu);
-}
-
-bool rpc_debug_app_scene_test_app_error_on_event(void* context, SceneManagerEvent event) {
-    RpcDebugApp* app = context;
-    SceneManager* scene_manager = app->scene_manager;
-
-    bool consumed = false;
-
-    if(event.type == SceneManagerEventTypeCustom) {
-        const uint32_t submenu_index = event.event;
-        if(submenu_index == SubmenuIndexSetErrorCode) {
-            scene_manager_next_scene(scene_manager, RpcDebugAppSceneInputErrorCode);
-            consumed = true;
-        } else if(submenu_index == SubmenuIndexSetErrorText) {
-            scene_manager_next_scene(scene_manager, RpcDebugAppSceneInputErrorText);
-            consumed = true;
-        }
-    }
-
-    return consumed;
-}
-
-void rpc_debug_app_scene_test_app_error_on_exit(void* context) {
-    RpcDebugApp* app = context;
-    submenu_reset(app->submenu);
-}

+ 0 - 58
applications/debug/rpc_debug_app/scenes/rpc_debug_app_scene_test_data_exchange.c

@@ -1,58 +0,0 @@
-#include "../rpc_debug_app.h"
-
-typedef enum {
-    SubmenuIndexSendData,
-    SubmenuIndexReceiveData,
-} SubmenuIndex;
-
-static void
-    rpc_debug_app_scene_test_data_exchange_submenu_callback(void* context, uint32_t index) {
-    RpcDebugApp* app = context;
-    view_dispatcher_send_custom_event(app->view_dispatcher, index);
-}
-
-void rpc_debug_app_scene_test_data_exchange_on_enter(void* context) {
-    RpcDebugApp* app = context;
-    Submenu* submenu = app->submenu;
-
-    submenu_add_item(
-        submenu,
-        "Send Data",
-        SubmenuIndexSendData,
-        rpc_debug_app_scene_test_data_exchange_submenu_callback,
-        app);
-    submenu_add_item(
-        submenu,
-        "Receive Data",
-        SubmenuIndexReceiveData,
-        rpc_debug_app_scene_test_data_exchange_submenu_callback,
-        app);
-
-    submenu_set_selected_item(submenu, SubmenuIndexSendData);
-    view_dispatcher_switch_to_view(app->view_dispatcher, RpcDebugAppViewSubmenu);
-}
-
-bool rpc_debug_app_scene_test_data_exchange_on_event(void* context, SceneManagerEvent event) {
-    RpcDebugApp* app = context;
-    SceneManager* scene_manager = app->scene_manager;
-
-    bool consumed = false;
-
-    if(event.type == SceneManagerEventTypeCustom) {
-        const uint32_t submenu_index = event.event;
-        if(submenu_index == SubmenuIndexSendData) {
-            scene_manager_next_scene(scene_manager, RpcDebugAppSceneInputDataExchange);
-            consumed = true;
-        } else if(submenu_index == SubmenuIndexReceiveData) {
-            scene_manager_next_scene(scene_manager, RpcDebugAppSceneReceiveDataExchange);
-            consumed = true;
-        }
-    }
-
-    return consumed;
-}
-
-void rpc_debug_app_scene_test_data_exchange_on_exit(void* context) {
-    RpcDebugApp* app = context;
-    submenu_reset(app->submenu);
-}

+ 0 - 11
applications/debug/text_box_test/application.fam

@@ -1,11 +0,0 @@
-App(
-    appid="text_box_test",
-    name="Text Box Test",
-    apptype=FlipperAppType.DEBUG,
-    entry_point="text_box_test_app",
-    cdefines=["APP_TEXT_BOX_TEST"],
-    requires=["gui"],
-    stack_size=1 * 1024,
-    order=140,
-    fap_category="Debug",
-)

+ 0 - 129
applications/debug/text_box_test/text_box_test.c

@@ -1,129 +0,0 @@
-#include <furi.h>
-#include <gui/gui.h>
-#include <input/input.h>
-#include <gui/elements.h>
-
-#define TAG "TextBoxTest"
-
-static void text_box_center_top_secondary_128x22(Canvas* canvas) {
-    canvas_draw_frame(canvas, 0, 0, 128, 22);
-    elements_text_box(canvas, 0, 0, 128, 22, AlignCenter, AlignTop, "secondary font test", false);
-}
-
-static void text_box_right_bottom_bold_128x22(Canvas* canvas) {
-    canvas_draw_frame(canvas, 0, 0, 128, 22);
-    elements_text_box(
-        canvas, 0, 0, 128, 22, AlignRight, AlignBottom, "\e#Bold font test\e#", false);
-}
-
-static void text_box_left_center_mixed_80x50(Canvas* canvas) {
-    canvas_draw_frame(canvas, 0, 0, 80, 50);
-    elements_text_box(
-        canvas,
-        0,
-        0,
-        80,
-        50,
-        AlignLeft,
-        AlignCenter,
-        "\e#Never\e# gonna give you up\n\e!Never\e! gonna let you down",
-        false);
-}
-
-static void text_box_center_center_secondary_110x44(Canvas* canvas) {
-    canvas_draw_frame(canvas, 4, 20, 110, 30);
-    elements_text_box(
-        canvas,
-        4,
-        20,
-        110,
-        30,
-        AlignCenter,
-        AlignCenter,
-        "Loooooooooooooo0000000ooong file name from happy 100500 Flipper 0wners",
-        true);
-}
-
-static void (*text_box_test_render[])(Canvas* canvas) = {
-    text_box_center_top_secondary_128x22,
-    text_box_right_bottom_bold_128x22,
-    text_box_left_center_mixed_80x50,
-    text_box_center_center_secondary_110x44,
-};
-
-typedef struct {
-    uint32_t idx;
-    FuriMutex* mutex;
-} TextBoxTestState;
-
-static void text_box_test_render_callback(Canvas* canvas, void* ctx) {
-    TextBoxTestState* state = ctx;
-    furi_mutex_acquire(state->mutex, FuriWaitForever);
-    canvas_clear(canvas);
-
-    text_box_test_render[state->idx](canvas);
-
-    furi_mutex_release(state->mutex);
-}
-
-static void text_box_test_input_callback(InputEvent* input_event, void* ctx) {
-    FuriMessageQueue* event_queue = ctx;
-    furi_message_queue_put(event_queue, input_event, FuriWaitForever);
-}
-
-int32_t text_box_test_app(void* p) {
-    UNUSED(p);
-    FuriMessageQueue* event_queue = furi_message_queue_alloc(32, sizeof(InputEvent));
-    furi_check(event_queue);
-
-    TextBoxTestState state = {.idx = 0, .mutex = NULL};
-    state.mutex = furi_mutex_alloc(FuriMutexTypeNormal);
-
-    if(!state.mutex) {
-        FURI_LOG_E(TAG, "Cannot create mutex");
-        return 0;
-    }
-
-    ViewPort* view_port = view_port_alloc();
-
-    view_port_draw_callback_set(view_port, text_box_test_render_callback, &state);
-    view_port_input_callback_set(view_port, text_box_test_input_callback, event_queue);
-
-    // Open GUI and register view_port
-    Gui* gui = furi_record_open(RECORD_GUI);
-    gui_add_view_port(gui, view_port, GuiLayerFullscreen);
-
-    uint32_t test_renders_num = COUNT_OF(text_box_test_render);
-    InputEvent event;
-    while(furi_message_queue_get(event_queue, &event, FuriWaitForever) == FuriStatusOk) {
-        furi_mutex_acquire(state.mutex, FuriWaitForever);
-
-        if(event.type == InputTypeShort) {
-            if(event.key == InputKeyRight) {
-                if(state.idx < test_renders_num - 1) {
-                    state.idx++;
-                }
-            } else if(event.key == InputKeyLeft) {
-                if(state.idx > 0) {
-                    state.idx--;
-                }
-            } else if(event.key == InputKeyBack) {
-                furi_mutex_release(state.mutex);
-                break;
-            }
-        }
-
-        furi_mutex_release(state.mutex);
-        view_port_update(view_port);
-    }
-
-    // remove & free all stuff created by app
-    gui_remove_view_port(gui, view_port);
-    view_port_free(view_port);
-    furi_message_queue_free(event_queue);
-    furi_mutex_free(state.mutex);
-
-    furi_record_close(RECORD_GUI);
-
-    return 0;
-}

+ 0 - 11
applications/debug/uart_echo/application.fam

@@ -1,11 +0,0 @@
-App(
-    appid="uart_echo",
-    name="UART Echo",
-    apptype=FlipperAppType.DEBUG,
-    entry_point="uart_echo_app",
-    cdefines=["APP_UART_ECHO"],
-    requires=["gui"],
-    stack_size=2 * 1024,
-    order=70,
-    fap_category="Debug",
-)

+ 0 - 271
applications/debug/uart_echo/uart_echo.c

@@ -1,271 +0,0 @@
-#include <furi.h>
-#include <gui/gui.h>
-#include <notification/notification.h>
-#include <notification/notification_messages.h>
-#include <gui/elements.h>
-#include <furi_hal_uart.h>
-#include <furi_hal_console.h>
-#include <gui/view_dispatcher.h>
-#include <gui/modules/dialog_ex.h>
-
-#define LINES_ON_SCREEN 6
-#define COLUMNS_ON_SCREEN 21
-
-typedef struct UartDumpModel UartDumpModel;
-
-typedef struct {
-    Gui* gui;
-    NotificationApp* notification;
-    ViewDispatcher* view_dispatcher;
-    View* view;
-    FuriThread* worker_thread;
-    FuriStreamBuffer* rx_stream;
-} UartEchoApp;
-
-typedef struct {
-    FuriString* text;
-} ListElement;
-
-struct UartDumpModel {
-    ListElement* list[LINES_ON_SCREEN];
-    uint8_t line;
-
-    char last_char;
-    bool escape;
-};
-
-typedef enum {
-    WorkerEventReserved = (1 << 0), // Reserved for StreamBuffer internal event
-    WorkerEventStop = (1 << 1),
-    WorkerEventRx = (1 << 2),
-} WorkerEventFlags;
-
-#define WORKER_EVENTS_MASK (WorkerEventStop | WorkerEventRx)
-
-const NotificationSequence sequence_notification = {
-    &message_display_backlight_on,
-    &message_green_255,
-    &message_delay_10,
-    NULL,
-};
-
-static void uart_echo_view_draw_callback(Canvas* canvas, void* _model) {
-    UartDumpModel* model = _model;
-
-    // Prepare canvas
-    canvas_clear(canvas);
-    canvas_set_color(canvas, ColorBlack);
-    canvas_set_font(canvas, FontKeyboard);
-
-    for(size_t i = 0; i < LINES_ON_SCREEN; i++) {
-        canvas_draw_str(
-            canvas,
-            0,
-            (i + 1) * (canvas_current_font_height(canvas) - 1),
-            furi_string_get_cstr(model->list[i]->text));
-
-        if(i == model->line) {
-            uint8_t width =
-                canvas_string_width(canvas, furi_string_get_cstr(model->list[i]->text));
-
-            canvas_draw_box(
-                canvas,
-                width,
-                (i) * (canvas_current_font_height(canvas) - 1) + 2,
-                2,
-                canvas_current_font_height(canvas) - 2);
-        }
-    }
-}
-
-static bool uart_echo_view_input_callback(InputEvent* event, void* context) {
-    UNUSED(event);
-    UNUSED(context);
-    return false;
-}
-
-static uint32_t uart_echo_exit(void* context) {
-    UNUSED(context);
-    return VIEW_NONE;
-}
-
-static void uart_echo_on_irq_cb(UartIrqEvent ev, uint8_t data, void* context) {
-    furi_assert(context);
-    UartEchoApp* app = context;
-
-    if(ev == UartIrqEventRXNE) {
-        furi_stream_buffer_send(app->rx_stream, &data, 1, 0);
-        furi_thread_flags_set(furi_thread_get_id(app->worker_thread), WorkerEventRx);
-    }
-}
-
-static void uart_echo_push_to_list(UartDumpModel* model, const char data) {
-    if(model->escape) {
-        // escape code end with letter
-        if((data >= 'a' && data <= 'z') || (data >= 'A' && data <= 'Z')) {
-            model->escape = false;
-        }
-    } else if(data == '[' && model->last_char == '\e') {
-        // "Esc[" is a escape code
-        model->escape = true;
-    } else if((data >= ' ' && data <= '~') || (data == '\n' || data == '\r')) {
-        bool new_string_needed = false;
-        if(furi_string_size(model->list[model->line]->text) >= COLUMNS_ON_SCREEN) {
-            new_string_needed = true;
-        } else if((data == '\n' || data == '\r')) {
-            // pack line breaks
-            if(model->last_char != '\n' && model->last_char != '\r') {
-                new_string_needed = true;
-            }
-        }
-
-        if(new_string_needed) {
-            if((model->line + 1) < LINES_ON_SCREEN) {
-                model->line += 1;
-            } else {
-                ListElement* first = model->list[0];
-
-                for(size_t i = 1; i < LINES_ON_SCREEN; i++) {
-                    model->list[i - 1] = model->list[i];
-                }
-
-                furi_string_reset(first->text);
-                model->list[model->line] = first;
-            }
-        }
-
-        if(data != '\n' && data != '\r') {
-            furi_string_push_back(model->list[model->line]->text, data);
-        }
-    }
-    model->last_char = data;
-}
-
-static int32_t uart_echo_worker(void* context) {
-    furi_assert(context);
-    UartEchoApp* app = context;
-
-    while(1) {
-        uint32_t events =
-            furi_thread_flags_wait(WORKER_EVENTS_MASK, FuriFlagWaitAny, FuriWaitForever);
-        furi_check((events & FuriFlagError) == 0);
-
-        if(events & WorkerEventStop) break;
-        if(events & WorkerEventRx) {
-            size_t length = 0;
-            do {
-                uint8_t data[64];
-                length = furi_stream_buffer_receive(app->rx_stream, data, 64, 0);
-                if(length > 0) {
-                    furi_hal_uart_tx(FuriHalUartIdUSART1, data, length);
-                    with_view_model(
-                        app->view,
-                        UartDumpModel * model,
-                        {
-                            for(size_t i = 0; i < length; i++) {
-                                uart_echo_push_to_list(model, data[i]);
-                            }
-                        },
-                        false);
-                }
-            } while(length > 0);
-
-            notification_message(app->notification, &sequence_notification);
-            with_view_model(
-                app->view, UartDumpModel * model, { UNUSED(model); }, true);
-        }
-    }
-
-    return 0;
-}
-
-static UartEchoApp* uart_echo_app_alloc() {
-    UartEchoApp* app = malloc(sizeof(UartEchoApp));
-
-    app->rx_stream = furi_stream_buffer_alloc(2048, 1);
-
-    // Gui
-    app->gui = furi_record_open(RECORD_GUI);
-    app->notification = furi_record_open(RECORD_NOTIFICATION);
-
-    // View dispatcher
-    app->view_dispatcher = view_dispatcher_alloc();
-    view_dispatcher_enable_queue(app->view_dispatcher);
-    view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen);
-
-    // Views
-    app->view = view_alloc();
-    view_set_draw_callback(app->view, uart_echo_view_draw_callback);
-    view_set_input_callback(app->view, uart_echo_view_input_callback);
-    view_allocate_model(app->view, ViewModelTypeLocking, sizeof(UartDumpModel));
-    with_view_model(
-        app->view,
-        UartDumpModel * model,
-        {
-            for(size_t i = 0; i < LINES_ON_SCREEN; i++) {
-                model->line = 0;
-                model->escape = false;
-                model->list[i] = malloc(sizeof(ListElement));
-                model->list[i]->text = furi_string_alloc();
-            }
-        },
-        true);
-
-    view_set_previous_callback(app->view, uart_echo_exit);
-    view_dispatcher_add_view(app->view_dispatcher, 0, app->view);
-    view_dispatcher_switch_to_view(app->view_dispatcher, 0);
-
-    app->worker_thread = furi_thread_alloc_ex("UsbUartWorker", 1024, uart_echo_worker, app);
-    furi_thread_start(app->worker_thread);
-
-    // Enable uart listener
-    furi_hal_console_disable();
-    furi_hal_uart_set_br(FuriHalUartIdUSART1, 115200);
-    furi_hal_uart_set_irq_cb(FuriHalUartIdUSART1, uart_echo_on_irq_cb, app);
-
-    return app;
-}
-
-static void uart_echo_app_free(UartEchoApp* app) {
-    furi_assert(app);
-
-    furi_hal_console_enable(); // this will also clear IRQ callback so thread is no longer referenced
-
-    furi_thread_flags_set(furi_thread_get_id(app->worker_thread), WorkerEventStop);
-    furi_thread_join(app->worker_thread);
-    furi_thread_free(app->worker_thread);
-
-    // Free views
-    view_dispatcher_remove_view(app->view_dispatcher, 0);
-
-    with_view_model(
-        app->view,
-        UartDumpModel * model,
-        {
-            for(size_t i = 0; i < LINES_ON_SCREEN; i++) {
-                furi_string_free(model->list[i]->text);
-                free(model->list[i]);
-            }
-        },
-        true);
-    view_free(app->view);
-    view_dispatcher_free(app->view_dispatcher);
-
-    // Close gui record
-    furi_record_close(RECORD_GUI);
-    furi_record_close(RECORD_NOTIFICATION);
-    app->gui = NULL;
-
-    furi_stream_buffer_free(app->rx_stream);
-
-    // Free rest
-    free(app);
-}
-
-int32_t uart_echo_app(void* p) {
-    UNUSED(p);
-    UartEchoApp* app = uart_echo_app_alloc();
-    view_dispatcher_run(app->view_dispatcher);
-    uart_echo_app_free(app);
-    return 0;
-}

+ 0 - 18
applications/debug/unit_tests/application.fam

@@ -1,18 +0,0 @@
-App(
-    appid="unit_tests",
-    apptype=FlipperAppType.STARTUP,
-    entry_point="unit_tests_on_system_start",
-    cdefines=["APP_UNIT_TESTS"],
-    provides=["delay_test"],
-    order=100,
-)
-
-App(
-    appid="delay_test",
-    name="Delay Test",
-    apptype=FlipperAppType.SYSTEM,
-    entry_point="delay_test_app",
-    stack_size=1 * 1024,
-    requires=["unit_tests"],
-    order=110,
-)

+ 0 - 110
applications/debug/unit_tests/bt/bt_test.c

@@ -1,110 +0,0 @@
-#include <furi.h>
-#include <furi_hal.h>
-#include "../minunit.h"
-
-#include <bt/bt_service/bt_keys_storage.h>
-#include <storage/storage.h>
-
-#define BT_TEST_KEY_STORAGE_FILE_PATH EXT_PATH("unit_tests/bt_test.keys")
-#define BT_TEST_NVM_RAM_BUFF_SIZE (507 * 4) // The same as in ble NVM storage
-
-typedef struct {
-    Storage* storage;
-    BtKeysStorage* bt_keys_storage;
-    uint8_t* nvm_ram_buff_dut;
-    uint8_t* nvm_ram_buff_ref;
-} BtTest;
-
-BtTest* bt_test = NULL;
-
-void bt_test_alloc() {
-    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);
-    bt_test->nvm_ram_buff_ref = malloc(BT_TEST_NVM_RAM_BUFF_SIZE);
-    bt_test->bt_keys_storage = bt_keys_storage_alloc(BT_TEST_KEY_STORAGE_FILE_PATH);
-    bt_keys_storage_set_ram_params(
-        bt_test->bt_keys_storage, bt_test->nvm_ram_buff_dut, BT_TEST_NVM_RAM_BUFF_SIZE);
-}
-
-void bt_test_free() {
-    furi_assert(bt_test);
-    free(bt_test->nvm_ram_buff_ref);
-    free(bt_test->nvm_ram_buff_dut);
-    bt_keys_storage_free(bt_test->bt_keys_storage);
-    furi_record_close(RECORD_STORAGE);
-    free(bt_test);
-    bt_test = NULL;
-}
-
-static void bt_test_keys_storage_profile() {
-    // 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++) {
-        bt_test->nvm_ram_buff_dut[i] = rand();
-        bt_test->nvm_ram_buff_ref[i] = bt_test->nvm_ram_buff_dut[i];
-    }
-    // Emulate update storage on initial connect
-    mu_assert(
-        bt_keys_storage_update(
-            bt_test->bt_keys_storage, bt_test->nvm_ram_buff_dut, nvm_change_size_on_connection),
-        "Failed to update key storage on initial connect");
-    memset(bt_test->nvm_ram_buff_dut, 0, BT_TEST_NVM_RAM_BUFF_SIZE);
-    mu_assert(bt_keys_storage_load(bt_test->bt_keys_storage), "Failed to load NVM");
-    mu_assert(
-        memcmp(
-            bt_test->nvm_ram_buff_ref, bt_test->nvm_ram_buff_dut, nvm_change_size_on_connection) ==
-            0,
-        "Wrong buffer loaded");
-
-    const int nvm_disconnect_update_offset = 84;
-    const int nvm_disconnect_update_size = 324;
-    const int nvm_total_size = nvm_change_size_on_connection -
-                               (nvm_change_size_on_connection - nvm_disconnect_update_offset) +
-                               nvm_disconnect_update_size;
-    // Emulate update storage on initial disconnect
-    for(size_t i = nvm_disconnect_update_offset;
-        i < nvm_disconnect_update_offset + nvm_disconnect_update_size;
-        i++) {
-        bt_test->nvm_ram_buff_dut[i] = rand();
-        bt_test->nvm_ram_buff_ref[i] = bt_test->nvm_ram_buff_dut[i];
-    }
-    mu_assert(
-        bt_keys_storage_update(
-            bt_test->bt_keys_storage,
-            &bt_test->nvm_ram_buff_dut[nvm_disconnect_update_offset],
-            nvm_disconnect_update_size),
-        "Failed to update key storage on initial disconnect");
-    memset(bt_test->nvm_ram_buff_dut, 0, BT_TEST_NVM_RAM_BUFF_SIZE);
-    mu_assert(bt_keys_storage_load(bt_test->bt_keys_storage), "Failed to load NVM");
-    mu_assert(
-        memcmp(bt_test->nvm_ram_buff_ref, bt_test->nvm_ram_buff_dut, nvm_total_size) == 0,
-        "Wrong buffer loaded");
-}
-
-static void bt_test_keys_remove_test_file() {
-    mu_assert(
-        storage_simply_remove(bt_test->storage, BT_TEST_KEY_STORAGE_FILE_PATH),
-        "Can't remove test file");
-}
-
-MU_TEST(bt_test_keys_storage_serial_profile) {
-    furi_assert(bt_test);
-
-    bt_test_keys_remove_test_file();
-    bt_test_keys_storage_profile();
-    bt_test_keys_remove_test_file();
-}
-
-MU_TEST_SUITE(test_bt) {
-    bt_test_alloc();
-
-    MU_RUN_TEST(bt_test_keys_storage_serial_profile);
-
-    bt_test_free();
-}
-
-int run_minunit_test_bt() {
-    MU_RUN_SUITE(test_bt);
-    return MU_EXIT_CODE;
-}

+ 0 - 337
applications/debug/unit_tests/flipper_format/flipper_format_string_test.c

@@ -1,337 +0,0 @@
-#include <furi.h>
-#include <flipper_format/flipper_format.h>
-#include <flipper_format/flipper_format_i.h>
-#include <toolbox/stream/stream.h>
-#include <storage/storage.h>
-#include "../minunit.h"
-
-static const char* test_filetype = "Flipper Format test";
-static const uint32_t test_version = 666;
-
-static const char* test_string_key = "String data";
-static const char* test_string_data = "String";
-static const char* test_string_updated_data = "New string";
-static const char* test_string_updated_2_data = "And some more";
-
-static const char* test_int_key = "Int32 data";
-static const int32_t test_int_data[] = {1234, -6345, 7813, 0};
-static const int32_t test_int_updated_data[] = {-1337, 69};
-static const int32_t test_int_updated_2_data[] = {-3, -2, -1, 0, 1, 2, 3};
-
-static const char* test_uint_key = "Uint32 data";
-static const uint32_t test_uint_data[] = {1234, 0, 5678, 9098, 7654321};
-static const uint32_t test_uint_updated_data[] = {8, 800, 555, 35, 35};
-static const uint32_t test_uint_updated_2_data[] = {20, 21};
-
-static const char* test_float_key = "Float data";
-static const float test_float_data[] = {1.5f, 1000.0f};
-static const float test_float_updated_data[] = {1.2f};
-static const float test_float_updated_2_data[] = {0.01f, 0.0f, -51.6f};
-
-static const char* test_hex_key = "Hex data";
-static const uint8_t test_hex_data[] = {0xDE, 0xAD, 0xBE};
-static const uint8_t test_hex_updated_data[] = {0xFE, 0xCA};
-static const uint8_t test_hex_updated_2_data[] = {0xCA, 0xCA, 0x05};
-
-static const char* test_hex_new_key = "New Hex data";
-static const uint8_t test_hex_new_data[] = {0xFF, 0x6A, 0x91};
-
-static const char* test_data_nix = "Filetype: Flipper Format test\n"
-                                   "Version: 666\n"
-                                   "# This is comment\n"
-                                   "String data: String\n"
-                                   "Int32 data: 1234 -6345 7813 0\n"
-                                   "Uint32 data: 1234 0 5678 9098 7654321\n"
-                                   "Float data: 1.5 1000.0\n"
-                                   "Hex data: DE AD BE";
-
-static const char* test_data_win = "Filetype: Flipper Format test\r\n"
-                                   "Version: 666\r\n"
-                                   "# This is comment\r\n"
-                                   "String data: String\r\n"
-                                   "Int32 data: 1234 -6345 7813 0\r\n"
-                                   "Uint32 data: 1234 0 5678 9098 7654321\r\n"
-                                   "Float data: 1.5 1000.0\r\n"
-                                   "Hex data: DE AD BE";
-
-#define ARRAY_W_COUNT(x) (x), (COUNT_OF(x))
-#define ARRAY_W_BSIZE(x) (x), (sizeof(x))
-
-MU_TEST_1(flipper_format_read_and_update_test, FlipperFormat* flipper_format) {
-    FuriString* tmpstr;
-    uint32_t version;
-    uint32_t uint32_data[COUNT_OF(test_uint_data)];
-    int32_t int32_data[COUNT_OF(test_int_data)];
-    float float_data[COUNT_OF(test_float_data)];
-    uint8_t hex_data[COUNT_OF(test_hex_data)];
-
-    uint32_t count;
-
-    // key exist test
-    size_t position_before = stream_tell(flipper_format_get_raw_stream(flipper_format));
-    mu_check(flipper_format_key_exist(flipper_format, test_hex_key));
-    mu_assert_int_eq(position_before, stream_tell(flipper_format_get_raw_stream(flipper_format)));
-
-    mu_check(!flipper_format_key_exist(flipper_format, "invalid key"));
-    mu_assert_int_eq(position_before, stream_tell(flipper_format_get_raw_stream(flipper_format)));
-
-    // stream seek to end test
-    mu_check(flipper_format_seek_to_end(flipper_format));
-    mu_assert_int_eq(
-        stream_size(flipper_format_get_raw_stream(flipper_format)),
-        stream_tell(flipper_format_get_raw_stream(flipper_format)));
-
-    // key exist test
-    position_before = stream_tell(flipper_format_get_raw_stream(flipper_format));
-    mu_check(flipper_format_key_exist(flipper_format, test_hex_key));
-    mu_assert_int_eq(position_before, stream_tell(flipper_format_get_raw_stream(flipper_format)));
-
-    mu_check(!flipper_format_key_exist(flipper_format, "invalid key"));
-    mu_assert_int_eq(position_before, stream_tell(flipper_format_get_raw_stream(flipper_format)));
-
-    // rewind
-    mu_check(flipper_format_rewind(flipper_format));
-
-    // key exist test
-    position_before = stream_tell(flipper_format_get_raw_stream(flipper_format));
-    mu_check(flipper_format_key_exist(flipper_format, test_hex_key));
-    mu_assert_int_eq(position_before, stream_tell(flipper_format_get_raw_stream(flipper_format)));
-
-    mu_check(!flipper_format_key_exist(flipper_format, "invalid key"));
-    mu_assert_int_eq(position_before, stream_tell(flipper_format_get_raw_stream(flipper_format)));
-
-    // read test
-    tmpstr = furi_string_alloc();
-
-    mu_check(flipper_format_read_header(flipper_format, tmpstr, &version));
-    mu_assert_string_eq(test_filetype, furi_string_get_cstr(tmpstr));
-    mu_assert_int_eq(test_version, version);
-
-    mu_check(flipper_format_read_string(flipper_format, test_string_key, tmpstr));
-    mu_assert_string_eq(test_string_data, furi_string_get_cstr(tmpstr));
-
-    mu_check(flipper_format_get_value_count(flipper_format, test_int_key, &count));
-    mu_assert_int_eq(COUNT_OF(test_int_data), count);
-    mu_check(flipper_format_read_int32(flipper_format, test_int_key, ARRAY_W_COUNT(int32_data)));
-    mu_check(memcmp(test_int_data, ARRAY_W_BSIZE(int32_data)) == 0);
-
-    mu_check(flipper_format_get_value_count(flipper_format, test_uint_key, &count));
-    mu_assert_int_eq(COUNT_OF(test_uint_data), count);
-    mu_check(
-        flipper_format_read_uint32(flipper_format, test_uint_key, ARRAY_W_COUNT(uint32_data)));
-    mu_check(memcmp(test_uint_data, ARRAY_W_BSIZE(uint32_data)) == 0);
-
-    mu_check(flipper_format_get_value_count(flipper_format, test_float_key, &count));
-    mu_assert_int_eq(COUNT_OF(test_float_data), count);
-    mu_check(flipper_format_read_float(flipper_format, test_float_key, ARRAY_W_COUNT(float_data)));
-    mu_check(memcmp(test_float_data, ARRAY_W_BSIZE(float_data)) == 0);
-
-    mu_check(flipper_format_get_value_count(flipper_format, test_hex_key, &count));
-    mu_assert_int_eq(COUNT_OF(test_hex_data), count);
-    mu_check(flipper_format_read_hex(flipper_format, test_hex_key, ARRAY_W_COUNT(hex_data)));
-    mu_check(memcmp(test_hex_data, ARRAY_W_BSIZE(hex_data)) == 0);
-
-    mu_check(!flipper_format_read_string(flipper_format, "Key that doesn't exist", tmpstr));
-
-    furi_string_free(tmpstr);
-
-    // update data
-    mu_check(flipper_format_rewind(flipper_format));
-    mu_check(flipper_format_update_string_cstr(
-        flipper_format, test_string_key, test_string_updated_data));
-    mu_check(flipper_format_update_int32(
-        flipper_format, test_int_key, ARRAY_W_COUNT(test_int_updated_data)));
-    mu_check(flipper_format_update_uint32(
-        flipper_format, test_uint_key, ARRAY_W_COUNT(test_uint_updated_data)));
-    mu_check(flipper_format_update_float(
-        flipper_format, test_float_key, ARRAY_W_COUNT(test_float_updated_data)));
-    mu_check(flipper_format_update_hex(
-        flipper_format, test_hex_key, ARRAY_W_COUNT(test_hex_updated_data)));
-
-    // read updated data test
-    uint32_t uint32_updated_data[COUNT_OF(test_uint_updated_data)];
-    int32_t int32_updated_data[COUNT_OF(test_int_updated_data)];
-    float float_updated_data[COUNT_OF(test_float_updated_data)];
-    uint8_t hex_updated_data[COUNT_OF(test_hex_updated_data)];
-
-    mu_check(flipper_format_rewind(flipper_format));
-    tmpstr = furi_string_alloc();
-
-    mu_check(flipper_format_read_header(flipper_format, tmpstr, &version));
-    mu_assert_string_eq(test_filetype, furi_string_get_cstr(tmpstr));
-    mu_assert_int_eq(test_version, version);
-
-    mu_check(flipper_format_read_string(flipper_format, test_string_key, tmpstr));
-    mu_assert_string_eq(test_string_updated_data, furi_string_get_cstr(tmpstr));
-
-    mu_check(flipper_format_get_value_count(flipper_format, test_int_key, &count));
-    mu_assert_int_eq(COUNT_OF(test_int_updated_data), count);
-    mu_check(flipper_format_read_int32(
-        flipper_format, test_int_key, ARRAY_W_COUNT(int32_updated_data)));
-    mu_check(memcmp(test_int_updated_data, ARRAY_W_BSIZE(int32_updated_data)) == 0);
-
-    mu_check(flipper_format_get_value_count(flipper_format, test_uint_key, &count));
-    mu_assert_int_eq(COUNT_OF(test_uint_updated_data), count);
-    mu_check(flipper_format_read_uint32(
-        flipper_format, test_uint_key, ARRAY_W_COUNT(uint32_updated_data)));
-    mu_check(memcmp(test_uint_updated_data, ARRAY_W_BSIZE(uint32_updated_data)) == 0);
-
-    mu_check(flipper_format_get_value_count(flipper_format, test_float_key, &count));
-    mu_assert_int_eq(COUNT_OF(test_float_updated_data), count);
-    mu_check(flipper_format_read_float(
-        flipper_format, test_float_key, ARRAY_W_COUNT(float_updated_data)));
-    mu_check(memcmp(test_float_updated_data, ARRAY_W_BSIZE(float_updated_data)) == 0);
-
-    mu_check(flipper_format_get_value_count(flipper_format, test_hex_key, &count));
-    mu_assert_int_eq(COUNT_OF(test_hex_updated_data), count);
-    mu_check(
-        flipper_format_read_hex(flipper_format, test_hex_key, ARRAY_W_COUNT(hex_updated_data)));
-    mu_check(memcmp(test_hex_updated_data, ARRAY_W_BSIZE(hex_updated_data)) == 0);
-
-    mu_check(!flipper_format_read_string(flipper_format, "Key that doesn't exist", tmpstr));
-
-    furi_string_free(tmpstr);
-
-    // update data
-    mu_check(flipper_format_rewind(flipper_format));
-    mu_check(flipper_format_insert_or_update_string_cstr(
-        flipper_format, test_string_key, test_string_updated_2_data));
-    mu_check(flipper_format_insert_or_update_int32(
-        flipper_format, test_int_key, ARRAY_W_COUNT(test_int_updated_2_data)));
-    mu_check(flipper_format_insert_or_update_uint32(
-        flipper_format, test_uint_key, ARRAY_W_COUNT(test_uint_updated_2_data)));
-    mu_check(flipper_format_insert_or_update_float(
-        flipper_format, test_float_key, ARRAY_W_COUNT(test_float_updated_2_data)));
-    mu_check(flipper_format_insert_or_update_hex(
-        flipper_format, test_hex_key, ARRAY_W_COUNT(test_hex_updated_2_data)));
-    mu_check(flipper_format_insert_or_update_hex(
-        flipper_format, test_hex_new_key, ARRAY_W_COUNT(test_hex_new_data)));
-
-    uint32_t uint32_updated_2_data[COUNT_OF(test_uint_updated_2_data)];
-    int32_t int32_updated_2_data[COUNT_OF(test_int_updated_2_data)];
-    float float_updated_2_data[COUNT_OF(test_float_updated_2_data)];
-    uint8_t hex_updated_2_data[COUNT_OF(test_hex_updated_2_data)];
-    uint8_t hex_new_data[COUNT_OF(test_hex_new_data)];
-
-    mu_check(flipper_format_rewind(flipper_format));
-    tmpstr = furi_string_alloc();
-
-    mu_check(flipper_format_read_header(flipper_format, tmpstr, &version));
-    mu_assert_string_eq(test_filetype, furi_string_get_cstr(tmpstr));
-    mu_assert_int_eq(test_version, version);
-
-    mu_check(flipper_format_read_string(flipper_format, test_string_key, tmpstr));
-    mu_assert_string_eq(test_string_updated_2_data, furi_string_get_cstr(tmpstr));
-
-    mu_check(flipper_format_get_value_count(flipper_format, test_int_key, &count));
-    mu_assert_int_eq(COUNT_OF(test_int_updated_2_data), count);
-    mu_check(flipper_format_read_int32(
-        flipper_format, test_int_key, ARRAY_W_COUNT(int32_updated_2_data)));
-    mu_check(memcmp(test_int_updated_2_data, ARRAY_W_BSIZE(int32_updated_2_data)) == 0);
-
-    mu_check(flipper_format_get_value_count(flipper_format, test_uint_key, &count));
-    mu_assert_int_eq(COUNT_OF(test_uint_updated_2_data), count);
-    mu_check(flipper_format_read_uint32(
-        flipper_format, test_uint_key, ARRAY_W_COUNT(uint32_updated_2_data)));
-    mu_check(memcmp(test_uint_updated_2_data, ARRAY_W_BSIZE(uint32_updated_2_data)) == 0);
-
-    mu_check(flipper_format_get_value_count(flipper_format, test_float_key, &count));
-    mu_assert_int_eq(COUNT_OF(test_float_updated_2_data), count);
-    mu_check(flipper_format_read_float(
-        flipper_format, test_float_key, ARRAY_W_COUNT(float_updated_2_data)));
-    mu_check(memcmp(test_float_updated_2_data, ARRAY_W_BSIZE(float_updated_2_data)) == 0);
-
-    mu_check(flipper_format_get_value_count(flipper_format, test_hex_key, &count));
-    mu_assert_int_eq(COUNT_OF(test_hex_updated_2_data), count);
-    mu_check(
-        flipper_format_read_hex(flipper_format, test_hex_key, ARRAY_W_COUNT(hex_updated_2_data)));
-    mu_check(memcmp(test_hex_updated_2_data, ARRAY_W_BSIZE(hex_updated_2_data)) == 0);
-
-    mu_check(flipper_format_get_value_count(flipper_format, test_hex_new_key, &count));
-    mu_assert_int_eq(COUNT_OF(test_hex_new_data), count);
-    mu_check(
-        flipper_format_read_hex(flipper_format, test_hex_new_key, ARRAY_W_COUNT(hex_new_data)));
-    mu_check(memcmp(test_hex_new_data, ARRAY_W_BSIZE(hex_new_data)) == 0);
-
-    mu_check(!flipper_format_read_string(flipper_format, "Key that doesn't exist", tmpstr));
-
-    furi_string_free(tmpstr);
-
-    // delete key test
-    mu_check(flipper_format_rewind(flipper_format));
-    mu_check(flipper_format_delete_key(flipper_format, test_uint_key));
-
-    // deleted key read test
-    mu_check(flipper_format_rewind(flipper_format));
-    mu_check(!flipper_format_read_uint32(
-        flipper_format, test_uint_key, ARRAY_W_COUNT(uint32_updated_data)));
-}
-
-MU_TEST(flipper_format_string_test) {
-    FlipperFormat* flipper_format = flipper_format_string_alloc();
-    Stream* stream = flipper_format_get_raw_stream(flipper_format);
-
-    mu_check(flipper_format_write_header_cstr(flipper_format, test_filetype, test_version));
-    mu_check(flipper_format_write_comment_cstr(flipper_format, "This is comment"));
-    mu_check(flipper_format_write_string_cstr(flipper_format, test_string_key, test_string_data));
-    mu_check(
-        flipper_format_write_int32(flipper_format, test_int_key, ARRAY_W_COUNT(test_int_data)));
-    mu_check(
-        flipper_format_write_uint32(flipper_format, test_uint_key, ARRAY_W_COUNT(test_uint_data)));
-    mu_check(flipper_format_write_float(
-        flipper_format, test_float_key, ARRAY_W_COUNT(test_float_data)));
-    mu_check(flipper_format_write_hex(flipper_format, test_hex_key, ARRAY_W_COUNT(test_hex_data)));
-
-    MU_RUN_TEST_1(flipper_format_read_and_update_test, flipper_format);
-
-    stream_clean(stream);
-    stream_write_cstring(stream, test_data_nix);
-    MU_RUN_TEST_1(flipper_format_read_and_update_test, flipper_format);
-
-    stream_clean(stream);
-    stream_write_cstring(stream, test_data_win);
-    MU_RUN_TEST_1(flipper_format_read_and_update_test, flipper_format);
-
-    flipper_format_free(flipper_format);
-}
-
-MU_TEST(flipper_format_file_test) {
-    Storage* storage = furi_record_open(RECORD_STORAGE);
-    FlipperFormat* flipper_format = flipper_format_file_alloc(storage);
-    mu_check(flipper_format_file_open_always(flipper_format, EXT_PATH("flipper.fff")));
-    Stream* stream = flipper_format_get_raw_stream(flipper_format);
-
-    mu_check(flipper_format_write_header_cstr(flipper_format, test_filetype, test_version));
-    mu_check(flipper_format_write_comment_cstr(flipper_format, "This is comment"));
-    mu_check(flipper_format_write_string_cstr(flipper_format, test_string_key, test_string_data));
-    mu_check(
-        flipper_format_write_int32(flipper_format, test_int_key, ARRAY_W_COUNT(test_int_data)));
-    mu_check(
-        flipper_format_write_uint32(flipper_format, test_uint_key, ARRAY_W_COUNT(test_uint_data)));
-    mu_check(flipper_format_write_float(
-        flipper_format, test_float_key, ARRAY_W_COUNT(test_float_data)));
-    mu_check(flipper_format_write_hex(flipper_format, test_hex_key, ARRAY_W_COUNT(test_hex_data)));
-
-    MU_RUN_TEST_1(flipper_format_read_and_update_test, flipper_format);
-
-    stream_clean(stream);
-    stream_write_cstring(stream, test_data_nix);
-    MU_RUN_TEST_1(flipper_format_read_and_update_test, flipper_format);
-
-    stream_clean(stream);
-    stream_write_cstring(stream, test_data_win);
-    MU_RUN_TEST_1(flipper_format_read_and_update_test, flipper_format);
-
-    flipper_format_free(flipper_format);
-    furi_record_close(RECORD_STORAGE);
-}
-
-MU_TEST_SUITE(flipper_format_string_suite) {
-    MU_RUN_TEST(flipper_format_string_test);
-    MU_RUN_TEST(flipper_format_file_test);
-}
-
-int run_minunit_test_flipper_format_string() {
-    MU_RUN_SUITE(flipper_format_string_suite);
-    return MU_EXIT_CODE;
-}

+ 0 - 551
applications/debug/unit_tests/flipper_format/flipper_format_test.c

@@ -1,551 +0,0 @@
-#include <furi.h>
-#include <flipper_format/flipper_format.h>
-#include <flipper_format/flipper_format_i.h>
-#include <toolbox/stream/stream.h>
-#include "../minunit.h"
-
-#define TEST_DIR TEST_DIR_NAME "/"
-#define TEST_DIR_NAME EXT_PATH("unit_tests_tmp")
-
-static const char* test_filetype = "Flipper File test";
-static const uint32_t test_version = 666;
-
-static const char* test_string_key = "String data";
-static const char* test_string_data = "String";
-static const char* test_string_updated_data = "New string";
-
-static const char* test_int_key = "Int32 data";
-static const int32_t test_int_data[] = {1234, -6345, 7813, 0};
-static const int32_t test_int_updated_data[] = {-1337, 69};
-
-static const char* test_uint_key = "Uint32 data";
-static const uint32_t test_uint_data[] = {1234, 0, 5678, 9098, 7654321};
-static const uint32_t test_uint_updated_data[] = {8, 800, 555, 35, 35};
-
-static const char* test_float_key = "Float data";
-static const float test_float_data[] = {1.5f, 1000.0f};
-static const float test_float_updated_data[] = {1.2f};
-
-static const char* test_bool_key = "Bool data";
-static const bool test_bool_data[] = {true, false};
-static const bool test_bool_updated_data[] = {false, true, true};
-
-static const char* test_hex_key = "Hex data";
-static const uint8_t test_hex_data[] = {0xDE, 0xAD, 0xBE};
-static const uint8_t test_hex_updated_data[] = {0xFE, 0xCA};
-
-#define READ_TEST_NIX "ff_nix.test"
-static const char* test_data_nix = "Filetype: Flipper File test\n"
-                                   "Version: 666\n"
-                                   "# This is comment\n"
-                                   "String data: String\n"
-                                   "Int32 data: 1234 -6345 7813 0\n"
-                                   "Uint32 data: 1234 0 5678 9098 7654321\n"
-                                   "Float data: 1.5 1000.0\n"
-                                   "Bool data: true false\n"
-                                   "Hex data: DE AD BE";
-
-#define READ_TEST_WIN "ff_win.test"
-static const char* test_data_win = "Filetype: Flipper File test\r\n"
-                                   "Version: 666\r\n"
-                                   "# This is comment\r\n"
-                                   "String data: String\r\n"
-                                   "Int32 data: 1234 -6345 7813 0\r\n"
-                                   "Uint32 data: 1234 0 5678 9098 7654321\r\n"
-                                   "Float data: 1.5 1000.0\r\n"
-                                   "Bool data: true false\r\n"
-                                   "Hex data: DE AD BE";
-
-#define READ_TEST_FLP "ff_flp.test"
-#define READ_TEST_ODD "ff_oddities.test"
-static const char* test_data_odd = "Filetype: Flipper File test\n"
-                                   // Tabs before newline
-                                   "Version: 666\t\t\n"
-                                   "# This is comment\n"
-                                   // Windows newline in a UNIX file
-                                   "String data: String\r\n"
-                                   // Trailing whitespace
-                                   "Int32 data: 1234 -6345 7813 0 \n"
-                                   // Extra whitespace
-                                   "Uint32 data:   1234  0   5678   9098  7654321  \n"
-                                   // Mixed whitespace
-                                   "Float data: 1.5\t \t1000.0\n"
-                                   // Leading tabs after key
-                                   "Bool data:\t\ttrue   false\n"
-                                   // Mixed trailing whitespace
-                                   "Hex data: DE AD BE\t    ";
-
-// data created by user on linux machine
-static const char* test_file_linux = TEST_DIR READ_TEST_NIX;
-// data created by user on windows machine
-static const char* test_file_windows = TEST_DIR READ_TEST_WIN;
-// data created by flipper itself
-static const char* test_file_flipper = TEST_DIR READ_TEST_FLP;
-// data containing odd user input
-static const char* test_file_oddities = TEST_DIR READ_TEST_ODD;
-
-static bool storage_write_string(const char* path, const char* data) {
-    Storage* storage = furi_record_open(RECORD_STORAGE);
-    File* file = storage_file_alloc(storage);
-    bool result = false;
-
-    do {
-        if(!storage_file_open(file, path, FSAM_WRITE, FSOM_CREATE_ALWAYS)) break;
-        if(storage_file_write(file, data, strlen(data)) != strlen(data)) break;
-
-        result = true;
-    } while(false);
-
-    storage_file_close(file);
-    storage_file_free(file);
-    furi_record_close(RECORD_STORAGE);
-
-    return result;
-}
-
-static void tests_setup() {
-    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() {
-    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);
-}
-
-static bool test_read(const char* file_name) {
-    Storage* storage = furi_record_open(RECORD_STORAGE);
-    bool result = false;
-
-    FlipperFormat* file = flipper_format_file_alloc(storage);
-    FuriString* string_value;
-    string_value = furi_string_alloc();
-    uint32_t uint32_value;
-    void* scratchpad = malloc(512);
-
-    do {
-        if(!flipper_format_file_open_existing(file, file_name)) break;
-
-        if(!flipper_format_read_header(file, string_value, &uint32_value)) break;
-        if(furi_string_cmp_str(string_value, test_filetype) != 0) break;
-        if(uint32_value != test_version) break;
-
-        if(!flipper_format_read_string(file, test_string_key, string_value)) break;
-        if(furi_string_cmp_str(string_value, test_string_data) != 0) break;
-
-        if(!flipper_format_get_value_count(file, test_int_key, &uint32_value)) break;
-        if(uint32_value != COUNT_OF(test_int_data)) break;
-        if(!flipper_format_read_int32(file, test_int_key, scratchpad, uint32_value)) break;
-        if(memcmp(scratchpad, test_int_data, sizeof(int32_t) * COUNT_OF(test_int_data)) != 0)
-            break;
-
-        if(!flipper_format_get_value_count(file, test_uint_key, &uint32_value)) break;
-        if(uint32_value != COUNT_OF(test_uint_data)) break;
-        if(!flipper_format_read_uint32(file, test_uint_key, scratchpad, uint32_value)) break;
-        if(memcmp(scratchpad, test_uint_data, sizeof(uint32_t) * COUNT_OF(test_uint_data)) != 0)
-            break;
-
-        if(!flipper_format_get_value_count(file, test_float_key, &uint32_value)) break;
-        if(uint32_value != COUNT_OF(test_float_data)) break;
-        if(!flipper_format_read_float(file, test_float_key, scratchpad, uint32_value)) break;
-        if(memcmp(scratchpad, test_float_data, sizeof(float) * COUNT_OF(test_float_data)) != 0)
-            break;
-
-        if(!flipper_format_get_value_count(file, test_bool_key, &uint32_value)) break;
-        if(uint32_value != COUNT_OF(test_bool_data)) break;
-        if(!flipper_format_read_bool(file, test_bool_key, scratchpad, uint32_value)) break;
-        if(memcmp(scratchpad, test_bool_data, sizeof(bool) * COUNT_OF(test_bool_data)) != 0) break;
-
-        if(!flipper_format_get_value_count(file, test_hex_key, &uint32_value)) break;
-        if(uint32_value != COUNT_OF(test_hex_data)) break;
-        if(!flipper_format_read_hex(file, test_hex_key, scratchpad, uint32_value)) break;
-        if(memcmp(scratchpad, test_hex_data, sizeof(uint8_t) * COUNT_OF(test_hex_data)) != 0)
-            break;
-
-        result = true;
-    } while(false);
-
-    free(scratchpad);
-    furi_string_free(string_value);
-
-    flipper_format_free(file);
-
-    furi_record_close(RECORD_STORAGE);
-
-    return result;
-}
-
-static bool test_read_updated(const char* file_name) {
-    Storage* storage = furi_record_open(RECORD_STORAGE);
-    bool result = false;
-
-    FlipperFormat* file = flipper_format_file_alloc(storage);
-    FuriString* string_value;
-    string_value = furi_string_alloc();
-    uint32_t uint32_value;
-    void* scratchpad = malloc(512);
-
-    do {
-        if(!flipper_format_file_open_existing(file, file_name)) break;
-
-        if(!flipper_format_read_header(file, string_value, &uint32_value)) break;
-        if(furi_string_cmp_str(string_value, test_filetype) != 0) break;
-        if(uint32_value != test_version) break;
-
-        if(!flipper_format_read_string(file, test_string_key, string_value)) break;
-        if(furi_string_cmp_str(string_value, test_string_updated_data) != 0) break;
-
-        if(!flipper_format_get_value_count(file, test_int_key, &uint32_value)) break;
-        if(uint32_value != COUNT_OF(test_int_updated_data)) break;
-        if(!flipper_format_read_int32(file, test_int_key, scratchpad, uint32_value)) break;
-        if(memcmp(
-               scratchpad,
-               test_int_updated_data,
-               sizeof(int32_t) * COUNT_OF(test_int_updated_data)) != 0)
-            break;
-
-        if(!flipper_format_get_value_count(file, test_uint_key, &uint32_value)) break;
-        if(uint32_value != COUNT_OF(test_uint_updated_data)) break;
-        if(!flipper_format_read_uint32(file, test_uint_key, scratchpad, uint32_value)) break;
-        if(memcmp(
-               scratchpad,
-               test_uint_updated_data,
-               sizeof(uint32_t) * COUNT_OF(test_uint_updated_data)) != 0)
-            break;
-
-        if(!flipper_format_get_value_count(file, test_float_key, &uint32_value)) break;
-        if(uint32_value != COUNT_OF(test_float_updated_data)) break;
-        if(!flipper_format_read_float(file, test_float_key, scratchpad, uint32_value)) break;
-        if(memcmp(
-               scratchpad,
-               test_float_updated_data,
-               sizeof(float) * COUNT_OF(test_float_updated_data)) != 0)
-            break;
-
-        if(!flipper_format_get_value_count(file, test_bool_key, &uint32_value)) break;
-        if(uint32_value != COUNT_OF(test_bool_updated_data)) break;
-        if(!flipper_format_read_bool(file, test_bool_key, scratchpad, uint32_value)) break;
-        if(memcmp(
-               scratchpad,
-               test_bool_updated_data,
-               sizeof(bool) * COUNT_OF(test_bool_updated_data)) != 0)
-            break;
-
-        if(!flipper_format_get_value_count(file, test_hex_key, &uint32_value)) break;
-        if(uint32_value != COUNT_OF(test_hex_updated_data)) break;
-        if(!flipper_format_read_hex(file, test_hex_key, scratchpad, uint32_value)) break;
-        if(memcmp(
-               scratchpad,
-               test_hex_updated_data,
-               sizeof(uint8_t) * COUNT_OF(test_hex_updated_data)) != 0)
-            break;
-
-        result = true;
-    } while(false);
-
-    free(scratchpad);
-    furi_string_free(string_value);
-
-    flipper_format_free(file);
-
-    furi_record_close(RECORD_STORAGE);
-
-    return result;
-}
-
-static bool test_write(const char* file_name) {
-    Storage* storage = furi_record_open(RECORD_STORAGE);
-    bool result = false;
-    FlipperFormat* file = flipper_format_file_alloc(storage);
-
-    do {
-        if(!flipper_format_file_open_always(file, file_name)) break;
-        if(!flipper_format_write_header_cstr(file, test_filetype, test_version)) break;
-        if(!flipper_format_write_comment_cstr(file, "This is comment")) break;
-        if(!flipper_format_write_string_cstr(file, test_string_key, test_string_data)) break;
-        if(!flipper_format_write_int32(file, test_int_key, test_int_data, COUNT_OF(test_int_data)))
-            break;
-        if(!flipper_format_write_uint32(
-               file, test_uint_key, test_uint_data, COUNT_OF(test_uint_data)))
-            break;
-        if(!flipper_format_write_float(
-               file, test_float_key, test_float_data, COUNT_OF(test_float_data)))
-            break;
-        if(!flipper_format_write_bool(
-               file, test_bool_key, test_bool_data, COUNT_OF(test_bool_data)))
-            break;
-        if(!flipper_format_write_hex(file, test_hex_key, test_hex_data, COUNT_OF(test_hex_data)))
-            break;
-        result = true;
-    } while(false);
-
-    flipper_format_free(file);
-    furi_record_close(RECORD_STORAGE);
-
-    return result;
-}
-
-static bool test_delete_last_key(const char* file_name) {
-    Storage* storage = furi_record_open(RECORD_STORAGE);
-    bool result = false;
-    FlipperFormat* file = flipper_format_file_alloc(storage);
-
-    do {
-        if(!flipper_format_file_open_existing(file, file_name)) break;
-        if(!flipper_format_delete_key(file, test_hex_key)) break;
-        result = true;
-    } while(false);
-
-    flipper_format_free(file);
-    furi_record_close(RECORD_STORAGE);
-
-    return result;
-}
-
-static bool test_append_key(const char* file_name) {
-    Storage* storage = furi_record_open(RECORD_STORAGE);
-    bool result = false;
-    FlipperFormat* file = flipper_format_file_alloc(storage);
-
-    do {
-        if(!flipper_format_file_open_append(file, file_name)) break;
-        if(!flipper_format_write_hex(file, test_hex_key, test_hex_data, COUNT_OF(test_hex_data)))
-            break;
-        result = true;
-    } while(false);
-
-    flipper_format_free(file);
-    furi_record_close(RECORD_STORAGE);
-
-    return result;
-}
-
-static bool test_update(const char* file_name) {
-    Storage* storage = furi_record_open(RECORD_STORAGE);
-    bool result = false;
-    FlipperFormat* file = flipper_format_file_alloc(storage);
-
-    do {
-        if(!flipper_format_file_open_existing(file, file_name)) break;
-        if(!flipper_format_update_string_cstr(file, test_string_key, test_string_updated_data))
-            break;
-        if(!flipper_format_update_int32(
-               file, test_int_key, test_int_updated_data, COUNT_OF(test_int_updated_data)))
-            break;
-        if(!flipper_format_update_uint32(
-               file, test_uint_key, test_uint_updated_data, COUNT_OF(test_uint_updated_data)))
-            break;
-        if(!flipper_format_update_float(
-               file, test_float_key, test_float_updated_data, COUNT_OF(test_float_updated_data)))
-            break;
-        if(!flipper_format_update_bool(
-               file, test_bool_key, test_bool_updated_data, COUNT_OF(test_bool_updated_data)))
-            break;
-        if(!flipper_format_update_hex(
-               file, test_hex_key, test_hex_updated_data, COUNT_OF(test_hex_updated_data)))
-            break;
-
-        result = true;
-    } while(false);
-
-    flipper_format_free(file);
-    furi_record_close(RECORD_STORAGE);
-
-    return result;
-}
-
-static bool test_update_backward(const char* file_name) {
-    Storage* storage = furi_record_open(RECORD_STORAGE);
-    bool result = false;
-    FlipperFormat* file = flipper_format_file_alloc(storage);
-
-    do {
-        if(!flipper_format_file_open_existing(file, file_name)) break;
-        if(!flipper_format_update_string_cstr(file, test_string_key, test_string_data)) break;
-        if(!flipper_format_update_int32(file, test_int_key, test_int_data, COUNT_OF(test_int_data)))
-            break;
-        if(!flipper_format_update_uint32(
-               file, test_uint_key, test_uint_data, COUNT_OF(test_uint_data)))
-            break;
-        if(!flipper_format_update_float(
-               file, test_float_key, test_float_data, COUNT_OF(test_float_data)))
-            break;
-        if(!flipper_format_update_bool(
-               file, test_bool_key, test_bool_data, COUNT_OF(test_bool_data)))
-            break;
-        if(!flipper_format_update_hex(file, test_hex_key, test_hex_data, COUNT_OF(test_hex_data)))
-            break;
-
-        result = true;
-    } while(false);
-
-    flipper_format_free(file);
-    furi_record_close(RECORD_STORAGE);
-
-    return result;
-}
-
-static bool test_write_multikey(const char* file_name) {
-    Storage* storage = furi_record_open(RECORD_STORAGE);
-    bool result = false;
-    FlipperFormat* file = flipper_format_file_alloc(storage);
-
-    do {
-        if(!flipper_format_file_open_always(file, file_name)) break;
-        if(!flipper_format_write_header_cstr(file, test_filetype, test_version)) break;
-
-        bool error = false;
-        for(uint8_t index = 0; index < 100; index++) {
-            if(!flipper_format_write_hex(file, test_hex_key, &index, 1)) {
-                error = true;
-                break;
-            }
-        }
-        if(error) break;
-
-        result = true;
-    } while(false);
-
-    flipper_format_free(file);
-    furi_record_close(RECORD_STORAGE);
-
-    return result;
-}
-
-static bool test_read_multikey(const char* file_name) {
-    Storage* storage = furi_record_open(RECORD_STORAGE);
-    bool result = false;
-    FlipperFormat* file = flipper_format_file_alloc(storage);
-
-    FuriString* string_value;
-    string_value = furi_string_alloc();
-    uint32_t uint32_value;
-
-    do {
-        if(!flipper_format_file_open_existing(file, file_name)) break;
-        if(!flipper_format_read_header(file, string_value, &uint32_value)) break;
-        if(furi_string_cmp_str(string_value, test_filetype) != 0) break;
-        if(uint32_value != test_version) break;
-
-        bool error = false;
-        uint8_t uint8_value;
-        for(uint8_t index = 0; index < 100; index++) {
-            if(!flipper_format_read_hex(file, test_hex_key, &uint8_value, 1)) {
-                error = true;
-                break;
-            }
-
-            if(uint8_value != index) {
-                error = true;
-                break;
-            }
-        }
-        if(error) break;
-
-        result = true;
-    } while(false);
-
-    furi_string_free(string_value);
-
-    flipper_format_free(file);
-    furi_record_close(RECORD_STORAGE);
-
-    return result;
-}
-
-MU_TEST(flipper_format_write_test) {
-    mu_assert(storage_write_string(test_file_linux, test_data_nix), "Write test error [Linux]");
-    mu_assert(
-        storage_write_string(test_file_windows, test_data_win), "Write test error [Windows]");
-    mu_assert(test_write(test_file_flipper), "Write test error [Flipper]");
-}
-
-MU_TEST(flipper_format_read_test) {
-    mu_assert(test_read(test_file_linux), "Read test error [Linux]");
-    mu_assert(test_read(test_file_windows), "Read test error [Windows]");
-    mu_assert(test_read(test_file_flipper), "Read test error [Flipper]");
-}
-
-MU_TEST(flipper_format_delete_test) {
-    mu_assert(test_delete_last_key(test_file_linux), "Cannot delete key [Linux]");
-    mu_assert(test_delete_last_key(test_file_windows), "Cannot delete key [Windows]");
-    mu_assert(test_delete_last_key(test_file_flipper), "Cannot delete key [Flipper]");
-}
-
-MU_TEST(flipper_format_delete_result_test) {
-    mu_assert(!test_read(test_file_linux), "Key deleted incorrectly [Linux]");
-    mu_assert(!test_read(test_file_windows), "Key deleted incorrectly [Windows]");
-    mu_assert(!test_read(test_file_flipper), "Key deleted incorrectly [Flipper]");
-}
-
-MU_TEST(flipper_format_append_test) {
-    mu_assert(test_append_key(test_file_linux), "Cannot append data [Linux]");
-    mu_assert(test_append_key(test_file_windows), "Cannot append data [Windows]");
-    mu_assert(test_append_key(test_file_flipper), "Cannot append data [Flipper]");
-}
-
-MU_TEST(flipper_format_append_result_test) {
-    mu_assert(test_read(test_file_linux), "Data appended incorrectly [Linux]");
-    mu_assert(test_read(test_file_windows), "Data appended incorrectly [Windows]");
-    mu_assert(test_read(test_file_flipper), "Data appended incorrectly [Flipper]");
-}
-
-MU_TEST(flipper_format_update_1_test) {
-    mu_assert(test_update(test_file_linux), "Cannot update data #1 [Linux]");
-    mu_assert(test_update(test_file_windows), "Cannot update data #1 [Windows]");
-    mu_assert(test_update(test_file_flipper), "Cannot update data #1 [Flipper]");
-}
-
-MU_TEST(flipper_format_update_1_result_test) {
-    mu_assert(test_read_updated(test_file_linux), "Data #1 updated incorrectly [Linux]");
-    mu_assert(test_read_updated(test_file_windows), "Data #1 updated incorrectly [Windows]");
-    mu_assert(test_read_updated(test_file_flipper), "Data #1 updated incorrectly [Flipper]");
-}
-
-MU_TEST(flipper_format_update_2_test) {
-    mu_assert(test_update_backward(test_file_linux), "Cannot update data #2 [Linux]");
-    mu_assert(test_update_backward(test_file_windows), "Cannot update data #2 [Windows]");
-    mu_assert(test_update_backward(test_file_flipper), "Cannot update data #2 [Flipper]");
-}
-
-MU_TEST(flipper_format_update_2_result_test) {
-    mu_assert(test_read(test_file_linux), "Data #2 updated incorrectly [Linux]");
-    mu_assert(test_read(test_file_windows), "Data #2 updated incorrectly [Windows]");
-    mu_assert(test_read(test_file_flipper), "Data #2 updated incorrectly [Flipper]");
-}
-
-MU_TEST(flipper_format_multikey_test) {
-    mu_assert(test_write_multikey(TEST_DIR "ff_multiline.test"), "Multikey write test error");
-    mu_assert(test_read_multikey(TEST_DIR "ff_multiline.test"), "Multikey read test error");
-}
-
-MU_TEST(flipper_format_oddities_test) {
-    mu_assert(
-        storage_write_string(test_file_oddities, test_data_odd), "Write test error [Oddities]");
-    mu_assert(test_read(test_file_linux), "Read test error [Oddities]");
-}
-
-MU_TEST_SUITE(flipper_format) {
-    tests_setup();
-    MU_RUN_TEST(flipper_format_write_test);
-    MU_RUN_TEST(flipper_format_read_test);
-    MU_RUN_TEST(flipper_format_delete_test);
-    MU_RUN_TEST(flipper_format_delete_result_test);
-    MU_RUN_TEST(flipper_format_append_test);
-    MU_RUN_TEST(flipper_format_append_result_test);
-    MU_RUN_TEST(flipper_format_update_1_test);
-    MU_RUN_TEST(flipper_format_update_1_result_test);
-    MU_RUN_TEST(flipper_format_update_2_test);
-    MU_RUN_TEST(flipper_format_update_2_result_test);
-    MU_RUN_TEST(flipper_format_multikey_test);
-    MU_RUN_TEST(flipper_format_oddities_test);
-    tests_teardown();
-}
-
-int run_minunit_test_flipper_format() {
-    MU_RUN_SUITE(flipper_format);
-    return MU_EXIT_CODE;
-}

+ 0 - 60
applications/debug/unit_tests/float_tools/float_tools_test.c

@@ -1,60 +0,0 @@
-#include <float.h>
-#include <float_tools.h>
-
-#include "../minunit.h"
-
-MU_TEST(float_tools_equal_test) {
-    mu_check(float_is_equal(FLT_MAX, FLT_MAX));
-    mu_check(float_is_equal(FLT_MIN, FLT_MIN));
-    mu_check(float_is_equal(-FLT_MAX, -FLT_MAX));
-    mu_check(float_is_equal(-FLT_MIN, -FLT_MIN));
-
-    mu_check(!float_is_equal(FLT_MIN, FLT_MAX));
-    mu_check(!float_is_equal(-FLT_MIN, FLT_MAX));
-    mu_check(!float_is_equal(FLT_MIN, -FLT_MAX));
-    mu_check(!float_is_equal(-FLT_MIN, -FLT_MAX));
-
-    const float pi = 3.14159f;
-    mu_check(float_is_equal(pi, pi));
-    mu_check(float_is_equal(-pi, -pi));
-    mu_check(!float_is_equal(pi, -pi));
-    mu_check(!float_is_equal(-pi, pi));
-
-    const float one_third = 1.f / 3.f;
-    const float one_third_dec = 0.3333333f;
-    mu_check(one_third != one_third_dec);
-    mu_check(float_is_equal(one_third, one_third_dec));
-
-    const float big_num = 1.e12f;
-    const float med_num = 95.389f;
-    const float smol_num = 1.e-12f;
-    mu_check(float_is_equal(big_num, big_num));
-    mu_check(float_is_equal(med_num, med_num));
-    mu_check(float_is_equal(smol_num, smol_num));
-    mu_check(!float_is_equal(smol_num, big_num));
-    mu_check(!float_is_equal(med_num, smol_num));
-    mu_check(!float_is_equal(big_num, med_num));
-
-    const float more_than_one = 1.f + FLT_EPSILON;
-    const float less_than_one = 1.f - FLT_EPSILON;
-    mu_check(!float_is_equal(more_than_one, less_than_one));
-    mu_check(!float_is_equal(more_than_one, -less_than_one));
-    mu_check(!float_is_equal(-more_than_one, less_than_one));
-    mu_check(!float_is_equal(-more_than_one, -less_than_one));
-
-    const float slightly_more_than_one = 1.f + FLT_EPSILON / 2.f;
-    const float slightly_less_than_one = 1.f - FLT_EPSILON / 2.f;
-    mu_check(float_is_equal(slightly_more_than_one, slightly_less_than_one));
-    mu_check(float_is_equal(-slightly_more_than_one, -slightly_less_than_one));
-    mu_check(!float_is_equal(slightly_more_than_one, -slightly_less_than_one));
-    mu_check(!float_is_equal(-slightly_more_than_one, slightly_less_than_one));
-}
-
-MU_TEST_SUITE(float_tools_suite) {
-    MU_RUN_TEST(float_tools_equal_test);
-}
-
-int run_minunit_test_float_tools() {
-    MU_RUN_SUITE(float_tools_suite);
-    return MU_EXIT_CODE;
-}

+ 0 - 39
applications/debug/unit_tests/furi/furi_memmgr_test.c

@@ -1,39 +0,0 @@
-#include "../minunit.h"
-#include <stdlib.h>
-#include <string.h>
-#include <stdbool.h>
-
-void test_furi_memmgr() {
-    void* ptr;
-
-    // allocate memory case
-    ptr = malloc(100);
-    mu_check(ptr != NULL);
-    // test that memory is zero-initialized after allocation
-    for(int i = 0; i < 100; i++) {
-        mu_assert_int_eq(0, ((uint8_t*)ptr)[i]);
-    }
-    free(ptr);
-
-    // reallocate memory case
-    ptr = malloc(100);
-    memset(ptr, 66, 100);
-    ptr = realloc(ptr, 200);
-    mu_check(ptr != NULL);
-
-    // test that memory is really reallocated
-    for(int i = 0; i < 100; i++) {
-        mu_assert_int_eq(66, ((uint8_t*)ptr)[i]);
-    }
-
-    // TODO: fix realloc to copy only old size, and write testcase that leftover of reallocated memory is zero-initialized
-    free(ptr);
-
-    // allocate and zero-initialize array (calloc)
-    ptr = calloc(100, 2);
-    mu_check(ptr != NULL);
-    for(int i = 0; i < 100 * 2; i++) {
-        mu_assert_int_eq(0, ((uint8_t*)ptr)[i]);
-    }
-    free(ptr);
-}

+ 0 - 45
applications/debug/unit_tests/furi/furi_pubsub_test.c

@@ -1,45 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <furi.h>
-#include "../minunit.h"
-
-const uint32_t context_value = 0xdeadbeef;
-const uint32_t notify_value_0 = 0x12345678;
-const uint32_t notify_value_1 = 0x11223344;
-
-uint32_t pubsub_value = 0;
-uint32_t pubsub_context_value = 0;
-
-void test_pubsub_handler(const void* arg, void* ctx) {
-    pubsub_value = *(uint32_t*)arg;
-    pubsub_context_value = *(uint32_t*)ctx;
-}
-
-void test_furi_pubsub() {
-    FuriPubSub* test_pubsub = NULL;
-    FuriPubSubSubscription* test_pubsub_subscription = NULL;
-
-    // init pubsub case
-    test_pubsub = furi_pubsub_alloc();
-    mu_assert_pointers_not_eq(test_pubsub, NULL);
-
-    // subscribe pubsub case
-    test_pubsub_subscription =
-        furi_pubsub_subscribe(test_pubsub, test_pubsub_handler, (void*)&context_value);
-    mu_assert_pointers_not_eq(test_pubsub_subscription, NULL);
-
-    /// notify pubsub case
-    furi_pubsub_publish(test_pubsub, (void*)&notify_value_0);
-    mu_assert_int_eq(pubsub_value, notify_value_0);
-    mu_assert_int_eq(pubsub_context_value, context_value);
-
-    // unsubscribe pubsub case
-    furi_pubsub_unsubscribe(test_pubsub, test_pubsub_subscription);
-
-    /// notify unsubscribed pubsub case
-    furi_pubsub_publish(test_pubsub, (void*)&notify_value_1);
-    mu_assert_int_not_eq(pubsub_value, notify_value_1);
-
-    // delete pubsub case
-    furi_pubsub_free(test_pubsub);
-}

+ 0 - 20
applications/debug/unit_tests/furi/furi_record_test.c

@@ -1,20 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <furi.h>
-#include "../minunit.h"
-
-void test_furi_create_open() {
-    // 1. Create record
-    uint8_t test_data = 0;
-    furi_record_create("test/holding", (void*)&test_data);
-
-    // 2. Open it
-    void* record = furi_record_open("test/holding");
-    mu_assert_pointers_eq(record, &test_data);
-
-    // 3. Close it
-    furi_record_close("test/holding");
-
-    // 4. Clean up
-    furi_record_destroy("test/holding");
-}

+ 0 - 469
applications/debug/unit_tests/furi/furi_string_test.c

@@ -1,469 +0,0 @@
-#include <furi.h>
-#include "../minunit.h"
-
-static void test_setup(void) {
-}
-
-static void test_teardown(void) {
-}
-
-static FuriString* furi_string_alloc_vprintf_test(const char format[], ...) {
-    va_list args;
-    va_start(args, format);
-    FuriString* string = furi_string_alloc_vprintf(format, args);
-    va_end(args);
-    return string;
-}
-
-MU_TEST(mu_test_furi_string_alloc_free) {
-    FuriString* tmp;
-    FuriString* string;
-
-    // test alloc and free
-    string = furi_string_alloc();
-    mu_check(string != NULL);
-    mu_check(furi_string_empty(string));
-    furi_string_free(string);
-
-    // test furi_string_alloc_set_str and free
-    string = furi_string_alloc_set_str("test");
-    mu_check(string != NULL);
-    mu_check(!furi_string_empty(string));
-    mu_check(furi_string_cmp(string, "test") == 0);
-    furi_string_free(string);
-
-    // test furi_string_alloc_set and free
-    tmp = furi_string_alloc_set("more");
-    string = furi_string_alloc_set(tmp);
-    furi_string_free(tmp);
-    mu_check(string != NULL);
-    mu_check(!furi_string_empty(string));
-    mu_check(furi_string_cmp(string, "more") == 0);
-    furi_string_free(string);
-
-    // test alloc_printf and free
-    string = furi_string_alloc_printf("test %d %s %c 0x%02x", 1, "two", '3', 0x04);
-    mu_check(string != NULL);
-    mu_check(!furi_string_empty(string));
-    mu_check(furi_string_cmp(string, "test 1 two 3 0x04") == 0);
-    furi_string_free(string);
-
-    // test alloc_vprintf and free
-    string = furi_string_alloc_vprintf_test("test %d %s %c 0x%02x", 4, "five", '6', 0x07);
-    mu_check(string != NULL);
-    mu_check(!furi_string_empty(string));
-    mu_check(furi_string_cmp(string, "test 4 five 6 0x07") == 0);
-    furi_string_free(string);
-
-    // test alloc_move and free
-    tmp = furi_string_alloc_set("move");
-    string = furi_string_alloc_move(tmp);
-    mu_check(string != NULL);
-    mu_check(!furi_string_empty(string));
-    mu_check(furi_string_cmp(string, "move") == 0);
-    furi_string_free(string);
-}
-
-MU_TEST(mu_test_furi_string_mem) {
-    FuriString* string = furi_string_alloc_set("test");
-    mu_check(string != NULL);
-    mu_check(!furi_string_empty(string));
-
-    // TODO: how to test furi_string_reserve?
-
-    // test furi_string_reset
-    furi_string_reset(string);
-    mu_check(furi_string_empty(string));
-
-    // test furi_string_swap
-    furi_string_set(string, "test");
-    FuriString* swap_string = furi_string_alloc_set("swap");
-    furi_string_swap(string, swap_string);
-    mu_check(furi_string_cmp(string, "swap") == 0);
-    mu_check(furi_string_cmp(swap_string, "test") == 0);
-    furi_string_free(swap_string);
-
-    // test furi_string_move
-    FuriString* move_string = furi_string_alloc_set("move");
-    furi_string_move(string, move_string);
-    mu_check(furi_string_cmp(string, "move") == 0);
-    // move_string is now empty
-    // and tested by leaked memory check at the end of the tests
-
-    furi_string_set(string, "abracadabra");
-
-    // test furi_string_hash
-    mu_assert_int_eq(0xc3bc16d7, furi_string_hash(string));
-
-    // test furi_string_size
-    mu_assert_int_eq(11, furi_string_size(string));
-
-    // test furi_string_empty
-    mu_check(!furi_string_empty(string));
-    furi_string_reset(string);
-    mu_check(furi_string_empty(string));
-
-    furi_string_free(string);
-}
-
-MU_TEST(mu_test_furi_string_getters) {
-    FuriString* string = furi_string_alloc_set("test");
-
-    // test furi_string_get_char
-    mu_check(furi_string_get_char(string, 0) == 't');
-    mu_check(furi_string_get_char(string, 1) == 'e');
-    mu_check(furi_string_get_char(string, 2) == 's');
-    mu_check(furi_string_get_char(string, 3) == 't');
-
-    // test furi_string_get_cstr
-    mu_assert_string_eq("test", furi_string_get_cstr(string));
-    furi_string_free(string);
-}
-
-static FuriString* furi_string_vprintf_test(FuriString* string, const char format[], ...) {
-    va_list args;
-    va_start(args, format);
-    furi_string_vprintf(string, format, args);
-    va_end(args);
-    return string;
-}
-
-MU_TEST(mu_test_furi_string_setters) {
-    FuriString* tmp;
-    FuriString* string = furi_string_alloc();
-
-    // test furi_string_set_str
-    furi_string_set_str(string, "test");
-    mu_assert_string_eq("test", furi_string_get_cstr(string));
-
-    // test furi_string_set
-    tmp = furi_string_alloc_set("more");
-    furi_string_set(string, tmp);
-    furi_string_free(tmp);
-    mu_assert_string_eq("more", furi_string_get_cstr(string));
-
-    // test furi_string_set_strn
-    furi_string_set_strn(string, "test", 2);
-    mu_assert_string_eq("te", furi_string_get_cstr(string));
-
-    // test furi_string_set_char
-    furi_string_set_char(string, 0, 'a');
-    furi_string_set_char(string, 1, 'b');
-    mu_assert_string_eq("ab", furi_string_get_cstr(string));
-
-    // test furi_string_set_n
-    tmp = furi_string_alloc_set("dodecahedron");
-    furi_string_set_n(string, tmp, 4, 5);
-    furi_string_free(tmp);
-    mu_assert_string_eq("cahed", furi_string_get_cstr(string));
-
-    // test furi_string_printf
-    furi_string_printf(string, "test %d %s %c 0x%02x", 1, "two", '3', 0x04);
-    mu_assert_string_eq("test 1 two 3 0x04", furi_string_get_cstr(string));
-
-    // test furi_string_vprintf
-    furi_string_vprintf_test(string, "test %d %s %c 0x%02x", 4, "five", '6', 0x07);
-    mu_assert_string_eq("test 4 five 6 0x07", furi_string_get_cstr(string));
-
-    furi_string_free(string);
-}
-
-static FuriString* furi_string_cat_vprintf_test(FuriString* string, const char format[], ...) {
-    va_list args;
-    va_start(args, format);
-    furi_string_cat_vprintf(string, format, args);
-    va_end(args);
-    return string;
-}
-
-MU_TEST(mu_test_furi_string_appends) {
-    FuriString* tmp;
-    FuriString* string = furi_string_alloc();
-
-    // test furi_string_push_back
-    furi_string_push_back(string, 't');
-    furi_string_push_back(string, 'e');
-    furi_string_push_back(string, 's');
-    furi_string_push_back(string, 't');
-    mu_assert_string_eq("test", furi_string_get_cstr(string));
-    furi_string_push_back(string, '!');
-    mu_assert_string_eq("test!", furi_string_get_cstr(string));
-
-    // test furi_string_cat_str
-    furi_string_cat_str(string, "test");
-    mu_assert_string_eq("test!test", furi_string_get_cstr(string));
-
-    // test furi_string_cat
-    tmp = furi_string_alloc_set("more");
-    furi_string_cat(string, tmp);
-    furi_string_free(tmp);
-    mu_assert_string_eq("test!testmore", furi_string_get_cstr(string));
-
-    // test furi_string_cat_printf
-    furi_string_cat_printf(string, "test %d %s %c 0x%02x", 1, "two", '3', 0x04);
-    mu_assert_string_eq("test!testmoretest 1 two 3 0x04", furi_string_get_cstr(string));
-
-    // test furi_string_cat_vprintf
-    furi_string_cat_vprintf_test(string, "test %d %s %c 0x%02x", 4, "five", '6', 0x07);
-    mu_assert_string_eq(
-        "test!testmoretest 1 two 3 0x04test 4 five 6 0x07", furi_string_get_cstr(string));
-
-    furi_string_free(string);
-}
-
-MU_TEST(mu_test_furi_string_compare) {
-    FuriString* string_1 = furi_string_alloc_set("string_1");
-    FuriString* string_2 = furi_string_alloc_set("string_2");
-
-    // test furi_string_cmp
-    mu_assert_int_eq(0, furi_string_cmp(string_1, string_1));
-    mu_assert_int_eq(0, furi_string_cmp(string_2, string_2));
-    mu_assert_int_eq(-1, furi_string_cmp(string_1, string_2));
-    mu_assert_int_eq(1, furi_string_cmp(string_2, string_1));
-
-    // test furi_string_cmp_str
-    mu_assert_int_eq(0, furi_string_cmp_str(string_1, "string_1"));
-    mu_assert_int_eq(0, furi_string_cmp_str(string_2, "string_2"));
-    mu_assert_int_eq(-1, furi_string_cmp_str(string_1, "string_2"));
-    mu_assert_int_eq(1, furi_string_cmp_str(string_2, "string_1"));
-
-    // test furi_string_cmpi
-    furi_string_set(string_1, "string");
-    furi_string_set(string_2, "StrIng");
-    mu_assert_int_eq(0, furi_string_cmpi(string_1, string_1));
-    mu_assert_int_eq(0, furi_string_cmpi(string_2, string_2));
-    mu_assert_int_eq(0, furi_string_cmpi(string_1, string_2));
-    mu_assert_int_eq(0, furi_string_cmpi(string_2, string_1));
-    furi_string_set(string_1, "string_1");
-    furi_string_set(string_2, "StrIng_2");
-    mu_assert_int_eq(32, furi_string_cmp(string_1, string_2));
-    mu_assert_int_eq(-32, furi_string_cmp(string_2, string_1));
-    mu_assert_int_eq(-1, furi_string_cmpi(string_1, string_2));
-    mu_assert_int_eq(1, furi_string_cmpi(string_2, string_1));
-
-    // test furi_string_cmpi_str
-    furi_string_set(string_1, "string");
-    mu_assert_int_eq(0, furi_string_cmp_str(string_1, "string"));
-    mu_assert_int_eq(32, furi_string_cmp_str(string_1, "String"));
-    mu_assert_int_eq(32, furi_string_cmp_str(string_1, "STring"));
-    mu_assert_int_eq(32, furi_string_cmp_str(string_1, "STRing"));
-    mu_assert_int_eq(32, furi_string_cmp_str(string_1, "STRIng"));
-    mu_assert_int_eq(32, furi_string_cmp_str(string_1, "STRINg"));
-    mu_assert_int_eq(32, furi_string_cmp_str(string_1, "STRING"));
-    mu_assert_int_eq(0, furi_string_cmpi_str(string_1, "string"));
-    mu_assert_int_eq(0, furi_string_cmpi_str(string_1, "String"));
-    mu_assert_int_eq(0, furi_string_cmpi_str(string_1, "STring"));
-    mu_assert_int_eq(0, furi_string_cmpi_str(string_1, "STRing"));
-    mu_assert_int_eq(0, furi_string_cmpi_str(string_1, "STRIng"));
-    mu_assert_int_eq(0, furi_string_cmpi_str(string_1, "STRINg"));
-    mu_assert_int_eq(0, furi_string_cmpi_str(string_1, "STRING"));
-
-    furi_string_free(string_1);
-    furi_string_free(string_2);
-}
-
-MU_TEST(mu_test_furi_string_search) {
-    //                                            012345678901234567
-    FuriString* haystack = furi_string_alloc_set("test321test123test");
-    FuriString* needle = furi_string_alloc_set("test");
-
-    // test furi_string_search
-    mu_assert_int_eq(0, furi_string_search(haystack, needle));
-    mu_assert_int_eq(7, furi_string_search(haystack, needle, 1));
-    mu_assert_int_eq(14, furi_string_search(haystack, needle, 8));
-    mu_assert_int_eq(FURI_STRING_FAILURE, furi_string_search(haystack, needle, 15));
-
-    FuriString* tmp = furi_string_alloc_set("testnone");
-    mu_assert_int_eq(FURI_STRING_FAILURE, furi_string_search(haystack, tmp));
-    furi_string_free(tmp);
-
-    // test furi_string_search_str
-    mu_assert_int_eq(0, furi_string_search_str(haystack, "test"));
-    mu_assert_int_eq(7, furi_string_search_str(haystack, "test", 1));
-    mu_assert_int_eq(14, furi_string_search_str(haystack, "test", 8));
-    mu_assert_int_eq(4, furi_string_search_str(haystack, "321"));
-    mu_assert_int_eq(11, furi_string_search_str(haystack, "123"));
-    mu_assert_int_eq(FURI_STRING_FAILURE, furi_string_search_str(haystack, "testnone"));
-    mu_assert_int_eq(FURI_STRING_FAILURE, furi_string_search_str(haystack, "test", 15));
-
-    // test furi_string_search_char
-    mu_assert_int_eq(0, furi_string_search_char(haystack, 't'));
-    mu_assert_int_eq(1, furi_string_search_char(haystack, 'e'));
-    mu_assert_int_eq(2, furi_string_search_char(haystack, 's'));
-    mu_assert_int_eq(3, furi_string_search_char(haystack, 't', 1));
-    mu_assert_int_eq(7, furi_string_search_char(haystack, 't', 4));
-    mu_assert_int_eq(FURI_STRING_FAILURE, furi_string_search_char(haystack, 'x'));
-
-    // test furi_string_search_rchar
-    mu_assert_int_eq(17, furi_string_search_rchar(haystack, 't'));
-    mu_assert_int_eq(15, furi_string_search_rchar(haystack, 'e'));
-    mu_assert_int_eq(16, furi_string_search_rchar(haystack, 's'));
-    mu_assert_int_eq(13, furi_string_search_rchar(haystack, '3'));
-    mu_assert_int_eq(FURI_STRING_FAILURE, furi_string_search_rchar(haystack, '3', 14));
-    mu_assert_int_eq(FURI_STRING_FAILURE, furi_string_search_rchar(haystack, 'x'));
-
-    furi_string_free(haystack);
-    furi_string_free(needle);
-}
-
-MU_TEST(mu_test_furi_string_equality) {
-    FuriString* string = furi_string_alloc_set("test");
-    FuriString* string_eq = furi_string_alloc_set("test");
-    FuriString* string_neq = furi_string_alloc_set("test2");
-
-    // test furi_string_equal
-    mu_check(furi_string_equal(string, string_eq));
-    mu_check(!furi_string_equal(string, string_neq));
-
-    // test furi_string_equal_str
-    mu_check(furi_string_equal_str(string, "test"));
-    mu_check(!furi_string_equal_str(string, "test2"));
-    mu_check(furi_string_equal_str(string_neq, "test2"));
-    mu_check(!furi_string_equal_str(string_neq, "test"));
-
-    furi_string_free(string);
-    furi_string_free(string_eq);
-    furi_string_free(string_neq);
-}
-
-MU_TEST(mu_test_furi_string_replace) {
-    FuriString* needle = furi_string_alloc_set("test");
-    FuriString* replace = furi_string_alloc_set("replace");
-    FuriString* string = furi_string_alloc_set("test123test");
-
-    // test furi_string_replace_at
-    furi_string_replace_at(string, 4, 3, "!biglongword!");
-    mu_assert_string_eq("test!biglongword!test", furi_string_get_cstr(string));
-
-    // test furi_string_replace
-    mu_assert_int_eq(17, furi_string_replace(string, needle, replace, 1));
-    mu_assert_string_eq("test!biglongword!replace", furi_string_get_cstr(string));
-    mu_assert_int_eq(0, furi_string_replace(string, needle, replace));
-    mu_assert_string_eq("replace!biglongword!replace", furi_string_get_cstr(string));
-    mu_assert_int_eq(FURI_STRING_FAILURE, furi_string_replace(string, needle, replace));
-    mu_assert_string_eq("replace!biglongword!replace", furi_string_get_cstr(string));
-
-    // test furi_string_replace_str
-    mu_assert_int_eq(20, furi_string_replace_str(string, "replace", "test", 1));
-    mu_assert_string_eq("replace!biglongword!test", furi_string_get_cstr(string));
-    mu_assert_int_eq(0, furi_string_replace_str(string, "replace", "test"));
-    mu_assert_string_eq("test!biglongword!test", furi_string_get_cstr(string));
-    mu_assert_int_eq(FURI_STRING_FAILURE, furi_string_replace_str(string, "replace", "test"));
-    mu_assert_string_eq("test!biglongword!test", furi_string_get_cstr(string));
-
-    // test furi_string_replace_all
-    furi_string_replace_all(string, needle, replace);
-    mu_assert_string_eq("replace!biglongword!replace", furi_string_get_cstr(string));
-
-    // test furi_string_replace_all_str
-    furi_string_replace_all_str(string, "replace", "test");
-    mu_assert_string_eq("test!biglongword!test", furi_string_get_cstr(string));
-
-    furi_string_free(string);
-    furi_string_free(needle);
-    furi_string_free(replace);
-}
-
-MU_TEST(mu_test_furi_string_start_end) {
-    FuriString* string = furi_string_alloc_set("start_end");
-    FuriString* start = furi_string_alloc_set("start");
-    FuriString* end = furi_string_alloc_set("end");
-
-    // test furi_string_start_with
-    mu_check(furi_string_start_with(string, start));
-    mu_check(!furi_string_start_with(string, end));
-
-    // test furi_string_start_with_str
-    mu_check(furi_string_start_with_str(string, "start"));
-    mu_check(!furi_string_start_with_str(string, "end"));
-
-    // test furi_string_end_with
-    mu_check(furi_string_end_with(string, end));
-    mu_check(!furi_string_end_with(string, start));
-
-    // test furi_string_end_with_str
-    mu_check(furi_string_end_with_str(string, "end"));
-    mu_check(!furi_string_end_with_str(string, "start"));
-
-    furi_string_free(string);
-    furi_string_free(start);
-    furi_string_free(end);
-}
-
-MU_TEST(mu_test_furi_string_trim) {
-    FuriString* string = furi_string_alloc_set("biglongstring");
-
-    // test furi_string_left
-    furi_string_left(string, 7);
-    mu_assert_string_eq("biglong", furi_string_get_cstr(string));
-
-    // test furi_string_right
-    furi_string_right(string, 3);
-    mu_assert_string_eq("long", furi_string_get_cstr(string));
-
-    // test furi_string_mid
-    furi_string_mid(string, 1, 2);
-    mu_assert_string_eq("on", furi_string_get_cstr(string));
-
-    // test furi_string_trim
-    furi_string_set(string, "   \n\r\tbiglongstring \n\r\t  ");
-    furi_string_trim(string);
-    mu_assert_string_eq("biglongstring", furi_string_get_cstr(string));
-    furi_string_set(string, "aaaabaaaabbaaabaaaabbtestaaaaaabbaaabaababaa");
-    furi_string_trim(string, "ab");
-    mu_assert_string_eq("test", furi_string_get_cstr(string));
-
-    furi_string_free(string);
-}
-
-MU_TEST(mu_test_furi_string_utf8) {
-    FuriString* utf8_string = furi_string_alloc_set("イルカ");
-
-    // test furi_string_utf8_length
-    mu_assert_int_eq(9, furi_string_size(utf8_string));
-    mu_assert_int_eq(3, furi_string_utf8_length(utf8_string));
-
-    // test furi_string_utf8_decode
-    const uint8_t dolphin_emoji_array[4] = {0xF0, 0x9F, 0x90, 0xAC};
-    FuriStringUTF8State state = FuriStringUTF8StateStarting;
-    FuriStringUnicodeValue value = 0;
-    furi_string_utf8_decode(dolphin_emoji_array[0], &state, &value);
-    mu_assert_int_eq(FuriStringUTF8StateDecoding3, state);
-    furi_string_utf8_decode(dolphin_emoji_array[1], &state, &value);
-    mu_assert_int_eq(FuriStringUTF8StateDecoding2, state);
-    furi_string_utf8_decode(dolphin_emoji_array[2], &state, &value);
-    mu_assert_int_eq(FuriStringUTF8StateDecoding1, state);
-    furi_string_utf8_decode(dolphin_emoji_array[3], &state, &value);
-    mu_assert_int_eq(FuriStringUTF8StateStarting, state);
-    mu_assert_int_eq(0x1F42C, value);
-
-    // test furi_string_utf8_push
-    furi_string_set(utf8_string, "");
-    furi_string_utf8_push(utf8_string, value);
-    mu_assert_string_eq("🐬", furi_string_get_cstr(utf8_string));
-
-    furi_string_free(utf8_string);
-}
-
-MU_TEST_SUITE(test_suite) {
-    MU_SUITE_CONFIGURE(&test_setup, &test_teardown);
-
-    MU_RUN_TEST(mu_test_furi_string_alloc_free);
-    MU_RUN_TEST(mu_test_furi_string_mem);
-    MU_RUN_TEST(mu_test_furi_string_getters);
-    MU_RUN_TEST(mu_test_furi_string_setters);
-    MU_RUN_TEST(mu_test_furi_string_appends);
-    MU_RUN_TEST(mu_test_furi_string_compare);
-    MU_RUN_TEST(mu_test_furi_string_search);
-    MU_RUN_TEST(mu_test_furi_string_equality);
-    MU_RUN_TEST(mu_test_furi_string_replace);
-    MU_RUN_TEST(mu_test_furi_string_start_end);
-    MU_RUN_TEST(mu_test_furi_string_trim);
-    MU_RUN_TEST(mu_test_furi_string_utf8);
-}
-
-int run_minunit_test_furi_string() {
-    MU_RUN_SUITE(test_suite);
-
-    return MU_EXIT_CODE;
-}

Некоторые файлы не были показаны из-за большого количества измененных файлов