From 6de50fcd0aa2513ee72e809d8f680b08a15e1fec Mon Sep 17 00:00:00 2001 From: jbohack Date: Sun, 1 Jan 2023 00:41:33 -0500 Subject: [PATCH 1/6] updated documentation (not finalized) --- documentation/readme.md | 178 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 175 insertions(+), 3 deletions(-) diff --git a/documentation/readme.md b/documentation/readme.md index ac5b617ab..3a714a593 100644 --- a/documentation/readme.md +++ b/documentation/readme.md @@ -1,5 +1,177 @@ -This documentation is work-in-progress. +

Xtreme Firmware Documentation

-For now just read the file names and look for what you need to know. This will be updated to a nice readable document shortly! +

+ +

-- 31.12.2022 ClaraCrazy +

Install:

+ +**NOTE: If you are coming from a different FW, it is recommended to delete / clear your "apps" folder on the SD card prior to updating. This folder houses all the .fap files, which do not update to the correct API versions by default if old ones are present (Thanks flipper devs). This does `NOT` remove any of your saved files!** +

+ +

Web Updater / Mobile App / Automatic qFlipper Update

+ +- Go to the latest release from [The releases tab](https://github.com/ClaraCrazy/Flipper-Xtreme/releases/latest) +- Download the .tgz file +- Run your updater of choice with it + +- Enjoy! +
+ +----- +
+ +

Manual Update (Because qFlipper loves to break every now and then for no reason at all)

+ +- Download the latest release (.zip) from [The releases tab](https://github.com/ClaraCrazy/Flipper-Xtreme/releases/latest) +- Extract the archive. This is now your new Firmware folder +- Open [qFlipper](https://flipperzero.one/update), head to `SD/Update` and simply move the firmware folder there +- On the Flipper, hit the `Arrow Down` button, this will get you to the file menu. Hit `Arrow Left` once, and then simply search for your updates folder +- Inside that folder, select the Firmware you just moved onto it, and run the file thats simply called `Update` + +- Enjoy! + +---- + +
+

Build it yourself:

+ +```bash +To download the needed tools: +$ git clone --recursive https://github.com/ClaraCrazy/Flipper-Xtreme.git +$ cd Flipper-Xtreme/ + +To flash directly to the Flipper (Needs to be connected via USB, qFlipper closed) +$ ./fbt flash_usb + +To just compile firmware +$ ./fbt updater_package + +If building FAPS: +$ ./fbt fap_dist + +If building image assets: +$ ./fbt resources icons dolphin_ext +``` + +
+

Safe for work mode:

+ +**Enable SFW mode with the steps listed below** +
+ +- Navigate to the main screen +- Press the UP button on the Flipper +- Press the 'SFW Mode' toggle + +---- + +
+

Support the project

+ +**If you like Xtreme Firmware and wish to help out, we would love it if you contributed to the project ❤️** +
+ +- [Bunq - My bank](https://bunq.me/ClaraK) +- [Paypal](https://paypal.me/RdX2020) +- [Patreon](https://patreon.com/CynthiaLabs) +- `Monero`: 41kyWeeoVdK4quzQ4M9ikVGs6tCQCLfdx8jLExTNsAu2SF1QAyDqRdjfGM6EL8L9NpXwt89HJeAoGf1aoArk7nDr4AMMV4T + + + +---- + + +
+

Applications we use thanks to the awesome contributers and community ❤️

+ +## GPIO +- [Lightmeter](https://github.com/oleksiikutuzov/flipperzero-lightmeter) +- [Air Mouse](https://github.com/ginkage/FlippAirMouse/) +- [Wifi Marauder](https://github.com/0xchocolate/flipperzero-firmware-with-wifi-marauder-companion) +- [Wifi Deauther](https://github.com/Timmotools/flipperzero_esp8266_deautherv2) +- [IFTTT Virtual Button for ESP8266 (By Ferrazzi)](https://github.com/Ferrazzi/FlipperZero_IFTTT_Virtual_Button) +- [Flashlight (By xMasterX)](https://github.com/xMasterX/flipper-flashlight) +- [GPIO Reader 1](https://github.com/biotinker/flipperzero-gpioreader) +- [GPIO Reader 2](https://github.com/aureli1c/flipperzero_GPIO_read) +- [Sentry Safe](https://github.com/H4ckd4ddy/flipperzero-sentry-safe-plugin) +- [Distance Sensor](https://github.com/Sanqui/flipperzero-firmware/tree/59656ca5fb644e0d4484259986b86a0b963f323d/applications/hc_sr04) +- [Temperature Sensor](https://github.com/Mywk/FlipperTemperatureSensor) +- [i2c Tools](https://github.com/NaejEL/flipperzero-i2ctools) +- [GPS](https://github.com/ezod/flipperzero-gps) +- [Mouse Jacker](https://github.com/mothball187/flipperzero-nrf24/tree/main/mousejacker) +- [Sniffer](https://github.com/mothball187/flipperzero-nrf24/tree/main/nrfsniff) +- [Scanner](https://github.com/vad7/nrf24scan) +- [ColecoVision Controller](https://github.com/ezod/flipperzero-rc2014-coleco) + + +## Games +- [2048](https://github.com/eugene-kirzhanov/flipper-zero-2048-game) +- [Arkanoid](https://github.com/DarkFlippers/unleashed-firmware/tree/dev/applications/plugins/arkanoid) +- [BlackJack](https://github.com/teeebor/flipper_games) +- [Doom](https://github.com/p4nic4ttack/doom-flipper-zero/) +- Multi Dice - In-house +- [Flappy Bird](https://github.com/DroomOne/flipperzero-firmware/tree/dev/applications/flappy_bird) +- [Game 15](https://github.com/x27/flipperzero-game15) +- [Game of Life (Updated to work by tgxn) (By itsyourbedtime)](https://github.com/tgxn/flipperzero-firmware/blob/dev/applications/game_of_life/game_of_life.c) +- Heap defense - Author Unknown +- [Mandelbrot Set (By Possibly-Matt)](https://github.com/Possibly-Matt/flipperzero-firmware-wPlugins) +- [Minesweeper](https://github.com/panki27/minesweeper) +- [Snake](https://github.com/flipperdevices/flipperzero-firmware/tree/dev/applications/plugins/snake_game) +- [Solitaire](https://github.com/teeebor/flipper_games) +- [Tetris](https://github.com/jeffplang/flipperzero-firmware/tree/tetris_game/applications/tetris_game) +- [Tic Tac Toe](https://github.com/gotnull/flipperzero-firmware-wPlugins/tree/420/applications/plugins/tictactoe_game) +- [Tamagotchi(By GMMan)](https://github.com/GMMan/flipperzero-tamagotch-p1) +- [Video Poker (By PixlEmly)](https://github.com/PixlEmly/flipperzero-firmware-testing/blob/420/applications/VideoPoker/poker.c) +- [Yatzee (By emfleak)](https://github.com/emfleak/flipperzero-yatzee) + + +## Misc +- [Authenticator (TOTP / HOTP)](https://github.com/akopachov/flipper-zero_authenticator) +- [Barcode Generator](https://github.com/McAzzaMan/flipperzero-firmware/tree/UPC-A_Barcode_Generator/applications/barcode_generator) +- [Caesar Cipher](https://github.com/panki27/caesar-cipher) +- Calculator - In house / notIntense +- [Counter](https://github.com/Krulknul/dolphin-counter) +- [Hex Viewer](https://github.com/QtRoS/flipper-zero-hex-viewer) +- [Mouse Jiggler](https://github.com/Jacob-Tate/flipperzero-firmware/blob/dev/applications/mouse_jiggler/mouse_jiggler.c) +- [Converter](https://github.com/theisolinearchip/flipperzero_stuff/tree/main/applications/multi_converter) +- [Vibrator](https://github.com/qqmajikpp/flipperzero-firmware-wPlugins/tree/420/applications/plugins/orgasmotron) +- [Paint](https://github.com/n-o-T-I-n-s-a-n-e) +- [UART Echo](https://github.com/flipperdevices/flipperzero-firmware/pull/831) +- [USB HID Autofire](https://github.com/pbek/usb_hid_autofire) +- [USB Keyboard & Mouse](https://github.com/huuck/FlipperZeroUSBKeyboard) / (https://github.com/DarkFlippers/unleashed-firmware) +- [Wii EC Analyzer](https://github.com/csBlueChip/FlipperZero_WiiEC) + + +## Music +- [BPM Tapper (By panki27)](https://github.com/panki27/bpm-tapper) +- [Metronome](https://github.com/panki27/Metronome) +- [Morse Code](https://github.com/DarkFlippers/unleashed-firmware/pull/144) +- Music Beeper - Author Unknown +- [Music Player](https://github.com/flipperdevices/flipperzero-firmware/pull/1189) +- [Ocarina](https://github.com/invalidna-me/flipperzero-ocarina) +- [Software Automatic Mouth aka SAM](https://github.com/ctoth/SAM) +- [Tuning Fork](https://github.com/besya/flipperzero-tuning-fork) +- [Music Tracker](https://github.com/DrZlo13/flipper-zero-music-tracker) + + +## Tools +- [Bluetooth Remote](https://github.com/flipperdevices/flipperzero-firmware/pull/1330) +- [Clock](https://github.com/kowalski7cc/flipperzero-firmware/tree/clock-v1) / In house +- [Countdown Timer](https://github.com/0w0mewo/fpz_cntdown_timer) +- [DAP Link](https://github.com/flipperdevices/flipperzero-firmware/pull/1897) +- [DTMF](https://github.com/litui/dtmf_dolphin) +- [Dolphin Backup & Restore](https://github.com/flipperdevices/flipperzero-firmware/pull/1384) +- [iButton Fuzzer](https://github.com/DarkFlippers/unleashed-firmware) +- [NFC Magic](https://github.com/flipperdevices/flipperzero-firmware/pull/1966) +- [POCSAG Pager](https://github.com/xMasterX/flipper-pager) +- [Password Generator](https://github.com/anakod/flipper_passgen) +- [PicoPass](https://github.com/flipperdevices/flipperzero-firmware/pull/1366) +- [RFID Fuzzer](https://github.com/RogueMaster/flipperzero-firmware-wPlugins/pull/245) +- [Spectrum Analyzer](https://github.com/jolcese/flipperzero-firmware/tree/spectrum/applications/spectrum_analyzer) +- [Sub-Ghz Bruteforce](https://github.com/derskythe/flipperzero-subbrute/tree/master) +- [Sub-Ghz Playlist](https://github.com/darmiel/flipper-playlist) +- [Protocol Visualizer](https://github.com/antirez/protoview) + + +--- From e78156d5a8c2367207cf3f8b73845aa117b38ba3 Mon Sep 17 00:00:00 2001 From: VerstreuteSeele Date: Sun, 1 Jan 2023 12:26:00 +0100 Subject: [PATCH 2/6] PaxGod Marketing Campaign --- .../external/PaxGod_TikTok_Marketing/frame_0.png | Bin 0 -> 5391 bytes .../external/PaxGod_TikTok_Marketing/frame_1.png | Bin 0 -> 5333 bytes .../PaxGod_TikTok_Marketing/frame_10.png | Bin 0 -> 5352 bytes .../PaxGod_TikTok_Marketing/frame_11.png | Bin 0 -> 5440 bytes .../PaxGod_TikTok_Marketing/frame_12.png | Bin 0 -> 5403 bytes .../PaxGod_TikTok_Marketing/frame_13.png | Bin 0 -> 5436 bytes .../PaxGod_TikTok_Marketing/frame_14.png | Bin 0 -> 5550 bytes .../PaxGod_TikTok_Marketing/frame_15.png | Bin 0 -> 5602 bytes .../PaxGod_TikTok_Marketing/frame_16.png | Bin 0 -> 5657 bytes .../PaxGod_TikTok_Marketing/frame_17.png | Bin 0 -> 5702 bytes .../PaxGod_TikTok_Marketing/frame_18.png | Bin 0 -> 5710 bytes .../PaxGod_TikTok_Marketing/frame_19.png | Bin 0 -> 5687 bytes .../external/PaxGod_TikTok_Marketing/frame_2.png | Bin 0 -> 5310 bytes .../PaxGod_TikTok_Marketing/frame_20.png | Bin 0 -> 5672 bytes .../PaxGod_TikTok_Marketing/frame_21.png | Bin 0 -> 5701 bytes .../PaxGod_TikTok_Marketing/frame_22.png | Bin 0 -> 5690 bytes .../PaxGod_TikTok_Marketing/frame_23.png | Bin 0 -> 5687 bytes .../PaxGod_TikTok_Marketing/frame_24.png | Bin 0 -> 5683 bytes .../PaxGod_TikTok_Marketing/frame_25.png | Bin 0 -> 5692 bytes .../PaxGod_TikTok_Marketing/frame_26.png | Bin 0 -> 5692 bytes .../PaxGod_TikTok_Marketing/frame_27.png | Bin 0 -> 5653 bytes .../external/PaxGod_TikTok_Marketing/frame_3.png | Bin 0 -> 5244 bytes .../external/PaxGod_TikTok_Marketing/frame_4.png | Bin 0 -> 5180 bytes .../external/PaxGod_TikTok_Marketing/frame_5.png | Bin 0 -> 5159 bytes .../external/PaxGod_TikTok_Marketing/frame_6.png | Bin 0 -> 5190 bytes .../external/PaxGod_TikTok_Marketing/frame_7.png | Bin 0 -> 5178 bytes .../external/PaxGod_TikTok_Marketing/frame_8.png | Bin 0 -> 5186 bytes .../external/PaxGod_TikTok_Marketing/frame_9.png | Bin 0 -> 5265 bytes .../external/PaxGod_TikTok_Marketing/meta.txt | 13 +++++++++++++ assets/dolphin/external/manifest.txt | 7 +++++++ .../dolphin/PaxGod_TikTok_Marketing/frame_0.bm | Bin 0 -> 416 bytes .../dolphin/PaxGod_TikTok_Marketing/frame_1.bm | Bin 0 -> 385 bytes .../dolphin/PaxGod_TikTok_Marketing/frame_10.bm | Bin 0 -> 365 bytes .../dolphin/PaxGod_TikTok_Marketing/frame_11.bm | Bin 0 -> 391 bytes .../dolphin/PaxGod_TikTok_Marketing/frame_12.bm | Bin 0 -> 395 bytes .../dolphin/PaxGod_TikTok_Marketing/frame_13.bm | Bin 0 -> 385 bytes .../dolphin/PaxGod_TikTok_Marketing/frame_14.bm | Bin 0 -> 440 bytes .../dolphin/PaxGod_TikTok_Marketing/frame_15.bm | Bin 0 -> 451 bytes .../dolphin/PaxGod_TikTok_Marketing/frame_16.bm | Bin 0 -> 440 bytes .../dolphin/PaxGod_TikTok_Marketing/frame_17.bm | Bin 0 -> 444 bytes .../dolphin/PaxGod_TikTok_Marketing/frame_18.bm | Bin 0 -> 451 bytes .../dolphin/PaxGod_TikTok_Marketing/frame_19.bm | Bin 0 -> 444 bytes .../dolphin/PaxGod_TikTok_Marketing/frame_2.bm | Bin 0 -> 409 bytes .../dolphin/PaxGod_TikTok_Marketing/frame_20.bm | Bin 0 -> 463 bytes .../dolphin/PaxGod_TikTok_Marketing/frame_21.bm | Bin 0 -> 454 bytes .../dolphin/PaxGod_TikTok_Marketing/frame_3.bm | Bin 0 -> 398 bytes .../dolphin/PaxGod_TikTok_Marketing/frame_4.bm | Bin 0 -> 390 bytes .../dolphin/PaxGod_TikTok_Marketing/frame_5.bm | Bin 0 -> 378 bytes .../dolphin/PaxGod_TikTok_Marketing/frame_6.bm | Bin 0 -> 350 bytes .../dolphin/PaxGod_TikTok_Marketing/frame_7.bm | Bin 0 -> 368 bytes .../dolphin/PaxGod_TikTok_Marketing/frame_8.bm | Bin 0 -> 361 bytes .../dolphin/PaxGod_TikTok_Marketing/frame_9.bm | Bin 0 -> 358 bytes .../dolphin/PaxGod_TikTok_Marketing/meta.txt | 14 ++++++++++++++ assets/resources/dolphin/manifest.txt | 7 +++++++ scripts/version.py | 2 +- 55 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 assets/dolphin/external/PaxGod_TikTok_Marketing/frame_0.png create mode 100644 assets/dolphin/external/PaxGod_TikTok_Marketing/frame_1.png create mode 100644 assets/dolphin/external/PaxGod_TikTok_Marketing/frame_10.png create mode 100644 assets/dolphin/external/PaxGod_TikTok_Marketing/frame_11.png create mode 100644 assets/dolphin/external/PaxGod_TikTok_Marketing/frame_12.png create mode 100644 assets/dolphin/external/PaxGod_TikTok_Marketing/frame_13.png create mode 100644 assets/dolphin/external/PaxGod_TikTok_Marketing/frame_14.png create mode 100644 assets/dolphin/external/PaxGod_TikTok_Marketing/frame_15.png create mode 100644 assets/dolphin/external/PaxGod_TikTok_Marketing/frame_16.png create mode 100644 assets/dolphin/external/PaxGod_TikTok_Marketing/frame_17.png create mode 100644 assets/dolphin/external/PaxGod_TikTok_Marketing/frame_18.png create mode 100644 assets/dolphin/external/PaxGod_TikTok_Marketing/frame_19.png create mode 100644 assets/dolphin/external/PaxGod_TikTok_Marketing/frame_2.png create mode 100644 assets/dolphin/external/PaxGod_TikTok_Marketing/frame_20.png create mode 100644 assets/dolphin/external/PaxGod_TikTok_Marketing/frame_21.png create mode 100644 assets/dolphin/external/PaxGod_TikTok_Marketing/frame_22.png create mode 100644 assets/dolphin/external/PaxGod_TikTok_Marketing/frame_23.png create mode 100644 assets/dolphin/external/PaxGod_TikTok_Marketing/frame_24.png create mode 100644 assets/dolphin/external/PaxGod_TikTok_Marketing/frame_25.png create mode 100644 assets/dolphin/external/PaxGod_TikTok_Marketing/frame_26.png create mode 100644 assets/dolphin/external/PaxGod_TikTok_Marketing/frame_27.png create mode 100644 assets/dolphin/external/PaxGod_TikTok_Marketing/frame_3.png create mode 100644 assets/dolphin/external/PaxGod_TikTok_Marketing/frame_4.png create mode 100644 assets/dolphin/external/PaxGod_TikTok_Marketing/frame_5.png create mode 100644 assets/dolphin/external/PaxGod_TikTok_Marketing/frame_6.png create mode 100644 assets/dolphin/external/PaxGod_TikTok_Marketing/frame_7.png create mode 100644 assets/dolphin/external/PaxGod_TikTok_Marketing/frame_8.png create mode 100644 assets/dolphin/external/PaxGod_TikTok_Marketing/frame_9.png create mode 100644 assets/dolphin/external/PaxGod_TikTok_Marketing/meta.txt create mode 100644 assets/resources/dolphin/PaxGod_TikTok_Marketing/frame_0.bm create mode 100644 assets/resources/dolphin/PaxGod_TikTok_Marketing/frame_1.bm create mode 100644 assets/resources/dolphin/PaxGod_TikTok_Marketing/frame_10.bm create mode 100644 assets/resources/dolphin/PaxGod_TikTok_Marketing/frame_11.bm create mode 100644 assets/resources/dolphin/PaxGod_TikTok_Marketing/frame_12.bm create mode 100644 assets/resources/dolphin/PaxGod_TikTok_Marketing/frame_13.bm create mode 100644 assets/resources/dolphin/PaxGod_TikTok_Marketing/frame_14.bm create mode 100644 assets/resources/dolphin/PaxGod_TikTok_Marketing/frame_15.bm create mode 100644 assets/resources/dolphin/PaxGod_TikTok_Marketing/frame_16.bm create mode 100644 assets/resources/dolphin/PaxGod_TikTok_Marketing/frame_17.bm create mode 100644 assets/resources/dolphin/PaxGod_TikTok_Marketing/frame_18.bm create mode 100644 assets/resources/dolphin/PaxGod_TikTok_Marketing/frame_19.bm create mode 100644 assets/resources/dolphin/PaxGod_TikTok_Marketing/frame_2.bm create mode 100644 assets/resources/dolphin/PaxGod_TikTok_Marketing/frame_20.bm create mode 100644 assets/resources/dolphin/PaxGod_TikTok_Marketing/frame_21.bm create mode 100644 assets/resources/dolphin/PaxGod_TikTok_Marketing/frame_3.bm create mode 100644 assets/resources/dolphin/PaxGod_TikTok_Marketing/frame_4.bm create mode 100644 assets/resources/dolphin/PaxGod_TikTok_Marketing/frame_5.bm create mode 100644 assets/resources/dolphin/PaxGod_TikTok_Marketing/frame_6.bm create mode 100644 assets/resources/dolphin/PaxGod_TikTok_Marketing/frame_7.bm create mode 100644 assets/resources/dolphin/PaxGod_TikTok_Marketing/frame_8.bm create mode 100644 assets/resources/dolphin/PaxGod_TikTok_Marketing/frame_9.bm create mode 100644 assets/resources/dolphin/PaxGod_TikTok_Marketing/meta.txt diff --git a/assets/dolphin/external/PaxGod_TikTok_Marketing/frame_0.png b/assets/dolphin/external/PaxGod_TikTok_Marketing/frame_0.png new file mode 100644 index 0000000000000000000000000000000000000000..7c2add0e906519636d5c610033929d0e1d8eba8d GIT binary patch literal 5391 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 literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/PaxGod_TikTok_Marketing/frame_1.png b/assets/dolphin/external/PaxGod_TikTok_Marketing/frame_1.png new file mode 100644 index 0000000000000000000000000000000000000000..27664d203b68b2ac8699d5a1ec77f5af85ced224 GIT binary patch literal 5333 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 literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/PaxGod_TikTok_Marketing/frame_10.png b/assets/dolphin/external/PaxGod_TikTok_Marketing/frame_10.png new file mode 100644 index 0000000000000000000000000000000000000000..da62ce4cf9941935f24d7cc69e375ec70f74842d GIT binary patch literal 5352 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 F{2yCOeL4UD literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/PaxGod_TikTok_Marketing/frame_11.png b/assets/dolphin/external/PaxGod_TikTok_Marketing/frame_11.png new file mode 100644 index 0000000000000000000000000000000000000000..7a850b0011c66e062935a212d2ed5edfe4ac1ad7 GIT binary patch literal 5440 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 kKdu^-^3C(*umcBroLFVKJgBSpWb4 literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/PaxGod_TikTok_Marketing/frame_12.png b/assets/dolphin/external/PaxGod_TikTok_Marketing/frame_12.png new file mode 100644 index 0000000000000000000000000000000000000000..b980807c77d2559772c8056372507fe14ebdf8ff GIT binary patch literal 5403 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 literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/PaxGod_TikTok_Marketing/frame_14.png b/assets/dolphin/external/PaxGod_TikTok_Marketing/frame_14.png new file mode 100644 index 0000000000000000000000000000000000000000..bd3c0165a5533d2aa9d4938597d2b9119278c32e GIT binary patch literal 5550 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 Xpo>=qeqNuDuCI-~2li1=fam`JxmdiD literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/PaxGod_TikTok_Marketing/frame_16.png b/assets/dolphin/external/PaxGod_TikTok_Marketing/frame_16.png new file mode 100644 index 0000000000000000000000000000000000000000..b08d48e7fa4191d9d31db65a6610f28a54337610 GIT binary patch literal 5657 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 N0+>n2nT!EE{|_pV$YKBh literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/PaxGod_TikTok_Marketing/frame_17.png b/assets/dolphin/external/PaxGod_TikTok_Marketing/frame_17.png new file mode 100644 index 0000000000000000000000000000000000000000..5bdd77c12334ccf87649060eb824da47fe03eef3 GIT binary patch literal 5702 zcmWlccT`ge(}!OG4)ew3Wlq%?ks)A@x zR1{r95rG9aDk@k5i0#uAvFon+d}scjbDlHjcjlQj0jr%|qD24?_~Z%vDpgfg0)e2W zrbeYwwY0SK^z`)g^^J^-OifKKEG%qoZ4m_Fa=9)pF7EE`-rnB6zP|qc{=vb)p`oGS z;o)1hY>A4BLQym}Ha00KDK#}UEiG;D-o4q`*#{0B$ji$sDk>@~D?51b;NioEYinzp znwpLsJJ!NoD-wx%`N}h*KlkCnKcyyU%ZrS|1V==;6t=u;p^NC7g;hM~7;A2R0k2N7(ip zCnwVtY8q;4II4#x4o|?J^!8j;=P$N1HnqIiztPMr(savJV4=1B6}~+%T@lNO0ni6eL#s82IwR>%L@mM1Cz={xP%rTnyIPlmFun7X^|$r znF?9-aG@i^HW|k@WEGQXLevpk zT1O2y>_?=z{QI-NcgRnDF#rBtS#MimF$PP(M16XxF&2&wOpV zwuGM$REtMcR8RhMerxQkPf79Sg!jG#^HY*xO=}U~n`rMIo)>R^mzQUP^a&M|1LsA< zhRqzYvLeb^QI$tzn4>cA+vB#Hy{EqB%VN%4&Dfgl$=fha*%IRwVPM_N9Ks%)TR57f zdBP70`lq&vk2mIg+a_{Q01)0L=fsfOOSv%A|*jQ~tzH zD%-%`U&Mpia`U;}fip|Td_Mlye-yUYzLbl*&@OuDGia=$|y9c0YBpufNitfI6T5v_7V_GJ?P`O^m(V`LKG67wVt-a8sZVrhQ~w-$ObYVRhxb2Cz2WGngj>Ff=9)ey}LHN+xvd>q?45@j$irvQ^yS6-$uKU-7%{Bkb12R{5L^%ng>lE;H^L2 z@+R6oQV|gO4Lmf@B4_E5y1i8DKO6K+3aKSOB@JO|JXAW6bh$~nnfJl6!;QCquNs0E zDvD$Z2odJ)_f0_`($t=|25H~+c)WX4Xul|bWh3py(C6mvsx%xULH^LiP@bFLANxUQ zsc9$>dSP1J0kB;8Ovh-F{j=}K&Qu5k5Wi)qK{*!y8u}cZXgeqqzOOC(Z%8MCMPdd% z*A1fOJ2x=V zAi#gjjFe!^*C;LIRJ$)?y05oBN0M)16~emV4q6386!$gs6`11Th#~Vqj3LQK_pCMZ z0`+!x=0#81+R-9A;aW>WNiNyH9S&IRb`BKSS)ZbGVq|`Sr;hd0xk|B!!hULZCB4rZ!K7g!ObCYTpBCjQm~u z>X`-<;ZWKlncn2>%>($dQV7F@jK&f~No)gvBZ2_j;ByWra&-h6l;kABl|3$NISFP( zZ$ZsWzF_4up6ZK!5KrGCnV2(`Ox6sAt!axeNV!`}=2br_J}Vk7aAYdfd)`eN<*H3S zPn3z3c|;NdP-!nZvwvMg6#yXeSytsc*R3pf)z@d#_0KbZdw3)%kHisyX3}FTKg$_6 zTpL;`?R5lGW^UEZ^&N?N6S=x_QPxq8)}hS>z&aGvXsG5>vf96J6hoNe5vlA$9JrD2o zJXgcFPk=KPVe4ORZ|%K^F3?|$Pkb-6)aB&{hD!#HES?=K9G%;{_}ipIt! z3niE%IHzU)HX;!0VTszOR#)LymKFDVjP23P3BJ5>b&VG?_RN&s5MyWCxNA9UJI#>! zYub_KbRR~@YOlA$b17@P`-?zBMa6a%E34+qgV%my#n>$nz?}iH9JKi{w`iZ+x{~7W zIWrxE%~6I4JdC1#7qIZA$YMGvSEr%oH|4>WN zVs7Zr1tco25*{v2v`QC{fm**r&2o3>6VuHr(wKMBel)`i6rCtu`|iDYk1L&%@l+`F zWA844ST$HSD_F-HF1fo{OvPTYSiT9`-d}Fg@HcE;{`#6;rL=f6D1#T9MW2pcxmv$v z1Nja)MC0C{8RXcuZjH>R(1q(IzA<@}fSV(q%CD|k5d4Et_y2m!iU$rjM!q7S`Ml%n zYCBd|(BGM3jDz#ZFj)QrQ(l;>?u$U0eCfM}C7R<~?>thYhwpIOAZ8^AB=S&jkLI1n z7IUA1tY~=-sy%*xP@sS(o|G0k0jJ zYu9}=o{z47HRD%M&})npq=Ff(Q=UY=kHHB}6p$qvdm9x6P)v zg)@iVF0rc7efCu#RpIDVrJhZKS1tjrD8NNP=CAzAckeqQ4CtVkder+lAp3iqJYVe9 ziAbkzX$_#YqV-6IiU8C`4@A`+_^y*SA_l&PZcx9Cdnu-8UUb#t0dy%yV}j<0kh265 zWU!MQrZ8Qz_+bzBQZsYa4+_03*f0qId(3=}qOgllXO^V?`l3lKDpu)5^$}1@Cf4SG zcSfT~I)svVBnPGivZzO;8876znG*1qp+bsKBOb$n5B=^B{IpMx^kp3z+W!CzP+w-L zAEMaFlF6c2ip0YrO^30}+V(P4nGx`S4>Oj4qy(^DC9UTcplV7W7a7=ZFD{&+C&y=R zU7&Rrf@FRfWjns^qpOk$LWirwnENr0cKNv%sap*0u#o}+0odIK?-0`s4&e+Fs5;XY z&eeE?$alXbT8O+Umt>E;rJ7Ux_r<#4SnR7q9HwS?*i=;{}5J|5jBJNP{rCIF#nsK zlFTQS#KC4ucG@T&I!C-zuGBH|V=LG~`;axQMDX6YnAib(yTbLJS}c2jpP0Pg46F>GpX@ zz=9fd)JGSA72}0=RrViN?}|y!&M(Q%oTGKzG1ik-TMNLEz37kQrIRN!&)GY_qyw6= zlH0zyyihp9@i%}6JvfXHH`ECm3J=TOHle+9a)B5|G2x)QY0?Hf0{?!YDY?Fe<=s$3 zZmt2yYK+# z@P}J;g8@agh6kG=nHA%D2VDp?iLskL18`toZ*e7Idv$4@s-gf4Oj#&fi_U{^{olPiID=1B#X+GuL zxH+IP-Q2mNnznd2;cfjs2`AhFwJZ){DIXz1wJJzCpA|ofgfcrW-rD>7-cUGX)GtBYpPK}T&ZFrYq1q;xX88_r%pCVP} zOdA6QWFP`PWnmw1JMQ^lLs4isEv`au=ZC>nwY2PdDP(}U>!6?}A3DPq+)3(*E^Q66 zC|Egf!I6X7NUb%_Y5sEbU$b3Z&NQ=S>LM9fp&-&^fQqCIlmYQoSf(5@0Duv1z*qqd zXh92wAX^GexB8E83=$XC0|{b83UyD5HH1(w(i8mY@N4@&Tu$^nbQO^l6$(qjv-VoY ziPHD2rx$yVD*tIY?Y7%g7a=pHklXn{(h`uePjw{$Fh)cG% zPLq_oYLt%`z;;za5(*FBg((kDo@;2WaN9>2>a}|y4(duhg=t*uD%~}+CgTC1{5>#2 zDLS2M?@Saz>u&ij5kcw2m3j3x0rd_=ETTv%koym&Wa^!=s&Pg{l$iA)eh z#hUw9bfm-X44~?DgINE+5iB6LqS6SY|v{mS|7kREZCHc9`_^C;VpkoKlk|Q%G0qyPKD2 zRxGYARu0_A*Cga<3L`x9Nj?Vyz%{ZmEL*7jZ%jS*q6k^5f8@x{*mEb{QGbdsBk_0- zTlDJ@ghhoc4H1P_j5pvp;F6fns z;=h0lx$(tYkSS7nN(#^c)gxj10!AN>T)%d*2P1!}`#=VYkvrPHop;Y{oEM*+S5I zVMZC~)X0c?8F);ngJ>H9&{Vo(2;xoWf$wAi%zw5;F~-mE;Nn6ZwXm2gK}MHZ00E<|Sq1grn? zF!mfy;~K^hFn;_b8GkXA`dDaBn_WK@{RKr1PO;fnF>WZyng<4M-S3x}`9^(bY38T@ z(lNGBaDD+m}dDG`Uco|snyFrx>IdLYty>4 Ov1lR+v{EsE+y4V%vHPL` literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/PaxGod_TikTok_Marketing/frame_18.png b/assets/dolphin/external/PaxGod_TikTok_Marketing/frame_18.png new file mode 100644 index 0000000000000000000000000000000000000000..94b25dd6b3c55d2993496b5c451f4125b341db93 GIT binary patch literal 5710 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 literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/PaxGod_TikTok_Marketing/frame_20.png b/assets/dolphin/external/PaxGod_TikTok_Marketing/frame_20.png new file mode 100644 index 0000000000000000000000000000000000000000..e0bbf11e9476472dde7cc3a5e185182475fa338d GIT binary patch literal 5672 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 literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/PaxGod_TikTok_Marketing/frame_23.png b/assets/dolphin/external/PaxGod_TikTok_Marketing/frame_23.png new file mode 100644 index 0000000000000000000000000000000000000000..0ad0197289e6fdde6eae3b076d01fd37e1e9da08 GIT binary patch literal 5687 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 literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/PaxGod_TikTok_Marketing/frame_25.png b/assets/dolphin/external/PaxGod_TikTok_Marketing/frame_25.png new file mode 100644 index 0000000000000000000000000000000000000000..6fd18ac9854d9a8ace2646280d0940b5fba11b52 GIT binary patch literal 5692 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 A0RR91 literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/PaxGod_TikTok_Marketing/frame_4.png b/assets/dolphin/external/PaxGod_TikTok_Marketing/frame_4.png new file mode 100644 index 0000000000000000000000000000000000000000..759d3242d3473e34eb028e57bd811af813d4f4a0 GIT binary patch literal 5180 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 TSHebVSKJmZCr`p&0O0z65??Hs literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/PaxGod_TikTok_Marketing/frame_6.png b/assets/dolphin/external/PaxGod_TikTok_Marketing/frame_6.png new file mode 100644 index 0000000000000000000000000000000000000000..fbea5c447ad311b076d437f84c0fc40af87dab3c GIT binary patch literal 5190 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 Goc{*|raU?T literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/PaxGod_TikTok_Marketing/frame_7.png b/assets/dolphin/external/PaxGod_TikTok_Marketing/frame_7.png new file mode 100644 index 0000000000000000000000000000000000000000..b1f48bf498e2b1f9d978b848fae1a8603d95adf2 GIT binary patch literal 5178 zcmWkxc{tRGvT7-uS*8COPVvaYP!5sFd` z9i(H2a;qjfMy20KTdC|SvemZh*Y|nYN91bToHkQZZB_<}Oq@?WKyEij4GdDN)z<~n=1qDS#MP+4W<>lqo)zxCLxVE;o zv9a;Qi4(1@t?ljYot>RsU0qVC^y<~C*RNl{apQ(eCL10e9vd5*oSdARntJ%~p+cc} z@#4kHmoHzvdbO~yu(-Imyu7@!vhwxo*R{1Z+E)|`1pokTO?AUwUQ*&FUQ$Z@9%2%2 z?_Qoa)6UuDe*kQLFo6Fl1~6-gVvDZHv5?c`cMto=63*)obc(M;SZW4eT1dNPJe%=- z;@{mSJqNs3zbgLR_w264U)wG||MN`+T~8HXRHUMUJ6v|SyrS|j7B*yTq}TennVMOc zThbY}9!?GpHV*aaYZ4Gfh!i9r znfAr;ZhjvES5=jjYa~q~9e1beIL%L8jTx5@$VA%KjBVt>;%6ew+QI!^Zt(CCGSx

U@^Aa%0yi3228@V!G1q(#hjPR~tuy{nB6tuY! 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 literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/PaxGod_TikTok_Marketing/frame_8.png b/assets/dolphin/external/PaxGod_TikTok_Marketing/frame_8.png new file mode 100644 index 0000000000000000000000000000000000000000..38b730fd14fc519691e5cb51797285cb1fe678fa GIT binary patch literal 5186 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 K!Biat;P!w1oJh?8 literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/PaxGod_TikTok_Marketing/meta.txt b/assets/dolphin/external/PaxGod_TikTok_Marketing/meta.txt new file mode 100644 index 000000000..f0fa77e2e --- /dev/null +++ b/assets/dolphin/external/PaxGod_TikTok_Marketing/meta.txt @@ -0,0 +1,13 @@ +Filetype: Flipper Animation +Version: 1 +Width: 128 +Height: 64 +Passive frames: 21 +Active frames: 1 +Frames order: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 +Active cycles: 1 +Frame rate: 5 +Duration: 3600 +Active cooldown: 7 + +Bubble slots: 0 \ No newline at end of file diff --git a/assets/dolphin/external/manifest.txt b/assets/dolphin/external/manifest.txt index 80a6de314..166f85246 100644 --- a/assets/dolphin/external/manifest.txt +++ b/assets/dolphin/external/manifest.txt @@ -106,6 +106,13 @@ Min level: 15 Max level: 30 Weight: 7 +Name: PaxGod_TikTok_Marketing +Min butthurt: 0 +Max butthurt: 14 +Min level: 11 +Max level: 30 +Weight: 3 + Name: lvl_16 Min butthurt: 0 Max butthurt: 14 diff --git a/assets/resources/dolphin/PaxGod_TikTok_Marketing/frame_0.bm b/assets/resources/dolphin/PaxGod_TikTok_Marketing/frame_0.bm new file mode 100644 index 0000000000000000000000000000000000000000..5401e21b2742ac70a3f2e21cffc20d99517dd429 GIT binary patch literal 416 zcmV;R0bl+B0Gt5;FMG%ha{2rq9{%*j64>fT9Pu zxfAFQN%%P%WDnL@gUCoA{{RjA9;g8a_&t-$KPR9*JQ4Hy1K^%;(0&iZAK>;c_&t&S zuk-u^{2tHr2iNc(@$h>8f&KUY1LFV>KDd0^f)6jp3?6WAusy&-KnI`ja6tC|`@usF z^aIN<4`rD{KLGN^1LisKACNwy9RPW80rNQg1IvsLSPk(MUkEr5ctG}Nr5p%8Abj{Q z{s92|LFy?e2LRkZ$Q!)@>`oydgVYpw4g3rUK=pYTD1gQM2c-NSqf-VDOt3H@Q2)i` z1ti#n$QFO_nLJHaAo3`b_&$Nb2Z_{)Mfin-&H?@-2*8>J0H6cVI3Y7Fm;r%B=wT>M Kf&79N5r7yR#J4B_ literal 0 HcmV?d00001 diff --git a/assets/resources/dolphin/PaxGod_TikTok_Marketing/frame_1.bm b/assets/resources/dolphin/PaxGod_TikTok_Marketing/frame_1.bm new file mode 100644 index 0000000000000000000000000000000000000000..49d9e5135894c85d2339e3d8fa92c5fc4f6ade0b GIT binary patch literal 385 zcmV-{0e=1g0DS=fE#L@$kN5y!a0mz~0H^#1o&X-O@F4?;9y|bg$G~HN2d97@x9}MF z0qO7{i75cWPB3~%0p|yRd;#hF2aNC@qV@k6Mt%>!`P4z}zz6ZYAou_9Kf&&wNH`3E z`#A@|q($au6Dg`#r{w50Pq3+4|D&6{eJ-c1qeS;@DFeE|A7Jz@OwkS z>-z_p5JBbsvxCpR4~2;Q5@iMl%8el3;CXQY_526yFdlqhe8&Oj!UxY_o_;iWfQA7) zMH~bOJ`j3>N!~a3Fc5wq`k((GI1hk5MP;5tz!Wehk$@z^EF%Cgxss>7 literal 0 HcmV?d00001 diff --git a/assets/resources/dolphin/PaxGod_TikTok_Marketing/frame_10.bm b/assets/resources/dolphin/PaxGod_TikTok_Marketing/frame_10.bm new file mode 100644 index 0000000000000000000000000000000000000000..9f8e4fb7ed8f1b5803b8ef5eecac7cb1f6652f98 GIT binary patch literal 365 zcmV-z0h0a!0BHdLU;F?5hl8sD{{RR*J^=OjfA8S);7@!J@Opm(>-hipFXQG1r~AeR z5%d4x;9`IQh5`>S06j;9I1;gq#2%lB86e5b4;Y8=GJ$a#kUZlP@X84U9@+ER1Mj{m zAbOvS9w3tk;blUq4<%89?j{d}dV~BBK=ywKJk7)pxOjb>1P@n9gVo-Sg9rFO%_apP zdN)WP;Qt4|03LJje}mP^VDtnSKE((A3n)GyNbv{Y|H1ZuV0qyUod(=ap3d&gU{d(P5XfT;Q1V%`<@S%0spyRQwRLu92!IgA1qbJvi~!*B Lr-#%4zkqmvm1MAU literal 0 HcmV?d00001 diff --git a/assets/resources/dolphin/PaxGod_TikTok_Marketing/frame_11.bm b/assets/resources/dolphin/PaxGod_TikTok_Marketing/frame_11.bm new file mode 100644 index 0000000000000000000000000000000000000000..38c7944ac4efc73677137956ec3861611ab226ea GIT binary patch literal 391 zcmV;20eJoa0D}PlUjzU1pMi?O0tdI_|N94@0uB#v_y772Kg2v-;PH=vhXMZz7y!Ni z@&AL%;UD;LU}NP6r}_uL<73rG*NQG$e@AM{Cs>P`=Z@q@-D59Ue((LRv& zN(00!O7#c$y@Bxo2gd>4p#KN>Jx0V2M`?rG01xnggUsF=a&2M5c20saqCvIEivAK-e2>Ci#^KqPz~egJwX6F!eH zdax3I{s+kbl3_## zoZ%Q?^d}fRcjyxbh`fX988Ch(%#;IybU0p58yr) z2oFJ^gV0`|z$pXRpnebNK3FI42b{zF4@vv|1f&mR0sKE8@`wZ1<{wBr5&;+=ubebr zfhf-)5P*8&-b4=+F)z>_F!}H(f1UI(C)zLg2b3E8ABg_}<}>>7l-uZ!DE`f`{&|KR@z z_&>nq@c+TX{15p6JpslKS^$5rAHXT6>--OR_&>q@4@a;+!Tt|;JP02c0D4cs>G%i2 z0YUTsRG7Uu0QG@`{2qc*2eHKg=impafj@#$uzvyQU_g1yALb7qxq$!Bc>q25u9^Z}lJtq(d2t9xO@OnTn0_OjK1P*`C_4ks@@(0iWXF&RUihMu>4^QwsyIcN0s(wn3jGPF}2tEo2AAg8GNCh7ThQ1g8 literal 0 HcmV?d00001 diff --git a/assets/resources/dolphin/PaxGod_TikTok_Marketing/frame_15.bm b/assets/resources/dolphin/PaxGod_TikTok_Marketing/frame_15.bm new file mode 100644 index 0000000000000000000000000000000000000000..bff1cf3e63b00acf617e13219e0f3520795af81e GIT binary patch literal 451 zcmV;!0X+Tz0KWkMCjveQYybQTaSs4Jz7z0zd@e9RdjB`z^nichU}V65`{4BdL*U@_ z@PEJpB`_e)1N?1vzE&(}+QOPDClZN+%>IDF5g0xr_y|16A8CPs&w=dzJNzGk2aW>BCSdea3?4iWz*>OK-iF~P zp^U-i-5dlkHdp|CK?mdyxI91~fU%B)+u#pN1_Eji&juc157;;?h4yJ}2-E1Rb70`X`L&A4ziukr4swWCV~s ze}MC!@gd@}-~;3S-xzBAf%9R&LP7Np|IpwDF#rfW|G@MFh(Avz53~t@1`Gow@q@*J zVDFdG0pXZ`{L tM-T3u6#0M*{%r9EkAUKh_qm5y044JWjf@{20D54-@qh=Ue0szMpMW$J%IyFE literal 0 HcmV?d00001 diff --git a/assets/resources/dolphin/PaxGod_TikTok_Marketing/frame_16.bm b/assets/resources/dolphin/PaxGod_TikTok_Marketing/frame_16.bm new file mode 100644 index 0000000000000000000000000000000000000000..d234a954f4ee7c9ed0bee2d02acc3f5e2af4a91e GIT binary patch literal 440 zcmV;p0Z0A;0JH%BCjwvyYybEPcMb&L9KH+x{0yIa_&tA{@OnTX_+Wbf!RdesDHy-~ z@KOH-tpNOgzycmPcw}H8^Zx_W;2t;_-2vwU{{qegK0pC*Fk{q$Pz3}IEC0jC9|xga z!RPq>i;e*pKA1epCIBcw07u9V8TsjCVE2au)8YPro09)Og9FmwKY99P0rG7?daI8A zcT)*O!SDx(Wd&B|w5E$q`ED#8&J-h()Ka9j5%<~7xykWrnpg_p0;*6K*0T=NA26#ps0zGH{fO*6c13(A2fPjMnFRlGPfCC4u&H?Z^ iqJ8{efq?_me!OvO00+PiDf#?GtbibTPvGJRAQb$zq{j#V literal 0 HcmV?d00001 diff --git a/assets/resources/dolphin/PaxGod_TikTok_Marketing/frame_17.bm b/assets/resources/dolphin/PaxGod_TikTok_Marketing/frame_17.bm new file mode 100644 index 0000000000000000000000000000000000000000..30fdc120ad021a74ff8a082646b39691bbd26d22 GIT binary patch literal 444 zcmV;t0Ym-)0Js4FB*K0OZ}<2Lehu(FxEKHU89)2jKs`Sb@OlY`4lZr@Jj25SfIvaV zfd7C53}3+_fCu0YK&Z#T>=+Pv{4e05fdkAOK=FfrhoS%&B>;|K0^ni8#t#%RgNpy~ z@sCn4eK2|dKWDWd7x*4vAw4EQh$qtrmGtz#a&m*l7!OMUKtt<)ESNlx&3~VwP#%Qz z@2Zp^2+_b#!R)>;c;Fxj0|&%^0SB1_**<~6fzN^W1Mor6CvXS5RABModwc=t01DrL|Ch!d z3m|*P|Nb02G!{iO2d$3*2?w{}9*}ZcEX*FT@P86a05E`j2TUHnz_o@dHBKUe}5TlpfC>z{eJ+F01WYnI0btD_yhxp90!1ZQuv@%9_s=4 m98mtR@mLYX9qT{f0K}eP0|gK~Z~_AWC@7hvMHu{mp*QfG#m3

$53V#B1JycU^Pj0m!7Je5ih zGJ0LX{EZv{h{5K*F?ir04B`jOe*q7f7u7zY!GX_#_XFTTZ-6}j0xvtj zJ}?k+dEWu^1P_=z{0jpIj4*z8;C#X20Q?9HbRU)s1XLfM3_L_1uy*;2>HuHRc*Lv$ z5jWHj8a@aD+|TacCeXKP`9wd8o)9&~jP>&+rdOd95J;_zsvoe}ME3m_A|d z69>2W9*c(fV< tJxBt9ID$R^1O7OmJ%oklhlA99oB$yMmH-Mf;DhG?3L;pEOd!LupMY8c%9sEE literal 0 HcmV?d00001 diff --git a/assets/resources/dolphin/PaxGod_TikTok_Marketing/frame_19.bm b/assets/resources/dolphin/PaxGod_TikTok_Marketing/frame_19.bm new file mode 100644 index 0000000000000000000000000000000000000000..01492a1b431b3b9bb6440a2149d3d44373449a88 GIT binary patch literal 444 zcmV;t0Ym-)0Js4F9AhzW1hw=01wVxz{tjFP|NaI~=smt0@OZ)i<@|$#*ZtoQpTqwT z7dQMKpYR~a0qNlX`^N+Y5oqurAoKnPL>^zr_@sg84iI?YAb;>#ln;OpKZlNfmT|y? z&*E!f0R92xKmQAm7AMmOnMA+^cq$0^!Q~zYth^rA_%J;#3DXCh{ss?8fIZQK4`gwJ z#?B9t`XfgGkT84;$YfyiXAnGL_y|16ACL$f_#Vpifbbykzqr=D#pF=pgL!2hludK=MhLJiz7;C;&cF z;s7z31JWOV;6dTw_WT3S|KP*IL1dF4ds=V+{eza$7!QHygU%2SpaFx=_zy(MgV+2I zMhS!R0uO%>JzeJji~!5V4^r`;&jIlVt^6K;z$k;F<2Y`Q283W9UG!M`{h6flh m5)gq6fYH43Hps8B|y)^9S60o}%&xs9cBa4@h`8*+vym zdoG9`!{k*MKNCa`Y4|^Y=Kzn3PF Dk9w{C literal 0 HcmV?d00001 diff --git a/assets/resources/dolphin/PaxGod_TikTok_Marketing/frame_20.bm b/assets/resources/dolphin/PaxGod_TikTok_Marketing/frame_20.bm new file mode 100644 index 0000000000000000000000000000000000000000..fadf12f2758a1a1dee3c312f7d6a02121cb09094 GIT binary patch literal 463 zcmV;=0Wkgn0LuXY9CPIl1h<3!1v>}wJ`ZX5Jvblmdwe_K^Zb9{V)p-Y@8Chef9LQC zz&QaU?+2H|{|A6v1*;g9JZkG zKOj6}VE+ffeM`fDP#8W7#Bnfr|AFa%hs=TYhZq{H!RD__^HemR_x5gR^C?Gxm@9~6#@{53g!0HeVH-~-rzpW~p|5$ZrtsYn6t zFf_2hA_w&V5WLEyZ(sn1#sSV65Pl)%u{s$20ESy1fIR*Iqu>Y+f+8RQf{YF$QxK97 F0pwOj+h+g( literal 0 HcmV?d00001 diff --git a/assets/resources/dolphin/PaxGod_TikTok_Marketing/frame_21.bm b/assets/resources/dolphin/PaxGod_TikTok_Marketing/frame_21.bm new file mode 100644 index 0000000000000000000000000000000000000000..ea71be67e9dd3055355b2fe819ebb34d9f16cc9e GIT binary patch literal 454 zcmV;%0XhBw0Kx$P9CP^r1hoTy0D%EV;s1k!+duyT7lY692e*U14?q0=0S*VR^WT38 z5VWI!Y*I=fL|j3>+45<@=?E4ht}RfCOG(a|fwC zLG=s|mH-}qfO#Us9wV{`+#Vngz*xsY^?!g^FcDCGAI4()AbrQwLJz9}?0*yf1K2_9 z|A0^+2=TZB>j4Bmjst=Zrup!J^8XpI40wR~FNi3-0QcX!)E^n}`7_8!fb$E9JVWG> z7yALubiW{cL99TM00=%K{wO&t!S4f~_^|NMSwVnh{s*1@#ejr^>;gCm_&;C(_g5G^ zNhS}t_&x9d^%j^u-XsrR0{p?`P!It_f%2X>2Y3oL1o{AkfPhkvAJhOa5?O=BAP;eY w1H>pr_81{ljp+vpAUu3&_6MTKd>l4=2iXXR^Mm*Rg?|DG%)v(oBBPOwW_ZrTP5=M^ literal 0 HcmV?d00001 diff --git a/assets/resources/dolphin/PaxGod_TikTok_Marketing/frame_3.bm b/assets/resources/dolphin/PaxGod_TikTok_Marketing/frame_3.bm new file mode 100644 index 0000000000000000000000000000000000000000..30b2bf584cdeea2c4a2035840419681914c9bc06 GIT binary patch literal 398 zcmV;90df8T0Ez(sANmFcPxt_!AcX>+03RRk{2U5i0DFcC{su3AJs|>x3zzU7k-&Px z#-$c0|%M>nC1^yMnT?S@>ifd zVfct2fFEB-eo_bc|NnvTp&s%0Vd44z^XJV0fd8-H@)HO=*hCK>&^)*R`VW{r(nI)2 z2>hrFQ3s*Oe-MA*Jgflt_+Q3^#}ItA)ruf;0Sp8le=z|A;a)}25Qx0N?A|i4gVgd* zV*?mHmm&@@0E`G;m;rJC1g=ey2b2Ilz;OqNj7MZRAbJ!=9$OSq1IYeG6OVv}5|iPA s|D)xxkAaKx69=yVvLN&5eu{(uXHobi;OHrh{BB_Rn0x?*Kr#>kK(D#FBme*a literal 0 HcmV?d00001 diff --git a/assets/resources/dolphin/PaxGod_TikTok_Marketing/frame_4.bm b/assets/resources/dolphin/PaxGod_TikTok_Marketing/frame_4.bm new file mode 100644 index 0000000000000000000000000000000000000000..4bcbb83bb02052c171c7e836e6e96c1515d0eb71 GIT binary patch literal 390 zcmV;10eSub0D=Jk7xVuD1E>4|P!KtPzwq#J@B#7$PXIl@#2`PwKBwel2b>^}17ZV| zIst$KoD3|W@f?Uh!3Yl_ddI==Pf&l~!SH`jc@7L8A8>k~%is@mdjr%0C-eu?o!jXH z56C@<@DEdYA`Biwbb+tPkYM+Nz<~-6fH=GmA87*zxcH0+4r843?9I82lzk1@?Ri-mB=3|0tb@4Ab0>tJIEg&j5>&a z{qTH1K_ed=4zX@v_T%5d1H}iY^d6Xd|AM{|5P47@=mHr3076mlc-R5$0l-7ZA`f^N z2uA}C@C(jBb|86Q%LUN~oWLI{bch4*;t(YIf9K%zVTeBfg4R%aIthG00Wyd@&m=A& z0y)eccnR=5e*p75lrlgMQNf4L_;VkCK?)-W{sYXwP(q5Xgw#WFD6l+Tf)6iz4j>O- kgnWi8l1PfUfD8{Wgw6yGhy{3zP>3)-X8ZoW<~OF?kh?9*{9YgZv-h{2!G39_``>oa`UL^FN?Hui*IL1Vx@e z`S1hLj9~RJll+1H53f7}{8w859Y6l?d&~jrKLH3oKk!w%LmNCmXy(VxaNx8jU(Y Y1>iib|1KbKQFnNK<9^wS}1LQ!TzCI2tU#2KeYRs;9fxdbQCxq>fr~VegXauWU+(%9*_`!o7HS!{|BxBAKn27zsmj( zfr$g#;174R1O8wqAbCOX0QV29{2qsLj04+%58L=X;Q;mj_($!C2e1Is=0{L_d;%jt zf1n6X#|ICR9RcHiOPiSBAAov6*yO%8f`i5eM=1C`8wL+pNIgd-2M3WbV~fEEAUwa& w90UY#KhpvfN)P-8iX`S>^j!=;;13}X!GOc*{}A`jRap#kPcH^8(MA8LaK%Hcr94~0Pi zjP7ED2l`-v@Tg#XGlU2!2{qBVDd8WD0QSZM z*M1K)d4t>j4>TUkErLr{v}bm+}G_GYH@T>lnWq$RAna*n`YmAok~ygdU^zAdo*t zA`c`1p@bfb^9Rr*f$Wc1+MxmS3kRZn!RZHe5Pgis4{-T|)chd#ccdKrApZyA^g;dr z9{?C!f)DUA0w65F{|B!CUqyol+xUV04k7%5%7Ab2eY=Ps>HL2XKf(SF@P0r+3brtO zd;$IsP%#6_UJvc~Ab$X1zk}hRK>r7i^a?>^2bn}c?HC8o_#SY8dbmgUcU)jSVc`B< z2tBZX^+gCgr}zM{@B!*d5P3Ju9`F!(F^>TMPygON41nMC3^WVVY&NTvq$BqRc zdW;MnIdM6U%m5>T2aLQPGylMWTqOqwoCmK=b}X|MT(kgVYLF@Ok(F z>%hN)3Iq=?z&(5r@j*w)%nvWb3~*%T2aH4fNJtquLE|1Rh(9~$u>_h#f$BjZdw+rI z2@rm!6dp$PO%OjKVE&DR;a;$?davQYK=$|p(J&~K2f*Ng_YVhbYAj9Mj@O%yoA83OUFg@@Xu>T9}{=oQGus$H*{|EF9-k|>n_&>q% z0SEXXxD93a1JDvc{9q72!Q|F3d=dxd4>`a+N+KU0I6UJ3^+1Sxex`H81J&Xn@%@9( z7!O$ZJin@Q2eN2W1aB9>@d4@z5P2))^gx0l3mF^b|NFqf%!1L$f z(WU={gUw)J@q>wso?rn7qCEUR_<%hBfc5wQg(^oC7Ky0fAAy1xNFKlj`~%38pap!4 EJYmqPVE_OC literal 0 HcmV?d00001 diff --git a/assets/resources/dolphin/PaxGod_TikTok_Marketing/meta.txt b/assets/resources/dolphin/PaxGod_TikTok_Marketing/meta.txt new file mode 100644 index 000000000..83bee1ed9 --- /dev/null +++ b/assets/resources/dolphin/PaxGod_TikTok_Marketing/meta.txt @@ -0,0 +1,14 @@ +Filetype: Flipper Animation +Version: 1 + +Width: 128 +Height: 64 +Passive frames: 21 +Active frames: 1 +Frames order: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 +Active cycles: 1 +Frame rate: 5 +Duration: 3600 +Active cooldown: 7 + +Bubble slots: 0 diff --git a/assets/resources/dolphin/manifest.txt b/assets/resources/dolphin/manifest.txt index 41cfe0899..80265a8b8 100644 --- a/assets/resources/dolphin/manifest.txt +++ b/assets/resources/dolphin/manifest.txt @@ -106,6 +106,13 @@ Min level: 15 Max level: 30 Weight: 7 +Name: PaxGod_TikTok_Marketing +Min butthurt: 0 +Max butthurt: 14 +Min level: 11 +Max level: 30 +Weight: 3 + Name: lvl_16 Min butthurt: 0 Max butthurt: 14 diff --git a/scripts/version.py b/scripts/version.py index 8eb38526f..f003cc256 100644 --- a/scripts/version.py +++ b/scripts/version.py @@ -14,7 +14,7 @@ class GitVersion: self.gitlist = [("commit", "rev-parse --short HEAD"), ("branch", "rev-parse --abbrev-ref") , ("branch_num", "rev-list -count HEAD")] def get_version_info(self): - commit = branch = branch_num = "XFW-0036_12282022" + commit = branch = branch_num = "XFW-0036" # We dont use an `or` in commands that we expect to fail. It will serve no function. # We also dont try;exept an entire block of code. This is bad practise. We only try the single part that we expect to fail! From d57a867f5c050992756b5247cdff657f0c0f0400 Mon Sep 17 00:00:00 2001 From: jbohack Date: Sun, 1 Jan 2023 22:14:15 -0500 Subject: [PATCH 3/6] modified u2f & bad usb sfw text --- applications/main/bad_usb/views/bad_usb_view.c | 4 ++-- applications/main/u2f/views/u2f_view.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/applications/main/bad_usb/views/bad_usb_view.c b/applications/main/bad_usb/views/bad_usb_view.c index 06f9ed1a2..2a15c4d4e 100644 --- a/applications/main/bad_usb/views/bad_usb_view.c +++ b/applications/main/bad_usb/views/bad_usb_view.c @@ -71,8 +71,8 @@ static void bad_usb_draw_callback(Canvas* canvas, void* _model) { canvas_draw_icon(canvas, 4, 26, &I_Clock_18x18); canvas_set_font(canvas, FontPrimary); if (settings->sfw_mode) { - canvas_draw_str_aligned(canvas, 127, 31, AlignRight, AlignBottom, "Connect me"); - canvas_draw_str_aligned(canvas, 127, 43, AlignRight, AlignBottom, "to a computer"); + canvas_draw_str_aligned(canvas, 127, 31, AlignRight, AlignBottom, "Connect to"); + canvas_draw_str_aligned(canvas, 127, 43, AlignRight, AlignBottom, "a device"); } else { canvas_draw_str_aligned(canvas, 127, 31, AlignRight, AlignBottom, "Plug me"); diff --git a/applications/main/u2f/views/u2f_view.c b/applications/main/u2f/views/u2f_view.c index 4f5d382d5..fb5eaac1f 100644 --- a/applications/main/u2f/views/u2f_view.c +++ b/applications/main/u2f/views/u2f_view.c @@ -25,7 +25,7 @@ static void u2f_view_draw_callback(Canvas* canvas, void* _model) { if (model->display_msg == U2fMsgNotConnected) { if (settings->sfw_mode) { canvas_draw_icon(canvas, 22, 15, &I_Connect_me_62x31_sfw); - canvas_draw_str_aligned(canvas, 128 / 2, 3, AlignCenter, AlignTop, "Connect me to computer"); + canvas_draw_str_aligned(canvas, 128 / 2, 3, AlignCenter, AlignTop, "Connect to a device"); } else { canvas_draw_icon(canvas, 22, 15, &I_Connect_me_62x31); From dd0fa33ef42c4a72ab6f27138072e9c6a58c7200 Mon Sep 17 00:00:00 2001 From: jbohack Date: Sun, 1 Jan 2023 23:41:28 -0500 Subject: [PATCH 4/6] fixed cvs_walgreens unirf pathing --- assets/resources/subghz/unirf/CVS_Walgreens.txt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/assets/resources/subghz/unirf/CVS_Walgreens.txt b/assets/resources/subghz/unirf/CVS_Walgreens.txt index ef3ef0c70..712543d76 100644 --- a/assets/resources/subghz/unirf/CVS_Walgreens.txt +++ b/assets/resources/subghz/unirf/CVS_Walgreens.txt @@ -1,10 +1,10 @@ Filetype: Flipper SubGhz RAW File Version: 1 -UP: /any/subghz/Walgreens/Walgreens_Cough.sub -DOWN: /any/subghz/CVS/CVS_Dental.sub -LEFT: /any/subghz/Walgreens/Walgreens_Skincare.sub -RIGHT: /subghz/Walgreens/Walgreens_Vitamin.sub -OK: /any/subghz/CVS/CVS_Stomach.sub +UP: /any/subghz/Stores/Walgreens/Walgreens_Cough.sub +DOWN: /any/subghz/Stores/CVS/CVS_Dental.sub +LEFT: /any/subghz/Stores/Walgreens/Walgreens_Skincare.sub +RIGHT: /any/subghz/Stores/Walgreens/Walgreens_Vitamin.sub +OK: /any/subghz/Stores/CVS/CVS_Stomach.sub ULABEL: Cough_Wal DLABEL: Dental_CVS LLABEL: Skincare_Wal From 72dc8e95d0941849929af98fd51a24590d61ca31 Mon Sep 17 00:00:00 2001 From: Georgii Surkov <37121527+gsurkov@users.noreply.github.com> Date: Mon, 2 Jan 2023 12:01:59 +0300 Subject: [PATCH 5/6] Add .kateconfig and .kateproject to .gitignore (#2237) --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitignore b/.gitignore index 61c594ed1..d54ed4a19 100644 --- a/.gitignore +++ b/.gitignore @@ -30,6 +30,10 @@ Brewfile.lock.json # Visual Studio Code .vscode/ +# Kate +.kateproject +.kateconfig + # legendary cmake's build CMakeLists.txt From b54c6c70d57d5c97a006b4b4bc77c66342fb1ca9 Mon Sep 17 00:00:00 2001 From: VerstreuteSeele Date: Mon, 2 Jan 2023 12:34:00 +0100 Subject: [PATCH 6/6] Fixed NFC --- applications/main/nfc/nfc.c | 16 ++ applications/main/nfc/nfc_i.h | 3 + .../main/nfc/scenes/nfc_scene_config.h | 13 ++ .../nfc/scenes/nfc_scene_delete_success.c | 11 +- .../main/nfc/scenes/nfc_scene_emulate_nfcv.c | 149 ++++++++++++++ .../main/nfc/scenes/nfc_scene_emulate_uid.c | 11 +- .../main/nfc/scenes/nfc_scene_extra_actions.c | 10 + .../scenes/nfc_scene_mf_classic_dict_attack.c | 6 +- .../nfc/scenes/nfc_scene_mf_classic_emulate.c | 11 +- .../nfc/scenes/nfc_scene_mf_classic_keys.c | 4 +- .../nfc_scene_mf_classic_update_success.c | 11 +- .../nfc_scene_mf_classic_write_success.c | 11 +- .../nfc/scenes/nfc_scene_mf_desfire_app.c | 21 +- .../nfc/scenes/nfc_scene_mf_desfire_data.c | 21 +- .../scenes/nfc_scene_mf_ultralight_emulate.c | 128 ++++++++++-- .../nfc_scene_mf_ultralight_key_input.c | 2 +- .../nfc/scenes/nfc_scene_mf_ultralight_menu.c | 18 +- .../nfc_scene_mf_ultralight_read_auth.c | 9 +- .../nfc_scene_mf_ultralight_unlock_auto.c | 3 +- .../main/nfc/scenes/nfc_scene_nfc_data_info.c | 170 ++++++++++++++- .../nfc/scenes/nfc_scene_nfcv_key_input.c | 48 +++++ .../main/nfc/scenes/nfc_scene_nfcv_menu.c | 63 ++++++ .../main/nfc/scenes/nfc_scene_nfcv_unlock.c | 155 ++++++++++++++ .../nfc/scenes/nfc_scene_nfcv_unlock_menu.c | 60 ++++++ .../main/nfc/scenes/nfc_scene_passport_auth.c | 194 ++++++++++++++++++ .../nfc_scene_passport_auth_save_name.c | 82 ++++++++ .../main/nfc/scenes/nfc_scene_passport_date.c | 126 ++++++++++++ .../nfc/scenes/nfc_scene_passport_docnr.c | 67 ++++++ .../main/nfc/scenes/nfc_scene_passport_menu.c | 57 +++++ .../nfc/scenes/nfc_scene_passport_pace_todo.c | 40 ++++ .../main/nfc/scenes/nfc_scene_passport_read.c | 90 ++++++++ .../nfc/scenes/nfc_scene_passport_read_auth.c | 142 +++++++++++++ applications/main/nfc/scenes/nfc_scene_read.c | 22 +- .../nfc/scenes/nfc_scene_restore_original.c | 11 +- applications/main/nfc/scenes/nfc_scene_rpc.c | 19 +- .../main/nfc/scenes/nfc_scene_save_name.c | 2 +- .../main/nfc/scenes/nfc_scene_save_success.c | 17 +- .../main/nfc/scenes/nfc_scene_saved_menu.c | 2 + applications/main/nfc/views/dict_attack.c | 4 +- 39 files changed, 1685 insertions(+), 144 deletions(-) create mode 100644 applications/main/nfc/scenes/nfc_scene_emulate_nfcv.c create mode 100644 applications/main/nfc/scenes/nfc_scene_nfcv_key_input.c create mode 100644 applications/main/nfc/scenes/nfc_scene_nfcv_menu.c create mode 100644 applications/main/nfc/scenes/nfc_scene_nfcv_unlock.c create mode 100644 applications/main/nfc/scenes/nfc_scene_nfcv_unlock_menu.c create mode 100644 applications/main/nfc/scenes/nfc_scene_passport_auth.c create mode 100644 applications/main/nfc/scenes/nfc_scene_passport_auth_save_name.c create mode 100644 applications/main/nfc/scenes/nfc_scene_passport_date.c create mode 100644 applications/main/nfc/scenes/nfc_scene_passport_docnr.c create mode 100644 applications/main/nfc/scenes/nfc_scene_passport_menu.c create mode 100644 applications/main/nfc/scenes/nfc_scene_passport_pace_todo.c create mode 100644 applications/main/nfc/scenes/nfc_scene_passport_read.c create mode 100644 applications/main/nfc/scenes/nfc_scene_passport_read_auth.c diff --git a/applications/main/nfc/nfc.c b/applications/main/nfc/nfc.c index cf4584d7a..90fcf9f27 100644 --- a/applications/main/nfc/nfc.c +++ b/applications/main/nfc/nfc.c @@ -87,6 +87,13 @@ Nfc* nfc_alloc() { nfc->view_dispatcher, NfcViewTextBox, text_box_get_view(nfc->text_box)); nfc->text_box_store = furi_string_alloc(); + // Variable Item List + nfc->variable_item_list = variable_item_list_alloc(); + view_dispatcher_add_view( + nfc->view_dispatcher, + NfcViewVarItemList, + variable_item_list_get_view(nfc->variable_item_list)); + // Custom Widget nfc->widget = widget_alloc(); view_dispatcher_add_view(nfc->view_dispatcher, NfcViewWidget, widget_get_view(nfc->widget)); @@ -159,6 +166,10 @@ void nfc_free(Nfc* nfc) { text_box_free(nfc->text_box); furi_string_free(nfc->text_box_store); + // Variable Item List + view_dispatcher_remove_view(nfc->view_dispatcher, NfcViewVarItemList); + variable_item_list_free(nfc->variable_item_list); + // Custom Widget view_dispatcher_remove_view(nfc->view_dispatcher, NfcViewWidget); widget_free(nfc->widget); @@ -290,6 +301,11 @@ int32_t nfc_app(void* p) { } else if(nfc->dev->format == NfcDeviceSaveFormatMifareClassic) { scene_manager_next_scene(nfc->scene_manager, NfcSceneMfClassicEmulate); DOLPHIN_DEED(DolphinDeedNfcEmulate); + } else if(nfc->dev->format == NfcDeviceSaveFormatNfcV) { + scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateNfcV); + DOLPHIN_DEED(DolphinDeedNfcEmulate); + } else if(nfc->dev->format == NfcDeviceSaveFormatBankCard) { + scene_manager_next_scene(nfc->scene_manager, NfcSceneDeviceInfo); } else { scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateUid); DOLPHIN_DEED(DolphinDeedNfcEmulate); diff --git a/applications/main/nfc/nfc_i.h b/applications/main/nfc/nfc_i.h index f7e489902..a3a62972c 100644 --- a/applications/main/nfc/nfc_i.h +++ b/applications/main/nfc/nfc_i.h @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -77,6 +78,7 @@ struct Nfc { TextInput* text_input; ByteInput* byte_input; TextBox* text_box; + VariableItemList* variable_item_list; Widget* widget; DictAttack* dict_attack; DetectReader* detect_reader; @@ -92,6 +94,7 @@ typedef enum { NfcViewTextInput, NfcViewByteInput, NfcViewTextBox, + NfcViewVarItemList, NfcViewWidget, NfcViewDictAttack, NfcViewDetectReader, diff --git a/applications/main/nfc/scenes/nfc_scene_config.h b/applications/main/nfc/scenes/nfc_scene_config.h index ce51d000d..045080fea 100644 --- a/applications/main/nfc/scenes/nfc_scene_config.h +++ b/applications/main/nfc/scenes/nfc_scene_config.h @@ -14,6 +14,11 @@ ADD_SCENE(nfc, file_select, FileSelect) ADD_SCENE(nfc, emulate_uid, EmulateUid) ADD_SCENE(nfc, nfca_read_success, NfcaReadSuccess) ADD_SCENE(nfc, nfca_menu, NfcaMenu) +ADD_SCENE(nfc, nfcv_menu, NfcVMenu) +ADD_SCENE(nfc, nfcv_unlock_menu, NfcVUnlockMenu) +ADD_SCENE(nfc, nfcv_key_input, NfcVKeyInput) +ADD_SCENE(nfc, nfcv_unlock, NfcVUnlock) +ADD_SCENE(nfc, emulate_nfcv, EmulateNfcV) ADD_SCENE(nfc, mf_ultralight_read_success, MfUltralightReadSuccess) ADD_SCENE(nfc, mf_ultralight_data, MfUltralightData) ADD_SCENE(nfc, mf_ultralight_menu, MfUltralightMenu) @@ -45,6 +50,14 @@ ADD_SCENE(nfc, mf_classic_update_success, MfClassicUpdateSuccess) ADD_SCENE(nfc, mf_classic_wrong_card, MfClassicWrongCard) ADD_SCENE(nfc, emv_read_success, EmvReadSuccess) ADD_SCENE(nfc, emv_menu, EmvMenu) +ADD_SCENE(nfc, passport_read, PassportReadSuccess) +ADD_SCENE(nfc, passport_read_auth, PassportReadAuthSuccess) +ADD_SCENE(nfc, passport_menu, PassportMenu) +ADD_SCENE(nfc, passport_auth, PassportAuth) +ADD_SCENE(nfc, passport_auth_save_name, PassportAuthSaveName) +ADD_SCENE(nfc, passport_date, PassportDate) +ADD_SCENE(nfc, passport_docnr, PassportDocNr) +ADD_SCENE(nfc, passport_pace_todo, PassportPaceTodo) ADD_SCENE(nfc, emulate_apdu_sequence, EmulateApduSequence) ADD_SCENE(nfc, device_info, DeviceInfo) ADD_SCENE(nfc, delete, Delete) diff --git a/applications/main/nfc/scenes/nfc_scene_delete_success.c b/applications/main/nfc/scenes/nfc_scene_delete_success.c index faa7fd7bb..1664a9e5b 100644 --- a/applications/main/nfc/scenes/nfc_scene_delete_success.c +++ b/applications/main/nfc/scenes/nfc_scene_delete_success.c @@ -1,5 +1,4 @@ #include "../nfc_i.h" -#include "../../../settings/desktop_settings/desktop_settings_app.h" void nfc_scene_delete_success_popup_callback(void* context) { Nfc* nfc = context; @@ -8,24 +7,16 @@ void nfc_scene_delete_success_popup_callback(void* context) { void nfc_scene_delete_success_on_enter(void* context) { Nfc* nfc = context; - DesktopSettings* settings = malloc(sizeof(DesktopSettings)); - DESKTOP_SETTINGS_LOAD(settings); // Setup view Popup* popup = nfc->popup; - if (settings->sfw_mode) { - popup_set_icon(popup, 0, 2, &I_DolphinMafia_115x62_sfw); - } - else { - popup_set_icon(popup, 0, 2, &I_DolphinMafia_115x62); - } + popup_set_icon(popup, 0, 2, &I_DolphinMafia_115x62); popup_set_header(popup, "Deleted", 83, 19, AlignLeft, AlignBottom); popup_set_timeout(popup, 1500); popup_set_context(popup, nfc); popup_set_callback(popup, nfc_scene_delete_success_popup_callback); popup_enable_timeout(popup); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup); - free(settings); } bool nfc_scene_delete_success_on_event(void* context, SceneManagerEvent event) { diff --git a/applications/main/nfc/scenes/nfc_scene_emulate_nfcv.c b/applications/main/nfc/scenes/nfc_scene_emulate_nfcv.c new file mode 100644 index 000000000..e6fc60d86 --- /dev/null +++ b/applications/main/nfc/scenes/nfc_scene_emulate_nfcv.c @@ -0,0 +1,149 @@ +#include "../nfc_i.h" + +#define NFC_SCENE_EMULATE_NFCV_LOG_SIZE_MAX (100) + +enum { + NfcSceneEmulateNfcVStateWidget, + NfcSceneEmulateNfcVStateTextBox, +}; + +bool nfc_emulate_nfcv_worker_callback(NfcWorkerEvent event, void* context) { + UNUSED(event); + furi_assert(context); + Nfc* nfc = context; + view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventWorkerExit); + return true; +} + +void nfc_scene_emulate_nfcv_widget_callback(GuiButtonType result, InputType type, void* context) { + furi_assert(context); + Nfc* nfc = context; + if(type == InputTypeShort) { + view_dispatcher_send_custom_event(nfc->view_dispatcher, result); + } +} + +void nfc_emulate_nfcv_textbox_callback(void* context) { + furi_assert(context); + Nfc* nfc = context; + view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventViewExit); +} + +// Add widget with device name or inform that data received +static void nfc_scene_emulate_nfcv_widget_config(Nfc* nfc, bool data_received) { + FuriHalNfcDevData* data = &nfc->dev->dev_data.nfc_data; + Widget* widget = nfc->widget; + widget_reset(widget); + FuriString* info_str; + info_str = furi_string_alloc(); + + widget_add_icon_element(widget, 0, 3, &I_RFIDDolphinSend_97x61); + widget_add_string_element( + widget, 89, 32, AlignCenter, AlignTop, FontPrimary, "Emulating NfcV"); + if(strcmp(nfc->dev->dev_name, "")) { + furi_string_printf(info_str, "%s", nfc->dev->dev_name); + } else { + for(uint8_t i = 0; i < data->uid_len; i++) { + furi_string_cat_printf(info_str, "%02X ", data->uid[i]); + } + } + furi_string_trim(info_str); + widget_add_text_box_element( + widget, 56, 43, 70, 21, AlignCenter, AlignTop, furi_string_get_cstr(info_str), true); + furi_string_free(info_str); + if(data_received) { + widget_add_button_element( + widget, GuiButtonTypeCenter, "Log", nfc_scene_emulate_nfcv_widget_callback, nfc); + } +} + +void nfc_scene_emulate_nfcv_on_enter(void* context) { + Nfc* nfc = context; + + // Setup Widget + nfc_scene_emulate_nfcv_widget_config(nfc, false); + // Setup TextBox + TextBox* text_box = nfc->text_box; + text_box_set_font(text_box, TextBoxFontHex); + text_box_set_focus(text_box, TextBoxFocusEnd); + furi_string_reset(nfc->text_box_store); + + // Set Widget state and view + scene_manager_set_scene_state( + nfc->scene_manager, NfcSceneEmulateNfcV, NfcSceneEmulateNfcVStateWidget); + view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewWidget); + // Start worker + memset(&nfc->dev->dev_data.reader_data, 0, sizeof(NfcReaderRequestData)); + nfc_worker_start( + nfc->worker, + NfcWorkerStateNfcVEmulate, + &nfc->dev->dev_data, + nfc_emulate_nfcv_worker_callback, + nfc); + + nfc_blink_emulate_start(nfc); +} + +bool nfc_scene_emulate_nfcv_on_event(void* context, SceneManagerEvent event) { + Nfc* nfc = context; + NfcVData* nfcv_data = &nfc->dev->dev_data.nfcv_data; + uint32_t state = scene_manager_get_scene_state(nfc->scene_manager, NfcSceneEmulateNfcV); + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == NfcCustomEventWorkerExit) { + // Add data button to widget if data is received for the first time + if(!furi_string_size(nfc->text_box_store)) { + nfc_scene_emulate_nfcv_widget_config(nfc, true); + } + if(strlen(nfcv_data->last_command) > 0) { + /* use the last n bytes from the log so there's enough space for the new log entry */ + size_t maxSize = + NFC_SCENE_EMULATE_NFCV_LOG_SIZE_MAX - (strlen(nfcv_data->last_command) + 1); + if(furi_string_size(nfc->text_box_store) >= maxSize) { + furi_string_right(nfc->text_box_store, (strlen(nfcv_data->last_command) + 1)); + } + furi_string_cat_printf(nfc->text_box_store, "%s", nfcv_data->last_command); + furi_string_push_back(nfc->text_box_store, '\n'); + text_box_set_text(nfc->text_box, furi_string_get_cstr(nfc->text_box_store)); + + /* clear previously logged command */ + strcpy(nfcv_data->last_command, ""); + } + consumed = true; + } else if(event.event == GuiButtonTypeCenter && state == NfcSceneEmulateNfcVStateWidget) { + view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewTextBox); + scene_manager_set_scene_state( + nfc->scene_manager, NfcSceneEmulateNfcV, NfcSceneEmulateNfcVStateTextBox); + consumed = true; + } else if(event.event == NfcCustomEventViewExit && state == NfcSceneEmulateNfcVStateTextBox) { + view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewWidget); + scene_manager_set_scene_state( + nfc->scene_manager, NfcSceneEmulateNfcV, NfcSceneEmulateNfcVStateWidget); + consumed = true; + } + } else if(event.type == SceneManagerEventTypeBack) { + if(state == NfcSceneEmulateNfcVStateTextBox) { + view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewWidget); + scene_manager_set_scene_state( + nfc->scene_manager, NfcSceneEmulateNfcV, NfcSceneEmulateNfcVStateWidget); + consumed = true; + } + } + + return consumed; +} + +void nfc_scene_emulate_nfcv_on_exit(void* context) { + Nfc* nfc = context; + + // Stop worker + nfc_worker_stop(nfc->worker); + + // Clear view + widget_reset(nfc->widget); + text_box_reset(nfc->text_box); + furi_string_reset(nfc->text_box_store); + + nfc_blink_stop(nfc); +} diff --git a/applications/main/nfc/scenes/nfc_scene_emulate_uid.c b/applications/main/nfc/scenes/nfc_scene_emulate_uid.c index eec43c92c..7316eebe0 100644 --- a/applications/main/nfc/scenes/nfc_scene_emulate_uid.c +++ b/applications/main/nfc/scenes/nfc_scene_emulate_uid.c @@ -1,5 +1,4 @@ #include "../nfc_i.h" -#include "../../../settings/desktop_settings/desktop_settings_app.h" #define NFC_SCENE_EMULATE_UID_LOG_SIZE_MAX (200) @@ -37,15 +36,8 @@ static void nfc_scene_emulate_uid_widget_config(Nfc* nfc, bool data_received) { widget_reset(widget); FuriString* info_str; info_str = furi_string_alloc(); - DesktopSettings* settings = malloc(sizeof(DesktopSettings)); - DESKTOP_SETTINGS_LOAD(settings); - if (settings->sfw_mode) { - widget_add_icon_element(widget, 0, 3, &I_NFC_dolphin_emulation_47x61_sfw); - } - else { - widget_add_icon_element(widget, 0, 3, &I_NFC_dolphin_emulation_47x61); - } + widget_add_icon_element(widget, 0, 3, &I_NFC_dolphin_emulation_47x61); widget_add_string_element(widget, 57, 13, AlignLeft, AlignTop, FontPrimary, "Emulating UID"); if(strcmp(nfc->dev->dev_name, "") != 0) { furi_string_printf(info_str, "%s", nfc->dev->dev_name); @@ -62,7 +54,6 @@ static void nfc_scene_emulate_uid_widget_config(Nfc* nfc, bool data_received) { widget_add_button_element( widget, GuiButtonTypeCenter, "Log", nfc_scene_emulate_uid_widget_callback, nfc); } - free(settings); } void nfc_scene_emulate_uid_on_enter(void* context) { diff --git a/applications/main/nfc/scenes/nfc_scene_extra_actions.c b/applications/main/nfc/scenes/nfc_scene_extra_actions.c index 717e8efc4..147c89757 100644 --- a/applications/main/nfc/scenes/nfc_scene_extra_actions.c +++ b/applications/main/nfc/scenes/nfc_scene_extra_actions.c @@ -4,6 +4,7 @@ enum SubmenuIndex { SubmenuIndexReadCardType, SubmenuIndexMfClassicKeys, SubmenuIndexMfUltralightUnlock, + SubmenuIndexNfcVUnlock, }; void nfc_scene_extra_actions_submenu_callback(void* context, uint32_t index) { @@ -34,6 +35,12 @@ void nfc_scene_extra_actions_on_enter(void* context) { SubmenuIndexMfUltralightUnlock, nfc_scene_extra_actions_submenu_callback, nfc); + submenu_add_item( + submenu, + "Unlock SLIX-L", + SubmenuIndexNfcVUnlock, + nfc_scene_extra_actions_submenu_callback, + nfc); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewMenu); } @@ -56,6 +63,9 @@ bool nfc_scene_extra_actions_on_event(void* context, SceneManagerEvent event) { scene_manager_set_scene_state(nfc->scene_manager, NfcSceneReadCardType, 0); scene_manager_next_scene(nfc->scene_manager, NfcSceneReadCardType); consumed = true; + } else if(event.event == SubmenuIndexNfcVUnlock) { + scene_manager_next_scene(nfc->scene_manager, NfcSceneNfcVUnlockMenu); + consumed = true; } scene_manager_set_scene_state(nfc->scene_manager, NfcSceneExtraActions, event.event); } diff --git a/applications/main/nfc/scenes/nfc_scene_mf_classic_dict_attack.c b/applications/main/nfc/scenes/nfc_scene_mf_classic_dict_attack.c index b82bf5521..9b477e301 100644 --- a/applications/main/nfc/scenes/nfc_scene_mf_classic_dict_attack.c +++ b/applications/main/nfc/scenes/nfc_scene_mf_classic_dict_attack.c @@ -58,7 +58,7 @@ static void nfc_scene_mf_classic_dict_attack_prepare_view(Nfc* nfc, DictAttackSt // If failed to load user dictionary - try the system dictionary if(!dict) { - FURI_LOG_E(TAG, "User dictionary not found"); + FURI_LOG_E(TAG, "User Dictionary Not Found"); state = DictAttackStateFlipperDictInProgress; } } @@ -67,8 +67,8 @@ static void nfc_scene_mf_classic_dict_attack_prepare_view(Nfc* nfc, DictAttackSt dict_attack_set_header(nfc->dict_attack, "MF Classic System Dictionary"); dict = mf_classic_dict_alloc(MfClassicDictTypeSystem); if(!dict) { - FURI_LOG_E(TAG, "Flipper dictionary not found"); - // Pass through to let the worker handle the failure + FURI_LOG_E(TAG, "Flipper Dictionary Not Found"); + // Pass through to let worker handle the failure } } // Free previous dictionary diff --git a/applications/main/nfc/scenes/nfc_scene_mf_classic_emulate.c b/applications/main/nfc/scenes/nfc_scene_mf_classic_emulate.c index 0fa624ad9..8c0f493e1 100644 --- a/applications/main/nfc/scenes/nfc_scene_mf_classic_emulate.c +++ b/applications/main/nfc/scenes/nfc_scene_mf_classic_emulate.c @@ -1,5 +1,4 @@ #include "../nfc_i.h" -#include "../../../settings/desktop_settings/desktop_settings_app.h" #define NFC_MF_CLASSIC_DATA_NOT_CHANGED (0UL) #define NFC_MF_CLASSIC_DATA_CHANGED (1UL) @@ -15,8 +14,6 @@ bool nfc_mf_classic_emulate_worker_callback(NfcWorkerEvent event, void* context) void nfc_scene_mf_classic_emulate_on_enter(void* context) { Nfc* nfc = context; - DesktopSettings* settings = malloc(sizeof(DesktopSettings)); - DESKTOP_SETTINGS_LOAD(settings); // Setup view Popup* popup = nfc->popup; @@ -26,12 +23,7 @@ void nfc_scene_mf_classic_emulate_on_enter(void* context) { } else { nfc_text_store_set(nfc, "MIFARE\nClassic"); } - if (settings->sfw_mode) { - popup_set_icon(popup, 0, 3, &I_NFC_dolphin_emulation_47x61_sfw); - } - else { - popup_set_icon(popup, 0, 3, &I_NFC_dolphin_emulation_47x61); - } + popup_set_icon(popup, 0, 3, &I_NFC_dolphin_emulation_47x61); popup_set_text(popup, nfc->text_store, 90, 28, AlignCenter, AlignTop); // Setup and start worker @@ -43,7 +35,6 @@ void nfc_scene_mf_classic_emulate_on_enter(void* context) { nfc_mf_classic_emulate_worker_callback, nfc); nfc_blink_emulate_start(nfc); - free(settings); } bool nfc_scene_mf_classic_emulate_on_event(void* context, SceneManagerEvent event) { diff --git a/applications/main/nfc/scenes/nfc_scene_mf_classic_keys.c b/applications/main/nfc/scenes/nfc_scene_mf_classic_keys.c index 8a7dc2c18..8b61904b4 100644 --- a/applications/main/nfc/scenes/nfc_scene_mf_classic_keys.c +++ b/applications/main/nfc/scenes/nfc_scene_mf_classic_keys.c @@ -28,9 +28,9 @@ void nfc_scene_mf_classic_keys_on_enter(void* context) { widget_add_string_element( nfc->widget, 0, 0, AlignLeft, AlignTop, FontPrimary, "MIFARE Classic Keys"); char temp_str[32]; - snprintf(temp_str, sizeof(temp_str), "System dict: %lu", flipper_dict_keys_total); + snprintf(temp_str, sizeof(temp_str), "System Dict: %ld", flipper_dict_keys_total); widget_add_string_element(nfc->widget, 0, 20, AlignLeft, AlignTop, FontSecondary, temp_str); - snprintf(temp_str, sizeof(temp_str), "User dict: %lu", user_dict_keys_total); + snprintf(temp_str, sizeof(temp_str), "User Dict: %ld", user_dict_keys_total); widget_add_string_element(nfc->widget, 0, 32, AlignLeft, AlignTop, FontSecondary, temp_str); widget_add_button_element( nfc->widget, GuiButtonTypeCenter, "Add", nfc_scene_mf_classic_keys_widget_callback, nfc); diff --git a/applications/main/nfc/scenes/nfc_scene_mf_classic_update_success.c b/applications/main/nfc/scenes/nfc_scene_mf_classic_update_success.c index a76a758b6..fef8fd5e9 100644 --- a/applications/main/nfc/scenes/nfc_scene_mf_classic_update_success.c +++ b/applications/main/nfc/scenes/nfc_scene_mf_classic_update_success.c @@ -1,6 +1,5 @@ #include "../nfc_i.h" #include -#include "../../../settings/desktop_settings/desktop_settings_app.h" void nfc_scene_mf_classic_update_success_popup_callback(void* context) { Nfc* nfc = context; @@ -10,18 +9,11 @@ void nfc_scene_mf_classic_update_success_popup_callback(void* context) { void nfc_scene_mf_classic_update_success_on_enter(void* context) { Nfc* nfc = context; DOLPHIN_DEED(DolphinDeedNfcSave); - DesktopSettings* settings = malloc(sizeof(DesktopSettings)); - DESKTOP_SETTINGS_LOAD(settings); notification_message(nfc->notifications, &sequence_success); Popup* popup = nfc->popup; - if (settings->sfw_mode) { - popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59_sfw); - } - else { - popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59); - } + popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59); popup_set_header(popup, "Updated!", 11, 20, AlignLeft, AlignBottom); popup_set_timeout(popup, 1500); popup_set_context(popup, nfc); @@ -29,7 +21,6 @@ void nfc_scene_mf_classic_update_success_on_enter(void* context) { popup_enable_timeout(popup); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup); - free(settings); } bool nfc_scene_mf_classic_update_success_on_event(void* context, SceneManagerEvent event) { diff --git a/applications/main/nfc/scenes/nfc_scene_mf_classic_write_success.c b/applications/main/nfc/scenes/nfc_scene_mf_classic_write_success.c index e425d8c3a..2f2a3beb1 100644 --- a/applications/main/nfc/scenes/nfc_scene_mf_classic_write_success.c +++ b/applications/main/nfc/scenes/nfc_scene_mf_classic_write_success.c @@ -1,6 +1,5 @@ #include "../nfc_i.h" #include -#include "../../../settings/desktop_settings/desktop_settings_app.h" void nfc_scene_mf_classic_write_success_popup_callback(void* context) { Nfc* nfc = context; @@ -10,18 +9,11 @@ void nfc_scene_mf_classic_write_success_popup_callback(void* context) { void nfc_scene_mf_classic_write_success_on_enter(void* context) { Nfc* nfc = context; DOLPHIN_DEED(DolphinDeedNfcSave); - DesktopSettings* settings = malloc(sizeof(DesktopSettings)); - DESKTOP_SETTINGS_LOAD(settings); notification_message(nfc->notifications, &sequence_success); Popup* popup = nfc->popup; - if (settings->sfw_mode) { - popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59_sfw); - } - else { - popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59); - } + popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59); popup_set_header(popup, "Successfully\nwritten", 13, 22, AlignLeft, AlignBottom); popup_set_timeout(popup, 1500); popup_set_context(popup, nfc); @@ -29,7 +21,6 @@ void nfc_scene_mf_classic_write_success_on_enter(void* context) { popup_enable_timeout(popup); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup); - free(settings); } bool nfc_scene_mf_classic_write_success_on_event(void* context, SceneManagerEvent event) { diff --git a/applications/main/nfc/scenes/nfc_scene_mf_desfire_app.c b/applications/main/nfc/scenes/nfc_scene_mf_desfire_app.c index 882dc5fea..afc5f0dee 100644 --- a/applications/main/nfc/scenes/nfc_scene_mf_desfire_app.c +++ b/applications/main/nfc/scenes/nfc_scene_mf_desfire_app.c @@ -51,18 +51,23 @@ void nfc_scene_mf_desfire_app_on_enter(void* context) { nfc_scene_mf_desfire_app_submenu_callback, nfc); - FuriString* label = furi_string_alloc(); + uint16_t cap = NFC_TEXT_STORE_SIZE; + char* buf = nfc->text_store; int idx = SubmenuIndexDynamic; for(MifareDesfireFile* file = app->file_head; file; file = file->next) { - furi_string_printf(label, "File %d", file->id); + int size = snprintf(buf, cap, "File %d", file->id); + if(size < 0 || size >= cap) { + FURI_LOG_W( + TAG, + "Exceeded NFC_TEXT_STORE_SIZE when preparing file id strings; menu truncated"); + break; + } + char* label = buf; + cap -= size + 1; + buf += size + 1; submenu_add_item( - nfc->submenu, - furi_string_get_cstr(label), - idx++, - nfc_scene_mf_desfire_app_submenu_callback, - nfc); + nfc->submenu, label, idx++, nfc_scene_mf_desfire_app_submenu_callback, nfc); } - furi_string_free(label); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewMenu); } diff --git a/applications/main/nfc/scenes/nfc_scene_mf_desfire_data.c b/applications/main/nfc/scenes/nfc_scene_mf_desfire_data.c index c7caee8dc..e619d0377 100644 --- a/applications/main/nfc/scenes/nfc_scene_mf_desfire_data.c +++ b/applications/main/nfc/scenes/nfc_scene_mf_desfire_data.c @@ -33,18 +33,21 @@ void nfc_scene_mf_desfire_data_on_enter(void* context) { nfc_scene_mf_desfire_data_submenu_callback, nfc); - FuriString* label = furi_string_alloc(); + uint16_t cap = NFC_TEXT_STORE_SIZE; + char* buf = nfc->text_store; int idx = SubmenuIndexDynamic; for(MifareDesfireApplication* app = data->app_head; app; app = app->next) { - furi_string_printf(label, "App %02x%02x%02x", app->id[0], app->id[1], app->id[2]); - submenu_add_item( - submenu, - furi_string_get_cstr(label), - idx++, - nfc_scene_mf_desfire_data_submenu_callback, - nfc); + int size = snprintf(buf, cap, "App %02x%02x%02x", app->id[0], app->id[1], app->id[2]); + if(size < 0 || size >= cap) { + FURI_LOG_W( + TAG, "Exceeded NFC_TEXT_STORE_SIZE when preparing app id strings; menu truncated"); + break; + } + char* label = buf; + cap -= size + 1; + buf += size + 1; + submenu_add_item(submenu, label, idx++, nfc_scene_mf_desfire_data_submenu_callback, nfc); } - furi_string_free(label); if(state >= MifareDesfireDataStateItem) { submenu_set_selected_item( diff --git a/applications/main/nfc/scenes/nfc_scene_mf_ultralight_emulate.c b/applications/main/nfc/scenes/nfc_scene_mf_ultralight_emulate.c index ca25b48c1..88b6b71d9 100644 --- a/applications/main/nfc/scenes/nfc_scene_mf_ultralight_emulate.c +++ b/applications/main/nfc/scenes/nfc_scene_mf_ultralight_emulate.c @@ -1,23 +1,103 @@ #include "../nfc_i.h" -#include "../../../settings/desktop_settings/desktop_settings_app.h" +#include + +#define NFC_SCENE_MF_ULTRALIGHT_EMULATE_LOG_SIZE_MAX (200) #define NFC_MF_UL_DATA_NOT_CHANGED (0UL) #define NFC_MF_UL_DATA_CHANGED (1UL) -bool nfc_mf_ultralight_emulate_worker_callback(NfcWorkerEvent event, void* context) { - UNUSED(event); - Nfc* nfc = context; +enum { + // View states + NfcSceneMfUltralightEmulateStateWidget, + NfcSceneMfUltralightEmulateStateTextBox, + NfcSceneMfUltralightEmulateStateMax = 0xFF, + // State flags + NfcSceneMfUltralightEmulateStateDataChanged = 1 << 8, + NfcSceneMfUltralightEmulateStateAuthAttempted = 1 << 9, + NfcSceneMfUltralightEmulateStateLogButtonShown = 1 << 10, +}; + +bool nfc_mf_ultralight_emulate_worker_callback(NfcWorkerEvent event, void* context) { + Nfc* nfc = context; + uint32_t state = + scene_manager_get_scene_state(nfc->scene_manager, NfcSceneMfUltralightEmulate); + + if(event == NfcWorkerEventSuccess) + state |= NfcSceneMfUltralightEmulateStateDataChanged; + else if(event == NfcWorkerEventMfUltralightPwdAuth) { + // Don't update if we're exiting + if(nfc_worker_get_state(nfc->worker) != NfcWorkerStateStop) { + // Event data is only available for the duration of this callback, so we're updating the + // text box right here + MfUltralightAuth* auth = nfc_worker_get_event_data(nfc->worker); + if(auth != NULL && furi_string_size(nfc->text_box_store) < + NFC_SCENE_MF_ULTRALIGHT_EMULATE_LOG_SIZE_MAX) { + furi_string_cat(nfc->text_box_store, "PWD:"); + for(size_t i = 0; i < sizeof(auth->pwd.raw); ++i) { + furi_string_cat_printf(nfc->text_box_store, " %02X", auth->pwd.raw[i]); + } + furi_string_push_back(nfc->text_box_store, '\n'); + text_box_set_text(nfc->text_box, furi_string_get_cstr(nfc->text_box_store)); + } + state |= NfcSceneMfUltralightEmulateStateAuthAttempted; + } + } + scene_manager_set_scene_state(nfc->scene_manager, NfcSceneMfUltralightEmulate, state); + view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventWorkerExit); - scene_manager_set_scene_state( - nfc->scene_manager, NfcSceneMfUltralightEmulate, NFC_MF_UL_DATA_CHANGED); return true; } +void nfc_scene_mf_ultralight_emulate_widget_callback( + GuiButtonType result, + InputType type, + void* context) { + furi_assert(context); + Nfc* nfc = context; + if(type == InputTypeShort) { + view_dispatcher_send_custom_event(nfc->view_dispatcher, result); + } +} + +void nfc_scene_mf_ultralight_emulate_widget_config(Nfc* nfc, bool auth_attempted) { + Widget* widget = nfc->widget; + widget_reset(widget); + FuriString* info_str; + info_str = furi_string_alloc(); + + widget_add_icon_element(widget, 0, 3, &I_RFIDDolphinSend_97x61); + if(strcmp(nfc->dev->dev_name, "")) { + furi_string_printf(info_str, "Emulating\n%s", nfc->dev->dev_name); + } else { + furi_string_printf(info_str, "Emulating\nMf Ultralight"); + } + + widget_add_string_multiline_element( + widget, 56, 31, AlignLeft, AlignTop, FontPrimary, furi_string_get_cstr(info_str)); + furi_string_free(info_str); + if(auth_attempted) { + widget_add_button_element( + widget, + GuiButtonTypeCenter, + "Log", + nfc_scene_mf_ultralight_emulate_widget_callback, + nfc); + } +} + void nfc_scene_mf_ultralight_emulate_on_enter(void* context) { Nfc* nfc = context; - DesktopSettings* settings = malloc(sizeof(DesktopSettings)); - DESKTOP_SETTINGS_LOAD(settings); + uint32_t state = + scene_manager_get_scene_state(nfc->scene_manager, NfcSceneMfUltralightEmulate); + // Setup Widget + nfc_scene_mf_ultralight_emulate_widget_config(nfc, false); + state &= ~NfcSceneMfUltralightEmulateStateLogButtonShown; + // Setup TextBox + TextBox* text_box = nfc->text_box; + text_box_set_font(text_box, TextBoxFontHex); + text_box_set_focus(text_box, TextBoxFocusEnd); + furi_string_reset(nfc->text_box_store); // Setup view MfUltralightType type = nfc->dev->dev_data.mf_ul_data.type; bool is_ultralight = (type == MfUltralightTypeUL11) || (type == MfUltralightTypeUL21) || @@ -31,16 +111,15 @@ void nfc_scene_mf_ultralight_emulate_on_enter(void* context) { } else { nfc_text_store_set(nfc, "MIFARE\nNTAG"); } - if (settings->sfw_mode) { - popup_set_icon(popup, 0, 3, &I_NFC_dolphin_emulation_47x61_sfw); - } - else { - popup_set_icon(popup, 0, 3, &I_NFC_dolphin_emulation_47x61); - } + popup_set_icon(popup, 0, 3, &I_NFC_dolphin_emulation_47x61); popup_set_text(popup, nfc->text_store, 90, 28, AlignCenter, AlignTop); - // Setup and start worker - view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup); + // Set Widget state and view + state = (state & ~NfcSceneMfUltralightEmulateStateMax) | + NfcSceneMfUltralightEmulateStateWidget; + scene_manager_set_scene_state(nfc->scene_manager, NfcSceneMfUltralightEmulate, state); + view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewWidget); + // Start worker nfc_worker_start( nfc->worker, NfcWorkerStateMfUltralightEmulate, @@ -48,7 +127,6 @@ void nfc_scene_mf_ultralight_emulate_on_enter(void* context) { nfc_mf_ultralight_emulate_worker_callback, nfc); nfc_blink_emulate_start(nfc); - free(settings); } bool nfc_scene_mf_ultralight_emulate_on_event(void* context, SceneManagerEvent event) { @@ -68,16 +146,28 @@ bool nfc_scene_mf_ultralight_emulate_on_event(void* context, SceneManagerEvent e nfc_device_save_shadow(nfc->dev, furi_string_get_cstr(nfc->dev->load_path)); } } - consumed = false; } return consumed; } void nfc_scene_mf_ultralight_emulate_on_exit(void* context) { Nfc* nfc = context; + uint32_t state = + scene_manager_get_scene_state(nfc->scene_manager, NfcSceneMfUltralightEmulate); + + // Stop worker + nfc_worker_stop(nfc->worker); + // Check if data changed and save in shadow file + if(state & NfcSceneMfUltralightEmulateStateDataChanged) { + state &= ~NfcSceneMfUltralightEmulateStateDataChanged; + scene_manager_set_scene_state(nfc->scene_manager, NfcSceneMfUltralightEmulate, state); + nfc_device_save_shadow(nfc->dev, nfc->dev->dev_name); + } // Clear view - popup_reset(nfc->popup); + widget_reset(nfc->widget); + text_box_reset(nfc->text_box); + furi_string_reset(nfc->text_box_store); nfc_blink_stop(nfc); } diff --git a/applications/main/nfc/scenes/nfc_scene_mf_ultralight_key_input.c b/applications/main/nfc/scenes/nfc_scene_mf_ultralight_key_input.c index 089187d5b..174d1a406 100644 --- a/applications/main/nfc/scenes/nfc_scene_mf_ultralight_key_input.c +++ b/applications/main/nfc/scenes/nfc_scene_mf_ultralight_key_input.c @@ -11,7 +11,7 @@ void nfc_scene_mf_ultralight_key_input_on_enter(void* context) { // Setup view ByteInput* byte_input = nfc->byte_input; - byte_input_set_header_text(byte_input, "Enter the password in hex"); + byte_input_set_header_text(byte_input, "Enter The Password In Hex"); byte_input_set_result_callback( byte_input, nfc_scene_mf_ultralight_key_input_byte_input_callback, diff --git a/applications/main/nfc/scenes/nfc_scene_mf_ultralight_menu.c b/applications/main/nfc/scenes/nfc_scene_mf_ultralight_menu.c index c511e9dcb..ddf30c54a 100644 --- a/applications/main/nfc/scenes/nfc_scene_mf_ultralight_menu.c +++ b/applications/main/nfc/scenes/nfc_scene_mf_ultralight_menu.c @@ -2,7 +2,8 @@ #include enum SubmenuIndex { - SubmenuIndexUnlock, + SubmenuIndexUnlockByReader, + SubmenuIndexUnlockByPassword, SubmenuIndexSave, SubmenuIndexEmulate, SubmenuIndexInfo, @@ -22,8 +23,14 @@ void nfc_scene_mf_ultralight_menu_on_enter(void* context) { if(!mf_ul_is_full_capture(data)) { submenu_add_item( submenu, - "Unlock", - SubmenuIndexUnlock, + "Unlock With Reader", + SubmenuIndexUnlockByReader, + nfc_scene_mf_ultralight_menu_submenu_callback, + nfc); + submenu_add_item( + submenu, + "Unlock With Password", + SubmenuIndexUnlockByPassword, nfc_scene_mf_ultralight_menu_submenu_callback, nfc); } @@ -63,7 +70,10 @@ bool nfc_scene_mf_ultralight_menu_on_event(void* context, SceneManagerEvent even DOLPHIN_DEED(DolphinDeedNfcEmulate); } consumed = true; - } else if(event.event == SubmenuIndexUnlock) { + } else if(event.event == SubmenuIndexUnlockByReader) { + scene_manager_next_scene(nfc->scene_manager, NfcSceneMfUltralightUnlockAuto); + consumed = true; + } else if(event.event == SubmenuIndexUnlockByPassword) { scene_manager_next_scene(nfc->scene_manager, NfcSceneMfUltralightUnlockMenu); consumed = true; } else if(event.event == SubmenuIndexInfo) { diff --git a/applications/main/nfc/scenes/nfc_scene_mf_ultralight_read_auth.c b/applications/main/nfc/scenes/nfc_scene_mf_ultralight_read_auth.c index 2ab5e3f3f..8e2dd0c22 100644 --- a/applications/main/nfc/scenes/nfc_scene_mf_ultralight_read_auth.c +++ b/applications/main/nfc/scenes/nfc_scene_mf_ultralight_read_auth.c @@ -24,21 +24,22 @@ void nfc_scene_mf_ultralight_read_auth_set_state(Nfc* nfc, NfcSceneMfUlReadState if(curr_state != state) { if(state == NfcSceneMfUlReadStateDetecting) { popup_reset(nfc->popup); - popup_set_text(nfc->popup, "Apply the\ntarget card", 97, 24, AlignCenter, AlignTop); + popup_set_text( + nfc->popup, "Apply Card To\nFlipper's Back", 97, 24, AlignCenter, AlignTop); popup_set_icon(nfc->popup, 0, 8, &I_NFC_manual_60x50); nfc_blink_read_start(nfc); } else if(state == NfcSceneMfUlReadStateReading) { popup_reset(nfc->popup); popup_set_header( - nfc->popup, "Reading card\nDon't move...", 85, 24, AlignCenter, AlignTop); + nfc->popup, "Reading Card\nDon't Move...", 85, 24, AlignCenter, AlignTop); popup_set_icon(nfc->popup, 12, 23, &A_Loading_24); nfc_blink_detect_start(nfc); } else if(state == NfcSceneMfUlReadStateNotSupportedCard) { popup_reset(nfc->popup); - popup_set_header(nfc->popup, "Wrong type of card!", 64, 3, AlignCenter, AlignTop); + popup_set_header(nfc->popup, "Wrong Type Of Card!", 64, 3, AlignCenter, AlignTop); popup_set_text( nfc->popup, - "Only MIFARE\nUltralight & NTAG\nare supported", + "Only MIFARE\nUltralight & NTAG\n Are Supported", 4, 22, AlignLeft, diff --git a/applications/main/nfc/scenes/nfc_scene_mf_ultralight_unlock_auto.c b/applications/main/nfc/scenes/nfc_scene_mf_ultralight_unlock_auto.c index c59fe3a7d..050f6db1e 100644 --- a/applications/main/nfc/scenes/nfc_scene_mf_ultralight_unlock_auto.c +++ b/applications/main/nfc/scenes/nfc_scene_mf_ultralight_unlock_auto.c @@ -31,7 +31,7 @@ void nfc_scene_mf_ultralight_unlock_auto_on_enter(void* context) { nfc_scene_mf_ultralight_unlock_auto_worker_callback, nfc); - nfc_blink_read_start(nfc); + nfc_blink_emulate_start(nfc); } bool nfc_scene_mf_ultralight_unlock_auto_on_event(void* context, SceneManagerEvent event) { @@ -58,6 +58,7 @@ void nfc_scene_mf_ultralight_unlock_auto_on_exit(void* context) { // Stop worker nfc_worker_stop(nfc->worker); // Clear view + popup_reset(nfc->popup); widget_reset(nfc->widget); nfc_blink_stop(nfc); diff --git a/applications/main/nfc/scenes/nfc_scene_nfc_data_info.c b/applications/main/nfc/scenes/nfc_scene_nfc_data_info.c index b44ab7823..372da8860 100644 --- a/applications/main/nfc/scenes/nfc_scene_nfc_data_info.c +++ b/applications/main/nfc/scenes/nfc_scene_nfc_data_info.c @@ -7,6 +7,17 @@ void nfc_scene_nfc_data_info_widget_callback(GuiButtonType result, InputType typ } } +uint32_t nfc_scene_nfc_data_info_get_key(uint8_t* data) { + uint32_t value = 0; + + for(uint32_t pos = 0; pos < 4; pos++) { + value <<= 8; + value |= data[pos]; + } + + return value; +} + void nfc_scene_nfc_data_info_on_enter(void* context) { Nfc* nfc = context; Widget* widget = nfc->widget; @@ -14,7 +25,8 @@ void nfc_scene_nfc_data_info_on_enter(void* context) { NfcDeviceData* dev_data = &nfc->dev->dev_data; NfcProtocol protocol = dev_data->protocol; uint8_t text_scroll_height = 0; - if((protocol == NfcDeviceProtocolMifareDesfire) || (protocol == NfcDeviceProtocolMifareUl)) { + if((protocol == NfcDeviceProtocolMifareDesfire) || (protocol == NfcDeviceProtocolMifareUl) || + (protocol == NfcDeviceProtocolNfcV)) { widget_add_button_element( widget, GuiButtonTypeRight, "More", nfc_scene_nfc_data_info_widget_callback, nfc); text_scroll_height = 52; @@ -32,6 +44,8 @@ void nfc_scene_nfc_data_info_on_enter(void* context) { // Set tag type if(protocol == NfcDeviceProtocolEMV) { furi_string_cat_printf(temp_str, "\e#EMV Bank Card\n"); + } else if(protocol == NfcDeviceProtocolMRTD) { + furi_string_cat_printf(temp_str, "\e#Passport/ID\n"); } else if(protocol == NfcDeviceProtocolMifareUl) { furi_string_cat_printf( temp_str, "\e#%s\n", nfc_mf_ul_type(dev_data->mf_ul_data.type, true)); @@ -40,19 +54,156 @@ void nfc_scene_nfc_data_info_on_enter(void* context) { temp_str, "\e#%s\n", nfc_mf_classic_type(dev_data->mf_classic_data.type)); } else if(protocol == NfcDeviceProtocolMifareDesfire) { furi_string_cat_printf(temp_str, "\e#MIFARE DESfire\n"); + } else if(protocol == NfcDeviceProtocolNfcV) { + switch(dev_data->nfcv_data.sub_type) { + case NfcVTypePlain: + furi_string_cat_printf(temp_str, "\e#ISO15693\n"); + break; + case NfcVTypeSlix: + furi_string_cat_printf(temp_str, "\e#ISO15693 SLIX\n"); + break; + case NfcVTypeSlixS: + furi_string_cat_printf(temp_str, "\e#ISO15693 SLIX-S\n"); + break; + case NfcVTypeSlixL: + furi_string_cat_printf(temp_str, "\e#ISO15693 SLIX-L\n"); + break; + case NfcVTypeSlix2: + furi_string_cat_printf(temp_str, "\e#ISO15693 SLIX2\n"); + break; + default: + furi_string_cat_printf(temp_str, "\e#ISO15693 (unknown)\n"); + break; + } } else { furi_string_cat_printf(temp_str, "\e#Unknown ISO tag\n"); } // Set tag iso data - char iso_type = FURI_BIT(nfc_data->sak, 5) ? '4' : '3'; - furi_string_cat_printf(temp_str, "ISO 14443-%c (NFC-A)\n", iso_type); - furi_string_cat_printf(temp_str, "UID:"); - for(size_t i = 0; i < nfc_data->uid_len; i++) { - furi_string_cat_printf(temp_str, " %02X", nfc_data->uid[i]); + if(protocol == NfcDeviceProtocolNfcV) { + NfcVData* nfcv_data = &nfc->dev->dev_data.nfcv_data; + + furi_string_cat_printf(temp_str, "UID:\n"); + for(size_t i = 0; i < nfc_data->uid_len; i++) { + furi_string_cat_printf(temp_str, " %02X", nfc_data->uid[i]); + } + furi_string_cat_printf(temp_str, "\n"); + + furi_string_cat_printf(temp_str, "DSFID: %02X\n", nfcv_data->dsfid); + furi_string_cat_printf(temp_str, "AFI: %02X\n", nfcv_data->afi); + furi_string_cat_printf(temp_str, "IC Ref: %02X\n", nfcv_data->ic_ref); + furi_string_cat_printf(temp_str, "Blocks: %02X\n", nfcv_data->block_num); + furi_string_cat_printf(temp_str, "Blocksize: %02X\n", nfcv_data->block_size); + + furi_string_cat_printf( + temp_str, "Data (%d byte)\n", nfcv_data->block_num * nfcv_data->block_size); + + int maxBlocks = nfcv_data->block_num; + if(maxBlocks > 32) { + maxBlocks = 32; + furi_string_cat_printf(temp_str, "(truncated to %d blocks)\n", maxBlocks); + } + + for(int block = 0; block < maxBlocks; block++) { + for(int pos = 0; pos < nfcv_data->block_size; pos++) { + furi_string_cat_printf( + temp_str, " %02X", nfcv_data->data[block * nfcv_data->block_size + pos]); + } + furi_string_cat_printf(temp_str, "\n"); + } + furi_string_cat_printf(temp_str, "\n"); + + switch(dev_data->nfcv_data.sub_type) { + case NfcVTypePlain: + furi_string_cat_printf(temp_str, "Type: Plain\n"); + break; + case NfcVTypeSlix: + furi_string_cat_printf(temp_str, "Type: SLIX\n"); + furi_string_cat_printf(temp_str, "Keys:\n"); + furi_string_cat_printf( + temp_str, + " EAS %08lX\n", + nfc_scene_nfc_data_info_get_key(nfcv_data->sub_data.slix.key_eas)); + break; + case NfcVTypeSlixS: + furi_string_cat_printf(temp_str, "Type: SLIX-S\n"); + furi_string_cat_printf(temp_str, "Keys:\n"); + furi_string_cat_printf( + temp_str, + " Read %08lX\n", + nfc_scene_nfc_data_info_get_key(nfcv_data->sub_data.slix.key_read)); + furi_string_cat_printf( + temp_str, + " Write %08lX\n", + nfc_scene_nfc_data_info_get_key(nfcv_data->sub_data.slix.key_write)); + furi_string_cat_printf( + temp_str, + " Privacy %08lX\n", + nfc_scene_nfc_data_info_get_key(nfcv_data->sub_data.slix.key_privacy)); + furi_string_cat_printf( + temp_str, + " Destroy %08lX\n", + nfc_scene_nfc_data_info_get_key(nfcv_data->sub_data.slix.key_destroy)); + furi_string_cat_printf( + temp_str, + " EAS %08lX\n", + nfc_scene_nfc_data_info_get_key(nfcv_data->sub_data.slix.key_eas)); + break; + case NfcVTypeSlixL: + furi_string_cat_printf(temp_str, "Type: SLIX-L\n"); + furi_string_cat_printf(temp_str, "Keys:\n"); + furi_string_cat_printf( + temp_str, + " Privacy %08lX\n", + nfc_scene_nfc_data_info_get_key(nfcv_data->sub_data.slix.key_privacy)); + furi_string_cat_printf( + temp_str, + " Destroy %08lX\n", + nfc_scene_nfc_data_info_get_key(nfcv_data->sub_data.slix.key_destroy)); + furi_string_cat_printf( + temp_str, + " EAS %08lX\n", + nfc_scene_nfc_data_info_get_key(nfcv_data->sub_data.slix.key_eas)); + break; + case NfcVTypeSlix2: + furi_string_cat_printf(temp_str, "Type: SLIX2\n"); + furi_string_cat_printf(temp_str, "Keys:\n"); + furi_string_cat_printf( + temp_str, + " Read %08lX\n", + nfc_scene_nfc_data_info_get_key(nfcv_data->sub_data.slix.key_read)); + furi_string_cat_printf( + temp_str, + " Write %08lX\n", + nfc_scene_nfc_data_info_get_key(nfcv_data->sub_data.slix.key_write)); + furi_string_cat_printf( + temp_str, + " Privacy %08lX\n", + nfc_scene_nfc_data_info_get_key(nfcv_data->sub_data.slix.key_privacy)); + furi_string_cat_printf( + temp_str, + " Destroy %08lX\n", + nfc_scene_nfc_data_info_get_key(nfcv_data->sub_data.slix.key_destroy)); + furi_string_cat_printf( + temp_str, + " EAS %08lX\n", + nfc_scene_nfc_data_info_get_key(nfcv_data->sub_data.slix.key_eas)); + break; + default: + furi_string_cat_printf(temp_str, "\e#ISO15693 (unknown)\n"); + break; + } + } else { + char iso_type = FURI_BIT(nfc_data->sak, 5) ? '4' : '3'; + furi_string_cat_printf(temp_str, "ISO 14443-%c (NFC-A)\n", iso_type); + furi_string_cat_printf(temp_str, "UID:"); + for(size_t i = 0; i < nfc_data->uid_len; i++) { + furi_string_cat_printf(temp_str, " %02X", nfc_data->uid[i]); + } + furi_string_cat_printf( + temp_str, "\nATQA: %02X %02X ", nfc_data->atqa[1], nfc_data->atqa[0]); + furi_string_cat_printf(temp_str, " SAK: %02X", nfc_data->sak); } - furi_string_cat_printf(temp_str, "\nATQA: %02X %02X ", nfc_data->atqa[1], nfc_data->atqa[0]); - furi_string_cat_printf(temp_str, " SAK: %02X", nfc_data->sak); // Set application specific data if(protocol == NfcDeviceProtocolMifareDesfire) { @@ -136,6 +287,9 @@ bool nfc_scene_nfc_data_info_on_event(void* context, SceneManagerEvent event) { } else if(protocol == NfcDeviceProtocolMifareUl) { scene_manager_next_scene(nfc->scene_manager, NfcSceneMfUltralightData); consumed = true; + } else if(protocol == NfcDeviceProtocolNfcV) { + scene_manager_next_scene(nfc->scene_manager, NfcSceneNfcVMenu); + consumed = true; } } } diff --git a/applications/main/nfc/scenes/nfc_scene_nfcv_key_input.c b/applications/main/nfc/scenes/nfc_scene_nfcv_key_input.c new file mode 100644 index 000000000..cc53c4dcb --- /dev/null +++ b/applications/main/nfc/scenes/nfc_scene_nfcv_key_input.c @@ -0,0 +1,48 @@ +#include "../nfc_i.h" +#include + +void nfc_scene_nfcv_key_input_byte_input_callback(void* context) { + Nfc* nfc = context; + NfcVSlixData* data = &nfc->dev->dev_data.nfcv_data.sub_data.slix; + + memcpy(data->key_privacy, nfc->byte_input_store, 4); + view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventByteInputDone); +} + +void nfc_scene_nfcv_key_input_on_enter(void* context) { + Nfc* nfc = context; + + // Setup view + ByteInput* byte_input = nfc->byte_input; + byte_input_set_header_text(byte_input, "Enter The Password In Hex"); + byte_input_set_result_callback( + byte_input, + nfc_scene_nfcv_key_input_byte_input_callback, + NULL, + nfc, + nfc->byte_input_store, + 4); + view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewByteInput); +} + +bool nfc_scene_nfcv_key_input_on_event(void* context, SceneManagerEvent event) { + Nfc* nfc = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == NfcCustomEventByteInputDone) { + scene_manager_next_scene(nfc->scene_manager, NfcSceneNfcVUnlock); + DOLPHIN_DEED(DolphinDeedNfcRead); + consumed = true; + } + } + return consumed; +} + +void nfc_scene_nfcv_key_input_on_exit(void* context) { + Nfc* nfc = context; + + // Clear view + byte_input_set_result_callback(nfc->byte_input, NULL, NULL, NULL, NULL, 0); + byte_input_set_header_text(nfc->byte_input, ""); +} diff --git a/applications/main/nfc/scenes/nfc_scene_nfcv_menu.c b/applications/main/nfc/scenes/nfc_scene_nfcv_menu.c new file mode 100644 index 000000000..b30495a05 --- /dev/null +++ b/applications/main/nfc/scenes/nfc_scene_nfcv_menu.c @@ -0,0 +1,63 @@ +#include "../nfc_i.h" +#include + +enum SubmenuIndex { + SubmenuIndexSave, + SubmenuIndexEmulate, +}; + +void nfc_scene_nfcv_menu_submenu_callback(void* context, uint32_t index) { + Nfc* nfc = context; + + view_dispatcher_send_custom_event(nfc->view_dispatcher, index); +} + +void nfc_scene_nfcv_menu_on_enter(void* context) { + Nfc* nfc = context; + Submenu* submenu = nfc->submenu; + + submenu_add_item(submenu, "Save", SubmenuIndexSave, nfc_scene_nfcv_menu_submenu_callback, nfc); + submenu_add_item( + submenu, "Emulate", SubmenuIndexEmulate, nfc_scene_nfcv_menu_submenu_callback, nfc); + + submenu_set_selected_item( + nfc->submenu, scene_manager_get_scene_state(nfc->scene_manager, NfcSceneNfcVMenu)); + + view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewMenu); +} + +bool nfc_scene_nfcv_menu_on_event(void* context, SceneManagerEvent event) { + Nfc* nfc = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == SubmenuIndexSave) { + nfc->dev->format = NfcDeviceSaveFormatNfcV; + // Clear device name + nfc_device_set_name(nfc->dev, ""); + scene_manager_next_scene(nfc->scene_manager, NfcSceneSaveName); + consumed = true; + } else if(event.event == SubmenuIndexEmulate) { + scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateNfcV); + if(scene_manager_has_previous_scene(nfc->scene_manager, NfcSceneSetType)) { + DOLPHIN_DEED(DolphinDeedNfcAddEmulate); + } else { + DOLPHIN_DEED(DolphinDeedNfcEmulate); + } + consumed = true; + } + scene_manager_set_scene_state(nfc->scene_manager, NfcSceneNfcVMenu, event.event); + + } else if(event.type == SceneManagerEventTypeBack) { + consumed = scene_manager_previous_scene(nfc->scene_manager); + } + + return consumed; +} + +void nfc_scene_nfcv_menu_on_exit(void* context) { + Nfc* nfc = context; + + // Clear view + submenu_reset(nfc->submenu); +} diff --git a/applications/main/nfc/scenes/nfc_scene_nfcv_unlock.c b/applications/main/nfc/scenes/nfc_scene_nfcv_unlock.c new file mode 100644 index 000000000..b52cc0caa --- /dev/null +++ b/applications/main/nfc/scenes/nfc_scene_nfcv_unlock.c @@ -0,0 +1,155 @@ +#include "../nfc_i.h" +#include + +typedef enum { + NfcSceneNfcVUnlockStateIdle, + NfcSceneNfcVUnlockStateDetecting, + NfcSceneNfcVUnlockStateUnlocked, + NfcSceneNfcVUnlockStateAlreadyUnlocked, + NfcSceneNfcVUnlockStateNotSupportedCard, +} NfcSceneNfcVUnlockState; + +static bool nfc_scene_nfcv_unlock_worker_callback(NfcWorkerEvent event, void* context) { + Nfc* nfc = context; + NfcVSlixData* data = &nfc->dev->dev_data.nfcv_data.sub_data.slix; + + if(event == NfcWorkerEventNfcVPassKey) { + memcpy(data->key_privacy, nfc->byte_input_store, 4); + } else { + view_dispatcher_send_custom_event(nfc->view_dispatcher, event); + } + return true; +} + +void nfc_scene_nfcv_unlock_popup_callback(void* context) { + Nfc* nfc = context; + view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventViewExit); +} + +void nfc_scene_nfcv_unlock_set_state(Nfc* nfc, NfcSceneNfcVUnlockState state) { + FuriHalNfcDevData* nfc_data = &(nfc->dev->dev_data.nfc_data); + NfcVData* nfcv_data = &(nfc->dev->dev_data.nfcv_data); + + uint32_t curr_state = scene_manager_get_scene_state(nfc->scene_manager, NfcSceneNfcVUnlock); + if(curr_state != state) { + Popup* popup = nfc->popup; + if(state == NfcSceneNfcVUnlockStateDetecting) { + popup_reset(popup); + popup_set_text( + popup, "Put figurine on\nFlipper's back", 97, 24, AlignCenter, AlignTop); + popup_set_icon(popup, 0, 8, &I_NFC_manual_60x50); + } else if(state == NfcSceneNfcVUnlockStateUnlocked) { + popup_reset(popup); + + if(nfc_worker_get_state(nfc->worker) == NfcWorkerStateNfcVUnlockAndSave) { + nfc_text_store_set( + nfc, + "%s/SLIX_%02X%02X%02X%02X%02X%02X%02X%02X%s", + NFC_APP_FOLDER, + nfc_data->uid[0], + nfc_data->uid[1], + nfc_data->uid[2], + nfc_data->uid[3], + nfc_data->uid[4], + nfc_data->uid[5], + nfc_data->uid[6], + nfc_data->uid[7], + NFC_APP_EXTENSION); + + nfc->dev->format = NfcDeviceSaveFormatNfcV; + + if(nfc_device_save(nfc->dev, nfc->text_store)) { + popup_set_header(popup, "Successfully\nsaved", 94, 3, AlignCenter, AlignTop); + } else { + popup_set_header( + popup, "Unlocked but\nsave failed!", 94, 3, AlignCenter, AlignTop); + } + } else { + popup_set_header(popup, "Successfully\nunlocked", 94, 3, AlignCenter, AlignTop); + } + + notification_message(nfc->notifications, &sequence_single_vibro); + //notification_message(nfc->notifications, &sequence_success); + + popup_set_icon(popup, 0, 6, &I_RFIDDolphinSuccess_108x57); + popup_set_context(popup, nfc); + popup_set_callback(popup, nfc_scene_nfcv_unlock_popup_callback); + popup_set_timeout(popup, 1500); + + view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup); + DOLPHIN_DEED(DolphinDeedNfcReadSuccess); + + } else if(state == NfcSceneNfcVUnlockStateAlreadyUnlocked) { + popup_reset(popup); + + popup_set_header(popup, "Already\nUnlocked!", 94, 3, AlignCenter, AlignTop); + popup_set_icon(popup, 0, 6, &I_RFIDDolphinSuccess_108x57); + popup_set_context(popup, nfc); + popup_set_callback(popup, nfc_scene_nfcv_unlock_popup_callback); + popup_set_timeout(popup, 1500); + + view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup); + } else if(state == NfcSceneNfcVUnlockStateNotSupportedCard) { + popup_reset(popup); + popup_set_header(popup, "Wrong Type Of Card!", 64, 3, AlignCenter, AlignTop); + popup_set_text(popup, nfcv_data->error, 4, 22, AlignLeft, AlignTop); + popup_set_icon(popup, 73, 20, &I_DolphinCommon_56x48); + } + scene_manager_set_scene_state(nfc->scene_manager, NfcSceneNfcVUnlock, state); + } +} + +void nfc_scene_nfcv_unlock_on_enter(void* context) { + Nfc* nfc = context; + + nfc_device_clear(nfc->dev); + // Setup view + nfc_scene_nfcv_unlock_set_state(nfc, NfcSceneNfcVUnlockStateDetecting); + view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup); + + // Start worker + nfc_worker_start( + nfc->worker, + NfcWorkerStateNfcVUnlockAndSave, + &nfc->dev->dev_data, + nfc_scene_nfcv_unlock_worker_callback, + nfc); + + nfc_blink_read_start(nfc); +} + +bool nfc_scene_nfcv_unlock_on_event(void* context, SceneManagerEvent event) { + Nfc* nfc = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == NfcWorkerEventCardDetected) { + nfc_scene_nfcv_unlock_set_state(nfc, NfcSceneNfcVUnlockStateUnlocked); + consumed = true; + } else if(event.event == NfcWorkerEventAborted) { + nfc_scene_nfcv_unlock_set_state(nfc, NfcSceneNfcVUnlockStateAlreadyUnlocked); + consumed = true; + } else if(event.event == NfcWorkerEventNoCardDetected) { + nfc_scene_nfcv_unlock_set_state(nfc, NfcSceneNfcVUnlockStateDetecting); + consumed = true; + } else if(event.event == NfcWorkerEventWrongCardDetected) { + nfc_scene_nfcv_unlock_set_state(nfc, NfcSceneNfcVUnlockStateNotSupportedCard); + } + } else if(event.type == SceneManagerEventTypeBack) { + consumed = scene_manager_search_and_switch_to_previous_scene( + nfc->scene_manager, NfcSceneNfcVUnlockMenu); + } + return consumed; +} + +void nfc_scene_nfcv_unlock_on_exit(void* context) { + Nfc* nfc = context; + + // Stop worker + nfc_worker_stop(nfc->worker); + // Clear view + popup_reset(nfc->popup); + nfc_blink_stop(nfc); + scene_manager_set_scene_state( + nfc->scene_manager, NfcSceneNfcVUnlock, NfcSceneNfcVUnlockStateIdle); +} diff --git a/applications/main/nfc/scenes/nfc_scene_nfcv_unlock_menu.c b/applications/main/nfc/scenes/nfc_scene_nfcv_unlock_menu.c new file mode 100644 index 000000000..9c4c81fbd --- /dev/null +++ b/applications/main/nfc/scenes/nfc_scene_nfcv_unlock_menu.c @@ -0,0 +1,60 @@ +#include "../nfc_i.h" +#include + +enum SubmenuIndex { + SubmenuIndexNfcVUnlockMenuManual, + SubmenuIndexNfcVUnlockMenuTonieBox, +}; + +void nfc_scene_nfcv_unlock_menu_submenu_callback(void* context, uint32_t index) { + Nfc* nfc = context; + + view_dispatcher_send_custom_event(nfc->view_dispatcher, index); +} + +void nfc_scene_nfcv_unlock_menu_on_enter(void* context) { + Nfc* nfc = context; + Submenu* submenu = nfc->submenu; + + uint32_t state = scene_manager_get_scene_state(nfc->scene_manager, NfcSceneNfcVUnlockMenu); + submenu_add_item( + submenu, + "Enter PWD Manually", + SubmenuIndexNfcVUnlockMenuManual, + nfc_scene_nfcv_unlock_menu_submenu_callback, + nfc); + submenu_add_item( + submenu, + "Auth As TonieBox", + SubmenuIndexNfcVUnlockMenuTonieBox, + nfc_scene_nfcv_unlock_menu_submenu_callback, + nfc); + submenu_set_selected_item(submenu, state); + view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewMenu); +} + +bool nfc_scene_nfcv_unlock_menu_on_event(void* context, SceneManagerEvent event) { + Nfc* nfc = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == SubmenuIndexNfcVUnlockMenuManual) { + nfc->dev->dev_data.nfcv_data.auth_method = NfcVAuthMethodManual; + scene_manager_next_scene(nfc->scene_manager, NfcSceneNfcVKeyInput); + consumed = true; + } else if(event.event == SubmenuIndexNfcVUnlockMenuTonieBox) { + nfc->dev->dev_data.nfcv_data.auth_method = NfcVAuthMethodTonieBox; + scene_manager_next_scene(nfc->scene_manager, NfcSceneNfcVUnlock); + DOLPHIN_DEED(DolphinDeedNfcRead); + consumed = true; + } + scene_manager_set_scene_state(nfc->scene_manager, NfcSceneNfcVUnlockMenu, event.event); + } + return consumed; +} + +void nfc_scene_nfcv_unlock_menu_on_exit(void* context) { + Nfc* nfc = context; + + submenu_reset(nfc->submenu); +} diff --git a/applications/main/nfc/scenes/nfc_scene_passport_auth.c b/applications/main/nfc/scenes/nfc_scene_passport_auth.c new file mode 100644 index 000000000..c90c38233 --- /dev/null +++ b/applications/main/nfc/scenes/nfc_scene_passport_auth.c @@ -0,0 +1,194 @@ +#include "../nfc_i.h" + +#define TAG "PassportAuth" + +#define MRTD_AUTH_METHOD_COUNT 4 +// Must match MrtdAuthMethod size (lib/nfc/protocols/mrtd_helpers.h) + +typedef enum { + NfcScenePassportAuthSelectDob, + NfcScenePassportAuthSelectDoe, + NfcScenePassportAuthSelectDocNr, + NfcScenePassportAuthSelectMethod, + NfcScenePassportAuthSelectAuth, + NfcScenePassportAuthSelectSave, + NfcScenePassportAuthSelectLoad, +} NfcScenePassportAuthSelect; + +void nfc_scene_passport_auth_var_list_enter_callback(void* context, uint32_t index) { + Nfc* nfc = context; + view_dispatcher_send_custom_event(nfc->view_dispatcher, index); +} + +void nfc_scene_passport_auth_method_changed(VariableItem* item) { + Nfc* nfc = variable_item_get_context(item); + uint8_t index = variable_item_get_current_value_index(item); + nfc->dev->dev_data.mrtd_data.auth.method = index; + variable_item_set_current_value_text(item, mrtd_auth_method_string(index)); +} + +bool nfc_scene_passport_auth_load(Nfc* nfc) { + const DialogsFileBrowserOptions browser_options = { + .extension = MRTD_APP_EXTENSION, + .skip_assets = true, + .icon = &I_u2f_10px, + .hide_ext = true, + .item_loader_callback = NULL, + .item_loader_context = NULL, + }; + + FuriString* mrtd_app_folder; + mrtd_app_folder = furi_string_alloc_set(MRTD_APP_FOLDER); + + FuriString* file_path; + file_path = furi_string_alloc(); + + bool res = + dialog_file_browser_show(nfc->dev->dialogs, file_path, mrtd_app_folder, &browser_options); + + furi_string_free(mrtd_app_folder); + + if(res) { + mrtd_auth_params_load( + nfc->dev->storage, + nfc->dev->dialogs, + &nfc->dev->dev_data.mrtd_data.auth, + furi_string_get_cstr(file_path), + true); + + nfc_scene_passport_auth_on_enter(nfc); + variable_item_list_set_selected_item( + nfc->variable_item_list, NfcScenePassportAuthSelectAuth); + } + + return res; +} + +void nfc_scene_passport_auth_on_enter(void* context) { + Nfc* nfc = context; + MrtdData* mrtd_data = &nfc->dev->dev_data.mrtd_data; + + // By entering the Auth menu, we default to Auth: Any + MrtdAuthMethod* auth_method = &mrtd_data->auth.method; + if(*auth_method == MrtdAuthMethodNone) { + *auth_method = MrtdAuthMethodAny; + } + + VariableItemList* variable_item_list = nfc->variable_item_list; + variable_item_list_reset(variable_item_list); + + VariableItem* item; + uint8_t value_index; + + const size_t temp_str_size = 15; + char temp_str[temp_str_size]; + snprintf( + temp_str, + temp_str_size, + "%02u%02u%02u", + mrtd_data->auth.birth_date.year, + mrtd_data->auth.birth_date.month, + mrtd_data->auth.birth_date.day); + + item = variable_item_list_add(variable_item_list, "Birth Date", 1, NULL, NULL); + variable_item_set_current_value_text(item, temp_str); + + snprintf( + temp_str, + temp_str_size, + "%02u%02u%02u", + mrtd_data->auth.expiry_date.year, + mrtd_data->auth.expiry_date.month, + mrtd_data->auth.expiry_date.day); + + item = variable_item_list_add(variable_item_list, "Expiry Date", 1, NULL, NULL); + variable_item_set_current_value_text(item, temp_str); + + item = variable_item_list_add(variable_item_list, "Document Nr.", 1, NULL, NULL); + + strncpy(temp_str, mrtd_data->auth.doc_number, temp_str_size); + temp_str[temp_str_size -1] = '\x00'; + if(strlen(temp_str) > 8) { + temp_str[8] = '.'; + temp_str[9] = '.'; + temp_str[10] = '.'; + temp_str[11] = '\x00'; + } + variable_item_set_current_value_text(item, temp_str); + + item = variable_item_list_add( + variable_item_list, + "Method", + MRTD_AUTH_METHOD_COUNT, + nfc_scene_passport_auth_method_changed, + nfc); + + value_index = *auth_method; + variable_item_set_current_value_index(item, value_index); + variable_item_set_current_value_text(item, mrtd_auth_method_string(value_index)); + + variable_item_list_add(variable_item_list, "Authenticate and read", 1, NULL, NULL); + + variable_item_list_add(variable_item_list, "Save parameters", 1, NULL, NULL); + variable_item_list_add(variable_item_list, "Load parameters", 1, NULL, NULL); + + variable_item_list_set_enter_callback( + variable_item_list, nfc_scene_passport_auth_var_list_enter_callback, nfc); + view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewVarItemList); +} + +bool nfc_scene_passport_auth_on_event(void* context, SceneManagerEvent event) { + Nfc* nfc = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + FURI_LOG_D(TAG, "event.event: %ld", event.event); + switch(event.event) { + case NfcScenePassportAuthSelectLoad: + nfc_scene_passport_auth_load(nfc); + consumed = true; + break; + case NfcScenePassportAuthSelectDob: + scene_manager_set_scene_state(nfc->scene_manager, NfcScenePassportDate, 0); + scene_manager_next_scene(nfc->scene_manager, NfcScenePassportDate); + consumed = true; + break; + case NfcScenePassportAuthSelectDoe: + scene_manager_set_scene_state(nfc->scene_manager, NfcScenePassportDate, 1); + scene_manager_next_scene(nfc->scene_manager, NfcScenePassportDate); + consumed = true; + break; + case NfcScenePassportAuthSelectDocNr: + scene_manager_next_scene(nfc->scene_manager, NfcScenePassportDocNr); + consumed = true; + break; + case NfcScenePassportAuthSelectMethod: + consumed = true; + break; + case NfcScenePassportAuthSelectAuth: + if(nfc->dev->dev_data.mrtd_data.auth.method == MrtdAuthMethodPace) { + scene_manager_next_scene(nfc->scene_manager, NfcScenePassportPaceTodo); + } else { + nfc_device_clear(nfc->dev); + scene_manager_next_scene(nfc->scene_manager, NfcSceneRead); + } + consumed = true; + break; + case NfcScenePassportAuthSelectSave: + scene_manager_next_scene(nfc->scene_manager, NfcScenePassportAuthSaveName); + consumed = true; + break; + } + } else if(event.type == SceneManagerEventTypeBack) { + consumed = scene_manager_previous_scene(nfc->scene_manager); + } + + return consumed; +} + +void nfc_scene_passport_auth_on_exit(void* context) { + Nfc* nfc = context; + + // Clear view + variable_item_list_reset(nfc->variable_item_list); +} diff --git a/applications/main/nfc/scenes/nfc_scene_passport_auth_save_name.c b/applications/main/nfc/scenes/nfc_scene_passport_auth_save_name.c new file mode 100644 index 000000000..65fee0bcf --- /dev/null +++ b/applications/main/nfc/scenes/nfc_scene_passport_auth_save_name.c @@ -0,0 +1,82 @@ +#include "../nfc_i.h" +#include +#include +#include + +void nfc_scene_passport_auth_save_name_text_input_callback(void* context) { + Nfc* nfc = context; + + view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventTextInputDone); +} + +void nfc_scene_passport_auth_save_name_on_enter(void* context) { + Nfc* nfc = context; + + MrtdData* mrtd_data = &nfc->dev->dev_data.mrtd_data; + + // Setup view + TextInput* text_input = nfc->text_input; + bool docnr_empty = false; + if(!strcmp(mrtd_data->auth.doc_number, "")) { + set_random_name(nfc->text_store, sizeof(nfc->text_store)); + docnr_empty = true; + } else { + nfc_text_store_set(nfc, mrtd_data->auth.doc_number); + } + text_input_set_header_text(text_input, "Name the parameters"); + text_input_set_result_callback( + text_input, + nfc_scene_passport_auth_save_name_text_input_callback, + nfc, + nfc->text_store, + NFC_DEV_NAME_MAX_LEN, + docnr_empty); + + FuriString* folder_path; + folder_path = furi_string_alloc(); + + if(furi_string_end_with(nfc->dev->load_path, NFC_APP_EXTENSION)) { + path_extract_dirname(furi_string_get_cstr(nfc->dev->load_path), folder_path); + } else { + furi_string_set(folder_path, NFC_APP_FOLDER); + } + + ValidatorIsFile* validator_is_file = + validator_is_file_alloc_init(furi_string_get_cstr(folder_path), NFC_APP_EXTENSION, NULL); + text_input_set_validator(text_input, validator_is_file_callback, validator_is_file); + + view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewTextInput); + + furi_string_free(folder_path); +} + +bool nfc_scene_passport_auth_save_name_on_event(void* context, SceneManagerEvent event) { + Nfc* nfc = context; + MrtdData* mrtd_data = &nfc->dev->dev_data.mrtd_data; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == NfcCustomEventTextInputDone) { + if(mrtd_auth_params_save( + nfc->dev->storage, nfc->dev->dialogs, &mrtd_data->auth, nfc->text_store)) { + scene_manager_next_scene(nfc->scene_manager, NfcSceneSaveSuccess); + consumed = true; + } else { + consumed = scene_manager_search_and_switch_to_previous_scene( + nfc->scene_manager, NfcSceneStart); + } + } + } + return consumed; +} + +void nfc_scene_passport_auth_save_name_on_exit(void* context) { + Nfc* nfc = context; + + // Clear view + void* validator_context = text_input_get_validator_callback_context(nfc->text_input); + text_input_set_validator(nfc->text_input, NULL, NULL); + validator_is_file_free(validator_context); + + text_input_reset(nfc->text_input); +} diff --git a/applications/main/nfc/scenes/nfc_scene_passport_date.c b/applications/main/nfc/scenes/nfc_scene_passport_date.c new file mode 100644 index 000000000..6655bdd59 --- /dev/null +++ b/applications/main/nfc/scenes/nfc_scene_passport_date.c @@ -0,0 +1,126 @@ +#include "../nfc_i.h" +#include "m-string.h" +#include + +#define TAG "PassportDate" + +#define DATE_LENGTH 6 + +//TODO: use types in .h file? also in nfc_scene_passport_bac.c +#define NFC_PASSPORT_DATE_BIRTH 0 +#define NFC_PASSPORT_DATE_EXPIRY 1 + +void nfc_scene_passport_date_text_input_callback(void* context) { + Nfc* nfc = context; + + view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventTextInputDone); +} + +void nfc_scene_passport_date_on_enter(void* context) { + Nfc* nfc = context; + + MrtdDate date_value; + + uint32_t date_type = scene_manager_get_scene_state(nfc->scene_manager, NfcScenePassportDate); + + //TODO: numbers only + TextInput* text_input = nfc->text_input; + + // TODO: Clean this up because I'm bad + date_value.year = 0; + date_value.month = 0; + date_value.day = 0; + + + switch(date_type) { + case NFC_PASSPORT_DATE_BIRTH: + text_input_set_header_text(text_input, "Birth Date"); + date_value = nfc->dev->dev_data.mrtd_data.auth.birth_date; + break; + case NFC_PASSPORT_DATE_EXPIRY: + text_input_set_header_text(text_input, "Expiry Date"); + date_value = nfc->dev->dev_data.mrtd_data.auth.expiry_date; + break; + } + + bool date_empty = false; + if(date_value.year == 0 || date_value.month == 0 || date_value.day == 0 || + date_value.year > 100 || date_value.month > 13 || date_value.day > 31) { + nfc_text_store_set(nfc, "YYMMDD"); + date_empty = true; + } else { + char temp_str[10]; + snprintf(temp_str, 10, "%02u%02u%02u", date_value.year, date_value.month, date_value.day); + + memcpy(nfc->text_store, temp_str, DATE_LENGTH); + nfc->text_store[DATE_LENGTH] = '\x00'; + } + + text_input_set_result_callback( + text_input, + nfc_scene_passport_date_text_input_callback, + nfc, + nfc->text_store, + DATE_LENGTH + 1, // incl. '\x00' + date_empty); // Use as template + + //TODO: add validator for valid date (YYMMDD) + + view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewTextInput); +} + +bool nfc_scene_passport_date_save(Nfc* nfc) { + int year; + int month; + int day; + int ret = sscanf(nfc->text_store, "%02d%02d%02d", &year, &month, &day); + + if(ret != 3) { + FURI_LOG_E(TAG, "Invalid date entered (YYMMDD): %s", nfc->text_store); + return false; + } + + MrtdDate date_value; + date_value.year = year; + date_value.month = month; + date_value.day = day; + + uint32_t date_type = scene_manager_get_scene_state(nfc->scene_manager, NfcScenePassportDate); + + //TODO: use types in .h file? also in nfc_scene_passport_bac.c + switch(date_type) { + case NFC_PASSPORT_DATE_BIRTH: + nfc->dev->dev_data.mrtd_data.auth.birth_date = date_value; + break; + case NFC_PASSPORT_DATE_EXPIRY: + nfc->dev->dev_data.mrtd_data.auth.expiry_date = date_value; + break; + } + + return true; +} + +bool nfc_scene_passport_date_on_event(void* context, SceneManagerEvent event) { + Nfc* nfc = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == NfcCustomEventTextInputDone) { + nfc_scene_passport_date_save(nfc); + //TODO: handle invalid date (returned false) + + consumed = scene_manager_search_and_switch_to_previous_scene( + nfc->scene_manager, NfcScenePassportAuth); + } + } + return consumed; +} + +void nfc_scene_passport_date_on_exit(void* context) { + Nfc* nfc = context; + + // Clear view + // TODO: clear validator + + text_input_reset(nfc->text_input); +} diff --git a/applications/main/nfc/scenes/nfc_scene_passport_docnr.c b/applications/main/nfc/scenes/nfc_scene_passport_docnr.c new file mode 100644 index 000000000..109415759 --- /dev/null +++ b/applications/main/nfc/scenes/nfc_scene_passport_docnr.c @@ -0,0 +1,67 @@ +#include "../nfc_i.h" +#include "m-string.h" +#include + +#define TAG "PassportDocnr" + +void nfc_scene_passport_docnr_text_input_callback(void* context) { + Nfc* nfc = context; + + view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventTextInputDone); +} + +void nfc_scene_passport_docnr_on_enter(void* context) { + Nfc* nfc = context; + + TextInput* text_input = nfc->text_input; + text_input_set_header_text(text_input, "Document Nr."); + + char* docnr = nfc->dev->dev_data.mrtd_data.auth.doc_number; + bool docnr_empty = false; + + if(*docnr) { + nfc_text_store_set(nfc, docnr); + docnr_empty = false; + } else { + nfc_text_store_set(nfc, "PA7HJ34M8"); + docnr_empty = true; + } + + text_input_set_result_callback( + text_input, + nfc_scene_passport_docnr_text_input_callback, + nfc, + nfc->text_store, + MRTD_DOCNR_MAX_LENGTH, // incl. '\x00' + docnr_empty); // Use as template + + //TODO: add validator? + + view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewTextInput); +} + +bool nfc_scene_passport_docnr_save(Nfc* nfc) { + strncpy(nfc->dev->dev_data.mrtd_data.auth.doc_number, nfc->text_store, MRTD_DOCNR_MAX_LENGTH); + return true; +} + +bool nfc_scene_passport_docnr_on_event(void* context, SceneManagerEvent event) { + Nfc* nfc = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == NfcCustomEventTextInputDone) { + nfc_scene_passport_docnr_save(nfc); + + consumed = scene_manager_search_and_switch_to_previous_scene( + nfc->scene_manager, NfcScenePassportAuth); + } + } + return consumed; +} + +void nfc_scene_passport_docnr_on_exit(void* context) { + Nfc* nfc = context; + + text_input_reset(nfc->text_input); +} diff --git a/applications/main/nfc/scenes/nfc_scene_passport_menu.c b/applications/main/nfc/scenes/nfc_scene_passport_menu.c new file mode 100644 index 000000000..27febcb18 --- /dev/null +++ b/applications/main/nfc/scenes/nfc_scene_passport_menu.c @@ -0,0 +1,57 @@ +#include "../nfc_i.h" + +enum SubmenuIndex { + SubmenuIndexSave, + SubmenuIndexInfo, +}; + +void nfc_scene_passport_menu_submenu_callback(void* context, uint32_t index) { + Nfc* nfc = context; + + view_dispatcher_send_custom_event(nfc->view_dispatcher, index); +} + +void nfc_scene_passport_menu_on_enter(void* context) { + Nfc* nfc = context; + Submenu* submenu = nfc->submenu; + + submenu_add_item( + submenu, "Save", SubmenuIndexSave, nfc_scene_passport_menu_submenu_callback, nfc); + submenu_add_item( + submenu, "Info", SubmenuIndexInfo, nfc_scene_passport_menu_submenu_callback, nfc); + submenu_set_selected_item( + nfc->submenu, scene_manager_get_scene_state(nfc->scene_manager, NfcScenePassportMenu)); + + view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewMenu); +} + +bool nfc_scene_passport_menu_on_event(void* context, SceneManagerEvent event) { + Nfc* nfc = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == SubmenuIndexSave) { + //TODO: save more than just UID + nfc->dev->format = NfcDeviceSaveFormatUid; + // Clear device name + nfc_device_set_name(nfc->dev, ""); + scene_manager_next_scene(nfc->scene_manager, NfcSceneSaveName); + consumed = true; + } else if(event.event == SubmenuIndexInfo) { + scene_manager_next_scene(nfc->scene_manager, NfcSceneNfcDataInfo); + consumed = true; + } + scene_manager_set_scene_state(nfc->scene_manager, NfcScenePassportMenu, event.event); + } else if(event.type == SceneManagerEventTypeBack) { + consumed = scene_manager_previous_scene(nfc->scene_manager); + } + + return consumed; +} + +void nfc_scene_passport_menu_on_exit(void* context) { + Nfc* nfc = context; + + // Clear view + submenu_reset(nfc->submenu); +} diff --git a/applications/main/nfc/scenes/nfc_scene_passport_pace_todo.c b/applications/main/nfc/scenes/nfc_scene_passport_pace_todo.c new file mode 100644 index 000000000..c6d7d7f6c --- /dev/null +++ b/applications/main/nfc/scenes/nfc_scene_passport_pace_todo.c @@ -0,0 +1,40 @@ +#include "../nfc_i.h" + +void nfc_scene_passport_pace_todo_popup_callback(void* context) { + Nfc* nfc = context; + view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventViewExit); +} + +void nfc_scene_passport_pace_todo_on_enter(void* context) { + Nfc* nfc = context; + + // Setup view + Popup* popup = nfc->popup; + popup_set_icon(popup, 64, 16, &I_DolphinCommon_56x48); + popup_set_header(popup, "PACE not yet implemented", 4, 4, AlignLeft, AlignTop); + popup_set_timeout(popup, 2000); + popup_set_context(popup, nfc); + popup_set_callback(popup, nfc_scene_passport_pace_todo_popup_callback); + popup_enable_timeout(popup); + view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup); +} + +bool nfc_scene_passport_pace_todo_on_event(void* context, SceneManagerEvent event) { + Nfc* nfc = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == NfcCustomEventViewExit) { + consumed = scene_manager_search_and_switch_to_previous_scene( + nfc->scene_manager, NfcScenePassportAuth); + } + } + return consumed; +} + +void nfc_scene_passport_pace_todo_on_exit(void* context) { + Nfc* nfc = context; + + // Clear view + popup_reset(nfc->popup); +} diff --git a/applications/main/nfc/scenes/nfc_scene_passport_read.c b/applications/main/nfc/scenes/nfc_scene_passport_read.c new file mode 100644 index 000000000..74f173b52 --- /dev/null +++ b/applications/main/nfc/scenes/nfc_scene_passport_read.c @@ -0,0 +1,90 @@ +#include "../nfc_i.h" +#include + +void nfc_scene_passport_read_widget_callback(GuiButtonType result, InputType type, void* context) { + Nfc* nfc = context; + if(type == InputTypeShort) { + view_dispatcher_send_custom_event(nfc->view_dispatcher, result); + } +} + +void nfc_scene_passport_read_on_enter(void* context) { + Nfc* nfc = context; + FuriHalNfcDevData* data = &nfc->dev->dev_data.nfc_data; + MrtdData* mrtd_data = &nfc->dev->dev_data.mrtd_data; + + DOLPHIN_DEED(DolphinDeedNfcReadSuccess); + + Widget* widget = nfc->widget; + + // Setup Custom Widget view + FuriString* temp_str; + temp_str = furi_string_alloc(); + furi_string_set(temp_str, "\e#Passport\n"); + char iso_type = FURI_BIT(data->sak, 5) ? '4' : '3'; + + char nfc_type; + switch(data->type) { + case FuriHalNfcTypeA: + nfc_type = 'A'; + break; + case FuriHalNfcTypeB: + nfc_type = 'B'; + break; + default: + nfc_type = '?'; + break; + } + furi_string_cat_printf(temp_str, "ISO 14443-%c (NFC-%c)\n", iso_type, nfc_type); + furi_string_cat_printf(temp_str, "UID:"); + for(size_t i = 0; i < data->uid_len; i++) { + furi_string_cat_printf(temp_str, " %02X", data->uid[i]); + } + furi_string_cat_printf(temp_str, "\nATQA: %02X %02X ", data->atqa[1], data->atqa[0]); + furi_string_cat_printf(temp_str, " SAK: %02X\n", data->sak); + + if(mrtd_data->auth.method != MrtdAuthMethodNone && !mrtd_data->auth_success) { + furi_string_cat_printf(temp_str, "Auth failed. Wrong params?"); + } + + widget_add_text_scroll_element(widget, 0, 0, 128, 52, furi_string_get_cstr(temp_str)); + furi_string_free(temp_str); + + widget_add_button_element( + nfc->widget, GuiButtonTypeLeft, "Retry", nfc_scene_passport_read_widget_callback, nfc); + widget_add_button_element( + nfc->widget, GuiButtonTypeCenter, "Auth", nfc_scene_passport_read_widget_callback, nfc); + widget_add_button_element( + nfc->widget, GuiButtonTypeRight, "More", nfc_scene_passport_read_widget_callback, nfc); + + view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewWidget); +} + +bool nfc_scene_passport_read_on_event(void* context, SceneManagerEvent event) { + Nfc* nfc = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == GuiButtonTypeLeft) { + scene_manager_next_scene(nfc->scene_manager, NfcSceneRetryConfirm); + consumed = true; + } else if(event.event == GuiButtonTypeCenter) { + scene_manager_next_scene(nfc->scene_manager, NfcScenePassportAuth); + consumed = true; + } else if(event.event == GuiButtonTypeRight) { + scene_manager_next_scene(nfc->scene_manager, NfcScenePassportMenu); + consumed = true; + } + } else if(event.type == SceneManagerEventTypeBack) { + scene_manager_next_scene(nfc->scene_manager, NfcSceneExitConfirm); + consumed = true; + } + return consumed; +} + +void nfc_scene_passport_read_on_exit(void* context) { + Nfc* nfc = context; + + // Clear view + widget_reset(nfc->widget); +} diff --git a/applications/main/nfc/scenes/nfc_scene_passport_read_auth.c b/applications/main/nfc/scenes/nfc_scene_passport_read_auth.c new file mode 100644 index 000000000..31a9e8ce1 --- /dev/null +++ b/applications/main/nfc/scenes/nfc_scene_passport_read_auth.c @@ -0,0 +1,142 @@ +#include "../nfc_i.h" +#include + +const char months[13][4] = { + "---", + "JAN", + "FEB", + "MAR", + "APR", + "MAY", + "JUN", + "JUL", + "AUG", + "SEP", + "OCT", + "NOV", + "DEC", +}; + +void nfc_scene_passport_read_auth_widget_callback( + GuiButtonType result, + InputType type, + void* context) { + Nfc* nfc = context; + if(type == InputTypeShort) { + view_dispatcher_send_custom_event(nfc->view_dispatcher, result); + } +} + +void nfc_scene_passport_read_auth_on_enter(void* context) { + Nfc* nfc = context; + MrtdData* mrtd_data = &nfc->dev->dev_data.mrtd_data; + + Widget* widget = nfc->widget; + + // Setup Custom Widget view + FuriString* temp_str; + temp_str = furi_string_alloc(); + furi_string_set(temp_str, "\e#Passport\n"); + furi_string_cat_printf( + temp_str, "Auth.method: %s\n", mrtd_auth_method_string(mrtd_data->auth_method_used)); + // TODO: indicate BAC / PACE used + + uint16_t lds_version = mrtd_data->files.EF_COM.lds_version; + furi_string_cat_printf(temp_str, "LDS version: %d.%d\n", lds_version / 100, lds_version % 100); + + uint32_t unicode_version = mrtd_data->files.EF_COM.unicode_version; + furi_string_cat_printf( + temp_str, + "Unicode version: %d.%d.%d\n", + (uint8_t)(unicode_version / 10000), + (uint8_t)(unicode_version / 100 % 100), + (uint8_t)(unicode_version % 100)); + + furi_string_cat_printf(temp_str, "Avail.files: "); + for(size_t i = 0; i < MAX_EFCOM_TAGS; ++i) { + uint8_t tag = mrtd_data->files.EF_COM.tag_list[i]; + const EFFile* file = mrtd_tag_to_file(tag); + if(file->tag) { + if(i > 0) furi_string_cat_printf(temp_str, ", "); + furi_string_cat_printf(temp_str, "%s", file->name); + } + } + furi_string_cat_printf(temp_str, "\n"); + + EF_DIR_contents* EF_DIR = &mrtd_data->files.EF_DIR; + if(EF_DIR->applications_count > 0) { + furi_string_cat_printf(temp_str, "Apps:\n"); + for(uint8_t i = 0; i < EF_DIR->applications_count; ++i) { + for(uint8_t n = 0; n < sizeof(AIDValue); ++n) { + furi_string_cat_printf(temp_str, "%02X ", EF_DIR->applications[i][n]); + } + furi_string_cat_printf(temp_str, "\n"); + } + } + + EF_DG1_contents* DG1 = &mrtd_data->files.DG1; + furi_string_cat_printf(temp_str, "\e#DG1\n"); + furi_string_cat_printf(temp_str, "Doc Type: %s\n", DG1->doctype); + furi_string_cat_printf(temp_str, "Issuing State: %s\n", DG1->issuing_state); + furi_string_cat_printf(temp_str, "Name: %s\n", DG1->name); + furi_string_cat_printf(temp_str, "DocNr: %s\n", DG1->docnr); + furi_string_cat_printf(temp_str, "Nationality: %s\n", DG1->nationality); + furi_string_cat_printf( + temp_str, + "Birth Date: %02d %s %02d\n", + DG1->birth_date.day, + months[DG1->birth_date.month], + DG1->birth_date.year); + furi_string_cat_printf(temp_str, "Sex: %s\n", DG1->sex); + furi_string_cat_printf( + temp_str, + "Expiry Date: %02d %s %02d\n", + DG1->expiry_date.day, + months[DG1->expiry_date.month], + DG1->expiry_date.year); + + widget_add_text_scroll_element(widget, 0, 0, 128, 52, furi_string_get_cstr(temp_str)); + furi_string_free(temp_str); + + widget_add_button_element( + nfc->widget, GuiButtonTypeLeft, "Retry", nfc_scene_passport_read_auth_widget_callback, nfc); + /* + widget_add_button_element( + nfc->widget, GuiButtonTypeCenter, "Auth", nfc_scene_passport_read_auth_widget_callback, nfc); + widget_add_button_element( + nfc->widget, GuiButtonTypeRight, "More", nfc_scene_passport_read_auth_widget_callback, nfc); + */ + + view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewWidget); +} + +bool nfc_scene_passport_read_auth_on_event(void* context, SceneManagerEvent event) { + Nfc* nfc = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == GuiButtonTypeLeft) { + nfc->dev->dev_data.mrtd_data.auth_success = false; + nfc->dev->dev_data.mrtd_data.auth.method = MrtdAuthMethodNone; + scene_manager_next_scene(nfc->scene_manager, NfcSceneRetryConfirm); + consumed = true; + } else if(event.event == GuiButtonTypeCenter) { + //scene_manager_next_scene(nfc->scene_manager, NfcScenePassportAuth); + //consumed = true; + } else if(event.event == GuiButtonTypeRight) { + //scene_manager_next_scene(nfc->scene_manager, NfcScenePassportMenu); + //consumed = true; + } + } else if(event.type == SceneManagerEventTypeBack) { + scene_manager_next_scene(nfc->scene_manager, NfcSceneExitConfirm); + consumed = true; + } + return consumed; +} + +void nfc_scene_passport_read_auth_on_exit(void* context) { + Nfc* nfc = context; + + // Clear view + widget_reset(nfc->widget); +} diff --git a/applications/main/nfc/scenes/nfc_scene_read.c b/applications/main/nfc/scenes/nfc_scene_read.c index 4252883b2..7164a155f 100644 --- a/applications/main/nfc/scenes/nfc_scene_read.c +++ b/applications/main/nfc/scenes/nfc_scene_read.c @@ -25,12 +25,12 @@ void nfc_scene_read_set_state(Nfc* nfc, NfcSceneReadState state) { if(state == NfcSceneReadStateDetecting) { popup_reset(nfc->popup); popup_set_text( - nfc->popup, "Apply card to\nFlipper's back", 97, 24, AlignCenter, AlignTop); + nfc->popup, "Apply Card To\nFlipper's Back", 97, 24, AlignCenter, AlignTop); popup_set_icon(nfc->popup, 0, 8, &I_NFC_manual_60x50); } else if(state == NfcSceneReadStateReading) { popup_reset(nfc->popup); popup_set_header( - nfc->popup, "Reading card\nDon't move...", 85, 24, AlignCenter, AlignTop); + nfc->popup, "Reading Card\nDon't Move...", 85, 24, AlignCenter, AlignTop); popup_set_icon(nfc->popup, 12, 23, &A_Loading_24); } scene_manager_set_scene_state(nfc->scene_manager, NfcSceneRead, state); @@ -68,6 +68,11 @@ bool nfc_scene_read_on_event(void* context, SceneManagerEvent event) { scene_manager_next_scene(nfc->scene_manager, NfcSceneNfcaReadSuccess); DOLPHIN_DEED(DolphinDeedNfcReadSuccess); consumed = true; + } else if(event.event == NfcWorkerEventReadNfcV) { + notification_message(nfc->notifications, &sequence_success); + scene_manager_next_scene(nfc->scene_manager, NfcSceneNfcDataInfo); + DOLPHIN_DEED(DolphinDeedNfcReadSuccess); + consumed = true; } else if(event.event == NfcWorkerEventReadMfUltralight) { notification_message(nfc->notifications, &sequence_success); // Set unlock password input to 0xFFFFFFFF only on fresh read @@ -90,6 +95,19 @@ bool nfc_scene_read_on_event(void* context, SceneManagerEvent event) { scene_manager_next_scene(nfc->scene_manager, NfcSceneEmvReadSuccess); DOLPHIN_DEED(DolphinDeedNfcReadSuccess); consumed = true; + } else if(event.event == NfcWorkerEventReadPassport) { + notification_message(nfc->notifications, &sequence_success); + FURI_LOG_D( + "NFC", + "Read passport, auth: %d, success: %d", + nfc->dev->dev_data.mrtd_data.auth.method, + nfc->dev->dev_data.mrtd_data.auth_success); + if(nfc->dev->dev_data.mrtd_data.auth_success) { + scene_manager_next_scene(nfc->scene_manager, NfcScenePassportReadAuthSuccess); + } else { + scene_manager_next_scene(nfc->scene_manager, NfcScenePassportReadSuccess); + } + consumed = true; } else if(event.event == NfcWorkerEventReadMfClassicDictAttackRequired) { if(mf_classic_dict_check_presence(MfClassicDictTypeSystem)) { scene_manager_next_scene(nfc->scene_manager, NfcSceneMfClassicDictAttack); diff --git a/applications/main/nfc/scenes/nfc_scene_restore_original.c b/applications/main/nfc/scenes/nfc_scene_restore_original.c index 3709008fd..3ecf5c048 100644 --- a/applications/main/nfc/scenes/nfc_scene_restore_original.c +++ b/applications/main/nfc/scenes/nfc_scene_restore_original.c @@ -1,5 +1,4 @@ #include "../nfc_i.h" -#include "../../../settings/desktop_settings/desktop_settings_app.h" void nfc_scene_restore_original_popup_callback(void* context) { Nfc* nfc = context; @@ -8,24 +7,16 @@ void nfc_scene_restore_original_popup_callback(void* context) { void nfc_scene_restore_original_on_enter(void* context) { Nfc* nfc = context; - DesktopSettings* settings = malloc(sizeof(DesktopSettings)); - DESKTOP_SETTINGS_LOAD(settings); // Setup view Popup* popup = nfc->popup; - if (settings->sfw_mode) { - popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59_sfw); - } - else { - popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59); - } + popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59); popup_set_header(popup, "Original file\nrestored", 13, 22, AlignLeft, AlignBottom); popup_set_timeout(popup, 1500); popup_set_context(popup, nfc); popup_set_callback(popup, nfc_scene_restore_original_popup_callback); popup_enable_timeout(popup); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup); - free(settings); } bool nfc_scene_restore_original_on_event(void* context, SceneManagerEvent event) { diff --git a/applications/main/nfc/scenes/nfc_scene_rpc.c b/applications/main/nfc/scenes/nfc_scene_rpc.c index e0da1317c..d06ee7564 100644 --- a/applications/main/nfc/scenes/nfc_scene_rpc.c +++ b/applications/main/nfc/scenes/nfc_scene_rpc.c @@ -1,25 +1,17 @@ #include "../nfc_i.h" -#include "../../../settings/desktop_settings/desktop_settings_app.h" void nfc_scene_rpc_on_enter(void* context) { Nfc* nfc = context; Popup* popup = nfc->popup; - DesktopSettings* settings = malloc(sizeof(DesktopSettings)); - DESKTOP_SETTINGS_LOAD(settings); popup_set_header(popup, "NFC", 89, 42, AlignCenter, AlignBottom); popup_set_text(popup, "RPC mode", 89, 44, AlignCenter, AlignTop); - if (settings->sfw_mode) { - popup_set_icon(popup, 0, 12, &I_NFC_dolphin_emulation_47x61_sfw); - } - else { - popup_set_icon(popup, 0, 12, &I_NFC_dolphin_emulation_47x61); - } + + popup_set_icon(popup, 0, 12, &I_NFC_dolphin_emulation_47x61); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup); notification_message(nfc->notifications, &sequence_display_backlight_on); - free(settings); } static bool nfc_scene_rpc_emulate_callback(NfcWorkerEvent event, void* context) { @@ -63,6 +55,13 @@ bool nfc_scene_rpc_on_event(void* context, SceneManagerEvent event) { &nfc->dev->dev_data, nfc_scene_rpc_emulate_callback, nfc); + } else if(nfc->dev->format == NfcDeviceSaveFormatNfcV) { + nfc_worker_start( + nfc->worker, + NfcWorkerStateNfcVEmulate, + &nfc->dev->dev_data, + nfc_scene_rpc_emulate_callback, + nfc); } else { nfc_worker_start( nfc->worker, NfcWorkerStateUidEmulate, &nfc->dev->dev_data, NULL, nfc); diff --git a/applications/main/nfc/scenes/nfc_scene_save_name.c b/applications/main/nfc/scenes/nfc_scene_save_name.c index 007274226..8f0e889ec 100644 --- a/applications/main/nfc/scenes/nfc_scene_save_name.c +++ b/applications/main/nfc/scenes/nfc_scene_save_name.c @@ -22,7 +22,7 @@ void nfc_scene_save_name_on_enter(void* context) { } else { nfc_text_store_set(nfc, nfc->dev->dev_name); } - text_input_set_header_text(text_input, "Name the card"); + text_input_set_header_text(text_input, "Name The Card"); text_input_set_result_callback( text_input, nfc_scene_save_name_text_input_callback, diff --git a/applications/main/nfc/scenes/nfc_scene_save_success.c b/applications/main/nfc/scenes/nfc_scene_save_success.c index 8e74a55ae..43f2246cd 100644 --- a/applications/main/nfc/scenes/nfc_scene_save_success.c +++ b/applications/main/nfc/scenes/nfc_scene_save_success.c @@ -1,5 +1,4 @@ #include "../nfc_i.h" -#include "../../../settings/desktop_settings/desktop_settings_app.h" void nfc_scene_save_success_popup_callback(void* context) { Nfc* nfc = context; @@ -8,24 +7,16 @@ void nfc_scene_save_success_popup_callback(void* context) { void nfc_scene_save_success_on_enter(void* context) { Nfc* nfc = context; - DesktopSettings* settings = malloc(sizeof(DesktopSettings)); - DESKTOP_SETTINGS_LOAD(settings); // Setup view Popup* popup = nfc->popup; - if (settings->sfw_mode) { - popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59_sfw); - } - else { - popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59); - } + popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59); popup_set_header(popup, "Saved!", 13, 22, AlignLeft, AlignBottom); popup_set_timeout(popup, 1500); popup_set_context(popup, nfc); popup_set_callback(popup, nfc_scene_save_success_popup_callback); popup_enable_timeout(popup); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup); - free(settings); } bool nfc_scene_save_success_on_event(void* context, SceneManagerEvent event) { @@ -40,6 +31,12 @@ bool nfc_scene_save_success_on_event(void* context, SceneManagerEvent event) { } else if(scene_manager_has_previous_scene(nfc->scene_manager, NfcSceneSavedMenu)) { consumed = scene_manager_search_and_switch_to_previous_scene( nfc->scene_manager, NfcSceneSavedMenu); + } else if(scene_manager_has_previous_scene(nfc->scene_manager, NfcScenePassportAuth)) { + consumed = scene_manager_search_and_switch_to_previous_scene( + nfc->scene_manager, NfcScenePassportAuth); + } else if(scene_manager_has_previous_scene(nfc->scene_manager, NfcSceneNfcDataInfo)) { + consumed = scene_manager_search_and_switch_to_previous_scene( + nfc->scene_manager, NfcSceneNfcDataInfo); } else { consumed = scene_manager_search_and_switch_to_another_scene( nfc->scene_manager, NfcSceneFileSelect); diff --git a/applications/main/nfc/scenes/nfc_scene_saved_menu.c b/applications/main/nfc/scenes/nfc_scene_saved_menu.c index c0d3ed5c6..616dc0ef7 100644 --- a/applications/main/nfc/scenes/nfc_scene_saved_menu.c +++ b/applications/main/nfc/scenes/nfc_scene_saved_menu.c @@ -117,6 +117,8 @@ bool nfc_scene_saved_menu_on_event(void* context, SceneManagerEvent event) { scene_manager_next_scene(nfc->scene_manager, NfcSceneMfUltralightEmulate); } else if(nfc->dev->format == NfcDeviceSaveFormatMifareClassic) { scene_manager_next_scene(nfc->scene_manager, NfcSceneMfClassicEmulate); + } else if(nfc->dev->format == NfcDeviceSaveFormatNfcV) { + scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateNfcV); } else { scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateUid); } diff --git a/applications/main/nfc/views/dict_attack.c b/applications/main/nfc/views/dict_attack.c index a539e514b..9ee9b1e15 100644 --- a/applications/main/nfc/views/dict_attack.c +++ b/applications/main/nfc/views/dict_attack.c @@ -32,7 +32,7 @@ static void dict_attack_draw_callback(Canvas* canvas, void* model) { DictAttackViewModel* m = model; if(m->state == DictAttackStateCardRemoved) { canvas_set_font(canvas, FontPrimary); - canvas_draw_str_aligned(canvas, 64, 4, AlignCenter, AlignTop, "Lost the tag!"); + canvas_draw_str_aligned(canvas, 64, 4, AlignCenter, AlignTop, "Lost The Tag!"); canvas_set_font(canvas, FontSecondary); elements_multiline_text_aligned( canvas, 64, 23, AlignCenter, AlignTop, "Make sure the tag is\npositioned correctly."); @@ -69,7 +69,7 @@ static void dict_attack_draw_callback(Canvas* canvas, void* model) { } elements_progress_bar_with_text(canvas, 0, 20, 128, dict_progress, draw_str); canvas_set_font(canvas, FontSecondary); - snprintf(draw_str, sizeof(draw_str), "Keys found: %d/%d", m->keys_found, m->keys_total); + snprintf(draw_str, sizeof(draw_str), "Keys Found: %d/%d", m->keys_found, m->keys_total); canvas_draw_str_aligned(canvas, 0, 33, AlignLeft, AlignTop, draw_str); snprintf( draw_str, sizeof(draw_str), "Sectors Read: %d/%d", m->sectors_read, m->sectors_total);