diff --git a/.ci_files/rgb.patch b/.ci_files/rgb.patch index ad0a8d80df..b5895d9c1f 100644 --- a/.ci_files/rgb.patch +++ b/.ci_files/rgb.patch @@ -637,9 +637,9 @@ index 83e1603..45798ca 100644 #include +#include - #define LED_CURRENT_RED 50 - #define LED_CURRENT_GREEN 50 -@@ -31,22 +32,21 @@ void furi_hal_light_init() { + #define LED_CURRENT_RED (50u) + #define LED_CURRENT_GREEN (50u) +@@ -31,22 +32,21 @@ void furi_hal_light_init(void) { } void furi_hal_light_set(Light light, uint8_t value) { diff --git a/.pvsconfig b/.pvsconfig index 49c63ad739..b6001ca5c0 100644 --- a/.pvsconfig +++ b/.pvsconfig @@ -1,10 +1,10 @@ # MLib macros we can't do much about. //-V:M_LET:1048,1044 //-V:M_EACH:1048,1044 -//-V:ARRAY_DEF:760,747,568,776,729,712,654 -//-V:LIST_DEF:760,747,568,712,729,654,776 +//-V:ARRAY_DEF:760,747,568,776,729,712,654,1103 +//-V:LIST_DEF:760,747,568,712,729,654,776,1103 //-V:BPTREE_DEF2:779,1086,557,773,512 -//-V:DICT_DEF2:779,524,776,760,1044,1001,729,590,568,747,685 +//-V:DICT_DEF2:779,524,776,760,1044,1001,729,590,568,747,685,1103 //-V:ALGO_DEF:1048,747,1044 //-V:TUPLE_DEF2:524,590,1001,760 @@ -42,8 +42,5 @@ # Model-related warnings //-V:with_view_model:1044,1048 -# Functions that always return the same error code -//-V:picopass_device_decrypt:1048 - # Examples //V_EXCLUDE_PATH applications/examples/ \ No newline at end of file diff --git a/.vscode/example/settings.json b/.vscode/example/settings.json index 00da3af2f8..a591949013 100644 --- a/.vscode/example/settings.json +++ b/.vscode/example/settings.json @@ -14,7 +14,7 @@ "*.scons": "python", "SConscript": "python", "SConstruct": "python", - "*.fam": "python", + "*.fam": "python" }, "clangd.arguments": [ // We might be able to tighten this a bit more to only include the correct toolchain. diff --git a/CHANGELOG.md b/CHANGELOG.md index 9f0aadb404..72b83ae12b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,94 +1,75 @@ ## New changes -* NFC: **EMV Fixes and imporvements** (old saved files may be not compatible now) (by @wosk & @Leptopt1los | PR #702) -* NFC: **Parsers refactoring** (by @Leptopt1los) -* NFC: **Kazan parser improved** - token parse option added (by @Leptopt1los) -* NFC: **Update ndef parser**, mf classic dict changes (by @Willy-JL) -* RFID: Test swap of em4100 t5577 blocks (details in issue 3463 OFW) -* RFID: Fix RAW read crash (by @Willy-JL) -* Infrared: Update universal remote assets (by @amec0e | PR #718 #719) -* SubGHz: Add 430.50 mhz (by @MizumasuShoichi | PR #721) -* SubGHz: **Magellan Event Code Update** (by @wooferguy | PR #713) -* SubGHz: Reduce subghz add manually scene flash size (by @Willy-JL) -* SubGHz: Fix led blink on decode raw > signal info (by @Willy-JL) -* HID App: apply fix for ms teams on macos (by @cpressland) -* HID App: merge official fw hid app keyboard changes -* Misc: Use non prefixed names for regular files with random name -* Misc: Revert usb cdc config changes to verify issue (storage timeout during firmware update) (OFW 3452) -* Misc: Fixes for text box and uart echo demo app, remove duplicated emv parser plugin (by @Willy-JL) -* Expansion `is_connected` API to check for VGM (by @HaxSam) -* New JavaScript Modules `UsbDisk`,`badusb.quit() + altstring`,`SubGHz`,`Submenu`,`BleBeacon`,`Keyboard`,`Math`,`GPIO`, `textbox` (by @Willy-JL, @Spooks4576, @Sil333033, @oldip) -* Apps: **BadBT renamed and moved from Apps-Bluetooth to Apps-Tools as BadKB** -* Apps: Added **FindMy Flipper** app -* Apps: NFC Magic - **Gen4 improvements** +* LFRFID: **Electra intercom protocol support** (Romania) (by @Leptopt1los | PR #750) +* NFC: Temp fix for `iso14443_4_layer_decode_block` crash +* NFC: CharlieCard parser (by @zacharyweiss) +* SubGHz: FAAC RC XT - add 0xB button code on arrow buttons for programming mode +* SubGHz: Add Manually - Sommer FM fixes +* SubGHz: Enabled tx-rx state on unused gpio pin by default (**external amp option was removed and is enabled by default now**) +* SubGHz: **Status output !TX/RX on the GDO2 CC1101 pin** (by @quen0n | PR #742) +* SubGHz: Reworked saved settings (by @xMasterX and @Willy-JL) +* Desktop: Fixes for animation unload (by @Willy-JL) +* iButton: Updated DS1420 for latest ibutton changes +* Misc: Allow no prefix usage of name_generator_make_detailed_datetime +* Misc: Allow setting view dispatcher callbacks to NULL +* Misc: Added `void` due to `-Wstrict-prototypes` +* Misc: Some code cleanup and proper log levels in nfc parsers +* Infrared: Allow external apps to use infrared settings (by @Willy-JL) +* JS & HAL: Various fixes and FURI_HAL_RANDOM_MAX define added (by @Willy-JL) +* JS: **BadUSB layout support** (by @Willy-JL) +* JS: New Modules `widget`, `vgm` and path globals (by @jamisonderek) +* Apps: Enhance Random Interval and Movement Functionality in HID Mouse Jiggler for Improved Stealth and Human-Like Behavior (by @gushmazuko | PR #746) +* Apps: NFC Magic - **Gen2 writing support, Gen4 NTAG password and PACK fixes** (by @Astrrra) +* Apps: MFKey - **fixed crashes**, add more free ram (by @noproto & @Willy-JL) * Apps: **Check out Apps updates by following** [this link](https://github.com/xMasterX/all-the-plugins/commits/dev) -* OFW: BLE/GAP fixes -* OFW: Add support for Pioneer SR IR remotes -* OFW: fbt/ufbt: Ensure POSIX paths are passed to GDB on all platforms -* OFW: Add support for DEFAULT_STRING_DELAY in Bad USB App -* OFW: Adding F13-F24 function key support to BadUSB -* OFW PR 3532: NFC UI fixes (by gornekich) -* OFW PR 3504: NFC: **Slix privacy password reveal and Desfire detect fix** (by gornekich) -* OFW: **Infrared fixes and more** -* OFW: NFC Parsers cosmetic fixes -* OFW: NFC wording fixes -* OFW: **Fix iButton emulation regression** -* OFW: Add the Freedom_2_dolphins animation -* OFW: Infrared: Add Fujitsu ASYG24KMTB -* OFW: Asynchronous Infrared remote manipulation -* OFW: Fix troika 4K keys -* OFW: Archive: Fix item focus after aborting the Delete operation -* OFW: Troyka parser improvements (by UL Team) -* OFW: NFC: Fix washcity plugin verify function being to greedy -* OFW: Parser for Santiago, Chile BIP transit card -* OFW: WiFi board: fixed update script on Windows (unfortunately also Mac and Linux) -* OFW: Gui: reset canvas orientation and frame when entering direct draw mode -* OFW: FBT/uFBT: Enable C++20/GNU23 in VSCode IntelliSense -* OFW: Toolchain fixes -* OFW: Quote $FBT_TOOLCHAIN_PATH to avoid splitting -* OFW: **ble: profile rework** -* OFW: lfrfid/em4100: added support for different bit rates (16clk was added back into UL, still not reading properly) -* OFW: T5577 lib: write with mask function added -* OFW: Archive: fixed Apps tab ext filter -* OFW: FuriHalRtc refactor: new datetime lib (by UL Team) -* OFW: bit_lib and nfc_util refactor (by UL Team) -* OFW: Gui text box: fix formatted string memory reservation -* OFW: JS debug disabled, archive and file browser fixes -* OFW: VSCode integration fixes for new toolchain -* OFW: **FIX ISO15693 emulation** -* OFW: JS serial module renamed, uart channel selection -* OFW: mjs: minor fixes -* OFW: **JavaScript runner** -* OFW: Fixed MyKey check LockID -* OFW: Check universal remote files before loading -* OFW: NFC: fix retry scene navigation logic -* OFW: Expansion module service improvements -* OFW: New toolchain with gcc 12 (+ aarch64 support!) -* OFW: HID app: keyboard modifiers fix -* OFW: CLI: cat command crash workaround -* OFW: NFC: Custom UID entry when adding manually -* OFW: Added NFC plugin; Some parser -* OFW: **Slix disable privacy** (Unlock SLIX-L) -* OFW: NFC: **Add support for Gallagher access control** (MIFARE Classic only) -* OFW: furi/core/timer: resolve timer handle use-after-free post deletion -* OFW: FuriHal: various GPIO improvements -* OFW: GUI: canvas commit callback has been moved to canvas. Direct Draw apps can now be streamed via RPC. -* OFW: nfc app: fix incorrect protocol detection in save scene (by UL Team) -* OFW: NFC: **MFC Unlock with Dictionary** -* OFW: ITSO Parser (UK) -* OFW: NFC: fix application opening from browser -* OFW: Rework more info scene for Ultralight cards -* OFW: NFC UI refactor -* OFW: Add an NFC parser for the San Francisco Bay Area "Clipper" transit card. -* OFW: Fix nfc_protocol_support_scene_save_name_on_event crash -* OFW: NFC: Display unread Mifare Classic bytes as question marks -* OFW: Troika layout fixes -* OFW: NFC: MF Classic parsers read() fix (dictionary attack skip) +* OFW PR 3616: NFC: Mf Desfire fix reading big files (by gornekich) +* OFW: iButton: fix crash when deleting some keys +* OFW: Desktop: cleanup error popups +* OFW: Troika parser visual fixes +* OFW: Fix the retry/exit confirmation prompts in iButton +* OFW: nfc app: add legacy keys for plantain cards +* OFW: GUI: Fix array out of bounds in menu exit +* OFW: add support for S(WTX) request in iso14443_4a_poller +* OFW: Mosgortrans parser output fixes +* OFW: BLE: Add GapPairingNone support +* OFW: iButton new UI +* OFW: FuriHal: add ADC API +* OFW: Mf Desfire multiple file rights support +* OFW: **Felica poller** (NFC-F) +* OFW: Desktop/Loader: Unload animations before loading FAPs +* OFW: JS Documentation +* OFW: **Update radio stack to v1.19.0** +* OFW: **Move crypto1 to helpers, add it to the public API** +* OFW: Explain RNG differences, add FURI_HAL_RANDOM_MAX +* OFW: Furi: Add "out of memory" and "malloc(0)" crash messages +* OFW: IR: Fix crash on duty_cycle=1 +* OFW: **Desktop: ensure that animation is unloaded before app start (fixes some out of memory crashes)** +* OFW: Hide unlock with reader for MFU-C +* OFW: fbt: fixed missing FBT_FAP_DEBUG_ELF_ROOT to dist env +* OFW: fbt: added -Wstrict-prototypes for main firmware +* OFW: Mifare Ultralight naming fix +* OFW: IR: Remember OTG state +* OFW: Bad USB: fix crash when selecting a keyboard layout +* OFW: L1_Mods animation update : adding VGM visual +* OFW: RFID Improvements +* OFW: Fixed plugins and UI +* OFW: **NFC: Fix mf desfire detect** +* OFW: infrared_transmit.h was missing `#pragma once` +* OFW: Show the wrong PIN Attempt count on the login screen +* OFW: SavedStruct: Introduce saved_struct_get_metadata +* OFW: JS CLI command +* OFW: Add ChromeOS Bad USB demo +* OFW: **Configurable Infrared TX output** (previous UL version is replaced with OFW version, new features added "AutoDetect" and saving settings) +* OFW: BadUSB: BLE, media keys, Fn/Globe key commands +* OFW: NFC: Slix privacy password reveal ->(was included in previous UL release) and **Desfire detect fix** +* OFW: github: additional pre-upload checks for doxygen workflow +* OFW: NFC UI fixes +* OFW: Gui: unicode support, new canvas API +* OFW: **Api Symbols: replace asserts with checks**

#### Known NFC post-refactor regressions list: - Mifare Mini clones reading is broken (original mini working fine) (OFW) - NFC CLI was removed with refactoring (OFW) (will be back soon) -- Current list of affected apps: https://github.com/xMasterX/all-the-plugins/tree/dev/apps_broken_by_last_refactors -- Also in app **Enhanced Sub-GHz Chat** - NFC part was temporarily removed to make app usable, NFC part of the app requires remaking it with new nfc stack +- Mifare Nested not ported to latest API yet, `unlshd-065` is the latest version on old NFC API that works with "nested app" ---- @@ -104,13 +85,14 @@ |cloudtips|only RU payments accepted|https://pay.cloudtips.ru/p/7b3e9d65| |YooMoney|only RU payments accepted|https://yoomoney.ru/fundraise/XA49mgQLPA0.221209| |USDT|(TRC20)|`TSXcitMSnWXUFqiUfEXrTVpVewXy2cYhrs`| -|BCH||`qquxfyzntuqufy2dx0hrfr4sndp0tucvky4sw8qyu3`| |ETH|(BSC/ERC20-Tokens)|`darkflippers.eth` (or `0xFebF1bBc8229418FF2408C07AF6Afa49152fEc6a`)| |BTC||`bc1q0np836jk9jwr4dd7p6qv66d04vamtqkxrecck9`| +|SOL|(Solana/Tokens)|`DSgwouAEgu8iP5yr7EHHDqMNYWZxAqXWsTEeqCAXGLj8`| |DOGE||`D6R6gYgBn5LwTNmPyvAQR6bZ9EtGgFCpvv`| |LTC||`ltc1q3ex4ejkl0xpx3znwrmth4lyuadr5qgv8tmq8z9`| +|BCH||`qquxfyzntuqufy2dx0hrfr4sndp0tucvky4sw8qyu3`| |XMR|(Monero)| `41xUz92suUu1u5Mu4qkrcs52gtfpu9rnZRdBpCJ244KRHf6xXSvVFevdf2cnjS7RAeYr5hn9MsEfxKoFDRSctFjG5fv1Mhn`| -|TON||`EQCOqcnYkvzOZUV_9bPE_8oTbOrOF03MnF-VcJyjisTZmpGf`| +|TON||`UQCOqcnYkvzOZUV_9bPE_8oTbOrOF03MnF-VcJyjisTZmsxa`| #### Thanks to our sponsors who supported project in the past and special thanks to sponsors who supports us on regular basis: ClaraCrazy, Pathfinder [Count Zero cDc], callmezimbra, Quen0n, MERRON, grvpvl (lvpvrg), art_col, ThurstonWaffles, Moneron, UterGrooll, LUCFER, Northpirate, zloepuzo, T.Rat, Alexey B., ionelife, ... diff --git a/ReadMe.md b/ReadMe.md index be41a8c1cf..1567936bd6 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -1,6 +1,6 @@

-fzCUSTOM +Unleashed Firmware Logo

@@ -20,15 +20,15 @@ ### Welcome to the Flipper Zero Unleashed Firmware repo! -#### **This firmware is a fork from** [flipperdevices/flipperzero-firmware](https://github.com/flipperdevices/flipperzero-firmware) +#### **This firmware is a fork from original (OFW) firmware** [flipperdevices/flipperzero-firmware](https://github.com/flipperdevices/flipperzero-firmware)
-### Most stable custom firmware focused on new features and improvements of original firmware components, with almost no UI changes +### Most stable custom firmware focused on new features and improvements of original firmware components, keeping compatibility with original firmware API and Apps
-##### This software is for experimental purposes only and is not meant for any illegal activity/purposes.
We do not condone illegal activity and strongly encourage keeping transmissions to legal/valid uses allowed by law.
Also, this software is made without any support from Flipper Devices and is in no way related to the official devs. +##### This software is for experimental purposes only and is not meant for any illegal activity/purposes.
We do not condone illegal activity and strongly encourage keeping transmissions to legal/valid uses allowed by law.
Also, this software is made without any support from Flipper Devices and is in no way related to the official team.
@@ -36,7 +36,7 @@ ## FAQ (frequently asked questions) [Follow this link to find answers to most asked questions](https://github.com/DarkFlippers/unleashed-firmware/blob/dev/documentation/FAQ.md) -## Dev builds (unstable) +## Dev builds (unstable) (built automatically from dev branch) - https://dev.unleashedflip.com/ - https://t.me/kotnehleb ## Releases in Telegram @@ -45,19 +45,20 @@ # What's changed - **Sub-GHz** *lib & hal* - Regional TX restrictions removed - - Extra Sub-GHz frequencies + - Extra Sub-GHz frequencies added - Frequency range can be extended in settings file (Warning: It can damage Flipper's hardware) - Many rolling code [protocols](https://github.com/DarkFlippers/unleashed-firmware#current-modified-and-new-sub-ghz-protocols-list) now have the ability to save & send captured signals - FAAC SLH (Spa) & BFT Mitto (keeloq secure with seed) manual creation - External CC1101 module support [(by quen0n)](https://github.com/DarkFlippers/unleashed-firmware/pull/307) - **Sub-GHz** *Main App* - - Save last used frequency [(by derskythe)](https://github.com/DarkFlippers/unleashed-firmware/pull/77) + - Save last used settings [(by derskythe)](https://github.com/DarkFlippers/unleashed-firmware/pull/77) - New frequency analyzer [(by ClusterM)](https://github.com/DarkFlippers/unleashed-firmware/pull/43) - Press OK in frequency analyzer to use detected frequency in Read modes [(by derskythe)](https://github.com/DarkFlippers/unleashed-firmware/pull/77) - Long press OK button in Sub-GHz Frequency analyzer to switch to Read menu [(by derskythe)](https://github.com/DarkFlippers/unleashed-firmware/pull/79) - New option to use timestamps + protocol name when you saving file, instead of random name or timestamp only - Enable in `Radio Settings -> Protocol Names = ON` - Read mode UI improvements (shows time when signal was received) (by @wosk) - External CC1101 module support (Hardware SPI used) + - External CC1101 module amplifier control (or LED control) support (enabled by default) - **Hold right in received signal list to delete selected signal** - **Custom buttons for Keeloq / Alutech AT4N / Nice Flor S / Somfy Telis / Security+ 2.0 / CAME Atomo** - now you can use arrow buttons to send signal with different button code - `Add manually` menu extended with new protocols @@ -75,12 +76,11 @@ - Recompiled IR TV Universal Remote for ALL buttons - Universal remotes for Projectors, Fans, A/Cs and Audio(soundbars, etc.) -> Also always updated and verified by our team - Infrared -> `RCA` Protocol - - Infrared -> Debug TX PIN output settings + - Infrared -> External IR modules support (with autodetect by OFW) - **NFC/RFID/iButton** - * LFRFID/iButton Fuzzer plugins - * Extra Mifare Classic keys + * LFRFID and iButton Fuzzer plugins + * Extra Mifare Classic keys in system dict * EMV Protocol + Public data parser (by @Leptopt1los and @wosk) - * NFC/LFRFID - Stop emulation after 5 mins to avoid antenna damage (by @Leptopt1los) * NFC `Add manually` -> Mifare Classic with custom UID * NFC parsers: Umarsh, Zolotaya Korona, Kazan, Metromoney, Moscow Social Card, Troika (reworked) and [many others](https://github.com/DarkFlippers/unleashed-firmware/tree/dev/applications/main/nfc/plugins/supported_cards) (by @Leptopt1los and @assasinfil) - **Quality of life & other features** @@ -91,7 +91,7 @@ - Battery percentage display with different styles `Settings -> Desktop -> Battery View` - More games in Dummy Mode -> click or hold any of arrow buttons - Lock device with pin(or regular lock if pin not set) by holding UP button on main screen [(by an4tur0r)](https://github.com/DarkFlippers/unleashed-firmware/pull/107) - - **BadBT** plugin (BT version of BadKB) [(by Willy-JL, ClaraCrazy, XFW contributors)](https://github.com/ClaraCrazy/Flipper-Xtreme/tree/dev/applications/main/bad_kb) - (See in Applications->Tools) - (aka BadUSB via Bluetooth) + - **BadKB** plugin [(by Willy-JL, ClaraCrazy, XFW contributors)](https://github.com/Flipper-XFW/Xtreme-Firmware/tree/dev/applications/main/bad_kb) - (See in Applications->Tools) - (aka BadUSB via Bluetooth) - BadUSB -> Keyboard layouts [(by rien > dummy-decoy)](https://github.com/dummy-decoy/flipperzero-firmware/tree/dummy_decoy/bad_usb_keyboard_layout) - Custom community plugins and games added + all known working apps can be downloaded in extra pack in every release - Other small fixes and changes throughout @@ -100,16 +100,16 @@ Also check the [changelog in releases](https://github.com/DarkFlippers/unleashed-firmware/releases) for latest updates! ### Current modified and new Sub-GHz protocols list: -Thanks to Official team (to their SubGHz Developer, Skorp) for implementing decoders for these protocols in OFW. +Thanks to Official team (to their SubGHz Developer, Skorp) for implementing support (decoder + encoder / or decode only) for these protocols in OFW. Keeloq [Not ALL systems supported for decode or emulation!] - [Supported manufacturers list](https://pastes.io/raw/unuj9bhe4m) -Encoders or sending made by @xMasterX: -- Nero Radio 57bit (+ 56bit encoder improvements) -- CAME 12bit/24bit encoder fixes (Fixes now merged in OFW) +Encoders or emulation support made by @xMasterX: +- Nero Radio 57bit (+ 56bit support) +- CAME 12bit/24bit encoder fixes (Fixes are now merged in OFW) - Keeloq: Dea Mio, Genius Bravo, GSN, HCS101, AN-Motors, JCM Tech, MHouse, Nice Smilo, DTM Neo, FAAC RC,XT, Mutancode, Normstahl, Beninca + Allmatic, Stilmatic, CAME Space, Aprimatic (model TR and similar), Centurion Nova (thanks Carlos !) -Encoders or sending made by @Eng1n33r(first implementation in Q2 2022) & @xMasterX (current version): +Encoders or emulation made by @Eng1n33r(first implementation in Q2 2022) and @xMasterX (current version): - CAME Atomo -> Update! check out new [instructions](https://github.com/DarkFlippers/unleashed-firmware/blob/dev/documentation/SubGHzRemoteProg.md) - Nice Flor S -> How to create new remote - [instructions](https://github.com/DarkFlippers/unleashed-firmware/blob/dev/documentation/SubGHzRemoteProg.md) - FAAC SLH (Spa) -> Update!!! Check out new [instructions](https://github.com/DarkFlippers/unleashed-firmware/blob/dev/documentation/SubGHzRemoteProg.md) @@ -117,7 +117,7 @@ Encoders or sending made by @Eng1n33r(first implementation in Q2 2022) & @xMaste - Star Line - Security+ v1 & v2 (encoders was made in OFW) -Encoders made by @assasinfil & @xMasterX: +Encoders made by @assasinfil and @xMasterX: - Somfy Telis -> How to create new remote - [instructions](https://github.com/DarkFlippers/unleashed-firmware/blob/dev/documentation/SubGHzRemoteProg.md) - Somfy Keytis - KingGates Stylo 4k @@ -126,10 +126,9 @@ Encoders made by @assasinfil & @xMasterX: ## Please support development of the project The majority of this project is developed and maintained by me, @xMasterX. -I'm unemployed, and the only income I receive is from your donations. Our team is small and the guys are working on this project as much as they can solely based on the enthusiasm they have for this project and the community. -- @Leptopt1los - NFC, RFID, IR Assets (only ACs), Plugins, and many other things -- @gid9798 - SubGHz, Plugins, many other things +- @Leptopt1los - NFC, RFID, Plugins, and many other things +- @gid9798 - SubGHz, Plugins, many other things - currently offline :( - @assasinfil - SubGHz protocols, NFC parsers - @Svaarich - UI design and animations - @amec0e - Infrared assets @@ -146,13 +145,14 @@ You can support us by using links or addresses below: |cloudtips|only RU payments accepted|https://pay.cloudtips.ru/p/7b3e9d65| |YooMoney|only RU payments accepted|https://yoomoney.ru/fundraise/XA49mgQLPA0.221209| |USDT|(TRC20)|`TSXcitMSnWXUFqiUfEXrTVpVewXy2cYhrs`| -|BCH||`qquxfyzntuqufy2dx0hrfr4sndp0tucvky4sw8qyu3`| |ETH|(BSC/ERC20-Tokens)|`darkflippers.eth` (or `0xFebF1bBc8229418FF2408C07AF6Afa49152fEc6a`)| |BTC||`bc1q0np836jk9jwr4dd7p6qv66d04vamtqkxrecck9`| +|SOL|(Solana/Tokens)|`DSgwouAEgu8iP5yr7EHHDqMNYWZxAqXWsTEeqCAXGLj8`| |DOGE||`D6R6gYgBn5LwTNmPyvAQR6bZ9EtGgFCpvv`| |LTC||`ltc1q3ex4ejkl0xpx3znwrmth4lyuadr5qgv8tmq8z9`| +|BCH||`qquxfyzntuqufy2dx0hrfr4sndp0tucvky4sw8qyu3`| |XMR|(Monero)| `41xUz92suUu1u5Mu4qkrcs52gtfpu9rnZRdBpCJ244KRHf6xXSvVFevdf2cnjS7RAeYr5hn9MsEfxKoFDRSctFjG5fv1Mhn`| -|TON||`EQCOqcnYkvzOZUV_9bPE_8oTbOrOF03MnF-VcJyjisTZmpGf`| +|TON||`UQCOqcnYkvzOZUV_9bPE_8oTbOrOF03MnF-VcJyjisTZmsxa`| ## Community apps included @@ -168,6 +168,8 @@ See full list and sources here: [xMasterX/all-the-plugins](https://github.com/xM ## [How to install](/documentation/HowToInstall.md) - [versions info](/CHANGELOG.md#recommended-update-option---web-updater): `n`,` `,`e`... ## Firmware & Development +### - **Developer Documentation** - [developer.flipper.net](https://developer.flipper.net/flipperzero/doxygen) + ### - **[How to build](/documentation/HowToBuild.md#how-to-build-by-yourself) | [Project-structure](#project-structure)** ### - **CLion IDE** - How to setup workspace for flipper firmware development [by Savely Krasovsky](https://krasovs.ky/2022/11/01/flipper-zero-clion.html) @@ -246,6 +248,8 @@ See full list and sources here: [xMasterX/all-the-plugins](https://github.com/xM * Official Docs: [docs.flipper.net](https://docs.flipper.net/) * Official Forum: [forum.flipperzero.one](https://forum.flipperzero.one/) +* Update! Developer Documentation [developer.flipper.net](https://developer.flipper.net/flipperzero/doxygen) + # Project structure - `applications` - Applications and services used in firmware diff --git a/SConstruct b/SConstruct index 83ee626f1b..268472a7c7 100644 --- a/SConstruct +++ b/SConstruct @@ -42,6 +42,7 @@ distenv = coreenv.Clone( "openocd", "blackmagic", "jflash", + "doxygen", ], ENV=os.environ, UPDATE_BUNDLE_DIR="dist/${DIST_DIR}/f${TARGET_HW}-update-${DIST_SUFFIX}", @@ -229,6 +230,7 @@ firmware_debug = distenv.PhonyTarget( source=firmware_env["FW_ELF"], GDBOPTS="${GDBOPTS_BASE}", GDBREMOTE="${OPENOCD_GDB_PIPE}", + FBT_FAP_DEBUG_ELF_ROOT=firmware_env["FBT_FAP_DEBUG_ELF_ROOT"], ) distenv.Depends(firmware_debug, firmware_flash) @@ -238,6 +240,7 @@ distenv.PhonyTarget( source=firmware_env["FW_ELF"], GDBOPTS="${GDBOPTS_BASE} ${GDBOPTS_BLACKMAGIC}", GDBREMOTE="${BLACKMAGIC_ADDR}", + FBT_FAP_DEBUG_ELF_ROOT=firmware_env["FBT_FAP_DEBUG_ELF_ROOT"], ) # Debug alien elf @@ -417,3 +420,18 @@ distenv.PhonyTarget( "env", "@echo $( ${FBT_SCRIPT_DIR.abspath}/toolchain/fbtenv.sh $)", ) + +doxy_build = distenv.DoxyBuild( + "documentation/doxygen/build/html/index.html", + "documentation/doxygen/Doxyfile-awesome.cfg", + doxy_env_variables={ + "DOXY_SRC_ROOT": Dir(".").abspath, + "DOXY_BUILD_DIR": Dir("documentation/doxygen/build").abspath, + "DOXY_CONFIG_DIR": "documentation/doxygen", + }, +) +distenv.Alias("doxygen", doxy_build) +distenv.AlwaysBuild(doxy_build) + +# Open generated documentation in browser +distenv.PhonyTarget("doxy", open_browser_action, source=doxy_build) diff --git a/applications/debug/accessor/accessor_app.h b/applications/debug/accessor/accessor_app.h index 2afd796d5a..bfd5c06e15 100644 --- a/applications/debug/accessor/accessor_app.h +++ b/applications/debug/accessor/accessor_app.h @@ -11,29 +11,29 @@ class AccessorApp { public: void run(void); - AccessorApp(); - ~AccessorApp(); + AccessorApp(void); + ~AccessorApp(void); enum class Scene : uint8_t { Exit, Start, }; - AccessorAppViewManager* get_view_manager(); + AccessorAppViewManager* get_view_manager(void); void switch_to_next_scene(Scene index); void search_and_switch_to_previous_scene(std::initializer_list scenes_list); bool switch_to_previous_scene(uint8_t count = 1); - Scene get_previous_scene(); + Scene get_previous_scene(void); - void notify_green_blink(); - void notify_success(); + void notify_green_blink(void); + void notify_success(void); - char* get_text_store(); - uint8_t get_text_store_size(); + char* get_text_store(void); + uint8_t get_text_store_size(void); void set_text_store(const char* text...); - WIEGAND* get_wiegand(); - OneWireHost* get_one_wire(); + WIEGAND* get_wiegand(void); + OneWireHost* get_one_wire(void); private: std::list previous_scenes_list = {Scene::Exit}; diff --git a/applications/debug/accessor/accessor_view_manager.h b/applications/debug/accessor/accessor_view_manager.h index 8cd4377975..66e54e41ce 100644 --- a/applications/debug/accessor/accessor_view_manager.h +++ b/applications/debug/accessor/accessor_view_manager.h @@ -15,16 +15,16 @@ class AccessorAppViewManager { FuriMessageQueue* event_queue; - AccessorAppViewManager(); - ~AccessorAppViewManager(); + AccessorAppViewManager(void); + ~AccessorAppViewManager(void); void switch_to(ViewType type); void receive_event(AccessorEvent* event); void send_event(AccessorEvent* event); - Submenu* get_submenu(); - Popup* get_popup(); + Submenu* get_submenu(void); + Popup* get_popup(void); private: ViewDispatcher* view_dispatcher; diff --git a/applications/debug/accessor/helpers/wiegand.h b/applications/debug/accessor/helpers/wiegand.h index be80f94cd5..1e1ab6bc80 100644 --- a/applications/debug/accessor/helpers/wiegand.h +++ b/applications/debug/accessor/helpers/wiegand.h @@ -2,19 +2,19 @@ class WIEGAND { public: - WIEGAND(); - void begin(); - void end(); - bool available(); - unsigned long getCode(); - unsigned long getCodeHigh(); - int getWiegandType(); + WIEGAND(void); + void begin(void); + void end(void); + bool available(void); + unsigned long getCode(void); + unsigned long getCodeHigh(void); + int getWiegandType(void); - static void ReadD0(); - static void ReadD1(); + static void ReadD0(void); + static void ReadD1(void); private: - static bool DoWiegandConversion(); + static bool DoWiegandConversion(void); static unsigned long GetCardId(unsigned long* codehigh, unsigned long* codelow, char bitlength); diff --git a/applications/debug/battery_test_app/battery_test_app.c b/applications/debug/battery_test_app/battery_test_app.c index 82c814ef4a..5f9934e777 100644 --- a/applications/debug/battery_test_app/battery_test_app.c +++ b/applications/debug/battery_test_app/battery_test_app.c @@ -32,7 +32,7 @@ static void battery_test_battery_info_update_model(void* context) { notification_message(app->notifications, &sequence_display_backlight_on); } -BatteryTestApp* battery_test_alloc() { +BatteryTestApp* battery_test_alloc(void) { BatteryTestApp* app = malloc(sizeof(BatteryTestApp)); // Records diff --git a/applications/debug/battery_test_app/views/battery_info.c b/applications/debug/battery_test_app/views/battery_info.c index 5353a2e2a6..4b5dcd6276 100644 --- a/applications/debug/battery_test_app/views/battery_info.c +++ b/applications/debug/battery_test_app/views/battery_info.c @@ -116,7 +116,7 @@ static void battery_info_draw_callback(Canvas* canvas, void* context) { draw_stat(canvas, 104, 42, &I_Health_16x16, health); } -BatteryInfo* battery_info_alloc() { +BatteryInfo* battery_info_alloc(void) { BatteryInfo* battery_info = malloc(sizeof(BatteryInfo)); battery_info->view = view_alloc(); view_set_context(battery_info->view, battery_info); diff --git a/applications/debug/battery_test_app/views/battery_info.h b/applications/debug/battery_test_app/views/battery_info.h index 7bfacf69e2..403caac4bb 100644 --- a/applications/debug/battery_test_app/views/battery_info.h +++ b/applications/debug/battery_test_app/views/battery_info.h @@ -14,7 +14,7 @@ typedef struct { uint8_t health; } BatteryInfoModel; -BatteryInfo* battery_info_alloc(); +BatteryInfo* battery_info_alloc(void); void battery_info_free(BatteryInfo* battery_info); diff --git a/applications/debug/bt_debug_app/bt_debug_app.c b/applications/debug/bt_debug_app/bt_debug_app.c index bf13f6570a..109feee602 100644 --- a/applications/debug/bt_debug_app/bt_debug_app.c +++ b/applications/debug/bt_debug_app/bt_debug_app.c @@ -28,7 +28,7 @@ uint32_t bt_debug_start_view(void* context) { return BtDebugAppViewSubmenu; } -BtDebugApp* bt_debug_app_alloc() { +BtDebugApp* bt_debug_app_alloc(void) { BtDebugApp* app = malloc(sizeof(BtDebugApp)); // Gui diff --git a/applications/debug/bt_debug_app/views/bt_carrier_test.c b/applications/debug/bt_debug_app/views/bt_carrier_test.c index 8e22404957..23066434b0 100644 --- a/applications/debug/bt_debug_app/views/bt_carrier_test.c +++ b/applications/debug/bt_debug_app/views/bt_carrier_test.c @@ -129,7 +129,7 @@ static void bt_test_carrier_timer_callback(void* context) { } } -BtCarrierTest* bt_carrier_test_alloc() { +BtCarrierTest* bt_carrier_test_alloc(void) { BtCarrierTest* bt_carrier_test = malloc(sizeof(BtCarrierTest)); bt_carrier_test->bt_test = bt_test_alloc(); bt_test_set_context(bt_carrier_test->bt_test, bt_carrier_test); diff --git a/applications/debug/bt_debug_app/views/bt_carrier_test.h b/applications/debug/bt_debug_app/views/bt_carrier_test.h index 51a4008901..07fedccc1b 100644 --- a/applications/debug/bt_debug_app/views/bt_carrier_test.h +++ b/applications/debug/bt_debug_app/views/bt_carrier_test.h @@ -3,7 +3,7 @@ typedef struct BtCarrierTest BtCarrierTest; -BtCarrierTest* bt_carrier_test_alloc(); +BtCarrierTest* bt_carrier_test_alloc(void); void bt_carrier_test_free(BtCarrierTest* bt_carrier_test); diff --git a/applications/debug/bt_debug_app/views/bt_packet_test.c b/applications/debug/bt_debug_app/views/bt_packet_test.c index 8a56a30031..c30c6b5d25 100644 --- a/applications/debug/bt_debug_app/views/bt_packet_test.c +++ b/applications/debug/bt_debug_app/views/bt_packet_test.c @@ -97,7 +97,7 @@ static void bt_test_packet_timer_callback(void* context) { } } -BtPacketTest* bt_packet_test_alloc() { +BtPacketTest* bt_packet_test_alloc(void) { BtPacketTest* bt_packet_test = malloc(sizeof(BtPacketTest)); bt_packet_test->bt_test = bt_test_alloc(); bt_test_set_context(bt_packet_test->bt_test, bt_packet_test); diff --git a/applications/debug/bt_debug_app/views/bt_packet_test.h b/applications/debug/bt_debug_app/views/bt_packet_test.h index 8ea449b211..e31af3218e 100644 --- a/applications/debug/bt_debug_app/views/bt_packet_test.h +++ b/applications/debug/bt_debug_app/views/bt_packet_test.h @@ -3,7 +3,7 @@ typedef struct BtPacketTest BtPacketTest; -BtPacketTest* bt_packet_test_alloc(); +BtPacketTest* bt_packet_test_alloc(void); void bt_packet_test_free(BtPacketTest* bt_packet_test); diff --git a/applications/debug/bt_debug_app/views/bt_test.c b/applications/debug/bt_debug_app/views/bt_test.c index cd52b8650e..792ebfd8f8 100644 --- a/applications/debug/bt_debug_app/views/bt_test.c +++ b/applications/debug/bt_debug_app/views/bt_test.c @@ -305,7 +305,7 @@ void bt_test_process_back(BtTest* bt_test) { } } -BtTest* bt_test_alloc() { +BtTest* bt_test_alloc(void) { BtTest* bt_test = malloc(sizeof(BtTest)); bt_test->view = view_alloc(); view_set_context(bt_test->view, bt_test); diff --git a/applications/debug/bt_debug_app/views/bt_test.h b/applications/debug/bt_debug_app/views/bt_test.h index 2d738cbd08..9d5ea26ec2 100644 --- a/applications/debug/bt_debug_app/views/bt_test.h +++ b/applications/debug/bt_debug_app/views/bt_test.h @@ -12,7 +12,7 @@ typedef void (*BtTestBackCallback)(void* context); typedef struct BtTestParam BtTestParam; typedef void (*BtTestParamChangeCallback)(BtTestParam* param); -BtTest* bt_test_alloc(); +BtTest* bt_test_alloc(void); void bt_test_free(BtTest* bt_test); diff --git a/applications/debug/ccid_test/ccid_test_app.c b/applications/debug/ccid_test/ccid_test_app.c index 3d7fba39de..50b356696c 100644 --- a/applications/debug/ccid_test/ccid_test_app.c +++ b/applications/debug/ccid_test/ccid_test_app.c @@ -90,7 +90,7 @@ uint32_t ccid_test_exit(void* context) { return VIEW_NONE; } -CcidTestApp* ccid_test_app_alloc() { +CcidTestApp* ccid_test_app_alloc(void) { CcidTestApp* app = malloc(sizeof(CcidTestApp)); // Gui diff --git a/applications/debug/crash_test/crash_test.c b/applications/debug/crash_test/crash_test.c index 92f1668be9..ae0074fe1c 100644 --- a/applications/debug/crash_test/crash_test.c +++ b/applications/debug/crash_test/crash_test.c @@ -50,7 +50,7 @@ static void crash_test_submenu_callback(void* context, uint32_t index) { furi_halt("Crash test: furi_halt"); break; default: - furi_crash("Programming error"); + furi_crash(); } } @@ -59,7 +59,7 @@ static uint32_t crash_test_exit_callback(void* context) { return VIEW_NONE; } -CrashTest* crash_test_alloc() { +CrashTest* crash_test_alloc(void) { CrashTest* instance = malloc(sizeof(CrashTest)); View* view = NULL; diff --git a/applications/debug/direct_draw/direct_draw.c b/applications/debug/direct_draw/direct_draw.c index 63e03530a7..bc1e554597 100644 --- a/applications/debug/direct_draw/direct_draw.c +++ b/applications/debug/direct_draw/direct_draw.c @@ -26,7 +26,7 @@ static void gui_input_events_callback(const void* value, void* ctx) { } } -static DirectDraw* direct_draw_alloc() { +static DirectDraw* direct_draw_alloc(void) { DirectDraw* instance = malloc(sizeof(DirectDraw)); instance->input = furi_record_open(RECORD_INPUT_EVENTS); diff --git a/applications/debug/display_test/display_test.c b/applications/debug/display_test/display_test.c index 8065a23a1f..ac1b6c65df 100644 --- a/applications/debug/display_test/display_test.c +++ b/applications/debug/display_test/display_test.c @@ -121,7 +121,7 @@ static void display_config_set_contrast(VariableItem* item) { display_test_reload_config(instance); } -DisplayTest* display_test_alloc() { +DisplayTest* display_test_alloc(void) { DisplayTest* instance = malloc(sizeof(DisplayTest)); View* view = NULL; diff --git a/applications/debug/display_test/view_display_test.c b/applications/debug/display_test/view_display_test.c index b47c74c6c2..d4fe433efe 100644 --- a/applications/debug/display_test/view_display_test.c +++ b/applications/debug/display_test/view_display_test.c @@ -154,7 +154,7 @@ static void view_display_test_timer_callback(void* context) { instance->view, ViewDisplayTestModel * model, { model->counter++; }, true); } -ViewDisplayTest* view_display_test_alloc() { +ViewDisplayTest* view_display_test_alloc(void) { ViewDisplayTest* instance = malloc(sizeof(ViewDisplayTest)); instance->view = view_alloc(); diff --git a/applications/debug/display_test/view_display_test.h b/applications/debug/display_test/view_display_test.h index cafa142a84..ca78e5ffe4 100644 --- a/applications/debug/display_test/view_display_test.h +++ b/applications/debug/display_test/view_display_test.h @@ -5,7 +5,7 @@ typedef struct ViewDisplayTest ViewDisplayTest; -ViewDisplayTest* view_display_test_alloc(); +ViewDisplayTest* view_display_test_alloc(void); void view_display_test_free(ViewDisplayTest* instance); diff --git a/applications/debug/expansion_test/expansion_test.c b/applications/debug/expansion_test/expansion_test.c index a0b8b42e8b..fc7fb18945 100644 --- a/applications/debug/expansion_test/expansion_test.c +++ b/applications/debug/expansion_test/expansion_test.c @@ -81,7 +81,7 @@ static void expansion_test_app_serial_rx_callback( } } -static ExpansionTestApp* expansion_test_app_alloc() { +static ExpansionTestApp* expansion_test_app_alloc(void) { ExpansionTestApp* instance = malloc(sizeof(ExpansionTestApp)); instance->buf = furi_stream_buffer_alloc(RECEIVE_BUFFER_SIZE, 1); return instance; diff --git a/applications/debug/lfrfid_debug/lfrfid_debug.c b/applications/debug/lfrfid_debug/lfrfid_debug.c index 63d66b68b9..8776f8b7ad 100644 --- a/applications/debug/lfrfid_debug/lfrfid_debug.c +++ b/applications/debug/lfrfid_debug/lfrfid_debug.c @@ -12,7 +12,7 @@ static bool lfrfid_debug_back_event_callback(void* context) { return scene_manager_handle_back_event(app->scene_manager); } -static LfRfidDebug* lfrfid_debug_alloc() { +static LfRfidDebug* lfrfid_debug_alloc(void) { LfRfidDebug* app = malloc(sizeof(LfRfidDebug)); app->view_dispatcher = view_dispatcher_alloc(); diff --git a/applications/debug/lfrfid_debug/views/lfrfid_debug_view_tune.c b/applications/debug/lfrfid_debug/views/lfrfid_debug_view_tune.c index 9e48a7e27f..6b9501e5b7 100644 --- a/applications/debug/lfrfid_debug/views/lfrfid_debug_view_tune.c +++ b/applications/debug/lfrfid_debug/views/lfrfid_debug_view_tune.c @@ -170,7 +170,7 @@ static bool lfrfid_debug_view_tune_input_callback(InputEvent* event, void* conte return consumed; } -LfRfidTuneView* lfrfid_debug_view_tune_alloc() { +LfRfidTuneView* lfrfid_debug_view_tune_alloc(void) { LfRfidTuneView* tune_view = malloc(sizeof(LfRfidTuneView)); tune_view->view = view_alloc(); view_set_context(tune_view->view, tune_view); diff --git a/applications/debug/lfrfid_debug/views/lfrfid_debug_view_tune.h b/applications/debug/lfrfid_debug/views/lfrfid_debug_view_tune.h index be54b63f9a..a0ee4cbf5c 100644 --- a/applications/debug/lfrfid_debug/views/lfrfid_debug_view_tune.h +++ b/applications/debug/lfrfid_debug/views/lfrfid_debug_view_tune.h @@ -3,7 +3,7 @@ typedef struct LfRfidTuneView LfRfidTuneView; -LfRfidTuneView* lfrfid_debug_view_tune_alloc(); +LfRfidTuneView* lfrfid_debug_view_tune_alloc(void); void lfrfid_debug_view_tune_free(LfRfidTuneView* tune_view); diff --git a/applications/debug/locale_test/locale_test.c b/applications/debug/locale_test/locale_test.c index a7cbd52f80..1ca077db1f 100644 --- a/applications/debug/locale_test/locale_test.c +++ b/applications/debug/locale_test/locale_test.c @@ -53,7 +53,7 @@ static uint32_t locale_test_exit(void* context) { return VIEW_NONE; } -static LocaleTestApp* locale_test_alloc() { +static LocaleTestApp* locale_test_alloc(void) { LocaleTestApp* app = malloc(sizeof(LocaleTestApp)); // Gui diff --git a/applications/debug/rpc_debug_app/rpc_debug_app.c b/applications/debug/rpc_debug_app/rpc_debug_app.c index 2a0756383c..5e53c221e1 100644 --- a/applications/debug/rpc_debug_app/rpc_debug_app.c +++ b/applications/debug/rpc_debug_app/rpc_debug_app.c @@ -83,7 +83,7 @@ static bool rpc_debug_app_rpc_init_rpc(RpcDebugApp* app, const char* args) { return ret; } -static RpcDebugApp* rpc_debug_app_alloc() { +static RpcDebugApp* rpc_debug_app_alloc(void) { RpcDebugApp* app = malloc(sizeof(RpcDebugApp)); app->gui = furi_record_open(RECORD_GUI); diff --git a/applications/debug/speaker_debug/speaker_debug.c b/applications/debug/speaker_debug/speaker_debug.c index e01d5b8ec4..82a6fbc774 100644 --- a/applications/debug/speaker_debug/speaker_debug.c +++ b/applications/debug/speaker_debug/speaker_debug.c @@ -21,7 +21,7 @@ typedef struct { Cli* cli; } SpeakerDebugApp; -static SpeakerDebugApp* speaker_app_alloc() { +static SpeakerDebugApp* speaker_app_alloc(void) { SpeakerDebugApp* app = (SpeakerDebugApp*)malloc(sizeof(SpeakerDebugApp)); app->music_worker = music_worker_alloc(); app->message_queue = furi_message_queue_alloc(8, sizeof(SpeakerDebugAppMessage)); diff --git a/applications/debug/subghz_test/protocol/princeton_for_testing.c b/applications/debug/subghz_test/protocol/princeton_for_testing.c index 334a8241bb..70f323937d 100644 --- a/applications/debug/subghz_test/protocol/princeton_for_testing.c +++ b/applications/debug/subghz_test/protocol/princeton_for_testing.c @@ -38,7 +38,7 @@ typedef enum { PrincetonDecoderStepCheckDuration, } PrincetonDecoderStep; -SubGhzEncoderPrinceton* subghz_encoder_princeton_for_testing_alloc() { +SubGhzEncoderPrinceton* subghz_encoder_princeton_for_testing_alloc(void) { SubGhzEncoderPrinceton* instance = malloc(sizeof(SubGhzEncoderPrinceton)); return instance; } diff --git a/applications/debug/subghz_test/protocol/princeton_for_testing.h b/applications/debug/subghz_test/protocol/princeton_for_testing.h index 7b4201d38a..281cb148b1 100644 --- a/applications/debug/subghz_test/protocol/princeton_for_testing.h +++ b/applications/debug/subghz_test/protocol/princeton_for_testing.h @@ -15,7 +15,7 @@ typedef void (*SubGhzDecoderPrincetonCallback)(SubGhzDecoderPrinceton* parser, v * Allocate SubGhzEncoderPrinceton * @return pointer to SubGhzEncoderPrinceton instance */ -SubGhzEncoderPrinceton* subghz_encoder_princeton_for_testing_alloc(); +SubGhzEncoderPrinceton* subghz_encoder_princeton_for_testing_alloc(void); /** * Free SubGhzEncoderPrinceton instance @@ -69,7 +69,7 @@ LevelDuration subghz_encoder_princeton_for_testing_yield(void* context); * Allocate SubGhzDecoderPrinceton * @return SubGhzDecoderPrinceton* */ -SubGhzDecoderPrinceton* subghz_decoder_princeton_for_testing_alloc(); +SubGhzDecoderPrinceton* subghz_decoder_princeton_for_testing_alloc(void); /** * Free SubGhzDecoderPrinceton diff --git a/applications/debug/subghz_test/scenes/subghz_test_scene_show_only_rx.c b/applications/debug/subghz_test/scenes/subghz_test_scene_show_only_rx.c index 3d5a54355c..d8eade41d6 100644 --- a/applications/debug/subghz_test/scenes/subghz_test_scene_show_only_rx.c +++ b/applications/debug/subghz_test/scenes/subghz_test_scene_show_only_rx.c @@ -12,7 +12,7 @@ void subghz_test_scene_show_only_rx_on_enter(void* context) { // Setup view Popup* popup = app->popup; - const char* header_text = "Transmission is blocked"; + const char* header_text = "Transmission is Blocked"; const char* message_text = "Transmission on\nthis frequency is\nrestricted in\nyour region"; if(!furi_hal_region_is_provisioned()) { header_text = "Firmware update needed"; diff --git a/applications/debug/subghz_test/subghz_test_app.c b/applications/debug/subghz_test/subghz_test_app.c index 704941fb28..6eba864f6e 100644 --- a/applications/debug/subghz_test/subghz_test_app.c +++ b/applications/debug/subghz_test/subghz_test_app.c @@ -21,7 +21,7 @@ static void subghz_test_app_tick_event_callback(void* context) { scene_manager_handle_tick_event(app->scene_manager); } -SubGhzTestApp* subghz_test_app_alloc() { +SubGhzTestApp* subghz_test_app_alloc(void) { SubGhzTestApp* app = malloc(sizeof(SubGhzTestApp)); // GUI diff --git a/applications/debug/subghz_test/views/subghz_test_carrier.c b/applications/debug/subghz_test/views/subghz_test_carrier.c index ec64e2d9b0..b6b4530ae9 100644 --- a/applications/debug/subghz_test/views/subghz_test_carrier.c +++ b/applications/debug/subghz_test/views/subghz_test_carrier.c @@ -219,7 +219,7 @@ void subghz_test_carrier_rssi_timer_callback(void* context) { false); } -SubGhzTestCarrier* subghz_test_carrier_alloc() { +SubGhzTestCarrier* subghz_test_carrier_alloc(void) { SubGhzTestCarrier* subghz_test_carrier = malloc(sizeof(SubGhzTestCarrier)); // View allocation and configuration diff --git a/applications/debug/subghz_test/views/subghz_test_carrier.h b/applications/debug/subghz_test/views/subghz_test_carrier.h index d171d19f46..0ba8bc8a26 100644 --- a/applications/debug/subghz_test/views/subghz_test_carrier.h +++ b/applications/debug/subghz_test/views/subghz_test_carrier.h @@ -16,7 +16,7 @@ void subghz_test_carrier_set_callback( SubGhzTestCarrierCallback callback, void* context); -SubGhzTestCarrier* subghz_test_carrier_alloc(); +SubGhzTestCarrier* subghz_test_carrier_alloc(void); void subghz_test_carrier_free(SubGhzTestCarrier* subghz_test_carrier); diff --git a/applications/debug/subghz_test/views/subghz_test_packet.c b/applications/debug/subghz_test/views/subghz_test_packet.c index 1f34582961..d50f10ad46 100644 --- a/applications/debug/subghz_test/views/subghz_test_packet.c +++ b/applications/debug/subghz_test/views/subghz_test_packet.c @@ -236,7 +236,7 @@ void subghz_test_packet_exit(void* context) { furi_hal_subghz_sleep(); } -SubGhzTestPacket* subghz_test_packet_alloc() { +SubGhzTestPacket* subghz_test_packet_alloc(void) { SubGhzTestPacket* instance = malloc(sizeof(SubGhzTestPacket)); // View allocation and configuration diff --git a/applications/debug/subghz_test/views/subghz_test_packet.h b/applications/debug/subghz_test/views/subghz_test_packet.h index f384cf4fea..3a8204f1fe 100644 --- a/applications/debug/subghz_test/views/subghz_test_packet.h +++ b/applications/debug/subghz_test/views/subghz_test_packet.h @@ -15,7 +15,7 @@ void subghz_test_packet_set_callback( SubGhzTestPacketCallback callback, void* context); -SubGhzTestPacket* subghz_test_packet_alloc(); +SubGhzTestPacket* subghz_test_packet_alloc(void); void subghz_test_packet_free(SubGhzTestPacket* subghz_test_packet); diff --git a/applications/debug/subghz_test/views/subghz_test_static.c b/applications/debug/subghz_test/views/subghz_test_static.c index 6764fd5ca9..22ad662c57 100644 --- a/applications/debug/subghz_test/views/subghz_test_static.c +++ b/applications/debug/subghz_test/views/subghz_test_static.c @@ -164,7 +164,7 @@ void subghz_test_static_exit(void* context) { furi_hal_subghz_sleep(); } -SubGhzTestStatic* subghz_test_static_alloc() { +SubGhzTestStatic* subghz_test_static_alloc(void) { SubGhzTestStatic* instance = malloc(sizeof(SubGhzTestStatic)); // View allocation and configuration diff --git a/applications/debug/subghz_test/views/subghz_test_static.h b/applications/debug/subghz_test/views/subghz_test_static.h index 9020364310..3bb6156f7e 100644 --- a/applications/debug/subghz_test/views/subghz_test_static.h +++ b/applications/debug/subghz_test/views/subghz_test_static.h @@ -15,7 +15,7 @@ void subghz_test_static_set_callback( SubGhzTestStaticCallback callback, void* context); -SubGhzTestStatic* subghz_test_static_alloc(); +SubGhzTestStatic* subghz_test_static_alloc(void); void subghz_test_static_free(SubGhzTestStatic* subghz_static); diff --git a/applications/debug/unit_tests/bit_lib/bit_lib_test.c b/applications/debug/unit_tests/bit_lib/bit_lib_test.c index 42b494413e..239a3b562a 100644 --- a/applications/debug/unit_tests/bit_lib/bit_lib_test.c +++ b/applications/debug/unit_tests/bit_lib/bit_lib_test.c @@ -734,7 +734,7 @@ MU_TEST_SUITE(test_bit_lib) { MU_RUN_TEST(test_bit_lib_bytes_to_num_bcd); } -int run_minunit_test_bit_lib() { +int run_minunit_test_bit_lib(void) { MU_RUN_SUITE(test_bit_lib); return MU_EXIT_CODE; } \ No newline at end of file diff --git a/applications/debug/unit_tests/bt/bt_test.c b/applications/debug/unit_tests/bt/bt_test.c index 32cf6533f8..a09b9894ba 100644 --- a/applications/debug/unit_tests/bt/bt_test.c +++ b/applications/debug/unit_tests/bt/bt_test.c @@ -17,7 +17,7 @@ typedef struct { BtTest* bt_test = NULL; -void bt_test_alloc() { +void bt_test_alloc(void) { bt_test = malloc(sizeof(BtTest)); bt_test->storage = furi_record_open(RECORD_STORAGE); bt_test->nvm_ram_buff_dut = malloc(BT_TEST_NVM_RAM_BUFF_SIZE); @@ -27,7 +27,7 @@ void bt_test_alloc() { bt_test->bt_keys_storage, bt_test->nvm_ram_buff_dut, BT_TEST_NVM_RAM_BUFF_SIZE); } -void bt_test_free() { +void bt_test_free(void) { furi_check(bt_test); free(bt_test->nvm_ram_buff_ref); free(bt_test->nvm_ram_buff_dut); @@ -37,7 +37,7 @@ void bt_test_free() { bt_test = NULL; } -static void bt_test_keys_storage_profile() { +static void bt_test_keys_storage_profile(void) { // Emulate nvm change on initial connection const int nvm_change_size_on_connection = 88; for(size_t i = 0; i < nvm_change_size_on_connection; i++) { @@ -82,7 +82,7 @@ static void bt_test_keys_storage_profile() { "Wrong buffer loaded"); } -static void bt_test_keys_remove_test_file() { +static void bt_test_keys_remove_test_file(void) { mu_assert( storage_simply_remove(bt_test->storage, BT_TEST_KEY_STORAGE_FILE_PATH), "Can't remove test file"); @@ -104,7 +104,7 @@ MU_TEST_SUITE(test_bt) { bt_test_free(); } -int run_minunit_test_bt() { +int run_minunit_test_bt(void) { MU_RUN_SUITE(test_bt); return MU_EXIT_CODE; } diff --git a/applications/debug/unit_tests/datetimelib/datetimelib_test.c b/applications/debug/unit_tests/datetimelib/datetimelib_test.c index bf8e6fabd7..c171a4413b 100644 --- a/applications/debug/unit_tests/datetimelib/datetimelib_test.c +++ b/applications/debug/unit_tests/datetimelib/datetimelib_test.c @@ -182,7 +182,7 @@ MU_TEST_SUITE(test_datetime_datetime_to_timestamp_suite) { MU_RUN_TEST(test_datetime_datetime_to_timestamp_max); } -int run_minunit_test_datetime() { +int run_minunit_test_datetime(void) { MU_RUN_SUITE(test_datetime_timestamp_to_datetime_suite); MU_RUN_SUITE(test_datetime_datetime_to_timestamp_suite); MU_RUN_SUITE(test_datetime_validate_datetime); diff --git a/applications/debug/unit_tests/dialogs/dialogs_file_browser_options.c b/applications/debug/unit_tests/dialogs/dialogs_file_browser_options.c index 2d5bad4c8a..657b933dfc 100644 --- a/applications/debug/unit_tests/dialogs/dialogs_file_browser_options.c +++ b/applications/debug/unit_tests/dialogs/dialogs_file_browser_options.c @@ -25,7 +25,7 @@ MU_TEST_SUITE(dialogs_file_browser_options) { MU_RUN_TEST(test_dialog_file_browser_set_basic_options_should_init_all_fields); } -int run_minunit_test_dialogs_file_browser_options() { +int run_minunit_test_dialogs_file_browser_options(void) { MU_RUN_SUITE(dialogs_file_browser_options); return MU_EXIT_CODE; diff --git a/applications/debug/unit_tests/expansion/expansion_test.c b/applications/debug/unit_tests/expansion/expansion_test.c index 50fe1b9f4d..c6a143ed34 100644 --- a/applications/debug/unit_tests/expansion/expansion_test.c +++ b/applications/debug/unit_tests/expansion/expansion_test.c @@ -194,7 +194,7 @@ MU_TEST_SUITE(test_expansion_suite) { MU_RUN_TEST(test_expansion_garbage_input); } -int run_minunit_test_expansion() { +int run_minunit_test_expansion(void) { MU_RUN_SUITE(test_expansion_suite); return MU_EXIT_CODE; } diff --git a/applications/debug/unit_tests/flipper_format/flipper_format_string_test.c b/applications/debug/unit_tests/flipper_format/flipper_format_string_test.c index 920a22a43b..99bb5dda59 100644 --- a/applications/debug/unit_tests/flipper_format/flipper_format_string_test.c +++ b/applications/debug/unit_tests/flipper_format/flipper_format_string_test.c @@ -331,7 +331,7 @@ MU_TEST_SUITE(flipper_format_string_suite) { MU_RUN_TEST(flipper_format_file_test); } -int run_minunit_test_flipper_format_string() { +int run_minunit_test_flipper_format_string(void) { MU_RUN_SUITE(flipper_format_string_suite); return MU_EXIT_CODE; } diff --git a/applications/debug/unit_tests/flipper_format/flipper_format_test.c b/applications/debug/unit_tests/flipper_format/flipper_format_test.c index 012e905b69..471055fb0c 100644 --- a/applications/debug/unit_tests/flipper_format/flipper_format_test.c +++ b/applications/debug/unit_tests/flipper_format/flipper_format_test.c @@ -103,14 +103,14 @@ static bool storage_write_string(const char* path, const char* data) { return result; } -static void tests_setup() { +static void tests_setup(void) { Storage* storage = furi_record_open(RECORD_STORAGE); mu_assert(storage_simply_remove_recursive(storage, TEST_DIR_NAME), "Cannot clean data"); mu_assert(storage_simply_mkdir(storage, TEST_DIR_NAME), "Cannot create dir"); furi_record_close(RECORD_STORAGE); } -static void tests_teardown() { +static void tests_teardown(void) { Storage* storage = furi_record_open(RECORD_STORAGE); mu_assert(storage_simply_remove_recursive(storage, TEST_DIR_NAME), "Cannot clean data"); furi_record_close(RECORD_STORAGE); @@ -545,7 +545,7 @@ MU_TEST_SUITE(flipper_format) { tests_teardown(); } -int run_minunit_test_flipper_format() { +int run_minunit_test_flipper_format(void) { MU_RUN_SUITE(flipper_format); return MU_EXIT_CODE; } diff --git a/applications/debug/unit_tests/float_tools/float_tools_test.c b/applications/debug/unit_tests/float_tools/float_tools_test.c index fc5b4ecfd8..91ac469378 100644 --- a/applications/debug/unit_tests/float_tools/float_tools_test.c +++ b/applications/debug/unit_tests/float_tools/float_tools_test.c @@ -54,7 +54,7 @@ MU_TEST_SUITE(float_tools_suite) { MU_RUN_TEST(float_tools_equal_test); } -int run_minunit_test_float_tools() { +int run_minunit_test_float_tools(void) { MU_RUN_SUITE(float_tools_suite); return MU_EXIT_CODE; } diff --git a/applications/debug/unit_tests/furi/furi_memmgr_test.c b/applications/debug/unit_tests/furi/furi_memmgr_test.c index 9012eed782..01e2c17f66 100644 --- a/applications/debug/unit_tests/furi/furi_memmgr_test.c +++ b/applications/debug/unit_tests/furi/furi_memmgr_test.c @@ -4,7 +4,7 @@ #include #include -void test_furi_memmgr() { +void test_furi_memmgr(void) { void* ptr; // allocate memory case diff --git a/applications/debug/unit_tests/furi/furi_pubsub_test.c b/applications/debug/unit_tests/furi/furi_pubsub_test.c index ddaeb746d9..8925ff42ec 100644 --- a/applications/debug/unit_tests/furi/furi_pubsub_test.c +++ b/applications/debug/unit_tests/furi/furi_pubsub_test.c @@ -15,7 +15,7 @@ void test_pubsub_handler(const void* arg, void* ctx) { pubsub_context_value = *(uint32_t*)ctx; } -void test_furi_pubsub() { +void test_furi_pubsub(void) { FuriPubSub* test_pubsub = NULL; FuriPubSubSubscription* test_pubsub_subscription = NULL; diff --git a/applications/debug/unit_tests/furi/furi_record_test.c b/applications/debug/unit_tests/furi/furi_record_test.c index 236e1efc56..10a5a83933 100644 --- a/applications/debug/unit_tests/furi/furi_record_test.c +++ b/applications/debug/unit_tests/furi/furi_record_test.c @@ -5,7 +5,7 @@ #define TEST_RECORD_NAME "test/holding" -void test_furi_create_open() { +void test_furi_create_open(void) { // Test that record does not exist mu_check(furi_record_exists(TEST_RECORD_NAME) == false); diff --git a/applications/debug/unit_tests/furi/furi_string_test.c b/applications/debug/unit_tests/furi/furi_string_test.c index 6cbcc0dcc7..853076b67b 100644 --- a/applications/debug/unit_tests/furi/furi_string_test.c +++ b/applications/debug/unit_tests/furi/furi_string_test.c @@ -462,7 +462,7 @@ MU_TEST_SUITE(test_suite) { MU_RUN_TEST(mu_test_furi_string_utf8); } -int run_minunit_test_furi_string() { +int run_minunit_test_furi_string(void) { MU_RUN_SUITE(test_suite); return MU_EXIT_CODE; diff --git a/applications/debug/unit_tests/furi/furi_test.c b/applications/debug/unit_tests/furi/furi_test.c index 33ec5fd019..e287f9927f 100644 --- a/applications/debug/unit_tests/furi/furi_test.c +++ b/applications/debug/unit_tests/furi/furi_test.c @@ -4,11 +4,11 @@ #include "../minunit.h" // v2 tests -void test_furi_create_open(); -void test_furi_concurrent_access(); -void test_furi_pubsub(); +void test_furi_create_open(void); +void test_furi_concurrent_access(void); +void test_furi_pubsub(void); -void test_furi_memmgr(); +void test_furi_memmgr(void); static int foo = 0; @@ -50,7 +50,7 @@ MU_TEST_SUITE(test_suite) { MU_RUN_TEST(mu_test_furi_memmgr); } -int run_minunit_test_furi() { +int run_minunit_test_furi(void) { MU_RUN_SUITE(test_suite); return MU_EXIT_CODE; diff --git a/applications/debug/unit_tests/furi_hal/furi_hal_crypto_tests.c b/applications/debug/unit_tests/furi_hal/furi_hal_crypto_tests.c index b06d51130f..c2bd6c5f81 100644 --- a/applications/debug/unit_tests/furi_hal/furi_hal_crypto_tests.c +++ b/applications/debug/unit_tests/furi_hal/furi_hal_crypto_tests.c @@ -409,16 +409,16 @@ static const uint8_t tv_gcm_tag_4[16] = { 0x1B, }; -static void furi_hal_crypto_ctr_setup() { +static void furi_hal_crypto_ctr_setup(void) { } -static void furi_hal_crypto_ctr_teardown() { +static void furi_hal_crypto_ctr_teardown(void) { } -static void furi_hal_crypto_gcm_setup() { +static void furi_hal_crypto_gcm_setup(void) { } -static void furi_hal_crypto_gcm_teardown() { +static void furi_hal_crypto_gcm_teardown(void) { } MU_TEST(furi_hal_crypto_ctr_1) { @@ -595,7 +595,7 @@ MU_TEST_SUITE(furi_hal_crypto_gcm_test) { MU_RUN_TEST(furi_hal_crypto_gcm_4); } -int run_minunit_test_furi_hal_crypto() { +int run_minunit_test_furi_hal_crypto(void) { MU_RUN_SUITE(furi_hal_crypto_ctr_test); MU_RUN_SUITE(furi_hal_crypto_gcm_test); return MU_EXIT_CODE; diff --git a/applications/debug/unit_tests/furi_hal/furi_hal_tests.c b/applications/debug/unit_tests/furi_hal/furi_hal_tests.c index a75615d0c0..0c5cec8a61 100644 --- a/applications/debug/unit_tests/furi_hal/furi_hal_tests.c +++ b/applications/debug/unit_tests/furi_hal/furi_hal_tests.c @@ -14,19 +14,19 @@ #define EEPROM_PAGE_SIZE 16 #define EEPROM_WRITE_DELAY_MS 6 -static void furi_hal_i2c_int_setup() { +static void furi_hal_i2c_int_setup(void) { furi_hal_i2c_acquire(&furi_hal_i2c_handle_power); } -static void furi_hal_i2c_int_teardown() { +static void furi_hal_i2c_int_teardown(void) { furi_hal_i2c_release(&furi_hal_i2c_handle_power); } -static void furi_hal_i2c_ext_setup() { +static void furi_hal_i2c_ext_setup(void) { furi_hal_i2c_acquire(&furi_hal_i2c_handle_external); } -static void furi_hal_i2c_ext_teardown() { +static void furi_hal_i2c_ext_teardown(void) { furi_hal_i2c_release(&furi_hal_i2c_handle_external); } @@ -227,7 +227,7 @@ MU_TEST_SUITE(furi_hal_i2c_ext_suite) { MU_RUN_TEST(furi_hal_i2c_ext_eeprom); } -int run_minunit_test_furi_hal() { +int run_minunit_test_furi_hal(void) { MU_RUN_SUITE(furi_hal_i2c_int_suite); MU_RUN_SUITE(furi_hal_i2c_ext_suite); return MU_EXIT_CODE; diff --git a/applications/debug/unit_tests/infrared/infrared_test.c b/applications/debug/unit_tests/infrared/infrared_test.c index ba57b78aad..4442fedb30 100644 --- a/applications/debug/unit_tests/infrared/infrared_test.c +++ b/applications/debug/unit_tests/infrared/infrared_test.c @@ -17,7 +17,7 @@ typedef struct { static InfraredTest* test; -static void infrared_test_alloc() { +static void infrared_test_alloc(void) { Storage* storage = furi_record_open(RECORD_STORAGE); test = malloc(sizeof(InfraredTest)); test->decoder_handler = infrared_alloc_decoder(); @@ -26,7 +26,7 @@ static void infrared_test_alloc() { test->file_path = furi_string_alloc(); } -static void infrared_test_free() { +static void infrared_test_free(void) { furi_check(test); infrared_free_decoder(test->decoder_handler); infrared_free_encoder(test->encoder_handler); @@ -545,7 +545,7 @@ MU_TEST_SUITE(infrared_test) { MU_RUN_TEST(infrared_test_encoder_decoder_all); } -int run_minunit_test_infrared() { +int run_minunit_test_infrared(void) { MU_RUN_SUITE(infrared_test); return MU_EXIT_CODE; } diff --git a/applications/debug/unit_tests/lfrfid/lfrfid_protocols.c b/applications/debug/unit_tests/lfrfid/lfrfid_protocols.c index d5c2433ba0..6a7dbab9cb 100644 --- a/applications/debug/unit_tests/lfrfid/lfrfid_protocols.c +++ b/applications/debug/unit_tests/lfrfid/lfrfid_protocols.c @@ -547,7 +547,7 @@ MU_TEST_SUITE(test_lfrfid_protocols_suite) { MU_RUN_TEST(test_lfrfid_protocol_fdxb_emulate_simple); } -int run_minunit_test_lfrfid_protocols() { +int run_minunit_test_lfrfid_protocols(void) { MU_RUN_SUITE(test_lfrfid_protocols_suite); return MU_EXIT_CODE; } \ No newline at end of file diff --git a/applications/debug/unit_tests/manifest/manifest.c b/applications/debug/unit_tests/manifest/manifest.c index 19370b0e13..e8ac93d7c0 100644 --- a/applications/debug/unit_tests/manifest/manifest.c +++ b/applications/debug/unit_tests/manifest/manifest.c @@ -69,7 +69,7 @@ MU_TEST_SUITE(manifest_suite) { MU_RUN_TEST(manifest_iteration_test); } -int run_minunit_test_manifest() { +int run_minunit_test_manifest(void) { MU_RUN_SUITE(manifest_suite); return MU_EXIT_CODE; } \ No newline at end of file diff --git a/applications/debug/unit_tests/nfc/nfc_test.c b/applications/debug/unit_tests/nfc/nfc_test.c index 29b9e80d93..c6304d53ca 100644 --- a/applications/debug/unit_tests/nfc/nfc_test.c +++ b/applications/debug/unit_tests/nfc/nfc_test.c @@ -7,10 +7,13 @@ #include #include #include +#include #include #include #include #include +#include +#include #include #include @@ -22,18 +25,35 @@ #define NFC_TEST_NFC_DEV_PATH EXT_PATH("unit_tests/nfc/nfc_device_test.nfc") #define NFC_APP_MF_CLASSIC_DICT_UNIT_TEST_PATH EXT_PATH("unit_tests/mf_dict.nfc") +#define NFC_TEST_FLAG_WORKER_DONE (1) + +typedef enum { + NfcTestMfClassicSendFrameTestStateAuth, + NfcTestMfClassicSendFrameTestStateReadBlock, + + NfcTestMfClassicSendFrameTestStateFail, + NfcTestMfClassicSendFrameTestStateSuccess, +} NfcTestMfClassicSendFrameTestState; + +typedef struct { + NfcTestMfClassicSendFrameTestState state; + BitBuffer* tx_buf; + BitBuffer* rx_buf; + FuriThreadId thread_id; +} NfcTestMfClassicSendFrameTest; + typedef struct { Storage* storage; } NfcTest; static NfcTest* nfc_test = NULL; -static void nfc_test_alloc() { +static void nfc_test_alloc(void) { nfc_test = malloc(sizeof(NfcTest)); nfc_test->storage = furi_record_open(RECORD_STORAGE); } -static void nfc_test_free() { +static void nfc_test_free(void) { furi_check(nfc_test); furi_record_close(RECORD_STORAGE); @@ -292,7 +312,7 @@ MU_TEST(ntag_213_locked_reader) { nfc_free(poller); } -static void mf_ultralight_write() { +static void mf_ultralight_write(void) { Nfc* poller = nfc_alloc(); Nfc* listener = nfc_alloc(); @@ -342,7 +362,7 @@ static void mf_ultralight_write() { nfc_free(poller); } -static void mf_classic_reader() { +static void mf_classic_reader(void) { Nfc* poller = nfc_alloc(); Nfc* listener = nfc_alloc(); @@ -368,7 +388,7 @@ static void mf_classic_reader() { nfc_free(poller); } -static void mf_classic_write() { +static void mf_classic_write(void) { Nfc* poller = nfc_alloc(); Nfc* listener = nfc_alloc(); @@ -396,7 +416,7 @@ static void mf_classic_write() { nfc_free(poller); } -static void mf_classic_value_block() { +static void mf_classic_value_block(void) { Nfc* poller = nfc_alloc(); Nfc* listener = nfc_alloc(); @@ -435,6 +455,109 @@ static void mf_classic_value_block() { nfc_free(poller); } +NfcCommand mf_classic_poller_send_frame_callback(NfcGenericEventEx event, void* context) { + furi_check(event.poller); + furi_check(event.parent_event_data); + furi_check(context); + + NfcCommand command = NfcCommandContinue; + MfClassicPoller* instance = event.poller; + NfcTestMfClassicSendFrameTest* frame_test = context; + Iso14443_3aPollerEvent* iso3_event = event.parent_event_data; + + MfClassicError error = MfClassicErrorNone; + if(iso3_event->type == Iso14443_3aPollerEventTypeReady) { + if(frame_test->state == NfcTestMfClassicSendFrameTestStateAuth) { + MfClassicKey key = { + .data = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + }; + error = mf_classic_poller_auth(instance, 0, &key, MfClassicKeyTypeA, NULL); + frame_test->state = (error == MfClassicErrorNone) ? + NfcTestMfClassicSendFrameTestStateReadBlock : + NfcTestMfClassicSendFrameTestStateFail; + } else if(frame_test->state == NfcTestMfClassicSendFrameTestStateReadBlock) { + do { + const uint8_t read_block_cmd[] = { + 0x30, + 0x01, + 0x8b, + 0xb9, + }; + bit_buffer_copy_bytes(frame_test->tx_buf, read_block_cmd, sizeof(read_block_cmd)); + + error = mf_classic_poller_send_encrypted_frame( + instance, frame_test->tx_buf, frame_test->rx_buf, 200000); + if(error != MfClassicErrorNone) break; + if(bit_buffer_get_size_bytes(frame_test->rx_buf) != 18) { + error = MfClassicErrorProtocol; + break; + } + + const uint8_t* rx_data = bit_buffer_get_data(frame_test->rx_buf); + const uint8_t rx_data_ref[16] = {0}; + if(memcmp(rx_data, rx_data_ref, sizeof(rx_data_ref)) != 0) { + error = MfClassicErrorProtocol; + break; + } + } while(false); + + frame_test->state = (error == MfClassicErrorNone) ? + NfcTestMfClassicSendFrameTestStateSuccess : + NfcTestMfClassicSendFrameTestStateFail; + } else if(frame_test->state == NfcTestMfClassicSendFrameTestStateSuccess) { + command = NfcCommandStop; + } else if(frame_test->state == NfcTestMfClassicSendFrameTestStateFail) { + command = NfcCommandStop; + } + } else { + frame_test->state = NfcTestMfClassicSendFrameTestStateFail; + command = NfcCommandStop; + } + + if(command == NfcCommandStop) { + furi_thread_flags_set(frame_test->thread_id, NFC_TEST_FLAG_WORKER_DONE); + } + + return command; +} + +MU_TEST(mf_classic_send_frame_test) { + Nfc* poller = nfc_alloc(); + Nfc* listener = nfc_alloc(); + + NfcDevice* nfc_device = nfc_device_alloc(); + nfc_data_generator_fill_data(NfcDataGeneratorTypeMfClassic4k_7b, nfc_device); + NfcListener* mfc_listener = nfc_listener_alloc( + listener, NfcProtocolMfClassic, nfc_device_get_data(nfc_device, NfcProtocolMfClassic)); + nfc_listener_start(mfc_listener, NULL, NULL); + + NfcPoller* mfc_poller = nfc_poller_alloc(poller, NfcProtocolMfClassic); + NfcTestMfClassicSendFrameTest context = { + .state = NfcTestMfClassicSendFrameTestStateAuth, + .thread_id = furi_thread_get_current_id(), + .tx_buf = bit_buffer_alloc(32), + .rx_buf = bit_buffer_alloc(32), + }; + nfc_poller_start_ex(mfc_poller, mf_classic_poller_send_frame_callback, &context); + + uint32_t flag = + furi_thread_flags_wait(NFC_TEST_FLAG_WORKER_DONE, FuriFlagWaitAny, FuriWaitForever); + mu_assert(flag == NFC_TEST_FLAG_WORKER_DONE, "Wrong thread flag"); + nfc_poller_stop(mfc_poller); + nfc_poller_free(mfc_poller); + + mu_assert( + context.state == NfcTestMfClassicSendFrameTestStateSuccess, "Wrong test state at the end"); + + bit_buffer_free(context.tx_buf); + bit_buffer_free(context.rx_buf); + nfc_listener_stop(mfc_listener); + nfc_listener_free(mfc_listener); + nfc_device_free(nfc_device); + nfc_free(listener); + nfc_free(poller); +} + MU_TEST(mf_classic_dict_test) { Storage* storage = furi_record_open(RECORD_STORAGE); if(storage_common_stat(storage, NFC_APP_MF_CLASSIC_DICT_UNIT_TEST_PATH, NULL) == FSE_OK) { @@ -538,17 +661,17 @@ MU_TEST_SUITE(nfc) { MU_RUN_TEST(mf_classic_1k_7b_file_test); MU_RUN_TEST(mf_classic_4k_4b_file_test); MU_RUN_TEST(mf_classic_4k_7b_file_test); - MU_RUN_TEST(mf_classic_reader); + MU_RUN_TEST(mf_classic_reader); MU_RUN_TEST(mf_classic_write); MU_RUN_TEST(mf_classic_value_block); - + MU_RUN_TEST(mf_classic_send_frame_test); MU_RUN_TEST(mf_classic_dict_test); nfc_test_free(); } -int run_minunit_test_nfc() { +int run_minunit_test_nfc(void) { MU_RUN_SUITE(nfc); return MU_EXIT_CODE; } diff --git a/applications/debug/unit_tests/nfc/nfc_transport.c b/applications/debug/unit_tests/nfc/nfc_transport.c index e9f4e21341..6886ef66da 100644 --- a/applications/debug/unit_tests/nfc/nfc_transport.c +++ b/applications/debug/unit_tests/nfc/nfc_transport.c @@ -115,7 +115,7 @@ static void nfc_prepare_col_res_data( } } -Nfc* nfc_alloc() { +Nfc* nfc_alloc(void) { Nfc* instance = malloc(sizeof(Nfc)); return instance; diff --git a/applications/debug/unit_tests/power/power_test.c b/applications/debug/unit_tests/power/power_test.c index a9b66b2211..03e0ad269f 100644 --- a/applications/debug/unit_tests/power/power_test.c +++ b/applications/debug/unit_tests/power/power_test.c @@ -63,7 +63,7 @@ MU_TEST_SUITE(test_power_suite) { power_test_deinit(); } -int run_minunit_test_power() { +int run_minunit_test_power(void) { MU_RUN_SUITE(test_power_suite); return MU_EXIT_CODE; } diff --git a/applications/debug/unit_tests/protocol_dict/protocol_dict_test.c b/applications/debug/unit_tests/protocol_dict/protocol_dict_test.c index 73e77ec900..6ecaa1a52f 100644 --- a/applications/debug/unit_tests/protocol_dict/protocol_dict_test.c +++ b/applications/debug/unit_tests/protocol_dict/protocol_dict_test.c @@ -18,7 +18,7 @@ typedef struct { static const uint32_t protocol_0_decoder_result = 0xDEADBEEF; -static void* protocol_0_alloc() { +static void* protocol_0_alloc(void) { void* data = malloc(sizeof(Protocol0Data)); return data; } @@ -63,7 +63,7 @@ typedef struct { static const uint64_t protocol_1_decoder_result = 0x1234567890ABCDEF; -static void* protocol_1_alloc() { +static void* protocol_1_alloc(void) { void* data = malloc(sizeof(Protocol1Data)); return data; } @@ -216,7 +216,7 @@ MU_TEST_SUITE(test_protocol_dict_suite) { MU_RUN_TEST(test_protocol_dict); } -int run_minunit_test_protocol_dict() { +int run_minunit_test_protocol_dict(void) { MU_RUN_SUITE(test_protocol_dict_suite); return MU_EXIT_CODE; } \ No newline at end of file diff --git a/applications/debug/unit_tests/rpc/rpc_test.c b/applications/debug/unit_tests/rpc/rpc_test.c index 3faf615721..cd692d69de 100644 --- a/applications/debug/unit_tests/rpc/rpc_test.c +++ b/applications/debug/unit_tests/rpc/rpc_test.c @@ -1840,7 +1840,7 @@ MU_TEST_SUITE(test_rpc_session) { furi_record_close(RECORD_STORAGE); } -int run_minunit_test_rpc() { +int run_minunit_test_rpc(void) { Storage* storage = furi_record_open(RECORD_STORAGE); if(storage_sd_status(storage) != FSE_OK) { FURI_LOG_E(TAG, "SD card not mounted - skip storage tests"); diff --git a/applications/debug/unit_tests/storage/dirwalk_test.c b/applications/debug/unit_tests/storage/dirwalk_test.c index 19ac336fff..415ec7dd43 100644 --- a/applications/debug/unit_tests/storage/dirwalk_test.c +++ b/applications/debug/unit_tests/storage/dirwalk_test.c @@ -266,7 +266,7 @@ MU_TEST_SUITE(test_dirwalk_suite) { furi_record_close(RECORD_STORAGE); } -int run_minunit_test_dirwalk() { +int run_minunit_test_dirwalk(void) { MU_RUN_SUITE(test_dirwalk_suite); return MU_EXIT_CODE; } \ No newline at end of file diff --git a/applications/debug/unit_tests/storage/storage_test.c b/applications/debug/unit_tests/storage/storage_test.c index 5ea36935b1..e4361f06c3 100644 --- a/applications/debug/unit_tests/storage/storage_test.c +++ b/applications/debug/unit_tests/storage/storage_test.c @@ -36,7 +36,7 @@ static bool storage_file_create(Storage* storage, const char* path, const char* return result; } -static void storage_file_open_lock_setup() { +static void storage_file_open_lock_setup(void) { Storage* storage = furi_record_open(RECORD_STORAGE); File* file = storage_file_alloc(storage); storage_simply_remove(storage, STORAGE_LOCKED_FILE); @@ -47,7 +47,7 @@ static void storage_file_open_lock_setup() { furi_record_close(RECORD_STORAGE); } -static void storage_file_open_lock_teardown() { +static void storage_file_open_lock_teardown(void) { Storage* storage = furi_record_open(RECORD_STORAGE); mu_check(storage_simply_remove(storage, STORAGE_LOCKED_FILE)); furi_record_close(RECORD_STORAGE); @@ -702,7 +702,7 @@ MU_TEST_SUITE(test_md5_calc_suite) { MU_RUN_TEST(test_md5_calc); } -int run_minunit_test_storage() { +int run_minunit_test_storage(void) { MU_RUN_SUITE(storage_file); MU_RUN_SUITE(storage_file_64k); MU_RUN_SUITE(storage_dir); diff --git a/applications/debug/unit_tests/stream/stream_test.c b/applications/debug/unit_tests/stream/stream_test.c index 2fa3b21a29..3e31773b4f 100644 --- a/applications/debug/unit_tests/stream/stream_test.c +++ b/applications/debug/unit_tests/stream/stream_test.c @@ -526,7 +526,7 @@ MU_TEST_SUITE(stream_suite) { MU_RUN_TEST(stream_buffered_large_file_test); } -int run_minunit_test_stream() { +int run_minunit_test_stream(void) { MU_RUN_SUITE(stream_suite); return MU_EXIT_CODE; } diff --git a/applications/debug/unit_tests/subghz/subghz_test.c b/applications/debug/unit_tests/subghz/subghz_test.c index 0e6509b62c..adb8b4965f 100644 --- a/applications/debug/unit_tests/subghz/subghz_test.c +++ b/applications/debug/unit_tests/subghz/subghz_test.c @@ -312,7 +312,7 @@ static LevelDuration subghz_hal_async_tx_test_yield(void* context) { furi_crash("Yield after reset"); } } else { - furi_crash("Programming error"); + furi_crash(); } } @@ -902,7 +902,7 @@ MU_TEST_SUITE(subghz) { subghz_test_deinit(); } -int run_minunit_test_subghz() { +int run_minunit_test_subghz(void) { MU_RUN_SUITE(subghz); return MU_EXIT_CODE; } diff --git a/applications/debug/unit_tests/test_index.c b/applications/debug/unit_tests/test_index.c index 60132a1616..5d0282bd77 100644 --- a/applications/debug/unit_tests/test_index.c +++ b/applications/debug/unit_tests/test_index.c @@ -8,31 +8,31 @@ #define TAG "UnitTests" -int run_minunit_test_furi(); -int run_minunit_test_furi_hal(); -int run_minunit_test_furi_hal_crypto(); -int run_minunit_test_furi_string(); -int run_minunit_test_infrared(); -int run_minunit_test_rpc(); -int run_minunit_test_manifest(); -int run_minunit_test_flipper_format(); -int run_minunit_test_flipper_format_string(); -int run_minunit_test_stream(); -int run_minunit_test_storage(); -int run_minunit_test_subghz(); -int run_minunit_test_dirwalk(); -int run_minunit_test_power(); -int run_minunit_test_protocol_dict(); -int run_minunit_test_lfrfid_protocols(); -int run_minunit_test_nfc(); -int run_minunit_test_bit_lib(); -int run_minunit_test_datetime(); -int run_minunit_test_float_tools(); -int run_minunit_test_bt(); -int run_minunit_test_dialogs_file_browser_options(); -int run_minunit_test_expansion(); - -typedef int (*UnitTestEntry)(); +int run_minunit_test_furi(void); +int run_minunit_test_furi_hal(void); +int run_minunit_test_furi_hal_crypto(void); +int run_minunit_test_furi_string(void); +int run_minunit_test_infrared(void); +int run_minunit_test_rpc(void); +int run_minunit_test_manifest(void); +int run_minunit_test_flipper_format(void); +int run_minunit_test_flipper_format_string(void); +int run_minunit_test_stream(void); +int run_minunit_test_storage(void); +int run_minunit_test_subghz(void); +int run_minunit_test_dirwalk(void); +int run_minunit_test_power(void); +int run_minunit_test_protocol_dict(void); +int run_minunit_test_lfrfid_protocols(void); +int run_minunit_test_nfc(void); +int run_minunit_test_bit_lib(void); +int run_minunit_test_datetime(void); +int run_minunit_test_float_tools(void); +int run_minunit_test_bt(void); +int run_minunit_test_dialogs_file_browser_options(void); +int run_minunit_test_expansion(void); + +typedef int (*UnitTestEntry)(void); typedef struct { const char* name; @@ -66,7 +66,7 @@ const UnitTest unit_tests[] = { {.name = "expansion", .entry = run_minunit_test_expansion}, }; -void minunit_print_progress() { +void minunit_print_progress(void) { static const char progress[] = {'\\', '|', '/', '-'}; static uint8_t progress_counter = 0; static uint32_t last_tick = 0; @@ -157,7 +157,7 @@ void unit_tests_cli(Cli* cli, FuriString* args, void* context) { furi_record_close(RECORD_LOADER); } -void unit_tests_on_system_start() { +void unit_tests_on_system_start(void) { #ifdef SRV_CLI Cli* cli = furi_record_open(RECORD_CLI); diff --git a/applications/debug/unit_tests/varint/varint_test.c b/applications/debug/unit_tests/varint/varint_test.c index 8faab13688..ac444013d3 100644 --- a/applications/debug/unit_tests/varint/varint_test.c +++ b/applications/debug/unit_tests/varint/varint_test.c @@ -82,7 +82,7 @@ MU_TEST_SUITE(test_varint_suite) { MU_RUN_TEST(test_varint_rand_i); } -int run_minunit_test_varint() { +int run_minunit_test_varint(void) { MU_RUN_SUITE(test_varint_suite); return MU_EXIT_CODE; } \ No newline at end of file diff --git a/applications/debug/usb_test/usb_test.c b/applications/debug/usb_test/usb_test.c index ed86c37a88..ddec9d9b05 100644 --- a/applications/debug/usb_test/usb_test.c +++ b/applications/debug/usb_test/usb_test.c @@ -55,7 +55,7 @@ uint32_t usb_test_exit(void* context) { return VIEW_NONE; } -UsbTestApp* usb_test_app_alloc() { +UsbTestApp* usb_test_app_alloc(void) { UsbTestApp* app = malloc(sizeof(UsbTestApp)); // Gui diff --git a/applications/drivers/subghz/cc1101_ext/cc1101_ext.c b/applications/drivers/subghz/cc1101_ext/cc1101_ext.c index 5c67579ccb..f77842a3a0 100644 --- a/applications/drivers/subghz/cc1101_ext/cc1101_ext.c +++ b/applications/drivers/subghz/cc1101_ext/cc1101_ext.c @@ -98,7 +98,7 @@ typedef struct { static SubGhzDeviceCC1101Ext* subghz_device_cc1101_ext = NULL; -static bool subghz_device_cc1101_ext_check_init() { +static bool subghz_device_cc1101_ext_check_init(void) { furi_assert(subghz_device_cc1101_ext->state == SubGhzDeviceCC1101ExtStateInit); subghz_device_cc1101_ext->state = SubGhzDeviceCC1101ExtStateIdle; @@ -182,6 +182,14 @@ static bool subghz_device_cc1101_ext_check_init() { furi_hal_gpio_init( subghz_device_cc1101_ext->g0_pin, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + // Reset GDO2 (!TX/RX) to floating state + cc1101_status = cc1101_write_reg( + subghz_device_cc1101_ext->spi_bus_handle, CC1101_IOCFG2, CC1101IocfgHighImpedance); + if(cc1101_status.CHIP_RDYn != 0) { + //timeout or error + break; + } + // Go to sleep cc1101_status = cc1101_shutdown(subghz_device_cc1101_ext->spi_bus_handle); if(cc1101_status.CHIP_RDYn != 0) { @@ -232,7 +240,7 @@ bool subghz_device_cc1101_ext_alloc(SubGhzDeviceConf* conf) { return subghz_device_cc1101_ext_check_init(); } -void subghz_device_cc1101_ext_free() { +void subghz_device_cc1101_ext_free(void) { furi_assert(subghz_device_cc1101_ext != NULL); furi_hal_spi_bus_handle_deinit(subghz_device_cc1101_ext->spi_bus_handle); @@ -248,11 +256,11 @@ void subghz_device_cc1101_ext_set_async_mirror_pin(const GpioPin* pin) { subghz_device_cc1101_ext->async_mirror_pin = pin; } -const GpioPin* subghz_device_cc1101_ext_get_data_gpio() { +const GpioPin* subghz_device_cc1101_ext_get_data_gpio(void) { return subghz_device_cc1101_ext->g0_pin; } -bool subghz_device_cc1101_ext_is_connect() { +bool subghz_device_cc1101_ext_is_connect(void) { bool ret = false; if(subghz_device_cc1101_ext == NULL) { // not initialized @@ -268,7 +276,7 @@ bool subghz_device_cc1101_ext_is_connect() { return ret; } -void subghz_device_cc1101_ext_sleep() { +void subghz_device_cc1101_ext_sleep(void) { furi_assert(subghz_device_cc1101_ext->state == SubGhzDeviceCC1101ExtStateIdle); furi_hal_spi_acquire(subghz_device_cc1101_ext->spi_bus_handle); @@ -283,7 +291,7 @@ void subghz_device_cc1101_ext_sleep() { furi_hal_spi_release(subghz_device_cc1101_ext->spi_bus_handle); } -void subghz_device_cc1101_ext_dump_state() { +void subghz_device_cc1101_ext_dump_state(void) { furi_hal_spi_acquire(subghz_device_cc1101_ext->spi_bus_handle); printf( "[subghz_device_cc1101_ext] cc1101 chip %d, version %d\r\n", @@ -348,19 +356,19 @@ void subghz_device_cc1101_ext_write_packet(const uint8_t* data, uint8_t size) { furi_hal_spi_release(subghz_device_cc1101_ext->spi_bus_handle); } -void subghz_device_cc1101_ext_flush_rx() { +void subghz_device_cc1101_ext_flush_rx(void) { furi_hal_spi_acquire(subghz_device_cc1101_ext->spi_bus_handle); cc1101_flush_rx(subghz_device_cc1101_ext->spi_bus_handle); furi_hal_spi_release(subghz_device_cc1101_ext->spi_bus_handle); } -void subghz_device_cc1101_ext_flush_tx() { +void subghz_device_cc1101_ext_flush_tx(void) { furi_hal_spi_acquire(subghz_device_cc1101_ext->spi_bus_handle); cc1101_flush_tx(subghz_device_cc1101_ext->spi_bus_handle); furi_hal_spi_release(subghz_device_cc1101_ext->spi_bus_handle); } -bool subghz_device_cc1101_ext_rx_pipe_not_empty() { +bool subghz_device_cc1101_ext_rx_pipe_not_empty(void) { CC1101RxBytes status[1]; furi_hal_spi_acquire(subghz_device_cc1101_ext->spi_bus_handle); cc1101_read_reg( @@ -376,7 +384,7 @@ bool subghz_device_cc1101_ext_rx_pipe_not_empty() { } } -bool subghz_device_cc1101_ext_is_rx_data_crc_valid() { +bool subghz_device_cc1101_ext_is_rx_data_crc_valid(void) { furi_hal_spi_acquire(subghz_device_cc1101_ext->spi_bus_handle); uint8_t data[1]; cc1101_read_reg( @@ -395,14 +403,14 @@ void subghz_device_cc1101_ext_read_packet(uint8_t* data, uint8_t* size) { furi_hal_spi_release(subghz_device_cc1101_ext->spi_bus_handle); } -void subghz_device_cc1101_ext_shutdown() { +void subghz_device_cc1101_ext_shutdown(void) { furi_hal_spi_acquire(subghz_device_cc1101_ext->spi_bus_handle); // Reset and shutdown cc1101_shutdown(subghz_device_cc1101_ext->spi_bus_handle); furi_hal_spi_release(subghz_device_cc1101_ext->spi_bus_handle); } -void subghz_device_cc1101_ext_reset() { +void subghz_device_cc1101_ext_reset(void) { furi_hal_spi_acquire(subghz_device_cc1101_ext->spi_bus_handle); furi_hal_gpio_init(subghz_device_cc1101_ext->g0_pin, GpioModeAnalog, GpioPullNo, GpioSpeedLow); cc1101_switch_to_idle(subghz_device_cc1101_ext->spi_bus_handle); @@ -410,40 +418,52 @@ void subghz_device_cc1101_ext_reset() { // Warning: push pull cc1101 clock output on GD0 cc1101_write_reg( subghz_device_cc1101_ext->spi_bus_handle, CC1101_IOCFG0, CC1101IocfgHighImpedance); + // Reset GDO2 (!TX/RX) to floating state + cc1101_write_reg( + subghz_device_cc1101_ext->spi_bus_handle, CC1101_IOCFG2, CC1101IocfgHighImpedance); furi_hal_spi_release(subghz_device_cc1101_ext->spi_bus_handle); } -void subghz_device_cc1101_ext_idle() { +void subghz_device_cc1101_ext_idle(void) { furi_hal_spi_acquire(subghz_device_cc1101_ext->spi_bus_handle); cc1101_switch_to_idle(subghz_device_cc1101_ext->spi_bus_handle); //waiting for the chip to switch to IDLE mode furi_check(cc1101_wait_status_state( subghz_device_cc1101_ext->spi_bus_handle, CC1101StateIDLE, 10000)); + // Reset GDO2 (!TX/RX) to floating state + cc1101_write_reg( + subghz_device_cc1101_ext->spi_bus_handle, CC1101_IOCFG2, CC1101IocfgHighImpedance); furi_hal_spi_release(subghz_device_cc1101_ext->spi_bus_handle); if(subghz_device_cc1101_ext->power_amp) { furi_hal_gpio_write(SUBGHZ_DEVICE_CC1101_EXT_E07_AMP_GPIO, 0); } } -void subghz_device_cc1101_ext_rx() { +void subghz_device_cc1101_ext_rx(void) { furi_hal_spi_acquire(subghz_device_cc1101_ext->spi_bus_handle); cc1101_switch_to_rx(subghz_device_cc1101_ext->spi_bus_handle); //waiting for the chip to switch to Rx mode furi_check( cc1101_wait_status_state(subghz_device_cc1101_ext->spi_bus_handle, CC1101StateRX, 10000)); + // Go GDO2 (!TX/RX) to high (RX state) + cc1101_write_reg( + subghz_device_cc1101_ext->spi_bus_handle, CC1101_IOCFG2, CC1101IocfgHW | CC1101_IOCFG_INV); + furi_hal_spi_release(subghz_device_cc1101_ext->spi_bus_handle); if(subghz_device_cc1101_ext->power_amp) { furi_hal_gpio_write(SUBGHZ_DEVICE_CC1101_EXT_E07_AMP_GPIO, 0); } } -bool subghz_device_cc1101_ext_tx() { +bool subghz_device_cc1101_ext_tx(void) { if(subghz_device_cc1101_ext->regulation != SubGhzDeviceCC1101ExtRegulationTxRx) return false; furi_hal_spi_acquire(subghz_device_cc1101_ext->spi_bus_handle); cc1101_switch_to_tx(subghz_device_cc1101_ext->spi_bus_handle); //waiting for the chip to switch to Tx mode furi_check( cc1101_wait_status_state(subghz_device_cc1101_ext->spi_bus_handle, CC1101StateTX, 10000)); + // Go GDO2 (!TX/RX) to low (TX state) + cc1101_write_reg(subghz_device_cc1101_ext->spi_bus_handle, CC1101_IOCFG2, CC1101IocfgHW); furi_hal_spi_release(subghz_device_cc1101_ext->spi_bus_handle); if(subghz_device_cc1101_ext->power_amp) { furi_hal_gpio_write(SUBGHZ_DEVICE_CC1101_EXT_E07_AMP_GPIO, 1); @@ -451,7 +471,7 @@ bool subghz_device_cc1101_ext_tx() { return true; } -float subghz_device_cc1101_ext_get_rssi() { +float subghz_device_cc1101_ext_get_rssi(void) { furi_hal_spi_acquire(subghz_device_cc1101_ext->spi_bus_handle); int32_t rssi_dec = cc1101_get_rssi(subghz_device_cc1101_ext->spi_bus_handle); furi_hal_spi_release(subghz_device_cc1101_ext->spi_bus_handle); @@ -466,7 +486,7 @@ float subghz_device_cc1101_ext_get_rssi() { return rssi; } -uint8_t subghz_device_cc1101_ext_get_lqi() { +uint8_t subghz_device_cc1101_ext_get_lqi(void) { furi_hal_spi_acquire(subghz_device_cc1101_ext->spi_bus_handle); uint8_t data[1]; cc1101_read_reg( @@ -525,7 +545,7 @@ uint32_t subghz_device_cc1101_ext_set_frequency(uint32_t value) { return real_frequency; } -static bool subghz_device_cc1101_ext_start_debug() { +static bool subghz_device_cc1101_ext_start_debug(void) { bool ret = false; if(subghz_device_cc1101_ext->async_mirror_pin != NULL) { furi_hal_gpio_init( @@ -538,7 +558,7 @@ static bool subghz_device_cc1101_ext_start_debug() { return ret; } -static bool subghz_device_cc1101_ext_stop_debug() { +static bool subghz_device_cc1101_ext_stop_debug(void) { bool ret = false; if(subghz_device_cc1101_ext->async_mirror_pin != NULL) { furi_hal_gpio_init( @@ -620,7 +640,7 @@ void subghz_device_cc1101_ext_start_async_rx( subghz_device_cc1101_ext->async_rx.capture_delta_duration = 0; } -void subghz_device_cc1101_ext_stop_async_rx() { +void subghz_device_cc1101_ext_stop_async_rx(void) { furi_assert(subghz_device_cc1101_ext->state == SubGhzDeviceCC1101ExtStateAsyncRx); subghz_device_cc1101_ext->state = SubGhzDeviceCC1101ExtStateIdle; @@ -858,13 +878,13 @@ bool subghz_device_cc1101_ext_start_async_tx(SubGhzDeviceCC1101ExtCallback callb return true; } -bool subghz_device_cc1101_ext_is_async_tx_complete() { +bool subghz_device_cc1101_ext_is_async_tx_complete(void) { return ( (subghz_device_cc1101_ext->state == SubGhzDeviceCC1101ExtStateAsyncTx) && (LL_TIM_GetAutoReload(TIM17) == 0)); } -void subghz_device_cc1101_ext_stop_async_tx() { +void subghz_device_cc1101_ext_stop_async_tx(void) { furi_assert(subghz_device_cc1101_ext->state == SubGhzDeviceCC1101ExtStateAsyncTx); // Shutdown radio diff --git a/applications/drivers/subghz/cc1101_ext/cc1101_ext.h b/applications/drivers/subghz/cc1101_ext/cc1101_ext.h index 64b7d4cc1a..0832de8ac3 100644 --- a/applications/drivers/subghz/cc1101_ext/cc1101_ext.h +++ b/applications/drivers/subghz/cc1101_ext/cc1101_ext.h @@ -29,7 +29,7 @@ void subghz_device_cc1101_ext_set_async_mirror_pin(const GpioPin* pin); * * @return pointer to the gpio pin structure */ -const GpioPin* subghz_device_cc1101_ext_get_data_gpio(); +const GpioPin* subghz_device_cc1101_ext_get_data_gpio(void); /** Initialize device * @@ -39,21 +39,21 @@ bool subghz_device_cc1101_ext_alloc(SubGhzDeviceConf* conf); /** Deinitialize device */ -void subghz_device_cc1101_ext_free(); +void subghz_device_cc1101_ext_free(void); /** Check and switch to power save mode Used by internal API-HAL * initialization routine Can be used to reinitialize device to safe state and * send it to sleep */ -bool subghz_device_cc1101_ext_is_connect(); +bool subghz_device_cc1101_ext_is_connect(void); /** Send device to sleep mode */ -void subghz_device_cc1101_ext_sleep(); +void subghz_device_cc1101_ext_sleep(void); /** Dump info to stdout */ -void subghz_device_cc1101_ext_dump_state(); +void subghz_device_cc1101_ext_dump_state(void); /** Load custom registers from preset * @@ -84,13 +84,13 @@ void subghz_device_cc1101_ext_write_packet(const uint8_t* data, uint8_t size); * * @return true if not empty */ -bool subghz_device_cc1101_ext_rx_pipe_not_empty(); +bool subghz_device_cc1101_ext_rx_pipe_not_empty(void); /** Check if received data crc is valid * * @return true if valid */ -bool subghz_device_cc1101_ext_is_rx_data_crc_valid(); +bool subghz_device_cc1101_ext_is_rx_data_crc_valid(void); /** Read packet from FIFO * @@ -101,47 +101,47 @@ void subghz_device_cc1101_ext_read_packet(uint8_t* data, uint8_t* size); /** Flush rx FIFO buffer */ -void subghz_device_cc1101_ext_flush_rx(); +void subghz_device_cc1101_ext_flush_rx(void); /** Flush tx FIFO buffer */ -void subghz_device_cc1101_ext_flush_tx(); +void subghz_device_cc1101_ext_flush_tx(void); /** Shutdown Issue SPWD command * @warning registers content will be lost */ -void subghz_device_cc1101_ext_shutdown(); +void subghz_device_cc1101_ext_shutdown(void); /** Reset Issue reset command * @warning registers content will be lost */ -void subghz_device_cc1101_ext_reset(); +void subghz_device_cc1101_ext_reset(void); /** Switch to Idle */ -void subghz_device_cc1101_ext_idle(); +void subghz_device_cc1101_ext_idle(void); /** Switch to Receive */ -void subghz_device_cc1101_ext_rx(); +void subghz_device_cc1101_ext_rx(void); /** Switch to Transmit * * @return true if the transfer is allowed by belonging to the region */ -bool subghz_device_cc1101_ext_tx(); +bool subghz_device_cc1101_ext_tx(void); /** Get RSSI value in dBm * * @return RSSI value */ -float subghz_device_cc1101_ext_get_rssi(); +float subghz_device_cc1101_ext_get_rssi(void); /** Get LQI * * @return LQI value */ -uint8_t subghz_device_cc1101_ext_get_lqi(); +uint8_t subghz_device_cc1101_ext_get_lqi(void); /** Check if frequency is in valid range * @@ -175,7 +175,7 @@ void subghz_device_cc1101_ext_start_async_rx( /** Disable signal timings capture Resets GPIO and TIM2 */ -void subghz_device_cc1101_ext_stop_async_rx(); +void subghz_device_cc1101_ext_stop_async_rx(void); /** Async TX callback type * @param context callback context @@ -196,11 +196,11 @@ bool subghz_device_cc1101_ext_start_async_tx(SubGhzDeviceCC1101ExtCallback callb * * @return true if TX complete */ -bool subghz_device_cc1101_ext_is_async_tx_complete(); +bool subghz_device_cc1101_ext_is_async_tx_complete(void); /** Stop async transmission and cleanup resources Resets GPIO, TIM2, and DMA1 */ -void subghz_device_cc1101_ext_stop_async_tx(); +void subghz_device_cc1101_ext_stop_async_tx(void); #ifdef __cplusplus } diff --git a/applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.c b/applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.c index 1f11931543..68f2b8aff9 100644 --- a/applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.c +++ b/applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.c @@ -105,6 +105,6 @@ static const FlipperAppPluginDescriptor subghz_device_cc1101_ext_descriptor = { .entry_point = &subghz_device_cc1101_ext, }; -const FlipperAppPluginDescriptor* subghz_device_cc1101_ext_ep() { +const FlipperAppPluginDescriptor* subghz_device_cc1101_ext_ep(void) { return &subghz_device_cc1101_ext_descriptor; } \ No newline at end of file diff --git a/applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h b/applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h index cf1ff3ee07..3fcee45d56 100644 --- a/applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h +++ b/applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h @@ -5,4 +5,4 @@ typedef struct SubGhzDeviceCC1101Ext SubGhzDeviceCC1101Ext; -const FlipperAppPluginDescriptor* subghz_device_cc1101_ext_ep(); +const FlipperAppPluginDescriptor* subghz_device_cc1101_ext_ep(void); diff --git a/applications/examples/example_adc/application.fam b/applications/examples/example_adc/application.fam new file mode 100644 index 0000000000..68aa2ac4d4 --- /dev/null +++ b/applications/examples/example_adc/application.fam @@ -0,0 +1,9 @@ +App( + appid="example_adc", + name="Example: ADC", + apptype=FlipperAppType.EXTERNAL, + entry_point="example_adc_main", + requires=["gui"], + stack_size=1 * 1024, + fap_category="Examples", +) diff --git a/applications/examples/example_adc/example_adc.c b/applications/examples/example_adc/example_adc.c new file mode 100644 index 0000000000..53f8d5c12d --- /dev/null +++ b/applications/examples/example_adc/example_adc.c @@ -0,0 +1,176 @@ +/** + * @file example_adc.c + * @brief ADC example. + */ +#include +#include + +#include +#include +#include + +const uint8_t font[] = + "`\2\3\2\3\4\1\2\4\5\11\0\376\6\376\7\377\1M\2\263\3\370 \6\315\364\371\6!\12\315" + "\364\201\260\35\312Q\0\42\11\315tJI\316\13\0#\14\315\264\223dP*\203R'\1$\15\315\264" + "\262A\311\266D\251l\71\0%\15\315\264\7%\61)J\42\345 \0&\14\315\264\263$\13\223\266$" + "\7\1'\10\315\364\201\60\347\10(\10\315\364\32[\313\0)\11\315\64\322b[\35\2*\12\315\264\263" + "(\222j\71\15+\11\315\364I\331\226\23\1,\10\315\364\271\205Y\10-\10\315\364\31t\26\0.\10" + "\315\364\71\346(\0/\14\315\364\221\60\13\263\60\13C\0\60\13\315\264\245Jb)E:\12\61\12\315" + "\364\201Ll\333A\0\62\12\315\264\245bV\33r\20\63\13\315\264\245Z\232D\221\216\2\64\14\315\364" + "\201LJ\242!\313v\20\65\14\315t\207$\134\223(\322Q\0\66\13\315\264\245p\252D\221\216\2\67" + "\12\315t\207\60+\326a\0\70\13\315\264\245\222T\211\42\35\5\71\13\315\264\245J\24\215\221\216\2:" + "\11\315\364i\71!G\1;\12\315\364I\71!\314B\0<\11\315\364\341\254Z\7\1=\12\315\364)" + "C<\344$\0>\11\315\364\301\264V\207\1\77\12\315\264\245Z\35\312a\0@\14\315\264\245J\242$" + "J\272\203\0A\15\315\264\245J\224\14I\224D\71\10B\13\315t\247\312T\211\222\35\5C\12\315\264" + "\245JX\212t\24D\15\315t\247J\224DI\224\354(\0E\14\315t\207$\234\302p\310A\0F" + "\12\315t\207$\234\302:\1G\14\315\264\245J\230(Q\244\243\0H\17\315t\243$J\206$J\242" + "$\312A\0I\11\315\264\267\260m\7\1J\12\315\364\221\260%\212t\24K\14\315t\243\244\244iI" + "T\7\1L\11\315t\303\216C\16\2M\17\315t\243dH\206$J\242$\312A\0N\16\315t\243" + "D\251(Q\22%Q\16\2O\15\315\264\245J\224DI\24\351(\0P\12\315t\247J\224LaN" + "Q\15\315\264\245J\224DI\42\251\61\0R\14\315t\247J\224L\225(\7\1S\13\315\264\245\222\232" + "D\221\216\2T\10\315\264\267\260;\12U\16\315t\243$J\242$J\242HG\1V\15\315t\243$" + "J\242$Jj\71\14W\17\315t\243$J\242dH\206$\312A\0X\15\315t\243$\212\64\251\22" + "\345 \0Y\13\315t\243$Jja\35\6Z\12\315t\207\60k\34r\20[\10\315\264\264\260G\31" + "\134\12\315\264\303\64L\303\64\14]\10\315t\304\276\351\0^\11\315\364\201,\311\271\1_\7\315\364y" + "\35\4`\10\315t\322\234'\0a\14\315\364IK\224$R\222\203\0b\13\315t\303p\252D\311\216" + "\2c\12\315\364IR%\335A\0d\14\315\364\221\60Z\242$\212v\20e\12\315\364I\322\220\244;" + "\10f\12\315\364\221,\333\302:\12g\14\315\364IK\224D\321\30I\0h\14\315t\303p\252DI" + "\224\203\0i\12\315\364\201\34\21k;\10j\12\315\364\201\34\21\273e\0k\13\315t\303J\244%Q" + "\35\4l\10\315\264\305n;\10m\14\315\364)CRQ\22\245\216\1n\13\315\364)%\245\224D\71" + "\10o\12\315\364IR%\212t\24p\13\315\364)S%J\246\60\4q\13\315\364IK\224D\321X" + "\1r\11\315\364)%\245\230\23s\12\315\364I\313\232\354(\0t\13\315\364\201\60\333\302\64\7\1u" + "\15\315\364)Q\22%\211\224\344 \0v\13\315\364)Q\22%\265\34\6w\13\315\364)\25%Q\272" + "\203\0x\12\315\364)Q\244Iu\20y\15\315\364)Q\22%Q\64F\22\0z\12\315\364)CV" + "\33r\20{\12\315\364\212\265\64\254&\0|\7\315\264\302~\7}\12\315t\322\260\232\205\265\14~\11" + "\315\364II;\13\0\177\6\315\364\371\6\0\0\0\4\377\377\0"; + +#define FONT_HEIGHT (8u) + +typedef float (*ValueConverter)(FuriHalAdcHandle* handle, uint16_t value); + +typedef struct { + const GpioPinRecord* pin; + float value; + ValueConverter converter; + const char* suffix; +} DataItem; + +typedef struct { + size_t count; + DataItem* items; +} Data; + +const GpioPinRecord item_vref = {.name = "VREF", .channel = FuriHalAdcChannelVREFINT}; +const GpioPinRecord item_temp = {.name = "TEMP", .channel = FuriHalAdcChannelTEMPSENSOR}; +const GpioPinRecord item_vbat = {.name = "VBAT", .channel = FuriHalAdcChannelVBAT}; + +static void app_draw_callback(Canvas* canvas, void* ctx) { + furi_assert(ctx); + Data* data = ctx; + + canvas_set_custom_u8g2_font(canvas, font); + char buffer[64]; + int32_t x = 0, y = FONT_HEIGHT; + for(size_t i = 0; i < data->count; i++) { + if(i == canvas_height(canvas) / FONT_HEIGHT) { + x = 64; + y = FONT_HEIGHT; + } + + snprintf( + buffer, + sizeof(buffer), + "%4s: %4.0f%s\n", + data->items[i].pin->name, + (double)data->items[i].value, + data->items[i].suffix); + canvas_draw_str(canvas, x, y, buffer); + y += FONT_HEIGHT; + } +} + +static void app_input_callback(InputEvent* input_event, void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; + furi_message_queue_put(event_queue, input_event, FuriWaitForever); +} + +int32_t example_adc_main(void* p) { + UNUSED(p); + + // Data + Data data = {}; + for(size_t i = 0; i < gpio_pins_count; i++) { + if(gpio_pins[i].channel != FuriHalAdcChannelNone) { + data.count++; + } + } + data.count += 3; // Special channels + data.items = malloc(data.count * sizeof(DataItem)); + size_t item_pos = 0; + for(size_t i = 0; i < gpio_pins_count; i++) { + if(gpio_pins[i].channel != FuriHalAdcChannelNone) { + furi_hal_gpio_init(gpio_pins[i].pin, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + data.items[item_pos].pin = &gpio_pins[i]; + data.items[item_pos].converter = furi_hal_adc_convert_to_voltage; + data.items[item_pos].suffix = "mV"; + item_pos++; + } + } + data.items[item_pos].pin = &item_vref; + data.items[item_pos].converter = furi_hal_adc_convert_vref; + data.items[item_pos].suffix = "mV"; + item_pos++; + data.items[item_pos].pin = &item_temp; + data.items[item_pos].converter = furi_hal_adc_convert_temp; + data.items[item_pos].suffix = "C"; + item_pos++; + data.items[item_pos].pin = &item_vbat; + data.items[item_pos].converter = furi_hal_adc_convert_vbat; + data.items[item_pos].suffix = "mV"; + item_pos++; + furi_assert(item_pos == data.count); + + // Alloc message queue + FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(InputEvent)); + + // Configure view port + ViewPort* view_port = view_port_alloc(); + view_port_draw_callback_set(view_port, app_draw_callback, &data); + view_port_input_callback_set(view_port, app_input_callback, event_queue); + + // Register view port in GUI + Gui* gui = furi_record_open(RECORD_GUI); + gui_add_view_port(gui, view_port, GuiLayerFullscreen); + + // Initialize ADC + FuriHalAdcHandle* adc_handle = furi_hal_adc_acquire(); + furi_hal_adc_configure(adc_handle); + + // Process events + InputEvent event; + bool running = true; + while(running) { + if(furi_message_queue_get(event_queue, &event, 100) == FuriStatusOk) { + if(event.type == InputTypePress && event.key == InputKeyBack) { + running = false; + } + } else { + for(size_t i = 0; i < data.count; i++) { + data.items[i].value = data.items[i].converter( + adc_handle, furi_hal_adc_read(adc_handle, data.items[i].pin->channel)); + } + view_port_update(view_port); + } + } + + furi_hal_adc_release(adc_handle); + view_port_enabled_set(view_port, false); + gui_remove_view_port(gui, view_port); + view_port_free(view_port); + furi_message_queue_free(event_queue); + furi_record_close(RECORD_GUI); + free(data.items); + + return 0; +} diff --git a/applications/examples/example_ble_beacon/ble_beacon_app.c b/applications/examples/example_ble_beacon/ble_beacon_app.c index 20e3e307ab..af21336027 100644 --- a/applications/examples/example_ble_beacon/ble_beacon_app.c +++ b/applications/examples/example_ble_beacon/ble_beacon_app.c @@ -57,7 +57,7 @@ static void ble_beacon_app_restore_beacon_state(BleBeaconApp* app) { app->beacon_data_len = furi_hal_bt_extra_beacon_get_data(app->beacon_data); } -static BleBeaconApp* ble_beacon_app_alloc() { +static BleBeaconApp* ble_beacon_app_alloc(void) { BleBeaconApp* app = malloc(sizeof(BleBeaconApp)); app->gui = furi_record_open(RECORD_GUI); diff --git a/applications/examples/example_custom_font/example_custom_font.c b/applications/examples/example_custom_font/example_custom_font.c index 2fec419041..a175838e31 100644 --- a/applications/examples/example_custom_font/example_custom_font.c +++ b/applications/examples/example_custom_font/example_custom_font.c @@ -11,35 +11,62 @@ //This arrays contains the font itself. You can use any u8g2 font you want /* -Fontname: -Raccoon-Fixed4x6-Medium-R-Normal--6-60-75-75-P-40-ISO10646-1 -Copyright: -Glyphs: 95/203 -BBX Build Mode: 0 + Fontname: -Misc-Fixed-Medium-R-Normal--6-60-75-75-C-40-ISO10646-1 + Copyright: Public domain font. Share and enjoy. + Glyphs: 191/919 + BBX Build Mode: 0 */ -const uint8_t u8g2_font_tom_thumb_4x6_tr[725] = - "_\0\2\2\2\3\3\4\4\3\6\0\377\5\377\5\0\0\352\1\330\2\270 \5\340\315\0!\6\265\310" - "\254\0\42\6\213\313$\25#\10\227\310\244\241\206\12$\10\227\310\215\70b\2%\10\227\310d\324F\1" - "&\10\227\310(\65R\22'\5\251\313\10(\6\266\310\251\62)\10\226\310\304\224\24\0*\6\217\312\244" - "\16+\7\217\311\245\225\0,\6\212\310)\0-\5\207\312\14.\5\245\310\4/\7\227\310Ve\4\60" - "\7\227\310-k\1\61\6\226\310\255\6\62\10\227\310h\220\312\1\63\11\227\310h\220\62X\0\64\10\227" - "\310$\65b\1\65\10\227\310\214\250\301\2\66\10\227\310\315\221F\0\67\10\227\310\314TF\0\70\10\227" - "\310\214\64\324\10\71\10\227\310\214\64\342\2:\6\255\311\244\0;\7\222\310e\240\0<\10\227\310\246\32" - "d\20=\6\217\311l\60>\11\227\310d\220A*\1\77\10\227\310\314\224a\2@\10\227\310UC\3" - "\1A\10\227\310UC\251\0B\10\227\310\250\264\322\2C\7\227\310\315\32\10D\10\227\310\250d-\0" - "E\10\227\310\214\70\342\0F\10\227\310\214\70b\4G\10\227\310\315\221\222\0H\10\227\310$\65\224\12" - "I\7\227\310\254X\15J\7\227\310\226\252\2K\10\227\310$\265\222\12L\7\227\310\304\346\0M\10\227" - "\310\244\61\224\12N\10\227\310\244q\250\0O\7\227\310UV\5P\10\227\310\250\264b\4Q\10\227\310" - "Uj$\1R\10\227\310\250\64V\1S\10\227\310m\220\301\2T\7\227\310\254\330\2U\7\227\310$" - "W\22V\10\227\310$\253L\0W\10\227\310$\65\206\12X\10\227\310$\325R\1Y\10\227\310$U" - "V\0Z\7\227\310\314T\16[\7\227\310\214X\16\134\10\217\311d\220A\0]\7\227\310\314r\4^" - "\5\213\313\65_\5\207\310\14`\6\212\313\304\0a\7\223\310\310\65\2b\10\227\310D\225\324\2c\7" - "\223\310\315\14\4d\10\227\310\246\245\222\0e\6\223\310\235\2f\10\227\310\246\264b\2g\10\227\307\35" - "\61%\0h\10\227\310D\225\254\0i\6\265\310\244\1j\10\233\307f\30U\5k\10\227\310\304\264T" - "\1l\7\227\310\310\326\0m\7\223\310\11\253\310d\220A*\1\77\11\253\310h\220\62L\0@\7" + "\253\310-\33\10A\10\253\310UC\251\0B\10\253\310\250\264\322\2C\10\253\310U\62U\0D\10\253" + "\310\250d-\0E\10\253\310\214\250\342\0F\10\253\310\214\250b\4G\10\253\310\315\244\222\0H\10\253" + "\310$\65\224\12I\7\253\310\254X\15J\7\253\310\226\252\2K\10\253\310$\265\222\12L\7\253\310\304" + "\346\0M\10\253\310\244\61\224\12N\10\253\310\252\241$\0O\7\253\310UV\5P\10\253\310\250\264b" + "\4Q\10\263\307UV\15\2R\10\253\310\250\264\222\12S\10\253\310m\220\301\2T\7\253\310\254\330\2" + "U\7\253\310$\327\10V\10\253\310$k\244\4W\10\253\310$\65\206\12X\10\253\310$\325R\1Y" + "\10\253\310$UV\0Z\7\253\310\314T\16[\6\352\310\254J\134\11\253\310\304\14\62\210\1]\6\252" + "\310\250j^\5\223\313\65_\5\213\307\14`\6\322\313\304\0a\7\243\310-\225\4b\10\253\310D\225" + "\324\2c\7\243\310\315\14\4d\10\253\310\246\245\222\0e\6\243\310USf\10\253\310\246\264b\2g" + "\10\253\307\255$\27\0h\10\253\310D\225\254\0i\10\253\310e$\323\0j\10\263\307fX.\0k" + "\10\253\310\304\264\222\12l\7\253\310\310\326\0m\10\243\310\244\241T\0n\7\243\310\250d\5o\7\243" + "\310U\252\2p\10\253\307\250\264b\4q\10\253\307-\225d\0r\10\243\310\244\25#\0s\10\243\310" + "\215\14\26\0t\10\253\310\245\25\63\10u\7\243\310$+\11v\7\243\310$\253\2w\10\243\310$\65" + "T\0x\7\243\310\244\62\25y\10\253\307$\225\344\2z\7\243\310\314\224\6{\10\263\307\246$k\20" + "|\6\351\310\14\1}\11\263\307d\20UL\21~\7\224\313%\225\0\0\0\0\4\377\377\4\1\11\253" + "\310\244\261\342\0\4\2\11\253\310\214\250\222\12\4\3\10\253\310\16Y\2\4\4\11\253\310M\225\201\0\4" + "\5\11\253\310m\220\301\2\4\6\10\253\310\254X\15\4\7\11\253\310\244\221b\32\4\10\10\253\310\226\252" + "\2\4\11\11\254\310L\325Z\2\4\12\11\254\310\244\326JK\4\13\11\253\310\250\250\222\12\4\14\10\253" + "\310\312\264\12\4\16\11\263\307\244\32u\2\4\17\11\263\307$\327H\11\4\20\11\253\310UC\251\0\4" + "\21\11\253\310\214\250\322\2\4\22\11\253\310\250\264\322\2\4\23\10\253\310\214\330\4\4\24\11\263\307\254\245" + "\206\12\4\25\11\253\310\214\250\342\0\4\26\12\253\310\244\221\322H\1\4\27\12\253\310h\220\62X\0\4" + "\30\11\253\310\304\64T\14\4\31\11\263\307\315\64T\14\4\32\11\253\310$\265\222\12\4\33\10\253\310-" + "W\0\4\34\11\253\310\244\241\254\0\4\35\11\253\310$\65\224\12\4\36\10\253\310UV\5\4\37\10\253" + "\310\214\344\12\4 \11\253\310\250\264b\4\4!\11\253\310U\62U\0\4\42\10\253\310\254\330\2\4#" + "\11\263\307$\253L\21\4$\12\253\310\245\221FJ\0\4%\11\253\310$\325R\1\4&\10\253\310$" + "\327\10\4'\11\253\310$\225d\1\4(\11\253\310$\65\216\0\4)\12\264\307\244\326#\203\0\4*" + "\13\254\310h\220\201LI\1\4+\12\254\310D\271\324H\1\4,\11\253\310\304\250\322\2\4-\11\253" + "\310h\220\344\2\4.\12\254\310\244\244.\225\0\4/\11\253\310\255\264T\0\4\60\10\243\310-\225\4" + "\4\61\11\253\310\315\221*\0\4\62\11\243\310\14\225\26\0\4\63\10\243\310\214X\2\4\64\11\253\307-" + "\65T\0\4\65\7\243\310US\4\66\11\244\310$S%\1\4\67\11\243\310\254\14\26\0\4\70\11\243" + "\310\244\61T\0\4\71\11\253\310\244\326P\1\4:\10\243\310$\265\12\4;\7\243\310-+\4<\11" + "\243\310\244\241T\0\4=\11\243\310\244\241T\0\4>\10\243\310U\252\2\4\77\10\243\310\214d\5\4" + "@\11\253\307\250\264b\4\4A\10\243\310\315\14\4\4B\10\243\310\254X\1\4C\11\253\307$\225\344" + "\2\4D\12\263\307\305\224T\231\0\4E\10\243\310\244\62\25\4F\11\253\307$k\304\0\4G\11\243" + "\310$\225d\0\4H\10\243\310\244q\4\4I\11\254\307\244\364\310 \4J\12\244\310h SR\0" + "\4K\11\244\310\304\245F\12\4L\11\243\310D\225\26\0\4M\10\243\310H\271\0\4N\12\244\310\244" + "\244\226J\0\4O\10\243\310\255\264\2\4Q\10\253\310\244\326\24\4R\11\263\307D\25U\31\4S\11" + "\253\310\246\64b\4\4T\11\243\310\215\224\201\0\4U\11\243\310\215\14\26\0\4V\11\253\310e$\323" + "\0\4W\11\253\310\244\14d\32\4X\11\263\307fX.\0\4Y\10\244\310\251\326\22\4Z\11\244\310" + "\244\264\322\22\4[\11\253\310D\25U\1\4\134\10\253\310\312\264\12\4^\11\263\307\244\32u\2\4_" + "\11\253\307$k\244\4\4\220\10\253\310\16Y\2\4\221\10\243\310\16\31\1\4\222\11\253\310\251\264b\2" + "\4\223\11\243\310\251\264\22\0\0"; // Screen is 128x64 px static void app_draw_callback(Canvas* canvas, void* ctx) { @@ -47,10 +74,11 @@ static void app_draw_callback(Canvas* canvas, void* ctx) { canvas_clear(canvas); - canvas_set_custom_u8g2_font(canvas, u8g2_font_tom_thumb_4x6_tr); + canvas_set_custom_u8g2_font(canvas, u8g2_font_4x6_t_cyrillic); canvas_draw_str(canvas, 0, 6, "This is a tiny custom font"); canvas_draw_str(canvas, 0, 12, "012345.?! ,:;\"\'@#$%"); + canvas_draw_str(canvas, 0, 18, "И немного юникода"); } static void app_input_callback(InputEvent* input_event, void* ctx) { @@ -66,7 +94,7 @@ int32_t example_custom_font_main(void* p) { // Configure view port ViewPort* view_port = view_port_alloc(); - view_port_draw_callback_set(view_port, app_draw_callback, view_port); + view_port_draw_callback_set(view_port, app_draw_callback, NULL); view_port_input_callback_set(view_port, app_input_callback, event_queue); // Register view port in GUI diff --git a/applications/examples/example_images/example_images.c b/applications/examples/example_images/example_images.c index c43a30b698..60269a81f7 100644 --- a/applications/examples/example_images/example_images.c +++ b/applications/examples/example_images/example_images.c @@ -13,7 +13,7 @@ #include "example_images_icons.h" typedef struct { - uint8_t x, y; + int32_t x, y; } ImagePosition; static ImagePosition image_position = {.x = 0, .y = 0}; @@ -23,7 +23,7 @@ static void app_draw_callback(Canvas* canvas, void* ctx) { UNUSED(ctx); canvas_clear(canvas); - canvas_draw_icon(canvas, image_position.x % 128, image_position.y % 64, &I_dolphin_71x25); + canvas_draw_icon(canvas, image_position.x, image_position.y, &I_dolphin_71x25); } static void app_input_callback(InputEvent* input_event, void* ctx) { @@ -39,7 +39,7 @@ int32_t example_images_main(void* p) { // Configure view port ViewPort* view_port = view_port_alloc(); - view_port_draw_callback_set(view_port, app_draw_callback, view_port); + view_port_draw_callback_set(view_port, app_draw_callback, NULL); view_port_input_callback_set(view_port, app_input_callback, event_queue); // Register view port in GUI diff --git a/applications/examples/example_plugins/plugin1.c b/applications/examples/example_plugins/plugin1.c index de8041f343..05036d252a 100644 --- a/applications/examples/example_plugins/plugin1.c +++ b/applications/examples/example_plugins/plugin1.c @@ -9,7 +9,7 @@ #include -static int example_plugin1_method1() { +static int example_plugin1_method1(void) { return 42; } @@ -32,6 +32,6 @@ static const FlipperAppPluginDescriptor example_plugin1_descriptor = { }; /* Plugin entry point - must return a pointer to const descriptor */ -const FlipperAppPluginDescriptor* example_plugin1_ep() { +const FlipperAppPluginDescriptor* example_plugin1_ep(void) { return &example_plugin1_descriptor; } diff --git a/applications/examples/example_plugins/plugin2.c b/applications/examples/example_plugins/plugin2.c index a196437f4b..bff170dde9 100644 --- a/applications/examples/example_plugins/plugin2.c +++ b/applications/examples/example_plugins/plugin2.c @@ -9,7 +9,7 @@ #include -static int example_plugin2_method1() { +static int example_plugin2_method1(void) { return 1337; } @@ -32,6 +32,6 @@ static const FlipperAppPluginDescriptor example_plugin2_descriptor = { }; /* Plugin entry point - must return a pointer to const descriptor */ -const FlipperAppPluginDescriptor* example_plugin2_ep() { +const FlipperAppPluginDescriptor* example_plugin2_ep(void) { return &example_plugin2_descriptor; } diff --git a/applications/examples/example_plugins/plugin_interface.h b/applications/examples/example_plugins/plugin_interface.h index 85428429ee..fadb9089fe 100644 --- a/applications/examples/example_plugins/plugin_interface.h +++ b/applications/examples/example_plugins/plugin_interface.h @@ -11,6 +11,6 @@ typedef struct { const char* name; - int (*method1)(); + int (*method1)(void); int (*method2)(int, int); } ExamplePlugin; diff --git a/applications/examples/example_plugins_advanced/app_api.c b/applications/examples/example_plugins_advanced/app_api.c index 42b3a1860d..4f314f4cec 100644 --- a/applications/examples/example_plugins_advanced/app_api.c +++ b/applications/examples/example_plugins_advanced/app_api.c @@ -8,7 +8,7 @@ void app_api_accumulator_set(uint32_t value) { accumulator = value; } -uint32_t app_api_accumulator_get() { +uint32_t app_api_accumulator_get(void) { return accumulator; } diff --git a/applications/examples/example_plugins_advanced/app_api.h b/applications/examples/example_plugins_advanced/app_api.h index 60a52e6f76..df80455d70 100644 --- a/applications/examples/example_plugins_advanced/app_api.h +++ b/applications/examples/example_plugins_advanced/app_api.h @@ -15,7 +15,7 @@ extern "C" { void app_api_accumulator_set(uint32_t value); -uint32_t app_api_accumulator_get(); +uint32_t app_api_accumulator_get(void); void app_api_accumulator_add(uint32_t value); diff --git a/applications/examples/example_plugins_advanced/plugin1.c b/applications/examples/example_plugins_advanced/plugin1.c index 9130810079..e45122d958 100644 --- a/applications/examples/example_plugins_advanced/plugin1.c +++ b/applications/examples/example_plugins_advanced/plugin1.c @@ -18,7 +18,7 @@ static void advanced_plugin1_method1(int arg1) { app_api_accumulator_add(arg1); } -static void advanced_plugin1_method2() { +static void advanced_plugin1_method2(void) { /* Accumulator value is stored inside host application */ FURI_LOG_I("TEST", "Plugin 1, accumulator: %lu", app_api_accumulator_get()); } @@ -38,6 +38,6 @@ static const FlipperAppPluginDescriptor advanced_plugin1_descriptor = { }; /* Plugin entry point - must return a pointer to const descriptor */ -const FlipperAppPluginDescriptor* advanced_plugin1_ep() { +const FlipperAppPluginDescriptor* advanced_plugin1_ep(void) { return &advanced_plugin1_descriptor; } diff --git a/applications/examples/example_plugins_advanced/plugin2.c b/applications/examples/example_plugins_advanced/plugin2.c index 1ea5590b22..efc8db4783 100644 --- a/applications/examples/example_plugins_advanced/plugin2.c +++ b/applications/examples/example_plugins_advanced/plugin2.c @@ -18,7 +18,7 @@ static void advanced_plugin2_method1(int arg1) { app_api_accumulator_mul(arg1); } -static void advanced_plugin2_method2() { +static void advanced_plugin2_method2(void) { /* Accumulator value is stored inside host application */ FURI_LOG_I("TEST", "Plugin 2, accumulator: %lu", app_api_accumulator_get()); } @@ -38,6 +38,6 @@ static const FlipperAppPluginDescriptor advanced_plugin2_descriptor = { }; /* Plugin entry point - must return a pointer to const descriptor */ -const FlipperAppPluginDescriptor* advanced_plugin2_ep() { +const FlipperAppPluginDescriptor* advanced_plugin2_ep(void) { return &advanced_plugin2_descriptor; } diff --git a/applications/examples/example_plugins_advanced/plugin_interface.h b/applications/examples/example_plugins_advanced/plugin_interface.h index d78dc9ecc1..4cef7567bc 100644 --- a/applications/examples/example_plugins_advanced/plugin_interface.h +++ b/applications/examples/example_plugins_advanced/plugin_interface.h @@ -12,5 +12,5 @@ typedef struct { const char* name; void (*method1)(int); - void (*method2)(); + void (*method2)(void); } AdvancedPlugin; diff --git a/applications/examples/example_thermo/example_thermo.c b/applications/examples/example_thermo/example_thermo.c index 576ece3826..dafe568863 100644 --- a/applications/examples/example_thermo/example_thermo.c +++ b/applications/examples/example_thermo/example_thermo.c @@ -315,7 +315,7 @@ static void example_thermo_run(ExampleThermoContext* context) { /******************** Initialisation & startup *****************************/ /* Allocate the memory and initialise the variables */ -static ExampleThermoContext* example_thermo_context_alloc() { +static ExampleThermoContext* example_thermo_context_alloc(void) { ExampleThermoContext* context = malloc(sizeof(ExampleThermoContext)); context->view_port = view_port_alloc(); diff --git a/applications/main/archive/archive.c b/applications/main/archive/archive.c index 066fcab059..7f01b2f750 100644 --- a/applications/main/archive/archive.c +++ b/applications/main/archive/archive.c @@ -18,7 +18,7 @@ static void archive_tick_event_callback(void* context) { scene_manager_handle_tick_event(archive->scene_manager); } -static ArchiveApp* archive_alloc() { +ArchiveApp* archive_alloc(void) { ArchiveApp* archive = malloc(sizeof(ArchiveApp)); archive->fav_move_str = furi_string_alloc(); diff --git a/applications/main/archive/helpers/archive_favorites.c b/applications/main/archive/helpers/archive_favorites.c index 682aa6b383..351d68c1d2 100644 --- a/applications/main/archive/helpers/archive_favorites.c +++ b/applications/main/archive/helpers/archive_favorites.c @@ -79,7 +79,7 @@ uint16_t archive_favorites_count(void* context) { return lines; } -static bool archive_favourites_rescan() { +static bool archive_favourites_rescan(void) { FuriString* buffer; buffer = furi_string_alloc(); Storage* storage = furi_record_open(RECORD_STORAGE); diff --git a/applications/main/archive/views/archive_browser_view.c b/applications/main/archive/views/archive_browser_view.c index 6e3e8c5ceb..d1eed91a09 100644 --- a/applications/main/archive/views/archive_browser_view.c +++ b/applications/main/archive/views/archive_browser_view.c @@ -687,7 +687,7 @@ static void browser_view_exit(void* context) { furi_timer_stop(browser->scroll_timer); } -ArchiveBrowserView* browser_alloc() { +ArchiveBrowserView* browser_alloc(void) { ArchiveBrowserView* browser = malloc(sizeof(ArchiveBrowserView)); browser->view = view_alloc(); view_allocate_model(browser->view, ViewModelTypeLocking, sizeof(ArchiveBrowserViewModel)); diff --git a/applications/main/archive/views/archive_browser_view.h b/applications/main/archive/views/archive_browser_view.h index 5541ba9fe5..87d029664a 100644 --- a/applications/main/archive/views/archive_browser_view.h +++ b/applications/main/archive/views/archive_browser_view.h @@ -126,8 +126,7 @@ void archive_browser_set_callback( View* archive_browser_get_view(ArchiveBrowserView* browser); -ArchiveBrowserView* browser_alloc(); - +ArchiveBrowserView* browser_alloc(void); void browser_free(ArchiveBrowserView* browser); void archive_browser_clipboard_set_mode(ArchiveBrowserView* browser, uint8_t mode); diff --git a/applications/main/bad_usb/application.fam b/applications/main/bad_usb/application.fam index 9844e248df..8d3909fccc 100644 --- a/applications/main/bad_usb/application.fam +++ b/applications/main/bad_usb/application.fam @@ -7,7 +7,7 @@ App( icon="A_BadUsb_14", order=70, resources="resources", - fap_libs=["assets"], + fap_libs=["assets", "ble_profile"], fap_icon="icon.png", fap_category="USB", ) diff --git a/applications/main/bad_usb/bad_usb_app.c b/applications/main/bad_usb/bad_usb_app.c index ea97c44878..0cf7f19248 100644 --- a/applications/main/bad_usb/bad_usb_app.c +++ b/applications/main/bad_usb/bad_usb_app.c @@ -1,11 +1,14 @@ #include "bad_usb_app_i.h" -#include "bad_usb_settings_filename.h" #include #include #include #include +#include -#define BAD_USB_SETTINGS_PATH BAD_USB_APP_BASE_FOLDER "/" BAD_USB_SETTINGS_FILE_NAME +#define BAD_USB_SETTINGS_PATH BAD_USB_APP_BASE_FOLDER "/.badusb.settings" +#define BAD_USB_SETTINGS_FILE_TYPE "Flipper BadUSB Settings File" +#define BAD_USB_SETTINGS_VERSION 1 +#define BAD_USB_SETTINGS_DEFAULT_LAYOUT BAD_USB_APP_PATH_LAYOUT_FOLDER "/en-US.kl" static bool bad_usb_app_custom_event_callback(void* context, uint32_t event) { furi_assert(context); @@ -26,46 +29,69 @@ static void bad_usb_app_tick_event_callback(void* context) { } static void bad_usb_load_settings(BadUsbApp* app) { - File* settings_file = storage_file_alloc(furi_record_open(RECORD_STORAGE)); - if(storage_file_open(settings_file, BAD_USB_SETTINGS_PATH, FSAM_READ, FSOM_OPEN_EXISTING)) { - char chr; - while((storage_file_read(settings_file, &chr, 1) == 1) && - !storage_file_eof(settings_file) && !isspace(chr)) { - furi_string_push_back(app->keyboard_layout, chr); - } - } else { - furi_string_reset(app->keyboard_layout); + Storage* storage = furi_record_open(RECORD_STORAGE); + FlipperFormat* fff = flipper_format_file_alloc(storage); + bool state = false; + + FuriString* temp_str = furi_string_alloc(); + uint32_t version = 0; + uint32_t interface = 0; + + if(flipper_format_file_open_existing(fff, BAD_USB_SETTINGS_PATH)) { + do { + if(!flipper_format_read_header(fff, temp_str, &version)) break; + if((strcmp(furi_string_get_cstr(temp_str), BAD_USB_SETTINGS_FILE_TYPE) != 0) || + (version != BAD_USB_SETTINGS_VERSION)) + break; + + if(!flipper_format_read_string(fff, "layout", temp_str)) break; + if(!flipper_format_read_uint32(fff, "interface", &interface, 1)) break; + if(interface > BadUsbHidInterfaceBle) break; + + state = true; + } while(0); } - storage_file_close(settings_file); - storage_file_free(settings_file); + flipper_format_free(fff); + furi_record_close(RECORD_STORAGE); + + if(state) { + furi_string_set(app->keyboard_layout, temp_str); + app->interface = interface; - if(!furi_string_empty(app->keyboard_layout)) { Storage* fs_api = furi_record_open(RECORD_STORAGE); FileInfo layout_file_info; FS_Error file_check_err = storage_common_stat( fs_api, furi_string_get_cstr(app->keyboard_layout), &layout_file_info); furi_record_close(RECORD_STORAGE); - if(file_check_err != FSE_OK) { - furi_string_reset(app->keyboard_layout); - return; - } - if(layout_file_info.size != 256) { - furi_string_reset(app->keyboard_layout); + if((file_check_err != FSE_OK) || (layout_file_info.size != 256)) { + furi_string_set(app->keyboard_layout, BAD_USB_SETTINGS_DEFAULT_LAYOUT); } + } else { + furi_string_set(app->keyboard_layout, BAD_USB_SETTINGS_DEFAULT_LAYOUT); + app->interface = BadUsbHidInterfaceUsb; } + + furi_string_free(temp_str); } static void bad_usb_save_settings(BadUsbApp* app) { - File* settings_file = storage_file_alloc(furi_record_open(RECORD_STORAGE)); - if(storage_file_open(settings_file, BAD_USB_SETTINGS_PATH, FSAM_WRITE, FSOM_OPEN_ALWAYS)) { - storage_file_write( - settings_file, - furi_string_get_cstr(app->keyboard_layout), - furi_string_size(app->keyboard_layout)); - storage_file_write(settings_file, "\n", 1); + Storage* storage = furi_record_open(RECORD_STORAGE); + FlipperFormat* fff = flipper_format_file_alloc(storage); + + if(flipper_format_file_open_always(fff, BAD_USB_SETTINGS_PATH)) { + do { + if(!flipper_format_write_header_cstr( + fff, BAD_USB_SETTINGS_FILE_TYPE, BAD_USB_SETTINGS_VERSION)) + break; + if(!flipper_format_write_string(fff, "layout", app->keyboard_layout)) break; + uint32_t interface_id = app->interface; + if(!flipper_format_write_uint32(fff, "interface", (const uint32_t*)&interface_id, 1)) + break; + } while(0); } - storage_file_close(settings_file); - storage_file_free(settings_file); + + flipper_format_free(fff); + furi_record_close(RECORD_STORAGE); } BadUsbApp* bad_usb_app_alloc(char* arg) { @@ -103,13 +129,15 @@ BadUsbApp* bad_usb_app_alloc(char* arg) { view_dispatcher_add_view( app->view_dispatcher, BadUsbAppViewError, widget_get_view(app->widget)); - app->submenu = submenu_alloc(); + app->var_item_list = variable_item_list_alloc(); view_dispatcher_add_view( - app->view_dispatcher, BadUsbAppViewConfig, submenu_get_view(app->submenu)); + app->view_dispatcher, + BadUsbAppViewConfig, + variable_item_list_get_view(app->var_item_list)); - app->bad_usb_view = bad_usb_alloc(); + app->bad_usb_view = bad_usb_view_alloc(); view_dispatcher_add_view( - app->view_dispatcher, BadUsbAppViewWork, bad_usb_get_view(app->bad_usb_view)); + app->view_dispatcher, BadUsbAppViewWork, bad_usb_view_get_view(app->bad_usb_view)); view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen); @@ -122,8 +150,6 @@ BadUsbApp* bad_usb_app_alloc(char* arg) { furi_check(furi_hal_usb_set_config(NULL, NULL)); if(!furi_string_empty(app->file_path)) { - app->bad_usb_script = bad_usb_script_open(app->file_path); - bad_usb_script_set_keyboard_layout(app->bad_usb_script, app->keyboard_layout); scene_manager_next_scene(app->scene_manager, BadUsbSceneWork); } else { furi_string_set(app->file_path, BAD_USB_APP_BASE_FOLDER); @@ -144,15 +170,15 @@ void bad_usb_app_free(BadUsbApp* app) { // Views view_dispatcher_remove_view(app->view_dispatcher, BadUsbAppViewWork); - bad_usb_free(app->bad_usb_view); + bad_usb_view_free(app->bad_usb_view); // Custom Widget view_dispatcher_remove_view(app->view_dispatcher, BadUsbAppViewError); widget_free(app->widget); - // Submenu + // Config menu view_dispatcher_remove_view(app->view_dispatcher, BadUsbAppViewConfig); - submenu_free(app->submenu); + variable_item_list_free(app->var_item_list); // View dispatcher view_dispatcher_free(app->view_dispatcher); diff --git a/applications/main/bad_usb/bad_usb_app_i.h b/applications/main/bad_usb/bad_usb_app_i.h index cf1c02ebc7..cb54d94e92 100644 --- a/applications/main/bad_usb/bad_usb_app_i.h +++ b/applications/main/bad_usb/bad_usb_app_i.h @@ -3,12 +3,12 @@ #include "bad_usb_app.h" #include "scenes/bad_usb_scene.h" #include "helpers/ducky_script.h" +#include "helpers/bad_usb_hid.h" #include #include #include #include -#include #include #include #include @@ -16,7 +16,7 @@ #include "views/bad_usb_view.h" #include -#define BAD_USB_APP_BASE_FOLDER ANY_PATH("badusb") +#define BAD_USB_APP_BASE_FOLDER EXT_PATH("badusb") #define BAD_USB_APP_PATH_LAYOUT_FOLDER BAD_USB_APP_BASE_FOLDER "/assets/layouts" #define BAD_USB_APP_SCRIPT_EXTENSION ".txt" #define BAD_USB_APP_LAYOUT_EXTENSION ".kl" @@ -33,7 +33,7 @@ struct BadUsbApp { NotificationApp* notifications; DialogsApp* dialogs; Widget* widget; - Submenu* submenu; + VariableItemList* var_item_list; BadUsbAppError error; FuriString* file_path; @@ -41,6 +41,7 @@ struct BadUsbApp { BadUsb* bad_usb_view; BadUsbScript* bad_usb_script; + BadUsbHidInterface interface; FuriHalUsbInterface* usb_if_prev; }; diff --git a/applications/main/bad_usb/bad_usb_settings_filename.h b/applications/main/bad_usb/bad_usb_settings_filename.h deleted file mode 100644 index 12ba8f31c4..0000000000 --- a/applications/main/bad_usb/bad_usb_settings_filename.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -#define BAD_USB_SETTINGS_FILE_NAME ".badusb.settings" diff --git a/applications/main/bad_usb/helpers/bad_usb_hid.c b/applications/main/bad_usb/helpers/bad_usb_hid.c new file mode 100644 index 0000000000..289e3ae8c1 --- /dev/null +++ b/applications/main/bad_usb/helpers/bad_usb_hid.c @@ -0,0 +1,226 @@ +#include "bad_usb_hid.h" +#include +#include +#include + +#define TAG "BadUSB HID" + +#define HID_BT_KEYS_STORAGE_NAME ".bt_hid.keys" + +void* hid_usb_init(FuriHalUsbHidConfig* hid_cfg) { + furi_check(furi_hal_usb_set_config(&usb_hid, hid_cfg)); + return NULL; +} + +void hid_usb_deinit(void* inst) { + UNUSED(inst); + furi_check(furi_hal_usb_set_config(NULL, NULL)); +} + +void hid_usb_set_state_callback(void* inst, HidStateCallback cb, void* context) { + UNUSED(inst); + furi_hal_hid_set_state_callback(cb, context); +} + +bool hid_usb_is_connected(void* inst) { + UNUSED(inst); + return furi_hal_hid_is_connected(); +} + +bool hid_usb_kb_press(void* inst, uint16_t button) { + UNUSED(inst); + return furi_hal_hid_kb_press(button); +} + +bool hid_usb_kb_release(void* inst, uint16_t button) { + UNUSED(inst); + return furi_hal_hid_kb_release(button); +} + +bool hid_usb_consumer_press(void* inst, uint16_t button) { + UNUSED(inst); + return furi_hal_hid_consumer_key_press(button); +} + +bool hid_usb_consumer_release(void* inst, uint16_t button) { + UNUSED(inst); + return furi_hal_hid_consumer_key_release(button); +} + +bool hid_usb_release_all(void* inst) { + UNUSED(inst); + bool state = furi_hal_hid_kb_release_all(); + state &= furi_hal_hid_consumer_key_release_all(); + return state; +} + +uint8_t hid_usb_get_led_state(void* inst) { + UNUSED(inst); + return furi_hal_hid_get_led_state(); +} + +static const BadUsbHidApi hid_api_usb = { + .init = hid_usb_init, + .deinit = hid_usb_deinit, + .set_state_callback = hid_usb_set_state_callback, + .is_connected = hid_usb_is_connected, + + .kb_press = hid_usb_kb_press, + .kb_release = hid_usb_kb_release, + .consumer_press = hid_usb_consumer_press, + .consumer_release = hid_usb_consumer_release, + .release_all = hid_usb_release_all, + .get_led_state = hid_usb_get_led_state, +}; + +typedef struct { + Bt* bt; + FuriHalBleProfileBase* profile; + HidStateCallback state_callback; + void* callback_context; + bool is_connected; +} BleHidInstance; + +static const BleProfileHidParams ble_hid_params = { + .device_name_prefix = "BadUSB", + .mac_xor = 0x0002, +}; + +static void hid_ble_connection_status_callback(BtStatus status, void* context) { + furi_assert(context); + BleHidInstance* ble_hid = context; + ble_hid->is_connected = (status == BtStatusConnected); + if(ble_hid->state_callback) { + ble_hid->state_callback(ble_hid->is_connected, ble_hid->callback_context); + } +} + +void* hid_ble_init(FuriHalUsbHidConfig* hid_cfg) { + UNUSED(hid_cfg); + BleHidInstance* ble_hid = malloc(sizeof(BleHidInstance)); + ble_hid->bt = furi_record_open(RECORD_BT); + bt_disconnect(ble_hid->bt); + + // Wait 2nd core to update nvm storage + furi_delay_ms(200); + + bt_keys_storage_set_storage_path(ble_hid->bt, APP_DATA_PATH(HID_BT_KEYS_STORAGE_NAME)); + + ble_hid->profile = bt_profile_start(ble_hid->bt, ble_profile_hid, (void*)&ble_hid_params); + furi_check(ble_hid->profile); + + furi_hal_bt_start_advertising(); + + bt_set_status_changed_callback(ble_hid->bt, hid_ble_connection_status_callback, ble_hid); + + return ble_hid; +} + +void hid_ble_deinit(void* inst) { + BleHidInstance* ble_hid = inst; + furi_assert(ble_hid); + + bt_set_status_changed_callback(ble_hid->bt, NULL, NULL); + bt_disconnect(ble_hid->bt); + + // Wait 2nd core to update nvm storage + furi_delay_ms(200); + bt_keys_storage_set_default_path(ble_hid->bt); + + furi_check(bt_profile_restore_default(ble_hid->bt)); + furi_record_close(RECORD_BT); + free(ble_hid); +} + +void hid_ble_set_state_callback(void* inst, HidStateCallback cb, void* context) { + BleHidInstance* ble_hid = inst; + furi_assert(ble_hid); + ble_hid->state_callback = cb; + ble_hid->callback_context = context; +} + +bool hid_ble_is_connected(void* inst) { + BleHidInstance* ble_hid = inst; + furi_assert(ble_hid); + return ble_hid->is_connected; +} + +bool hid_ble_kb_press(void* inst, uint16_t button) { + BleHidInstance* ble_hid = inst; + furi_assert(ble_hid); + return ble_profile_hid_kb_press(ble_hid->profile, button); +} + +bool hid_ble_kb_release(void* inst, uint16_t button) { + BleHidInstance* ble_hid = inst; + furi_assert(ble_hid); + return ble_profile_hid_kb_release(ble_hid->profile, button); +} + +bool hid_ble_consumer_press(void* inst, uint16_t button) { + BleHidInstance* ble_hid = inst; + furi_assert(ble_hid); + return ble_profile_hid_consumer_key_press(ble_hid->profile, button); +} + +bool hid_ble_consumer_release(void* inst, uint16_t button) { + BleHidInstance* ble_hid = inst; + furi_assert(ble_hid); + return ble_profile_hid_consumer_key_release(ble_hid->profile, button); +} + +bool hid_ble_release_all(void* inst) { + BleHidInstance* ble_hid = inst; + furi_assert(ble_hid); + bool state = ble_profile_hid_kb_release_all(ble_hid->profile); + state &= ble_profile_hid_consumer_key_release_all(ble_hid->profile); + return state; +} + +uint8_t hid_ble_get_led_state(void* inst) { + UNUSED(inst); + FURI_LOG_W(TAG, "hid_ble_get_led_state not implemented"); + return 0; +} + +static const BadUsbHidApi hid_api_ble = { + .init = hid_ble_init, + .deinit = hid_ble_deinit, + .set_state_callback = hid_ble_set_state_callback, + .is_connected = hid_ble_is_connected, + + .kb_press = hid_ble_kb_press, + .kb_release = hid_ble_kb_release, + .consumer_press = hid_ble_consumer_press, + .consumer_release = hid_ble_consumer_release, + .release_all = hid_ble_release_all, + .get_led_state = hid_ble_get_led_state, +}; + +const BadUsbHidApi* bad_usb_hid_get_interface(BadUsbHidInterface interface) { + if(interface == BadUsbHidInterfaceUsb) { + return &hid_api_usb; + } else { + return &hid_api_ble; + } +} + +void bad_usb_hid_ble_remove_pairing(void) { + Bt* bt = furi_record_open(RECORD_BT); + bt_disconnect(bt); + + // Wait 2nd core to update nvm storage + furi_delay_ms(200); + + furi_hal_bt_stop_advertising(); + + bt_keys_storage_set_storage_path(bt, APP_DATA_PATH(HID_BT_KEYS_STORAGE_NAME)); + bt_forget_bonded_devices(bt); + + // Wait 2nd core to update nvm storage + furi_delay_ms(200); + bt_keys_storage_set_default_path(bt); + + furi_check(bt_profile_restore_default(bt)); + furi_record_close(RECORD_BT); +} \ No newline at end of file diff --git a/applications/main/bad_usb/helpers/bad_usb_hid.h b/applications/main/bad_usb/helpers/bad_usb_hid.h new file mode 100644 index 0000000000..71d3a58e79 --- /dev/null +++ b/applications/main/bad_usb/helpers/bad_usb_hid.h @@ -0,0 +1,35 @@ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +typedef enum { + BadUsbHidInterfaceUsb, + BadUsbHidInterfaceBle, +} BadUsbHidInterface; + +typedef struct { + void* (*init)(FuriHalUsbHidConfig* hid_cfg); + void (*deinit)(void* inst); + void (*set_state_callback)(void* inst, HidStateCallback cb, void* context); + bool (*is_connected)(void* inst); + + bool (*kb_press)(void* inst, uint16_t button); + bool (*kb_release)(void* inst, uint16_t button); + bool (*consumer_press)(void* inst, uint16_t button); + bool (*consumer_release)(void* inst, uint16_t button); + bool (*release_all)(void* inst); + uint8_t (*get_led_state)(void* inst); +} BadUsbHidApi; + +const BadUsbHidApi* bad_usb_hid_get_interface(BadUsbHidInterface interface); + +void bad_usb_hid_ble_remove_pairing(void); + +#ifdef __cplusplus +} +#endif diff --git a/applications/main/bad_usb/helpers/ducky_script.c b/applications/main/bad_usb/helpers/ducky_script.c index 2b3d998a47..e1bd44169e 100644 --- a/applications/main/bad_usb/helpers/ducky_script.c +++ b/applications/main/bad_usb/helpers/ducky_script.c @@ -3,7 +3,6 @@ #include #include #include -#include #include #include "ducky_script.h" #include "ducky_script_i.h" @@ -71,39 +70,40 @@ bool ducky_get_number(const char* param, uint32_t* val) { return false; } -void ducky_numlock_on() { - if((furi_hal_hid_get_led_state() & HID_KB_LED_NUM) == 0) { - furi_hal_hid_kb_press(HID_KEYBOARD_LOCK_NUM_LOCK); - furi_hal_hid_kb_release(HID_KEYBOARD_LOCK_NUM_LOCK); +void ducky_numlock_on(BadUsbScript* bad_usb) { + if((bad_usb->hid->get_led_state(bad_usb->hid_inst) & HID_KB_LED_NUM) == 0) { + bad_usb->hid->kb_press(bad_usb->hid_inst, HID_KEYBOARD_LOCK_NUM_LOCK); + bad_usb->hid->kb_release(bad_usb->hid_inst, HID_KEYBOARD_LOCK_NUM_LOCK); } } -bool ducky_numpad_press(const char num) { + +bool ducky_numpad_press(BadUsbScript* bad_usb, const char num) { if((num < '0') || (num > '9')) return false; uint16_t key = numpad_keys[num - '0']; - furi_hal_hid_kb_press(key); - furi_hal_hid_kb_release(key); + bad_usb->hid->kb_press(bad_usb->hid_inst, key); + bad_usb->hid->kb_release(bad_usb->hid_inst, key); return true; } -bool ducky_altchar(const char* charcode) { +bool ducky_altchar(BadUsbScript* bad_usb, const char* charcode) { uint8_t i = 0; bool state = false; - furi_hal_hid_kb_press(KEY_MOD_LEFT_ALT); + bad_usb->hid->kb_press(bad_usb->hid_inst, KEY_MOD_LEFT_ALT); while(!ducky_is_line_end(charcode[i])) { - state = ducky_numpad_press(charcode[i]); + state = ducky_numpad_press(bad_usb, charcode[i]); if(state == false) break; i++; } - furi_hal_hid_kb_release(KEY_MOD_LEFT_ALT); + bad_usb->hid->kb_release(bad_usb->hid_inst, KEY_MOD_LEFT_ALT); return state; } -bool ducky_altstring(const char* param) { +bool ducky_altstring(BadUsbScript* bad_usb, const char* param) { uint32_t i = 0; bool state = false; @@ -116,7 +116,7 @@ bool ducky_altstring(const char* param) { char temp_str[4]; snprintf(temp_str, 4, "%u", param[i]); - state = ducky_altchar(temp_str); + state = ducky_altchar(bad_usb, temp_str); if(state == false) break; i++; } @@ -140,12 +140,12 @@ bool ducky_string(BadUsbScript* bad_usb, const char* param) { if(param[i] != '\n') { uint16_t keycode = BADUSB_ASCII_TO_KEY(bad_usb, param[i]); if(keycode != HID_KEYBOARD_NONE) { - furi_hal_hid_kb_press(keycode); - furi_hal_hid_kb_release(keycode); + bad_usb->hid->kb_press(bad_usb->hid_inst, keycode); + bad_usb->hid->kb_release(bad_usb->hid_inst, keycode); } } else { - furi_hal_hid_kb_press(HID_KEYBOARD_RETURN); - furi_hal_hid_kb_release(HID_KEYBOARD_RETURN); + bad_usb->hid->kb_press(bad_usb->hid_inst, HID_KEYBOARD_RETURN); + bad_usb->hid->kb_release(bad_usb->hid_inst, HID_KEYBOARD_RETURN); } i++; } @@ -163,12 +163,12 @@ static bool ducky_string_next(BadUsbScript* bad_usb) { if(print_char != '\n') { uint16_t keycode = BADUSB_ASCII_TO_KEY(bad_usb, print_char); if(keycode != HID_KEYBOARD_NONE) { - furi_hal_hid_kb_press(keycode); - furi_hal_hid_kb_release(keycode); + bad_usb->hid->kb_press(bad_usb->hid_inst, keycode); + bad_usb->hid->kb_release(bad_usb->hid_inst, keycode); } } else { - furi_hal_hid_kb_press(HID_KEYBOARD_RETURN); - furi_hal_hid_kb_release(HID_KEYBOARD_RETURN); + bad_usb->hid->kb_press(bad_usb->hid_inst, HID_KEYBOARD_RETURN); + bad_usb->hid->kb_release(bad_usb->hid_inst, HID_KEYBOARD_RETURN); } bad_usb->string_print_pos++; @@ -205,8 +205,8 @@ static int32_t ducky_parse_line(BadUsbScript* bad_usb, FuriString* line) { key |= ducky_get_keycode(bad_usb, line_tmp + offset, true); } } - furi_hal_hid_kb_press(key); - furi_hal_hid_kb_release(key); + bad_usb->hid->kb_press(bad_usb->hid_inst, key); + bad_usb->hid->kb_release(bad_usb->hid_inst, key); return 0; } @@ -235,6 +235,17 @@ static bool ducky_set_usb_id(BadUsbScript* bad_usb, const char* line) { return false; } +static void bad_usb_hid_state_callback(bool state, void* context) { + furi_assert(context); + BadUsbScript* bad_usb = context; + + if(state == true) { + furi_thread_flags_set(furi_thread_get_id(bad_usb->thread), WorkerEvtConnect); + } else { + furi_thread_flags_set(furi_thread_get_id(bad_usb->thread), WorkerEvtDisconnect); + } +} + static bool ducky_script_preload(BadUsbScript* bad_usb, File* script_file) { uint8_t ret = 0; uint32_t line_len = 0; @@ -269,10 +280,11 @@ static bool ducky_script_preload(BadUsbScript* bad_usb, File* script_file) { } if(id_set) { - furi_check(furi_hal_usb_set_config(&usb_hid, &bad_usb->hid_cfg)); + bad_usb->hid_inst = bad_usb->hid->init(&bad_usb->hid_cfg); } else { - furi_check(furi_hal_usb_set_config(&usb_hid, NULL)); + bad_usb->hid_inst = bad_usb->hid->init(NULL); } + bad_usb->hid->set_state_callback(bad_usb->hid_inst, bad_usb_hid_state_callback, bad_usb); storage_file_seek(script_file, 0, true); furi_string_reset(bad_usb->line); @@ -349,17 +361,6 @@ static int32_t ducky_script_execute_next(BadUsbScript* bad_usb, File* script_fil return 0; } -static void bad_usb_hid_state_callback(bool state, void* context) { - furi_assert(context); - BadUsbScript* bad_usb = context; - - if(state == true) { - furi_thread_flags_set(furi_thread_get_id(bad_usb->thread), WorkerEvtConnect); - } else { - furi_thread_flags_set(furi_thread_get_id(bad_usb->thread), WorkerEvtDisconnect); - } -} - static uint32_t bad_usb_flags_get(uint32_t flags_mask, uint32_t timeout) { uint32_t flags = furi_thread_flags_get(); furi_check((flags & FuriFlagError) == 0); @@ -386,8 +387,6 @@ static int32_t bad_usb_worker(void* context) { bad_usb->line_prev = furi_string_alloc(); bad_usb->string_print = furi_string_alloc(); - furi_hal_hid_set_state_callback(bad_usb_hid_state_callback, bad_usb); - while(1) { if(worker_state == BadUsbStateInit) { // State: initialization if(storage_file_open( @@ -396,7 +395,7 @@ static int32_t bad_usb_worker(void* context) { FSAM_READ, FSOM_OPEN_EXISTING)) { if((ducky_script_preload(bad_usb, script_file)) && (bad_usb->st.line_nb > 0)) { - if(furi_hal_hid_is_connected()) { + if(bad_usb->hid->is_connected(bad_usb->hid_inst)) { worker_state = BadUsbStateIdle; // Ready to run } else { worker_state = BadUsbStateNotConnected; // USB not connected @@ -412,7 +411,8 @@ static int32_t bad_usb_worker(void* context) { } else if(worker_state == BadUsbStateNotConnected) { // State: USB not connected uint32_t flags = bad_usb_flags_get( - WorkerEvtEnd | WorkerEvtConnect | WorkerEvtStartStop, FuriWaitForever); + WorkerEvtEnd | WorkerEvtConnect | WorkerEvtDisconnect | WorkerEvtStartStop, + FuriWaitForever); if(flags & WorkerEvtEnd) { break; @@ -494,10 +494,10 @@ static int32_t bad_usb_worker(void* context) { break; } else if(flags & WorkerEvtStartStop) { worker_state = BadUsbStateIdle; // Stop executing script - furi_hal_hid_kb_release_all(); + bad_usb->hid->release_all(bad_usb->hid_inst); } else if(flags & WorkerEvtDisconnect) { worker_state = BadUsbStateNotConnected; // USB disconnected - furi_hal_hid_kb_release_all(); + bad_usb->hid->release_all(bad_usb->hid_inst); } else if(flags & WorkerEvtPauseResume) { pause_state = BadUsbStateRunning; worker_state = BadUsbStatePaused; // Pause @@ -517,12 +517,12 @@ static int32_t bad_usb_worker(void* context) { delay_val = 0; worker_state = BadUsbStateScriptError; bad_usb->st.state = worker_state; - furi_hal_hid_kb_release_all(); + bad_usb->hid->release_all(bad_usb->hid_inst); } else if(delay_val == SCRIPT_STATE_END) { // End of script delay_val = 0; worker_state = BadUsbStateIdle; bad_usb->st.state = BadUsbStateDone; - furi_hal_hid_kb_release_all(); + bad_usb->hid->release_all(bad_usb->hid_inst); continue; } else if(delay_val == SCRIPT_STATE_STRING_START) { // Start printing string with delays delay_val = bad_usb->defdelay; @@ -550,7 +550,7 @@ static int32_t bad_usb_worker(void* context) { worker_state = BadUsbStateRunning; } else if(flags & WorkerEvtDisconnect) { worker_state = BadUsbStateNotConnected; // USB disconnected - furi_hal_hid_kb_release_all(); + bad_usb->hid->release_all(bad_usb->hid_inst); } bad_usb->st.state = worker_state; continue; @@ -565,11 +565,11 @@ static int32_t bad_usb_worker(void* context) { } else if(flags & WorkerEvtStartStop) { worker_state = BadUsbStateIdle; // Stop executing script bad_usb->st.state = worker_state; - furi_hal_hid_kb_release_all(); + bad_usb->hid->release_all(bad_usb->hid_inst); } else if(flags & WorkerEvtDisconnect) { worker_state = BadUsbStateNotConnected; // USB disconnected bad_usb->st.state = worker_state; - furi_hal_hid_kb_release_all(); + bad_usb->hid->release_all(bad_usb->hid_inst); } else if(flags & WorkerEvtPauseResume) { if(pause_state == BadUsbStateRunning) { if(delay_val > 0) { @@ -599,10 +599,10 @@ static int32_t bad_usb_worker(void* context) { break; } else if(flags & WorkerEvtStartStop) { worker_state = BadUsbStateIdle; // Stop executing script - furi_hal_hid_kb_release_all(); + bad_usb->hid->release_all(bad_usb->hid_inst); } else if(flags & WorkerEvtDisconnect) { worker_state = BadUsbStateNotConnected; // USB disconnected - furi_hal_hid_kb_release_all(); + bad_usb->hid->release_all(bad_usb->hid_inst); } else if(flags & WorkerEvtPauseResume) { pause_state = BadUsbStateStringDelay; worker_state = BadUsbStatePaused; // Pause @@ -632,7 +632,8 @@ static int32_t bad_usb_worker(void* context) { } } - furi_hal_hid_set_state_callback(NULL, NULL); + bad_usb->hid->set_state_callback(bad_usb->hid_inst, NULL, NULL); + bad_usb->hid->deinit(bad_usb->hid_inst); storage_file_close(script_file); storage_file_free(script_file); @@ -651,7 +652,7 @@ static void bad_usb_script_set_default_keyboard_layout(BadUsbScript* bad_usb) { memcpy(bad_usb->layout, hid_asciimap, MIN(sizeof(hid_asciimap), sizeof(bad_usb->layout))); } -BadUsbScript* bad_usb_script_open(FuriString* file_path) { +BadUsbScript* bad_usb_script_open(FuriString* file_path, BadUsbHidInterface interface) { furi_assert(file_path); BadUsbScript* bad_usb = malloc(sizeof(BadUsbScript)); @@ -661,6 +662,7 @@ BadUsbScript* bad_usb_script_open(FuriString* file_path) { bad_usb->st.state = BadUsbStateInit; bad_usb->st.error[0] = '\0'; + bad_usb->hid = bad_usb_hid_get_interface(interface); bad_usb->thread = furi_thread_alloc_ex("BadUsbWorker", 2048, bad_usb_worker, bad_usb); furi_thread_start(bad_usb->thread); diff --git a/applications/main/bad_usb/helpers/ducky_script.h b/applications/main/bad_usb/helpers/ducky_script.h index dca61ed4e4..9519623f60 100644 --- a/applications/main/bad_usb/helpers/ducky_script.h +++ b/applications/main/bad_usb/helpers/ducky_script.h @@ -6,6 +6,7 @@ extern "C" { #include #include +#include "bad_usb_hid.h" typedef enum { BadUsbStateInit, @@ -33,7 +34,7 @@ typedef struct { typedef struct BadUsbScript BadUsbScript; -BadUsbScript* bad_usb_script_open(FuriString* file_path); +BadUsbScript* bad_usb_script_open(FuriString* file_path, BadUsbHidInterface interface); void bad_usb_script_close(BadUsbScript* bad_usb); diff --git a/applications/main/bad_usb/helpers/ducky_script_commands.c b/applications/main/bad_usb/helpers/ducky_script_commands.c index fdf963b404..7f9a48fb20 100644 --- a/applications/main/bad_usb/helpers/ducky_script_commands.c +++ b/applications/main/bad_usb/helpers/ducky_script_commands.c @@ -1,5 +1,4 @@ #include -#include #include "ducky_script.h" #include "ducky_script_i.h" @@ -93,9 +92,9 @@ static int32_t ducky_fnc_sysrq(BadUsbScript* bad_usb, const char* line, int32_t line = &line[ducky_get_command_len(line) + 1]; uint16_t key = ducky_get_keycode(bad_usb, line, true); - furi_hal_hid_kb_press(KEY_MOD_LEFT_ALT | HID_KEYBOARD_PRINT_SCREEN); - furi_hal_hid_kb_press(key); - furi_hal_hid_kb_release_all(); + bad_usb->hid->kb_press(bad_usb->hid_inst, KEY_MOD_LEFT_ALT | HID_KEYBOARD_PRINT_SCREEN); + bad_usb->hid->kb_press(bad_usb->hid_inst, key); + bad_usb->hid->release_all(bad_usb->hid_inst); return 0; } @@ -103,8 +102,8 @@ static int32_t ducky_fnc_altchar(BadUsbScript* bad_usb, const char* line, int32_ UNUSED(param); line = &line[ducky_get_command_len(line) + 1]; - ducky_numlock_on(); - bool state = ducky_altchar(line); + ducky_numlock_on(bad_usb); + bool state = ducky_altchar(bad_usb, line); if(!state) { return ducky_error(bad_usb, "Invalid altchar %s", line); } @@ -115,8 +114,8 @@ static int32_t ducky_fnc_altstring(BadUsbScript* bad_usb, const char* line, int3 UNUSED(param); line = &line[ducky_get_command_len(line) + 1]; - ducky_numlock_on(); - bool state = ducky_altstring(line); + ducky_numlock_on(bad_usb); + bool state = ducky_altstring(bad_usb, line); if(!state) { return ducky_error(bad_usb, "Invalid altstring %s", line); } @@ -135,7 +134,7 @@ static int32_t ducky_fnc_hold(BadUsbScript* bad_usb, const char* line, int32_t p if(bad_usb->key_hold_nb > (HID_KB_MAX_KEYS - 1)) { return ducky_error(bad_usb, "Too many keys are hold"); } - furi_hal_hid_kb_press(key); + bad_usb->hid->kb_press(bad_usb->hid_inst, key); return 0; } @@ -151,7 +150,36 @@ static int32_t ducky_fnc_release(BadUsbScript* bad_usb, const char* line, int32_ return ducky_error(bad_usb, "No keys are hold"); } bad_usb->key_hold_nb--; - furi_hal_hid_kb_release(key); + bad_usb->hid->kb_release(bad_usb->hid_inst, key); + return 0; +} + +static int32_t ducky_fnc_media(BadUsbScript* bad_usb, const char* line, int32_t param) { + UNUSED(param); + + line = &line[ducky_get_command_len(line) + 1]; + uint16_t key = ducky_get_media_keycode_by_name(line); + if(key == HID_CONSUMER_UNASSIGNED) { + return ducky_error(bad_usb, "No keycode defined for %s", line); + } + bad_usb->hid->consumer_press(bad_usb->hid_inst, key); + bad_usb->hid->consumer_release(bad_usb->hid_inst, key); + return 0; +} + +static int32_t ducky_fnc_globe(BadUsbScript* bad_usb, const char* line, int32_t param) { + UNUSED(param); + + line = &line[ducky_get_command_len(line) + 1]; + uint16_t key = ducky_get_keycode(bad_usb, line, true); + if(key == HID_KEYBOARD_NONE) { + return ducky_error(bad_usb, "No keycode defined for %s", line); + } + + bad_usb->hid->consumer_press(bad_usb->hid_inst, HID_CONSUMER_FN_GLOBE); + bad_usb->hid->kb_press(bad_usb->hid_inst, key); + bad_usb->hid->kb_release(bad_usb->hid_inst, key); + bad_usb->hid->consumer_release(bad_usb->hid_inst, HID_CONSUMER_FN_GLOBE); return 0; } @@ -183,6 +211,8 @@ static const DuckyCmd ducky_commands[] = { {"HOLD", ducky_fnc_hold, -1}, {"RELEASE", ducky_fnc_release, -1}, {"WAIT_FOR_BUTTON_PRESS", ducky_fnc_waitforbutton, -1}, + {"MEDIA", ducky_fnc_media, -1}, + {"GLOBE", ducky_fnc_globe, -1}, }; #define TAG "BadUsb" diff --git a/applications/main/bad_usb/helpers/ducky_script_i.h b/applications/main/bad_usb/helpers/ducky_script_i.h index 9c1025b00b..bbafdccb6a 100644 --- a/applications/main/bad_usb/helpers/ducky_script_i.h +++ b/applications/main/bad_usb/helpers/ducky_script_i.h @@ -7,6 +7,7 @@ extern "C" { #include #include #include "ducky_script.h" +#include "bad_usb_hid.h" #define SCRIPT_STATE_ERROR (-1) #define SCRIPT_STATE_END (-2) @@ -19,6 +20,8 @@ extern "C" { struct BadUsbScript { FuriHalUsbHidConfig hid_cfg; + const BadUsbHidApi* hid; + void* hid_inst; FuriThread* thread; BadUsbState st; @@ -50,15 +53,17 @@ bool ducky_is_line_end(const char chr); uint16_t ducky_get_keycode_by_name(const char* param); +uint16_t ducky_get_media_keycode_by_name(const char* param); + bool ducky_get_number(const char* param, uint32_t* val); -void ducky_numlock_on(void); +void ducky_numlock_on(BadUsbScript* bad_usb); -bool ducky_numpad_press(const char num); +bool ducky_numpad_press(BadUsbScript* bad_usb, const char num); -bool ducky_altchar(const char* charcode); +bool ducky_altchar(BadUsbScript* bad_usb, const char* charcode); -bool ducky_altstring(const char* param); +bool ducky_altstring(BadUsbScript* bad_usb, const char* param); bool ducky_string(BadUsbScript* bad_usb, const char* param); diff --git a/applications/main/bad_usb/helpers/ducky_script_keycodes.c b/applications/main/bad_usb/helpers/ducky_script_keycodes.c index 56b5144d48..290618c131 100644 --- a/applications/main/bad_usb/helpers/ducky_script_keycodes.c +++ b/applications/main/bad_usb/helpers/ducky_script_keycodes.c @@ -1,5 +1,4 @@ #include -#include #include "ducky_script_i.h" typedef struct { @@ -78,6 +77,37 @@ static const DuckyKey ducky_keys[] = { {"F24", HID_KEYBOARD_F24}, }; +static const DuckyKey ducky_media_keys[] = { + {"POWER", HID_CONSUMER_POWER}, + {"REBOOT", HID_CONSUMER_RESET}, + {"SLEEP", HID_CONSUMER_SLEEP}, + {"LOGOFF", HID_CONSUMER_AL_LOGOFF}, + + {"EXIT", HID_CONSUMER_AC_EXIT}, + {"HOME", HID_CONSUMER_AC_HOME}, + {"BACK", HID_CONSUMER_AC_BACK}, + {"FORWARD", HID_CONSUMER_AC_FORWARD}, + {"REFRESH", HID_CONSUMER_AC_REFRESH}, + + {"SNAPSHOT", HID_CONSUMER_SNAPSHOT}, + + {"PLAY", HID_CONSUMER_PLAY}, + {"PAUSE", HID_CONSUMER_PAUSE}, + {"PLAY_PAUSE", HID_CONSUMER_PLAY_PAUSE}, + {"NEXT_TRACK", HID_CONSUMER_SCAN_NEXT_TRACK}, + {"PREV_TRACK", HID_CONSUMER_SCAN_PREVIOUS_TRACK}, + {"STOP", HID_CONSUMER_STOP}, + {"EJECT", HID_CONSUMER_EJECT}, + + {"MUTE", HID_CONSUMER_MUTE}, + {"VOLUME_UP", HID_CONSUMER_VOLUME_INCREMENT}, + {"VOLUME_DOWN", HID_CONSUMER_VOLUME_DECREMENT}, + + {"FN", HID_CONSUMER_FN_GLOBE}, + {"BRIGHT_UP", HID_CONSUMER_BRIGHTNESS_INCREMENT}, + {"BRIGHT_DOWN", HID_CONSUMER_BRIGHTNESS_DECREMENT}, +}; + uint16_t ducky_get_keycode_by_name(const char* param) { for(size_t i = 0; i < COUNT_OF(ducky_keys); i++) { size_t key_cmd_len = strlen(ducky_keys[i].name); @@ -89,3 +119,15 @@ uint16_t ducky_get_keycode_by_name(const char* param) { return HID_KEYBOARD_NONE; } + +uint16_t ducky_get_media_keycode_by_name(const char* param) { + for(size_t i = 0; i < COUNT_OF(ducky_media_keys); i++) { + size_t key_cmd_len = strlen(ducky_media_keys[i].name); + if((strncmp(param, ducky_media_keys[i].name, key_cmd_len) == 0) && + (ducky_is_line_end(param[key_cmd_len]))) { + return ducky_media_keys[i].keycode; + } + } + + return HID_CONSUMER_UNASSIGNED; +} diff --git a/applications/main/bad_usb/resources/badusb/demo_chromeos.txt b/applications/main/bad_usb/resources/badusb/demo_chromeos.txt new file mode 100644 index 0000000000..c5f675fb33 --- /dev/null +++ b/applications/main/bad_usb/resources/badusb/demo_chromeos.txt @@ -0,0 +1,80 @@ +REM This is BadUSB demo script for ChromeOS by kowalski7cc + +REM Open a new tab +CTRL t +REM wait for some slower chromebooks +DELAY 1000 +REM Open an empty editable page +DEFAULT_DELAY 50 +STRING data:text/html,