1
mirror of https://github.com/DarkFlippers/unleashed-firmware.git synced 2025-12-12 20:49:49 +04:00

Merge branch 'dev' into release

This commit is contained in:
MX
2023-06-02 19:52:05 +03:00
304 changed files with 9281 additions and 4662 deletions

View File

@@ -85,6 +85,13 @@ Min level: 1
Max level: 3
Weight: 3
Name: L1_Kaiju_128x64
Min butthurt: 0
Max butthurt: 10
Min level: 1
Max level: 3
Weight: 4
Name: L2_Wake_up_128x64
Min butthurt: 0
Max butthurt: 12

22
.gitignore vendored
View File

@@ -30,28 +30,26 @@ bindings/
.mxproject
Brewfile.lock.json
# Visual Studio Code
/.vscode/
# Kate
.kateproject
.kateconfig
# legendary cmake's
build
CMakeLists.txt
# bundle output
dist
# kde
.directory
null.d
# SCons
.sconsign.dblite
# Visual Studio Code
/.vscode
# bundle output
/dist
# SCons build dir
build/
/build
# Toolchain
/toolchain
@@ -65,3 +63,5 @@ PVS-Studio.log
*.PVS-Studio.*
.gdbinit
/fbt_options_local.py

View File

@@ -1,40 +1,31 @@
### New changes
* !!! **Warning! After installing, Desktop settings (Favoutite apps, PIN Code, AutoLock time..) will be resetted to default due to settings changes, Please set your PIN code, Favourite apps again in Settings->Desktop** !!!
* If you have copied any apps manually into `apps` folder - remove `apps` folder or that specific apps you copied on your microSD before installing this release to avoid issues due to OFW API version update! If you using regular builds or extra pack builds (e) without your manually added apps, all included apps will be installed automatically, no extra actions needed!
-----
* Desktop: **Show clock on main screen** (Enable in Settings->Desktop->Show Clock) (by @gid9798 | PR #484)
* SubGHz Remote: New plugin - Configurator (Remote Maker) - Now you can create and edit map files on flipper! (by @gid9798 | PR #487)
* SubGHz Remote: Full refactoring, app was re-made from scratch (by @gid9798)
* Archive: Fix rename, show error message to user
* API: Cleanup, mini refactoring of some apps (+6k of free flash space)
* LFRFID: Debug: Allow PSK RAW emulation in gui
* SubGHz: Security+ 2.0 -> add extra custom button `0x78` - Fixes issue #469
* SubGHz: Various fixes (by @gid9798)
* SubGHz: Fix counter settings in debug
* SubGHz: Move dangerous_settings check (by @gid9798 | PR #475)
* Misc: Move NFC plugins into NFC folder
* Misc: Name changer code moved to proper place, load after system startup + extra checks
* Plugins: Merge tiktok and ytshorts remote into one (by @Willy-JL)
* Plugins: NMEA GPS UART - stability fix
* Plugins: Port XFW keyboard with extra symbols to WiFi Marauder instead of using UART Term keyboard (thanks to @Willy-JL)
* Plugins: Moved from extra pack to main FW: Mifare Nested [(by AloneLiberty)](https://github.com/AloneLiberty/FlipperNested) - Works with PC and python app `FlipperNested`
* Plugins: Update TOTP (Authenticator) [(by akopachov)](https://github.com/akopachov/flipper-zero_authenticator) (+ Add option to set custom fonts)
* Plugins: Update NMEA GPS UART [(by ezod)](https://github.com/ezod/flipperzero-gps) (GLL support)
* Plugins: Update WiFi Marauder [(by 0xchocolate)](https://github.com/0xchocolate/flipperzero-firmware-with-wifi-marauder-companion)
* OFW PR 2680: RFID - Add support for Nexkey/Nexwatch (by @mauimauer)
* OFW: nfc: Mifare Ultralight C detection
* OFW: api: added toolbox/api_lock.h
* OFW: NFC: Add support for Gen4 "ultimate card" in Magic app
* OFW: desktop: Refactor favorites settings and allow app browser in selection
* OFW: Infrared: respect carrier frequency and duty cycle settings -> **Breaking API change, API version was changed from 26.x to 27.x**
* OFW: Desktop,Rpc: desktop status subscription
* OFW: Storage, common_rename: check that old path is exists
* OFW: Services: remove deallocator for persistent services
* OFW: Storage: common_rename is now POSIX compliant
* OFW: Removed user-specific data from tar artifacts
* OFW: fbt: Fix tar uid overflow when packaging
* OFW: fbt: Use union for old py (Fix builds if using older python versions)
* OFW: USB HID report timeout
* SubGHz Remote: Fixed BinRAW support, + many other fixes (by @gid9798 | PR #492)
* SubGHz: Keeloq mfname refactoring (by @gid9798 | PR #479)
* Desktop Clock: Some improvements and fixes (by @gid9798 | PR #490)
* LF RFID: Cleanup duplicated code (by @gid9798 | PR #493)
* NFC V: Code review fixes + some GUI rework (by @nvx & @xMasterX)
* NFC V: Fixed crash when exiting emulation and starting it again
* Infrared: Use Universal AC Remote from OFW, same for Audio remote, and rename buttons in OFW naming scheme
* Infrared: Update universal remote assets (by @amec0e)
* GUI Keyboard: Fix crash when renaming files with long file name (Fixed issue #489)
* Misc: Fix APP_IDs to match new regex (regex check will be added in OFW soon)
* Plugins: ESP8266 Deauther - Crash fix (Fixed issue #497)
* Plugins: Update -> Mifare Nested [(by AloneLiberty)](https://github.com/AloneLiberty/FlipperNested)
* Plugins: Update -> TOTP (Authenticator) [(by akopachov)](https://github.com/akopachov/flipper-zero_authenticator)
* Plugins: Update -> ESP32: WiFi Marauder companion plugin [(by 0xchocolate)](https://github.com/0xchocolate/flipperzero-wifi-marauder)
* Plugins: Update -> UART Terminal [(by cool4uma)](https://github.com/cool4uma/UART_Terminal/tree/main)
* OFW: NFC: fix MFC timings -> **Fixes issues with Mifare Classic emulation that could happen after unlshd-049 release**
* OFW: Update dolphin.py
* OFW: NFC Magic: Fix gen1 writing with invalid BCC (lost fix from PR 2511)
* OFW: SubGhz: fix flipper crashes after exiting broadcast blocking message and crash cli
* OFW: Dolphin: new animation
* OFW: fbt: added hooks for build & dist environments; added FW_ORIGIN_* macro for apps & SDK
* OFW: FuriHal: add bus abstraction -> **Breaking API change, API version was changed from 27.x to 28.x**
* OFW: Implement support for reading Opal card (Sydney, Australia)
* OFW: BadUSB: script execution pause
* OFW: IR Universal AC: Add Carrier 42QHB12D8S
#### [🎲 Download latest extra apps pack](https://github.com/xMasterX/all-the-plugins/archive/refs/heads/main.zip)

View File

@@ -143,7 +143,7 @@ You can support us by using links or addresses below:
- WAV Player [(OFW: DrZlo13)](https://github.com/flipperdevices/flipperzero-firmware/tree/zlo/wav-player) - Fixed and improved by [LTVA1](https://github.com/LTVA1/wav_player) -> Also outputs audio on `PA6` - `3(A6)` pin
- Barcode generator plugin [(original by McAzzaMan)](https://github.com/McAzzaMan/flipperzero-firmware/tree/UPC-A_Barcode_Generator/applications/barcode_generator) - [EAN-8 and refactoring](https://github.com/DarkFlippers/unleashed-firmware/pull/154) by @msvsergey
- GPIO: Sentry Safe plugin [(by H4ckd4ddy)](https://github.com/H4ckd4ddy/flipperzero-sentry-safe-plugin)
- ESP32: WiFi Marauder companion plugin [(by 0xchocolate)](https://github.com/0xchocolate/flipperzero-firmware-with-wifi-marauder-companion) - Saving .pcap on flipper microSD [by tcpassos](https://github.com/tcpassos/flipperzero-firmware-with-wifi-marauder-companion) -> Only with custom marauder build (It is necessary to uncomment "#define WRITE_PACKETS_SERIAL" in configs.h (in marauder fw) and compile the firmware for the wifi board.) Or download precompiled build -> [Download esp32_marauder_ver_flipper_sd_serial.bin](https://github.com/justcallmekoko/ESP32Marauder/releases/latest)
- ESP32: WiFi Marauder companion plugin [(by 0xchocolate)](https://github.com/0xchocolate/flipperzero-wifi-marauder) - Saving .pcap on flipper microSD [by tcpassos](https://github.com/tcpassos/flipperzero-firmware-with-wifi-marauder-companion) -> Only with custom marauder build (It is necessary to uncomment "#define WRITE_PACKETS_SERIAL" in configs.h (in marauder fw) and compile the firmware for the wifi board.) Or download precompiled build -> [Download esp32_marauder_ver_flipper_sd_serial.bin](https://github.com/justcallmekoko/ESP32Marauder/releases/latest)
- NRF24: Sniffer & MouseJacker (with changes) [(by mothball187)](https://github.com/mothball187/flipperzero-nrf24/tree/main/mousejacker)
- Simple Clock (timer by GMMan) [(original by CompaqDisc)](https://gist.github.com/CompaqDisc/4e329c501bd03c1e801849b81f48ea61)
- **Sub-GHz Remote** [(by @gid9798)](https://github.com/gid9798)

View File

@@ -7,8 +7,8 @@ App(
"vibro_test",
"keypad_test",
"usb_test",
"USB_Mouse",
"UART_Echo",
"usb_mouse",
"uart_echo",
"display_test",
"text_box_test",
"file_browser_test",

View File

@@ -14,9 +14,7 @@ void lfrfid_debug_scene_tune_on_enter(void* context) {
furi_hal_rfid_comp_set_callback(comparator_trigger_callback, app);
furi_hal_rfid_comp_start();
furi_hal_rfid_pins_read();
furi_hal_rfid_tim_read(125000, 0.5);
furi_hal_rfid_tim_read_start();
furi_hal_rfid_tim_read_start(125000, 0.5);
view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidDebugViewTune);
}
@@ -43,6 +41,5 @@ void lfrfid_debug_scene_tune_on_exit(void* context) {
furi_hal_gpio_init_simple(&gpio_ext_pa7, GpioModeAnalog);
furi_hal_rfid_tim_read_stop();
furi_hal_rfid_tim_reset();
furi_hal_rfid_pins_reset();
}

View File

@@ -1,5 +1,5 @@
App(
appid="UART_Echo",
appid="uart_echo",
name="UART Echo",
apptype=FlipperAppType.DEBUG,
entry_point="uart_echo_app",

View File

@@ -27,6 +27,12 @@ static const uint32_t nfc_test_file_version = 1;
#define NFC_TEST_DATA_MAX_LEN 18
#define NFC_TETS_TIMINGS_MAX_LEN 1350
// Maximum allowed time for buffer preparation to fit 500us nt message timeout
#define NFC_TEST_4_BYTE_BUILD_BUFFER_TIM_MAX (150)
#define NFC_TEST_16_BYTE_BUILD_BUFFER_TIM_MAX (640)
#define NFC_TEST_4_BYTE_BUILD_SIGNAL_TIM_MAX (110)
#define NFC_TEST_16_BYTE_BUILD_SIGNAL_TIM_MAX (440)
typedef struct {
Storage* storage;
NfcaSignal* signal;
@@ -89,13 +95,13 @@ static bool nfc_test_read_signal_from_file(const char* file_name) {
static bool nfc_test_digital_signal_test_encode(
const char* file_name,
uint32_t encode_max_time,
uint32_t build_signal_max_time_us,
uint32_t build_buffer_max_time_us,
uint32_t timing_tolerance,
uint32_t timings_sum_tolerance) {
furi_assert(nfc_test);
bool success = false;
uint32_t time = 0;
uint32_t dut_timings_sum = 0;
uint32_t ref_timings_sum = 0;
uint8_t parity[10] = {};
@@ -109,17 +115,37 @@ static bool nfc_test_digital_signal_test_encode(
// Encode signal
FURI_CRITICAL_ENTER();
time = DWT->CYCCNT;
uint32_t time_start = DWT->CYCCNT;
nfca_signal_encode(
nfc_test->signal, nfc_test->test_data, nfc_test->test_data_len * 8, parity);
uint32_t time_signal =
(DWT->CYCCNT - time_start) / furi_hal_cortex_instructions_per_microsecond();
time_start = DWT->CYCCNT;
digital_signal_prepare_arr(nfc_test->signal->tx_signal);
time = (DWT->CYCCNT - time) / furi_hal_cortex_instructions_per_microsecond();
uint32_t time_buffer =
(DWT->CYCCNT - time_start) / furi_hal_cortex_instructions_per_microsecond();
FURI_CRITICAL_EXIT();
// Check timings
if(time > encode_max_time) {
if(time_signal > build_signal_max_time_us) {
FURI_LOG_E(
TAG, "Encoding time: %ld us while accepted value: %ld us", time, encode_max_time);
TAG,
"Build signal time: %ld us while accepted value: %ld us",
time_signal,
build_signal_max_time_us);
break;
}
if(time_buffer > build_buffer_max_time_us) {
FURI_LOG_E(
TAG,
"Build buffer time: %ld us while accepted value: %ld us",
time_buffer,
build_buffer_max_time_us);
break;
}
@@ -156,7 +182,16 @@ static bool nfc_test_digital_signal_test_encode(
break;
}
FURI_LOG_I(TAG, "Encoding time: %ld us. Acceptable time: %ld us", time, encode_max_time);
FURI_LOG_I(
TAG,
"Build signal time: %ld us. Acceptable time: %ld us",
time_signal,
build_signal_max_time_us);
FURI_LOG_I(
TAG,
"Build buffer time: %ld us. Acceptable time: %ld us",
time_buffer,
build_buffer_max_time_us);
FURI_LOG_I(
TAG,
"Timings sum difference: %ld [1/64MHZ]. Acceptable difference: %ld [1/64MHz]",
@@ -171,11 +206,19 @@ static bool nfc_test_digital_signal_test_encode(
MU_TEST(nfc_digital_signal_test) {
mu_assert(
nfc_test_digital_signal_test_encode(
NFC_TEST_RESOURCES_DIR NFC_TEST_SIGNAL_SHORT_FILE, 500, 1, 37),
NFC_TEST_RESOURCES_DIR NFC_TEST_SIGNAL_SHORT_FILE,
NFC_TEST_4_BYTE_BUILD_SIGNAL_TIM_MAX,
NFC_TEST_4_BYTE_BUILD_BUFFER_TIM_MAX,
1,
37),
"NFC short digital signal test failed\r\n");
mu_assert(
nfc_test_digital_signal_test_encode(
NFC_TEST_RESOURCES_DIR NFC_TEST_SIGNAL_LONG_FILE, 2000, 1, 37),
NFC_TEST_RESOURCES_DIR NFC_TEST_SIGNAL_LONG_FILE,
NFC_TEST_16_BYTE_BUILD_SIGNAL_TIM_MAX,
NFC_TEST_16_BYTE_BUILD_BUFFER_TIM_MAX,
1,
37),
"NFC long digital signal test failed\r\n");
}

View File

@@ -1,5 +1,5 @@
App(
appid="USB_Mouse",
appid="usb_mouse",
name="USB Mouse",
apptype=FlipperAppType.DEBUG,
entry_point="usb_mouse_app",

View File

@@ -1,5 +1,5 @@
App(
appid="Arkanoid",
appid="arkanoid",
name="Arkanoid",
apptype=FlipperAppType.EXTERNAL,
entry_point="arkanoid_game_app",

View File

@@ -13,5 +13,4 @@ App(
fap_category="Tools",
fap_icon="images/badbt_10px.png",
fap_icon_assets="images",
fap_icon_assets_symbol="bad_bt",
)

View File

@@ -1,5 +1,5 @@
App(
appid="Barcode_Generator",
appid="barcode_generator",
name="Barcode Generator",
apptype=FlipperAppType.EXTERNAL,
entry_point="barcode_generator_app",

View File

@@ -1,5 +1,5 @@
App(
appid="Blackjack",
appid="blackjack",
name="Blackjack",
apptype=FlipperAppType.EXTERNAL,
entry_point="blackjack_app",

View File

@@ -14,7 +14,7 @@
#include "util.h"
#include "ui.h"
#include "Blackjack_icons.h"
#include "blackjack_icons.h"
#define DEALER_MAX 17

View File

@@ -1,5 +1,5 @@
App(
appid="DOOM",
appid="doom",
name="DOOM",
apptype=FlipperAppType.EXTERNAL,
entry_point="doom_app",

View File

@@ -1,5 +1,5 @@
App(
appid="ESP8266_Deauther",
appid="esp8266_deauther",
name="[ESP8266] Deauther",
apptype=FlipperAppType.EXTERNAL,
entry_point="esp8266_deauth_app",

View File

@@ -371,8 +371,8 @@ int32_t esp8266_deauth_app(void* p) {
view_port_input_callback_set(view_port, esp8266_deauth_module_input_callback, event_queue);
// Open GUI and register view_port
Gui* gui = furi_record_open(RECORD_GUI);
gui_add_view_port(gui, view_port, GuiLayerFullscreen);
app->m_gui = furi_record_open(RECORD_GUI);
gui_add_view_port(app->m_gui, view_port, GuiLayerFullscreen);
//notification_message(app->notification, &sequence_set_only_blue_255);
@@ -513,7 +513,7 @@ int32_t esp8266_deauth_app(void* p) {
view_port_enabled_set(view_port, false);
gui_remove_view_port(gui, view_port);
gui_remove_view_port(app->m_gui, view_port);
// Close gui record
furi_record_close(RECORD_GUI);

View File

@@ -1,5 +1,5 @@
App(
appid="FlappyBird",
appid="flappy_bird",
name="Flappy Bird",
apptype=FlipperAppType.EXTERNAL,
entry_point="flappy_game_app",

View File

@@ -1,6 +1,6 @@
#include <stdlib.h>
#include <FlappyBird_icons.h>
#include <flappy_bird_icons.h>
#include <furi.h>
#include <gui/gui.h>
#include <gui/icon_animation_i.h>

View File

@@ -1,5 +1,5 @@
App(
appid="RFID_Fuzzer",
appid="rfid_fuzzer",
name="RFID Fuzzer",
apptype=FlipperAppType.EXTERNAL,
entry_point="flipfrid_start",

View File

@@ -15,7 +15,7 @@
#include <toolbox/stream/file_stream.h>
#include <toolbox/stream/buffered_file_stream.h>
#include <RFID_Fuzzer_icons.h>
#include <rfid_fuzzer_icons.h>
#include <lib/lfrfid/lfrfid_worker.h>
#include <lfrfid/protocols/lfrfid_protocols.h>

View File

@@ -1,5 +1,5 @@
App(
appid="i2cTools",
appid="i2c_tools",
name="[GPIO] i2c Tools",
apptype=FlipperAppType.EXTERNAL,
entry_point="i2ctools_app",

View File

@@ -1,7 +1,7 @@
#include <furi.h>
#include <furi_hal.h>
#include <gui/gui.h>
#include <i2cTools_icons.h>
#include <i2c_tools_icons.h>
#define APP_NAME "I2C Tools"
#define SCAN_MENU_TEXT "Scan"

View File

@@ -1,7 +1,7 @@
#include <furi.h>
#include <furi_hal.h>
#include <gui/gui.h>
#include <i2cTools_icons.h>
#include <i2c_tools_icons.h>
#include "../i2cscanner.h"
#define SCAN_TEXT "SCAN"

View File

@@ -1,7 +1,7 @@
#include <furi.h>
#include <furi_hal.h>
#include <gui/gui.h>
#include <i2cTools_icons.h>
#include <i2c_tools_icons.h>
#include "../i2csender.h"
#define SEND_TEXT "SEND"

View File

@@ -1,7 +1,7 @@
#include <furi.h>
#include <furi_hal.h>
#include <gui/gui.h>
#include <i2cTools_icons.h>
#include <i2c_tools_icons.h>
#include "../i2csniffer.h"
#define SNIFF_TEXT "SNIFF"

View File

@@ -1,5 +1,5 @@
App(
appid="iBtn_Fuzzer",
appid="ibtn_fuzzer",
name="iButton Fuzzer",
apptype=FlipperAppType.EXTERNAL,
entry_point="ibtnfuzzer_start",

View File

@@ -15,7 +15,7 @@
#include <toolbox/stream/file_stream.h>
#include <toolbox/stream/buffered_file_stream.h>
#include <iBtn_Fuzzer_icons.h>
#include <ibtn_fuzzer_icons.h>
#include <lib/ibutton/ibutton_worker.h>
#include <lib/ibutton/ibutton_key.h>

View File

@@ -1,5 +1,5 @@
App(
appid="Metronome",
appid="metronome",
name="Metronome",
apptype=FlipperAppType.EXTERNAL,
entry_point="metronome_app",

View File

@@ -1,6 +1,6 @@
#include <gui/canvas.h>
#include <gui/icon_i.h>
#include <Metronome_icons.h>
#include <metronome_icons.h>
//lib can only do bottom left/right
void elements_button_top_left(Canvas* canvas, const char* str) {

View File

@@ -21,5 +21,5 @@ App(
fap_author="AloneLiberty",
fap_description="Recover Mifare Classic keys",
fap_weburl="https://github.com/AloneLiberty/FlipperNested",
fap_version=(1, 4)
fap_version="1.5.0"
)

View File

@@ -5,28 +5,6 @@
#include "../../lib/crypto1/crypto1.h"
#define TAG "Nested"
void nfc_util_num2bytes(uint64_t src, uint8_t len, uint8_t* dest) {
furi_assert(dest);
furi_assert(len <= 8);
while(len--) {
dest[len] = (uint8_t)src;
src >>= 8;
}
}
uint64_t nfc_util_bytes2num(const uint8_t* src, uint8_t len) {
furi_assert(src);
furi_assert(len <= 8);
uint64_t res = 0;
while(len--) {
res = (res << 8) | (*src);
src++;
}
return res;
}
uint16_t nfca_get_crc16(uint8_t* buff, uint16_t len) {
uint16_t crc = 0x6363; // NFCA_CRC_INIT
uint8_t byte = 0;

View File

@@ -396,6 +396,7 @@ void mifare_nested_blink_stop(MifareNested* mifare_nested) {
int32_t mifare_nested_app(void* p) {
UNUSED(p);
MifareNested* mifare_nested = mifare_nested_alloc();
scene_manager_next_scene(mifare_nested->scene_manager, MifareNestedSceneStart);

View File

@@ -21,7 +21,7 @@
#include <gui/modules/variable_item_list.h>
#include "mifare_nested_icons.h"
#define NESTED_VERSION_APP "1.4.6"
#define NESTED_VERSION_APP "1.5.0"
#define NESTED_GITHUB_LINK "https://github.com/AloneLiberty/FlipperNested"
#define NESTED_RECOVER_KEYS_GITHUB_LINK "https://github.com/AloneLiberty/FlipperNestedRecovery"
#define NESTED_NONCE_FORMAT_VERSION "3"
@@ -99,6 +99,7 @@ struct MifareNested {
NestedState* nested_state;
CheckKeysState* keys_state;
SaveNoncesResult_t* save_state;
MifareNestedWorkerState collecting_type;

View File

@@ -296,7 +296,7 @@ uint32_t mifare_nested_worker_predict_delay(
}
// This part of attack is my attempt to implement it on Flipper.
// Proxmark can do this in 2 fucking steps, but idk how.
// Check README.md for more info
// First, we find RPNG rounds per 1000 us
for(uint32_t rtr = 0; rtr < 25; rtr++) {
@@ -448,7 +448,7 @@ uint32_t mifare_nested_worker_predict_delay(
return 1;
}
void mifare_nested_worker_write_nonces(
SaveNoncesResult_t* mifare_nested_worker_write_nonces(
FuriHalNfcDevData* data,
Storage* storage,
NonceList_t* nonces,
@@ -459,6 +459,11 @@ void mifare_nested_worker_write_nonces(
uint32_t distance) {
FuriString* path = furi_string_alloc();
Stream* file_stream = file_stream_alloc(storage);
SaveNoncesResult_t* result = malloc(sizeof(SaveNoncesResult_t));
result->saved = 0;
result->invalid = 0;
result->skipped = 0;
mifare_nested_worker_get_nonces_file_path(data, path);
file_stream_open(file_stream, furi_string_get_cstr(path), FSAM_READ_WRITE, FSOM_CREATE_ALWAYS);
@@ -472,23 +477,26 @@ void mifare_nested_worker_write_nonces(
for(uint8_t tries = 0; tries < tries_count; tries++) {
for(uint8_t sector = 0; sector < sector_count; sector++) {
for(uint8_t key_type = 0; key_type < 2; key_type++) {
if(nonces->nonces[sector][key_type][tries]->collected &&
!nonces->nonces[sector][key_type][tries]->skipped) {
if(nonces->nonces[sector][key_type][tries]->invalid) {
result->invalid++;
} else if(nonces->nonces[sector][key_type][tries]->skipped) {
result->skipped++;
} else if(nonces->nonces[sector][key_type][tries]->collected) {
if(nonces->nonces[sector][key_type][tries]->hardnested) {
FuriString* path = furi_string_alloc();
FuriString* hardnested_path = furi_string_alloc();
mifare_nested_worker_get_hardnested_file_path(
data, path, sector, key_type);
data, hardnested_path, sector, key_type);
FuriString* str = furi_string_alloc_printf(
"HardNested: Key %c cuid 0x%08lx file %s sec %u\n",
!key_type ? 'A' : 'B',
nonces->cuid,
furi_string_get_cstr(path),
furi_string_get_cstr(hardnested_path),
sector);
stream_write_string(file_stream, str);
furi_string_free(path);
furi_string_free(hardnested_path);
furi_string_free(str);
} else {
FuriString* str = furi_string_alloc_printf(
@@ -515,6 +523,8 @@ void mifare_nested_worker_write_nonces(
stream_write_string(file_stream, str);
furi_string_free(str);
}
result->saved++;
}
}
}
@@ -529,10 +539,20 @@ void mifare_nested_worker_write_nonces(
}
free_nonces(nonces, sector_count, free_tries_count);
furi_string_free(path);
file_stream_close(file_stream);
free(file_stream);
if(!result->saved) {
FURI_LOG_E(TAG, "No nonces collected, removing file...");
if(!storage_simply_remove(storage, furi_string_get_cstr(path))) {
FURI_LOG_E(TAG, "Failed to remove .nonces file");
}
}
furi_string_free(path);
furi_record_close(RECORD_STORAGE);
return result;
}
bool mifare_nested_worker_check_initial_keys(
@@ -759,7 +779,7 @@ void mifare_nested_worker_collect_nonces_static(MifareNestedWorker* mifare_neste
mifare_nested_worker_get_block_by_sector(sector),
key_type);
info->skipped = true;
info->invalid = true;
nonces.nonces[sector][key_type][0] = info;
@@ -818,12 +838,20 @@ void mifare_nested_worker_collect_nonces_static(MifareNestedWorker* mifare_neste
break;
}
mifare_nested_worker_write_nonces(&data, storage, &nonces, 1, 1, sector_count, 0, 0);
SaveNoncesResult_t* result =
mifare_nested_worker_write_nonces(&data, storage, &nonces, 1, 1, sector_count, 0, 0);
free(mf_data);
mifare_nested_worker->callback(
MifareNestedWorkerEventNoncesCollected, mifare_nested_worker->context);
if(result->saved) {
mifare_nested_worker->callback(
MifareNestedWorkerEventNoncesCollected, mifare_nested_worker->context);
} else {
mifare_nested_worker->context->save_state = result;
mifare_nested_worker->callback(
MifareNestedWorkerEventNoNoncesCollected, mifare_nested_worker->context);
}
nfc_deactivate();
}
@@ -930,7 +958,7 @@ void mifare_nested_worker_collect_nonces_hard(MifareNestedWorker* mifare_nested_
mifare_nested_worker_get_block_by_sector(sector),
key_type);
info->skipped = true;
info->invalid = true;
nonces.nonces[sector][key_type][0] = info;
mifare_nested_worker->context->nonces = &nonces;
@@ -1059,12 +1087,20 @@ void mifare_nested_worker_collect_nonces_hard(MifareNestedWorker* mifare_nested_
}
}
mifare_nested_worker_write_nonces(&data, storage, &nonces, 1, 1, sector_count, 0, 0);
SaveNoncesResult_t* result =
mifare_nested_worker_write_nonces(&data, storage, &nonces, 1, 1, sector_count, 0, 0);
free(mf_data);
mifare_nested_worker->callback(
MifareNestedWorkerEventNoncesCollected, mifare_nested_worker->context);
if(result->saved) {
mifare_nested_worker->callback(
MifareNestedWorkerEventNoncesCollected, mifare_nested_worker->context);
} else {
mifare_nested_worker->context->save_state = result;
mifare_nested_worker->callback(
MifareNestedWorkerEventNoNoncesCollected, mifare_nested_worker->context);
}
nfc_deactivate();
}
@@ -1368,13 +1404,20 @@ void mifare_nested_worker_collect_nonces(MifareNestedWorker* mifare_nested_worke
break;
}
mifare_nested_worker_write_nonces(
SaveNoncesResult_t* result = mifare_nested_worker_write_nonces(
&data, storage, &nonces, tries_count, 3, sector_count, delay, distance);
free(mf_data);
mifare_nested_worker->callback(
MifareNestedWorkerEventNoncesCollected, mifare_nested_worker->context);
if(result->saved) {
mifare_nested_worker->callback(
MifareNestedWorkerEventNoncesCollected, mifare_nested_worker->context);
} else {
mifare_nested_worker->context->save_state = result;
mifare_nested_worker->callback(
MifareNestedWorkerEventNoNoncesCollected, mifare_nested_worker->context);
}
nfc_deactivate();
}

View File

@@ -22,6 +22,7 @@ typedef enum {
MifareNestedWorkerEventReserved = 1000,
MifareNestedWorkerEventNoTagDetected,
MifareNestedWorkerEventNoNoncesCollected,
MifareNestedWorkerEventNoncesCollected,
MifareNestedWorkerEventCollecting,
@@ -64,8 +65,9 @@ typedef struct {
uint32_t target_nt[2];
uint32_t target_ks[2];
uint8_t parity[2][4];
bool collected;
bool skipped;
bool invalid;
bool collected;
bool hardnested;
} Nonces;
@@ -87,3 +89,9 @@ typedef struct {
uint32_t sector_keys;
bool tag_lost;
} KeyInfo_t;
typedef struct {
uint32_t saved;
uint32_t invalid;
uint32_t skipped;
} SaveNoncesResult_t;

View File

@@ -51,7 +51,7 @@ void mifare_nested_scene_about_on_enter(void* context) {
14,
AlignCenter,
AlignBottom,
"\e#\e! Flipper (Mifare) Nested \e!\n",
"\e#\e! Flipper Nested \e!\n",
false);
widget_add_text_scroll_element(
mifare_nested->widget, 0, 16, 128, 50, furi_string_get_cstr(temp_str));

View File

@@ -56,14 +56,7 @@ bool mifare_nested_scene_check_on_event(void* context, SceneManagerEvent event)
bool consumed = false;
if(event.type == SceneManagerEventTypeCustom) {
if(event.event == MifareNestedWorkerEventNoncesCollected) {
scene_manager_next_scene(
mifare_nested->scene_manager, MifareNestedSceneNoncesCollected);
consumed = true;
} else if(event.event == MifareNestedWorkerEventAttackFailed) {
scene_manager_next_scene(mifare_nested->scene_manager, MifareNestedSceneFailed);
consumed = true;
} else if(event.event == MifareNestedWorkerEventCollecting) {
if(event.event == MifareNestedWorkerEventCollecting) {
if(mifare_nested->run == NestedRunAttack) {
if(mifare_nested->settings->only_hardnested) {
FURI_LOG_I("MifareNested", "Using Hard Nested because user settings");

View File

@@ -84,13 +84,6 @@ bool mifare_nested_scene_check_keys_on_event(void* context, SceneManagerEvent ev
if(event.event == GuiButtonTypeCenter) {
scene_manager_search_and_switch_to_previous_scene(mifare_nested->scene_manager, 0);
consumed = true;
} else if(event.event == MifareNestedWorkerEventNoncesCollected) {
scene_manager_next_scene(
mifare_nested->scene_manager, MifareNestedSceneNoncesCollected);
consumed = true;
} else if(event.event == MifareNestedWorkerEventNeedKey) {
scene_manager_next_scene(mifare_nested->scene_manager, MifareNestedSceneNoKeys);
consumed = true;
} else if(event.event == MifareNestedWorkerEventKeysFound) {
scene_manager_next_scene(mifare_nested->scene_manager, MifareNestedSceneAddedKeys);
consumed = true;

View File

@@ -120,6 +120,10 @@ bool mifare_nested_scene_collecting_on_event(void* context, SceneManagerEvent ev
scene_manager_next_scene(
mifare_nested->scene_manager, MifareNestedSceneNoncesCollected);
consumed = true;
} else if(event.event == MifareNestedWorkerEventNoNoncesCollected) {
scene_manager_next_scene(
mifare_nested->scene_manager, MifareNestedSceneNoNoncesCollected);
consumed = true;
} else if(event.event == MifareNestedWorkerEventAttackFailed) {
scene_manager_next_scene(mifare_nested->scene_manager, MifareNestedSceneFailed);
consumed = true;

View File

@@ -10,4 +10,5 @@ ADD_SCENE(mifare_nested, about, About)
ADD_SCENE(mifare_nested, static_encrypted_nonce, StaticEncryptedNonce)
ADD_SCENE(mifare_nested, need_key_recovery, NeedKeyRecovery)
ADD_SCENE(mifare_nested, need_collection, NeedCollection)
ADD_SCENE(mifare_nested, settings, Settings)
ADD_SCENE(mifare_nested, settings, Settings)
ADD_SCENE(mifare_nested, no_nonces_collected, NoNoncesCollected)

View File

@@ -0,0 +1,94 @@
#include "../mifare_nested_i.h"
void mifare_nested_scene_no_nonces_collected_widget_callback(
GuiButtonType result,
InputType type,
void* context) {
MifareNested* mifare_nested = context;
if(type == InputTypeShort) {
view_dispatcher_send_custom_event(mifare_nested->view_dispatcher, result);
}
}
void mifare_nested_scene_no_nonces_collected_on_enter(void* context) {
MifareNested* mifare_nested = context;
Widget* widget = mifare_nested->widget;
SaveNoncesResult_t* save_state = mifare_nested->save_state;
notification_message(mifare_nested->notifications, &sequence_error);
widget_add_icon_element(widget, 73, 12, &I_DolphinCry);
widget_add_string_element(
widget, 0, 0, AlignLeft, AlignTop, FontPrimary, "No nonces collected");
uint32_t index = 12;
if(save_state->skipped) {
char append_skipped[8] = {'s', 'e', 'c', 't', 'o', 'r', ' ', '\0'};
if(save_state->skipped != 1) {
append_skipped[6] = 's';
}
char draw_str[32] = {};
snprintf(
draw_str, sizeof(draw_str), "Skipped: %lu %s", save_state->skipped, append_skipped);
widget_add_string_element(widget, 0, index, AlignLeft, AlignTop, FontSecondary, draw_str);
widget_add_string_element(
widget, 0, index + 10, AlignLeft, AlignTop, FontSecondary, "(already has keys)");
index += 20;
}
if(save_state->invalid) {
char append_invalid[8] = {'s', 'e', 'c', 't', 'o', 'r', ' ', '\0'};
if(save_state->invalid != 1) {
append_invalid[6] = 's';
}
char draw_str[32] = {};
snprintf(
draw_str, sizeof(draw_str), "Invalid: %lu %s", save_state->invalid, append_invalid);
widget_add_string_element(widget, 0, index, AlignLeft, AlignTop, FontSecondary, draw_str);
widget_add_string_element(
widget, 0, index + 10, AlignLeft, AlignTop, FontSecondary, "(can't auth)");
}
free(save_state);
widget_add_button_element(
widget,
GuiButtonTypeLeft,
"Back",
mifare_nested_scene_no_nonces_collected_widget_callback,
mifare_nested);
// Setup and start worker
view_dispatcher_switch_to_view(mifare_nested->view_dispatcher, MifareNestedViewWidget);
}
bool mifare_nested_scene_no_nonces_collected_on_event(void* context, SceneManagerEvent event) {
MifareNested* mifare_nested = context;
bool consumed = false;
if(event.type == SceneManagerEventTypeCustom) {
if(event.event == GuiButtonTypeCenter || event.event == GuiButtonTypeLeft) {
scene_manager_search_and_switch_to_previous_scene(mifare_nested->scene_manager, 0);
consumed = true;
}
} else if(event.type == SceneManagerEventTypeBack) {
scene_manager_search_and_switch_to_previous_scene(mifare_nested->scene_manager, 0);
consumed = true;
}
return consumed;
}
void mifare_nested_scene_no_nonces_collected_on_exit(void* context) {
MifareNested* mifare_nested = context;
widget_reset(mifare_nested->widget);
}

View File

@@ -1,5 +1,5 @@
App(
appid="Minesweeper",
appid="minesweeper",
name="Minesweeper",
apptype=FlipperAppType.EXTERNAL,
entry_point="minesweeper_app",

View File

@@ -1,5 +1,5 @@
App(
appid="NRF24_Mouse_Jacker",
appid="nrf24_mouse_jacker",
name="[NRF24] Mouse Jacker",
apptype=FlipperAppType.EXTERNAL,
entry_point="mousejacker_app",

View File

@@ -10,7 +10,7 @@
#include <furi_hal_resources.h>
#include <nrf24.h>
#include "mousejacker_ducky.h"
#include <NRF24_Mouse_Jacker_icons.h>
#include <nrf24_mouse_jacker_icons.h>
#define TAG "mousejacker"
#define LOGITECH_MAX_CHANNEL 85

View File

@@ -1,5 +1,5 @@
App(
appid="Multi_Converter",
appid="multi_converter",
name="Multi Converter",
apptype=FlipperAppType.EXTERNAL,
entry_point="multi_converter_app",

View File

@@ -1,5 +1,5 @@
App(
appid="Music_Player",
appid="music_player",
name="Music Player",
apptype=FlipperAppType.EXTERNAL,
entry_point="music_player_app",

View File

@@ -3,7 +3,7 @@
#include <furi.h>
#include <furi_hal.h>
#include <Music_Player_icons.h>
#include <music_player_icons.h>
#include <gui/gui.h>
#include <dialogs/dialogs.h>
#include <storage/storage.h>

View File

@@ -5,7 +5,6 @@
#define TAG "Magic"
#define MAGIC_CMD_WUPA (0x40)
#define MAGIC_CMD_WIPE (0x41)
#define MAGIC_CMD_ACCESS (0x43)
#define MAGIC_MIFARE_READ_CMD (0x30)
@@ -144,32 +143,3 @@ bool magic_gen1_write_blk(uint8_t block_num, MfClassicBlock* data) {
return write_success;
}
bool magic_gen1_wipe() {
bool wipe_success = false;
uint8_t tx_data[MAGIC_BUFFER_SIZE] = {};
uint8_t rx_data[MAGIC_BUFFER_SIZE] = {};
uint16_t rx_len = 0;
FuriHalNfcReturn ret = 0;
do {
tx_data[0] = MAGIC_CMD_WIPE;
ret = furi_hal_nfc_ll_txrx_bits(
tx_data,
8,
rx_data,
sizeof(rx_data),
&rx_len,
FURI_HAL_NFC_LL_TXRX_FLAGS_CRC_TX_MANUAL | FURI_HAL_NFC_LL_TXRX_FLAGS_AGC_ON |
FURI_HAL_NFC_LL_TXRX_FLAGS_CRC_RX_KEEP,
furi_hal_nfc_ll_ms2fc(2000));
if(ret != FuriHalNfcReturnIncompleteByte) break;
if(rx_len != 4) break;
if(rx_data[0] != MAGIC_ACK) break;
wipe_success = true;
} while(false);
return wipe_success;
}

View File

@@ -9,5 +9,3 @@ bool magic_gen1_read_block(uint8_t block_num, MfClassicBlock* data);
bool magic_gen1_data_access_cmd();
bool magic_gen1_write_blk(uint8_t block_num, MfClassicBlock* data);
bool magic_gen1_wipe();

View File

@@ -1,175 +0,0 @@
#include "classic_gen1.h"
#include <furi_hal_nfc.h>
#define TAG "Magic"
#define MAGIC_CMD_WUPA (0x40)
#define MAGIC_CMD_WIPE (0x41)
#define MAGIC_CMD_ACCESS (0x43)
#define MAGIC_MIFARE_READ_CMD (0x30)
#define MAGIC_MIFARE_WRITE_CMD (0xA0)
#define MAGIC_ACK (0x0A)
#define MAGIC_BUFFER_SIZE (32)
bool magic_gen1_wupa() {
bool magic_activated = false;
uint8_t tx_data[MAGIC_BUFFER_SIZE] = {};
uint8_t rx_data[MAGIC_BUFFER_SIZE] = {};
uint16_t rx_len = 0;
FuriHalNfcReturn ret = 0;
do {
// Start communication
tx_data[0] = MAGIC_CMD_WUPA;
ret = furi_hal_nfc_ll_txrx_bits(
tx_data,
7,
rx_data,
sizeof(rx_data),
&rx_len,
FURI_HAL_NFC_LL_TXRX_FLAGS_CRC_TX_MANUAL | FURI_HAL_NFC_LL_TXRX_FLAGS_AGC_ON |
FURI_HAL_NFC_LL_TXRX_FLAGS_CRC_RX_KEEP,
furi_hal_nfc_ll_ms2fc(20));
if(ret != FuriHalNfcReturnIncompleteByte) break;
if(rx_len != 4) break;
if(rx_data[0] != MAGIC_ACK) break;
magic_activated = true;
} while(false);
return magic_activated;
}
bool magic_gen1_data_access_cmd() {
bool write_cmd_success = false;
uint8_t tx_data[MAGIC_BUFFER_SIZE] = {};
uint8_t rx_data[MAGIC_BUFFER_SIZE] = {};
uint16_t rx_len = 0;
FuriHalNfcReturn ret = 0;
do {
tx_data[0] = MAGIC_CMD_ACCESS;
ret = furi_hal_nfc_ll_txrx_bits(
tx_data,
8,
rx_data,
sizeof(rx_data),
&rx_len,
FURI_HAL_NFC_LL_TXRX_FLAGS_CRC_TX_MANUAL | FURI_HAL_NFC_LL_TXRX_FLAGS_AGC_ON |
FURI_HAL_NFC_LL_TXRX_FLAGS_CRC_RX_KEEP,
furi_hal_nfc_ll_ms2fc(20));
if(ret != FuriHalNfcReturnIncompleteByte) break;
if(rx_len != 4) break;
if(rx_data[0] != MAGIC_ACK) break;
write_cmd_success = true;
} while(false);
return write_cmd_success;
}
bool magic_gen1_read_block(uint8_t block_num, MfClassicBlock* data) {
furi_assert(data);
bool read_success = false;
uint8_t tx_data[MAGIC_BUFFER_SIZE] = {};
uint8_t rx_data[MAGIC_BUFFER_SIZE] = {};
uint16_t rx_len = 0;
FuriHalNfcReturn ret = 0;
do {
tx_data[0] = MAGIC_MIFARE_READ_CMD;
tx_data[1] = block_num;
ret = furi_hal_nfc_ll_txrx_bits(
tx_data,
2 * 8,
rx_data,
sizeof(rx_data),
&rx_len,
FURI_HAL_NFC_LL_TXRX_FLAGS_AGC_ON,
furi_hal_nfc_ll_ms2fc(20));
if(ret != FuriHalNfcReturnOk) break;
if(rx_len != 16 * 8) break;
memcpy(data->value, rx_data, sizeof(data->value));
read_success = true;
} while(false);
return read_success;
}
bool magic_gen1_write_blk(uint8_t block_num, MfClassicBlock* data) {
furi_assert(data);
bool write_success = false;
uint8_t tx_data[MAGIC_BUFFER_SIZE] = {};
uint8_t rx_data[MAGIC_BUFFER_SIZE] = {};
uint16_t rx_len = 0;
FuriHalNfcReturn ret = 0;
do {
tx_data[0] = MAGIC_MIFARE_WRITE_CMD;
tx_data[1] = block_num;
ret = furi_hal_nfc_ll_txrx_bits(
tx_data,
2 * 8,
rx_data,
sizeof(rx_data),
&rx_len,
FURI_HAL_NFC_LL_TXRX_FLAGS_AGC_ON | FURI_HAL_NFC_LL_TXRX_FLAGS_CRC_RX_KEEP,
furi_hal_nfc_ll_ms2fc(20));
if(ret != FuriHalNfcReturnIncompleteByte) break;
if(rx_len != 4) break;
if(rx_data[0] != MAGIC_ACK) break;
memcpy(tx_data, data->value, sizeof(data->value));
ret = furi_hal_nfc_ll_txrx_bits(
tx_data,
16 * 8,
rx_data,
sizeof(rx_data),
&rx_len,
FURI_HAL_NFC_LL_TXRX_FLAGS_AGC_ON | FURI_HAL_NFC_LL_TXRX_FLAGS_CRC_RX_KEEP,
furi_hal_nfc_ll_ms2fc(20));
if(ret != FuriHalNfcReturnIncompleteByte) break;
if(rx_len != 4) break;
if(rx_data[0] != MAGIC_ACK) break;
write_success = true;
} while(false);
return write_success;
}
bool magic_gen1_wipe() {
bool wipe_success = false;
uint8_t tx_data[MAGIC_BUFFER_SIZE] = {};
uint8_t rx_data[MAGIC_BUFFER_SIZE] = {};
uint16_t rx_len = 0;
FuriHalNfcReturn ret = 0;
do {
tx_data[0] = MAGIC_CMD_WIPE;
ret = furi_hal_nfc_ll_txrx_bits(
tx_data,
8,
rx_data,
sizeof(rx_data),
&rx_len,
FURI_HAL_NFC_LL_TXRX_FLAGS_CRC_TX_MANUAL | FURI_HAL_NFC_LL_TXRX_FLAGS_AGC_ON |
FURI_HAL_NFC_LL_TXRX_FLAGS_CRC_RX_KEEP,
furi_hal_nfc_ll_ms2fc(2000));
if(ret != FuriHalNfcReturnIncompleteByte) break;
if(rx_len != 4) break;
if(rx_data[0] != MAGIC_ACK) break;
wipe_success = true;
} while(false);
return wipe_success;
}

View File

@@ -95,51 +95,49 @@ void nfc_magic_worker_write(NfcMagicWorker* nfc_magic_worker) {
while(nfc_magic_worker->state == NfcMagicWorkerStateWrite) {
do {
if(furi_hal_nfc_detect(&nfc_data, 200)) {
if(nfc_data.cuid != magic_dev->cuid) break;
if(!card_found_notified) {
nfc_magic_worker->callback(
NfcMagicWorkerEventCardDetected, nfc_magic_worker->context);
card_found_notified = true;
}
furi_hal_nfc_sleep();
magic_activate();
if(magic_dev->type == MagicTypeClassicGen1) {
if(dev_protocol != NfcDeviceProtocolMifareClassic) break;
MfClassicData* mfc_data = &dev_data->mf_classic_data;
if(mfc_data->type != MfClassicType1k) break;
if(magic_dev->type == MagicTypeClassicGen1) {
if(furi_hal_nfc_detect(&nfc_data, 200)) {
magic_deactivate();
magic_activate();
if(!magic_gen1_wupa()) {
FURI_LOG_E(TAG, "Not Magic card");
FURI_LOG_E(TAG, "No card response to WUPA (not a magic card)");
nfc_magic_worker->callback(
NfcMagicWorkerEventWrongCard, nfc_magic_worker->context);
done = true;
break;
}
magic_deactivate();
}
magic_activate();
if(magic_gen1_wupa()) {
if(!magic_gen1_data_access_cmd()) {
FURI_LOG_E(TAG, "Not Magic card");
FURI_LOG_E(
TAG, "No card response to data access command (not a magic card)");
nfc_magic_worker->callback(
NfcMagicWorkerEventWrongCard, nfc_magic_worker->context);
done = true;
break;
}
MfClassicData* mfc_data = &dev_data->mf_classic_data;
for(size_t i = 0; i < 64; i++) {
FURI_LOG_D(TAG, "Writing block %d", i);
if(!magic_gen1_write_blk(i, &mfc_data->block[i])) {
FURI_LOG_E(TAG, "Failed to write %d block", i);
done = true;
nfc_magic_worker->callback(
NfcMagicWorkerEventFail, nfc_magic_worker->context);
done = true;
break;
}
}
done = true;
nfc_magic_worker->callback(
NfcMagicWorkerEventSuccess, nfc_magic_worker->context);
done = true;
break;
} else if(magic_dev->type == MagicTypeGen4) {
}
} else if(magic_dev->type == MagicTypeGen4) {
if(furi_hal_nfc_detect(&nfc_data, 200)) {
uint8_t gen4_config[28];
uint32_t password = magic_dev->password;
@@ -199,6 +197,7 @@ void nfc_magic_worker_write(NfcMagicWorker* nfc_magic_worker) {
gen4_config[25] = dev_data->nfc_data.atqa[1];
gen4_config[26] = dev_data->nfc_data.sak;
furi_hal_nfc_sleep();
furi_hal_nfc_activate_nfca(200, &cuid);
if(!magic_gen4_set_cfg(password, gen4_config, sizeof(gen4_config), false)) {
nfc_magic_worker->callback(
@@ -397,6 +396,11 @@ void nfc_magic_worker_wipe(NfcMagicWorker* nfc_magic_worker) {
MfClassicBlock block;
memset(&block, 0, sizeof(MfClassicBlock));
MfClassicBlock empty_block;
memset(&empty_block, 0, sizeof(MfClassicBlock));
MfClassicBlock trailer_block;
memset(&trailer_block, 0xff, sizeof(MfClassicBlock));
block.value[0] = 0x01;
block.value[1] = 0x02;
block.value[2] = 0x03;
@@ -405,6 +409,10 @@ void nfc_magic_worker_wipe(NfcMagicWorker* nfc_magic_worker) {
block.value[5] = 0x08;
block.value[6] = 0x04;
trailer_block.value[7] = 0x07;
trailer_block.value[8] = 0x80;
trailer_block.value[9] = 0x69;
while(nfc_magic_worker->state == NfcMagicWorkerStateWipe) {
do {
magic_deactivate();
@@ -418,10 +426,26 @@ void nfc_magic_worker_wipe(NfcMagicWorker* nfc_magic_worker) {
card_found_notified = true;
}
if(!magic_gen1_wipe()) break;
if(!magic_gen1_data_access_cmd()) break;
if(!magic_gen1_write_blk(0, &block)) break;
for(size_t i = 1; i < 64; i++) {
FURI_LOG_D(TAG, "Wiping block %d", i);
bool success = false;
if((i | 0x03) == i) {
success = magic_gen1_write_blk(i, &trailer_block);
} else {
success = magic_gen1_write_blk(i, &empty_block);
}
if(!success) {
FURI_LOG_E(TAG, "Failed to write %d block", i);
nfc_magic_worker->callback(
NfcMagicWorkerEventFail, nfc_magic_worker->context);
break;
}
}
card_wiped = true;
nfc_magic_worker->callback(NfcMagicWorkerEventSuccess, nfc_magic_worker->context);
} else if(magic_dev->type == MagicTypeGen4) {

View File

@@ -1,5 +1,5 @@
App(
appid="NRF24_Sniffer",
appid="nrf24_sniffer",
name="[NRF24] Sniffer",
apptype=FlipperAppType.EXTERNAL,
entry_point="nrfsniff_app",

View File

@@ -1,5 +1,5 @@
App(
appid="Picopass",
appid="picopass",
name="[iClass] PicoPass",
apptype=FlipperAppType.EXTERNAL,
targets=["f7"],

View File

@@ -2,7 +2,7 @@
#include <toolbox/path.h>
#include <flipper_format/flipper_format.h>
#include <Picopass_icons.h>
#include <picopass_icons.h>
#define TAG "PicopassDevice"

View File

@@ -25,7 +25,7 @@
#include <storage/storage.h>
#include <lib/toolbox/path.h>
#include <Picopass_icons.h>
#include <picopass_icons.h>
#define PICOPASS_TEXT_STORE_SIZE 128

View File

@@ -1,5 +1,5 @@
App(
appid="SubGHz_Playlist",
appid="subghz_playlist",
name="Sub-GHz Playlist",
apptype=FlipperAppType.EXTERNAL,
entry_point="playlist_app",

View File

@@ -6,7 +6,7 @@
#include <storage/storage.h>
#include <lib/toolbox/path.h>
#include <SubGHz_Playlist_icons.h>
#include <subghz_playlist_icons.h>
#include <lib/subghz/protocols/protocol_items.h>
#include <flipper_format/flipper_format_i.h>

View File

@@ -1,5 +1,5 @@
App(
appid="GPIO_Sentry_Safe",
appid="gpio_sentry_safe",
name="[GPIO] Sentry Safe",
apptype=FlipperAppType.EXTERNAL,
entry_point="sentry_safe_app",

View File

@@ -1,5 +1,5 @@
App(
appid="Signal_Generator",
appid="signal_generator",
name="Signal Generator",
apptype=FlipperAppType.EXTERNAL,
entry_point="signal_gen_app",

View File

@@ -1,7 +1,7 @@
#include "../signal_gen_app_i.h"
#include <furi_hal.h>
#include <gui/elements.h>
#include <Signal_Generator_icons.h>
#include <signal_generator_icons.h>
typedef enum {
LineIndexChannel,

View File

@@ -1,5 +1,5 @@
App(
appid="Snake",
appid="snake",
name="Snake Game",
apptype=FlipperAppType.EXTERNAL,
entry_point="snake_game_app",

View File

@@ -1,5 +1,5 @@
App(
appid="Solitaire",
appid="solitaire",
name="Solitaire",
apptype=FlipperAppType.EXTERNAL,
entry_point="solitaire_app",

View File

@@ -4,7 +4,7 @@
#include <gui/canvas_i.h>
#include "defines.h"
#include "common/ui.h"
#include "Solitaire_icons.h"
#include "solitaire_icons.h"
#include <notification/notification.h>
#include <notification/notification_messages.h>
void init(GameState* game_state);

View File

@@ -1,5 +1,5 @@
App(
appid="Spectrum_Analyzer",
appid="spectrum_analyzer",
name="Spectrum Analyzer",
apptype=FlipperAppType.EXTERNAL,
entry_point="spectrum_analyzer_app",

View File

@@ -9,11 +9,13 @@ typedef enum {
} SubRemEditMenuState;
typedef enum {
// SubmenuIndex
// StartSubmenuIndex
SubmenuIndexSubRemEditMapFile = 0,
SubmenuIndexSubRemNewMapFile,
#if FURI_DEBUG
SubmenuIndexSubRemRemoteView,
SubmenuIndexSubRemAbout,
#endif
// SubmenuIndexSubRemAbout,
// EditSubmenuIndex
EditSubmenuIndexEditLabel,
@@ -45,8 +47,4 @@ typedef enum {
SubRemCustomEventSceneEditPreviewSaved,
SubRemCustomEventSceneNewName,
// // SceneStates
// SubRemSceneOpenMapFileStateOpen,
// SubRemSceneOpenMapFileStateEdit,
} SubRemCustomEvent;

View File

@@ -147,8 +147,7 @@ SubRemLoadSubState subrem_sub_preset_load(
if(protocol->flag & SubGhzProtocolFlag_Send) {
if((protocol->type == SubGhzProtocolTypeStatic) ||
(protocol->type == SubGhzProtocolTypeDynamic) ||
// TODO: BINRAW It probably works, but checks are needed.
// (protocol->type == SubGhzProtocolTypeBinRAW) ||
(protocol->type == SubGhzProtocolTypeBinRAW) ||
(protocol->type == SubGhzProtocolTypeRAW)) {
sub_preset->type = protocol->type;
} else {

View File

@@ -23,10 +23,6 @@
#include <flipper_format/flipper_format_i.h>
#include <lib/subghz/subghz_setting.h>
#include <lib/subghz/receiver.h>
#include <lib/subghz/transmitter.h>
#define SUBREM_APP_FOLDER EXT_PATH("subghz_remote")
#define SUBREM_MAX_LEN_NAME 64

View File

@@ -1,5 +1,5 @@
App(
appid="Tetris",
appid="tetris",
name="Tetris",
apptype=FlipperAppType.EXTERNAL,
entry_point="tetris_game_app",

View File

@@ -1,5 +1,5 @@
App(
appid="TicTacToe",
appid="tictactoe",
name="Tic Tac Toe",
apptype=FlipperAppType.EXTERNAL,
entry_point="tictactoe_game_app",

View File

@@ -12,3 +12,6 @@
// Target firmware to build for
#define TOTP_TARGET_FIRMWARE TOTP_FIRMWARE_UL_XFW
// Max custom fonts value
#define MAX_CUSTOM_FONTS (9)

View File

@@ -10,3 +10,6 @@
#include "712serif/712serif.h"
#include "graph35pix/graph35pix.h"
#include "karma_future/karma_future.h"
#include "funclimbing/funclimbing.h"
#include "dpcomic/dpcomic.h"
#include "pixelflag/pixelflag.h"

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,7 @@
#pragma once
/* GENERATED BY https://github.com/pavius/the-dot-factory */
#include "../font_info.h"
extern const FONT_INFO dPComic_18ptFontInfo;

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,7 @@
#pragma once
/* GENERATED BY https://github.com/pavius/the-dot-factory */
#include "../font_info.h"
extern const FONT_INFO funclimbingDemo_18ptFontInfo;

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,7 @@
#pragma once
/* GENERATED BY https://github.com/pavius/the-dot-factory */
#include "../font_info.h"
extern const FONT_INFO pixelFlag_18ptFontInfo;

View File

@@ -250,7 +250,7 @@ bool totp_scene_app_settings_handle_event(
#endif
else if(scene_state->selected_control == FontSelector) {
totp_roll_value_uint8_t(
&scene_state->selected_font, 1, 0, 6, RollOverflowBehaviorStop);
&scene_state->selected_font, 1, 0, MAX_CUSTOM_FONTS, RollOverflowBehaviorStop);
}
break;
case InputKeyLeft:
@@ -274,7 +274,7 @@ bool totp_scene_app_settings_handle_event(
#endif
else if(scene_state->selected_control == FontSelector) {
totp_roll_value_uint8_t(
&scene_state->selected_font, -1, 0, 6, RollOverflowBehaviorStop);
&scene_state->selected_font, -1, 0, MAX_CUSTOM_FONTS, RollOverflowBehaviorStop);
}
break;
case InputKeyOk:

View File

@@ -165,6 +165,15 @@ static void draw_totp_code(Canvas* const canvas, const PluginState* const plugin
case 6:
current_font = &karmaFuture_14ptFontInfo;
break;
case 7:
current_font = &funclimbingDemo_18ptFontInfo;
break;
case 8:
current_font = &dPComic_18ptFontInfo;
break;
case 9:
current_font = &pixelFlag_18ptFontInfo;
break;
default:
current_font = &modeNine_15ptFontInfo;
break;
@@ -222,6 +231,15 @@ static void on_new_token_code_generated(bool time_left, void* context) {
case 6:
current_font = &karmaFuture_14ptFontInfo;
break;
case 7:
current_font = &funclimbingDemo_18ptFontInfo;
break;
case 8:
current_font = &dPComic_18ptFontInfo;
break;
case 9:
current_font = &pixelFlag_18ptFontInfo;
break;
default:
current_font = &modeNine_15ptFontInfo;
break;

View File

@@ -28,7 +28,7 @@ const UART_TerminalItem items[NUM_MENU_ITEMS] = {
9,
{"115200", "2400", "9600", "19200", "38400", "57600", "230400", "460800", "921600"},
NO_ARGS,
FOCUS_CONSOLE_TOGGLE,
FOCUS_CONSOLE_END,
NO_TIP},
{"Send command", {""}, 1, {""}, INPUT_ARGS, FOCUS_CONSOLE_END, NO_TIP},
{"Send AT command", {""}, 1, {"AT"}, INPUT_ARGS, FOCUS_CONSOLE_END, NO_TIP},

View File

@@ -1,5 +1,5 @@
App(
appid="WAV_Player",
appid="wav_player",
name="WAV Player",
apptype=FlipperAppType.EXTERNAL,
entry_point="wav_player_app",

View File

@@ -12,7 +12,7 @@
#include "wav_player_view.h"
#include <math.h>
#include <WAV_Player_icons.h>
#include <wav_player_icons.h>
#define TAG "WavPlayer"

View File

@@ -0,0 +1,19 @@
# WiFi Marauder companion app for Flipper Zero
## https://github.com/0xchocolate/flipperzero-wifi-marauder
Requires a connected dev board running Marauder FW. [See install instructions from UberGuidoZ here.](https://github.com/UberGuidoZ/Flipper/tree/main/Wifi_DevBoard#marauder-install-information)
## Support
For app feedback, bugs, and feature requests, please [create an issue here](https://github.com/0xchocolate/flipperzero-firmware-with-wifi-marauder-companion/issues).
You can find me (0xchocolate) on discord as @cococode#6011.
If you'd like to donate to the app development effort:
**ETH**: `0xf32A1F0CD6122C97d8953183E53cB889cc087C9b`
**BTC**: `bc1qtw7s25cwdkuaups22yna8sttfxn0usm2f35wc3`
Find more info about Marauder and support its developer (justcallmekoko aka WillStunForFood) here: https://github.com/justcallmekoko/ESP32Marauder
If you found the app preinstalled in a firmware release, consider supporting the maintainers!

View File

@@ -1,5 +1,5 @@
App(
appid="ESP32_WiFi_Marauder",
appid="esp32_wifi_marauder",
name="[ESP32] WiFi Marauder",
apptype=FlipperAppType.EXTERNAL,
entry_point="wifi_marauder_app",

View File

@@ -4,7 +4,7 @@
extern "C" {
#endif
#define WIFI_MARAUDER_APP_VERSION "v0.3.7"
#define WIFI_MARAUDER_APP_VERSION "v0.4.0"
typedef struct WifiMarauderApp WifiMarauderApp;

View File

@@ -21,7 +21,7 @@
#include <gui/modules/widget.h>
#include "wifi_marauder_text_input.h"
#include <ESP32_WiFi_Marauder_icons.h>
#include <esp32_wifi_marauder_icons.h>
#include <storage/storage.h>
#include <lib/toolbox/path.h>
#include <dialogs/dialogs.h>

View File

@@ -1,6 +1,6 @@
#include "wifi_marauder_text_input.h"
#include <gui/elements.h>
#include "ESP32_WiFi_Marauder_icons.h"
#include "esp32_wifi_marauder_icons.h"
#include "wifi_marauder_app_i.h"
#include <furi.h>

View File

@@ -1,5 +1,5 @@
App(
appid="WiFi_Scanner",
appid="wifi_scanner",
name="[WiFi] Scanner",
apptype=FlipperAppType.EXTERNAL,
entry_point="wifi_scanner_app",

View File

@@ -889,8 +889,8 @@ int32_t wifi_scanner_app(void* p) {
view_port_input_callback_set(view_port, wifi_module_input_callback, event_queue);
// Open GUI and register view_port
Gui* gui = furi_record_open(RECORD_GUI);
gui_add_view_port(gui, view_port, GuiLayerFullscreen);
app->m_gui = furi_record_open(RECORD_GUI);
gui_add_view_port(app->m_gui, view_port, GuiLayerFullscreen);
//notification_message(app->notification, &sequence_set_only_blue_255);
@@ -1040,7 +1040,7 @@ int32_t wifi_scanner_app(void* p) {
view_port_enabled_set(view_port, false);
gui_remove_view_port(gui, view_port);
gui_remove_view_port(app->m_gui, view_port);
// Close gui record
furi_record_close(RECORD_GUI);

View File

@@ -1,5 +1,5 @@
App(
appid="Zombiez",
appid="zombiez",
name="Zombiez",
apptype=FlipperAppType.EXTERNAL,
entry_point="zombiez_game_app",

View File

@@ -16,10 +16,11 @@
(((uint8_t)x < 128) ? (script->layout[(uint8_t)x]) : HID_KEYBOARD_NONE)
typedef enum {
WorkerEvtToggle = (1 << 0),
WorkerEvtEnd = (1 << 1),
WorkerEvtConnect = (1 << 2),
WorkerEvtDisconnect = (1 << 3),
WorkerEvtStartStop = (1 << 0),
WorkerEvtPauseResume = (1 << 1),
WorkerEvtEnd = (1 << 2),
WorkerEvtConnect = (1 << 3),
WorkerEvtDisconnect = (1 << 4),
} WorkerEvtFlags;
static const char ducky_cmd_id[] = {"ID"};
@@ -372,6 +373,7 @@ static int32_t bad_usb_worker(void* context) {
BadUsbScript* bad_usb = context;
BadUsbWorkerState worker_state = BadUsbStateInit;
BadUsbWorkerState pause_state = BadUsbStateRunning;
int32_t delay_val = 0;
FURI_LOG_I(WORKER_TAG, "Init");
@@ -406,24 +408,24 @@ static int32_t bad_usb_worker(void* context) {
} else if(worker_state == BadUsbStateNotConnected) { // State: USB not connected
uint32_t flags = bad_usb_flags_get(
WorkerEvtEnd | WorkerEvtConnect | WorkerEvtToggle, FuriWaitForever);
WorkerEvtEnd | WorkerEvtConnect | WorkerEvtStartStop, FuriWaitForever);
if(flags & WorkerEvtEnd) {
break;
} else if(flags & WorkerEvtConnect) {
worker_state = BadUsbStateIdle; // Ready to run
} else if(flags & WorkerEvtToggle) {
} else if(flags & WorkerEvtStartStop) {
worker_state = BadUsbStateWillRun; // Will run when USB is connected
}
bad_usb->st.state = worker_state;
} else if(worker_state == BadUsbStateIdle) { // State: ready to start
uint32_t flags = bad_usb_flags_get(
WorkerEvtEnd | WorkerEvtToggle | WorkerEvtDisconnect, FuriWaitForever);
WorkerEvtEnd | WorkerEvtStartStop | WorkerEvtDisconnect, FuriWaitForever);
if(flags & WorkerEvtEnd) {
break;
} else if(flags & WorkerEvtToggle) { // Start executing script
} else if(flags & WorkerEvtStartStop) { // Start executing script
DOLPHIN_DEED(DolphinDeedBadUsbPlayScript);
delay_val = 0;
bad_usb->buf_len = 0;
@@ -442,7 +444,7 @@ static int32_t bad_usb_worker(void* context) {
} else if(worker_state == BadUsbStateWillRun) { // State: start on connection
uint32_t flags = bad_usb_flags_get(
WorkerEvtEnd | WorkerEvtConnect | WorkerEvtToggle, FuriWaitForever);
WorkerEvtEnd | WorkerEvtConnect | WorkerEvtStartStop, FuriWaitForever);
if(flags & WorkerEvtEnd) {
break;
@@ -458,17 +460,17 @@ static int32_t bad_usb_worker(void* context) {
storage_file_seek(script_file, 0, true);
// extra time for PC to recognize Flipper as keyboard
flags = furi_thread_flags_wait(
WorkerEvtEnd | WorkerEvtDisconnect | WorkerEvtToggle,
WorkerEvtEnd | WorkerEvtDisconnect | WorkerEvtStartStop,
FuriFlagWaitAny | FuriFlagNoClear,
1500);
if(flags == (unsigned)FuriFlagErrorTimeout) {
// If nothing happened - start script execution
worker_state = BadUsbStateRunning;
} else if(flags & WorkerEvtToggle) {
} else if(flags & WorkerEvtStartStop) {
worker_state = BadUsbStateIdle;
furi_thread_flags_clear(WorkerEvtToggle);
furi_thread_flags_clear(WorkerEvtStartStop);
}
} else if(flags & WorkerEvtToggle) { // Cancel scheduled execution
} else if(flags & WorkerEvtStartStop) { // Cancel scheduled execution
worker_state = BadUsbStateNotConnected;
}
bad_usb->st.state = worker_state;
@@ -476,18 +478,23 @@ static int32_t bad_usb_worker(void* context) {
} else if(worker_state == BadUsbStateRunning) { // State: running
uint16_t delay_cur = (delay_val > 1000) ? (1000) : (delay_val);
uint32_t flags = furi_thread_flags_wait(
WorkerEvtEnd | WorkerEvtToggle | WorkerEvtDisconnect, FuriFlagWaitAny, delay_cur);
WorkerEvtEnd | WorkerEvtStartStop | WorkerEvtPauseResume | WorkerEvtDisconnect,
FuriFlagWaitAny,
delay_cur);
delay_val -= delay_cur;
if(!(flags & FuriFlagError)) {
if(flags & WorkerEvtEnd) {
break;
} else if(flags & WorkerEvtToggle) {
} else if(flags & WorkerEvtStartStop) {
worker_state = BadUsbStateIdle; // Stop executing script
furi_hal_hid_kb_release_all();
} else if(flags & WorkerEvtDisconnect) {
worker_state = BadUsbStateNotConnected; // USB disconnected
furi_hal_hid_kb_release_all();
} else if(flags & WorkerEvtPauseResume) {
pause_state = BadUsbStateRunning;
worker_state = BadUsbStatePaused; // Pause
}
bad_usb->st.state = worker_state;
continue;
@@ -526,13 +533,13 @@ static int32_t bad_usb_worker(void* context) {
furi_check((flags & FuriFlagError) == 0);
}
} else if(worker_state == BadUsbStateWaitForBtn) { // State: Wait for button Press
uint16_t delay_cur = (delay_val > 1000) ? (1000) : (delay_val);
uint32_t flags = furi_thread_flags_wait(
WorkerEvtEnd | WorkerEvtToggle | WorkerEvtDisconnect, FuriFlagWaitAny, delay_cur);
uint32_t flags = bad_usb_flags_get(
WorkerEvtEnd | WorkerEvtStartStop | WorkerEvtPauseResume | WorkerEvtDisconnect,
FuriWaitForever);
if(!(flags & FuriFlagError)) {
if(flags & WorkerEvtEnd) {
break;
} else if(flags & WorkerEvtToggle) {
} else if(flags & WorkerEvtStartStop) {
delay_val = 0;
worker_state = BadUsbStateRunning;
} else if(flags & WorkerEvtDisconnect) {
@@ -542,21 +549,55 @@ static int32_t bad_usb_worker(void* context) {
bad_usb->st.state = worker_state;
continue;
}
} else if(worker_state == BadUsbStatePaused) { // State: Paused
uint32_t flags = bad_usb_flags_get(
WorkerEvtEnd | WorkerEvtStartStop | WorkerEvtPauseResume | WorkerEvtDisconnect,
FuriWaitForever);
if(!(flags & FuriFlagError)) {
if(flags & WorkerEvtEnd) {
break;
} else if(flags & WorkerEvtStartStop) {
worker_state = BadUsbStateIdle; // Stop executing script
bad_usb->st.state = worker_state;
furi_hal_hid_kb_release_all();
} else if(flags & WorkerEvtDisconnect) {
worker_state = BadUsbStateNotConnected; // USB disconnected
bad_usb->st.state = worker_state;
furi_hal_hid_kb_release_all();
} else if(flags & WorkerEvtPauseResume) {
if(pause_state == BadUsbStateRunning) {
if(delay_val > 0) {
bad_usb->st.state = BadUsbStateDelay;
bad_usb->st.delay_remain = delay_val / 1000;
} else {
bad_usb->st.state = BadUsbStateRunning;
delay_val = 0;
}
worker_state = BadUsbStateRunning; // Resume
} else if(pause_state == BadUsbStateStringDelay) {
bad_usb->st.state = BadUsbStateRunning;
worker_state = BadUsbStateStringDelay; // Resume
}
}
continue;
}
} else if(worker_state == BadUsbStateStringDelay) { // State: print string with delays
uint32_t flags = furi_thread_flags_wait(
WorkerEvtEnd | WorkerEvtToggle | WorkerEvtDisconnect,
FuriFlagWaitAny,
uint32_t flags = bad_usb_flags_get(
WorkerEvtEnd | WorkerEvtStartStop | WorkerEvtPauseResume | WorkerEvtDisconnect,
bad_usb->stringdelay);
if(!(flags & FuriFlagError)) {
if(flags & WorkerEvtEnd) {
break;
} else if(flags & WorkerEvtToggle) {
} else if(flags & WorkerEvtStartStop) {
worker_state = BadUsbStateIdle; // Stop executing script
furi_hal_hid_kb_release_all();
} else if(flags & WorkerEvtDisconnect) {
worker_state = BadUsbStateNotConnected; // USB disconnected
furi_hal_hid_kb_release_all();
} else if(flags & WorkerEvtPauseResume) {
pause_state = BadUsbStateStringDelay;
worker_state = BadUsbStatePaused; // Pause
}
bad_usb->st.state = worker_state;
continue;
@@ -651,9 +692,14 @@ void bad_usb_script_set_keyboard_layout(BadUsbScript* bad_usb, FuriString* layou
storage_file_free(layout_file);
}
void bad_usb_script_toggle(BadUsbScript* bad_usb) {
void bad_usb_script_start_stop(BadUsbScript* bad_usb) {
furi_assert(bad_usb);
furi_thread_flags_set(furi_thread_get_id(bad_usb->thread), WorkerEvtToggle);
furi_thread_flags_set(furi_thread_get_id(bad_usb->thread), WorkerEvtStartStop);
}
void bad_usb_script_pause_resume(BadUsbScript* bad_usb) {
furi_assert(bad_usb);
furi_thread_flags_set(furi_thread_get_id(bad_usb->thread), WorkerEvtPauseResume);
}
BadUsbState* bad_usb_script_get_state(BadUsbScript* bad_usb) {

View File

@@ -16,6 +16,7 @@ typedef enum {
BadUsbStateDelay,
BadUsbStateStringDelay,
BadUsbStateWaitForBtn,
BadUsbStatePaused,
BadUsbStateDone,
BadUsbStateScriptError,
BadUsbStateFileError,
@@ -42,7 +43,9 @@ void bad_usb_script_start(BadUsbScript* bad_usb);
void bad_usb_script_stop(BadUsbScript* bad_usb);
void bad_usb_script_toggle(BadUsbScript* bad_usb);
void bad_usb_script_start_stop(BadUsbScript* bad_usb);
void bad_usb_script_pause_resume(BadUsbScript* bad_usb);
BadUsbState* bad_usb_script_get_state(BadUsbScript* bad_usb);

View File

@@ -21,7 +21,10 @@ bool bad_usb_scene_work_on_event(void* context, SceneManagerEvent event) {
}
consumed = true;
} else if(event.event == InputKeyOk) {
bad_usb_script_toggle(app->bad_usb_script);
bad_usb_script_start_stop(app->bad_usb_script);
consumed = true;
} else if(event.event == InputKeyRight) {
bad_usb_script_pause_resume(app->bad_usb_script);
consumed = true;
}
} else if(event.type == SceneManagerEventTypeTick) {

View File

@@ -16,6 +16,7 @@ typedef struct {
char file_name[MAX_NAME_LEN];
char layout[MAX_NAME_LEN];
BadUsbState state;
bool pause_wait;
uint8_t anim_frame;
} BadUsbModel;
@@ -31,11 +32,7 @@ static void bad_usb_draw_callback(Canvas* canvas, void* _model) {
if(strlen(model->layout) == 0) {
furi_string_set(disp_str, "(default)");
} else {
furi_string_reset(disp_str);
furi_string_push_back(disp_str, '(');
for(size_t i = 0; i < strlen(model->layout); i++)
furi_string_push_back(disp_str, model->layout[i]);
furi_string_push_back(disp_str, ')');
furi_string_printf(disp_str, "(%s)", model->layout);
}
elements_string_fit_width(canvas, disp_str, 128 - 2);
canvas_draw_str(
@@ -45,34 +42,42 @@ static void bad_usb_draw_callback(Canvas* canvas, void* _model) {
canvas_draw_icon(canvas, 22, 24, &I_UsbTree_48x22);
if((model->state.state == BadUsbStateIdle) || (model->state.state == BadUsbStateDone) ||
(model->state.state == BadUsbStateNotConnected)) {
BadUsbWorkerState state = model->state.state;
if((state == BadUsbStateIdle) || (state == BadUsbStateDone) ||
(state == BadUsbStateNotConnected)) {
elements_button_center(canvas, "Run");
elements_button_left(canvas, "Config");
} else if((model->state.state == BadUsbStateRunning) || (model->state.state == BadUsbStateDelay)) {
} else if((state == BadUsbStateRunning) || (state == BadUsbStateDelay)) {
elements_button_center(canvas, "Stop");
} else if(model->state.state == BadUsbStateWaitForBtn) {
if(!model->pause_wait) {
elements_button_right(canvas, "Pause");
}
} else if(state == BadUsbStatePaused) {
elements_button_center(canvas, "End");
elements_button_right(canvas, "Resume");
} else if(state == BadUsbStateWaitForBtn) {
elements_button_center(canvas, "Press to continue");
} else if(model->state.state == BadUsbStateWillRun) {
} else if(state == BadUsbStateWillRun) {
elements_button_center(canvas, "Cancel");
}
if(model->state.state == BadUsbStateNotConnected) {
if(state == BadUsbStateNotConnected) {
canvas_draw_icon(canvas, 4, 26, &I_Clock_18x18);
canvas_set_font(canvas, FontPrimary);
canvas_draw_str_aligned(canvas, 127, 31, AlignRight, AlignBottom, "Connect");
canvas_draw_str_aligned(canvas, 127, 43, AlignRight, AlignBottom, "to USB");
} else if(model->state.state == BadUsbStateWillRun) {
} else if(state == BadUsbStateWillRun) {
canvas_draw_icon(canvas, 4, 26, &I_Clock_18x18);
canvas_set_font(canvas, FontPrimary);
canvas_draw_str_aligned(canvas, 127, 31, AlignRight, AlignBottom, "Will run");
canvas_draw_str_aligned(canvas, 127, 43, AlignRight, AlignBottom, "on connect");
} else if(model->state.state == BadUsbStateFileError) {
} else if(state == BadUsbStateFileError) {
canvas_draw_icon(canvas, 4, 26, &I_Error_18x18);
canvas_set_font(canvas, FontPrimary);
canvas_draw_str_aligned(canvas, 127, 31, AlignRight, AlignBottom, "File");
canvas_draw_str_aligned(canvas, 127, 43, AlignRight, AlignBottom, "ERROR");
} else if(model->state.state == BadUsbStateScriptError) {
} else if(state == BadUsbStateScriptError) {
canvas_draw_icon(canvas, 4, 26, &I_Error_18x18);
canvas_set_font(canvas, FontPrimary);
canvas_draw_str_aligned(canvas, 127, 33, AlignRight, AlignBottom, "ERROR:");
@@ -87,12 +92,12 @@ static void bad_usb_draw_callback(Canvas* canvas, void* _model) {
canvas_draw_str_aligned(
canvas, 127, 56, AlignRight, AlignBottom, furi_string_get_cstr(disp_str));
furi_string_reset(disp_str);
} else if(model->state.state == BadUsbStateIdle) {
} else if(state == BadUsbStateIdle) {
canvas_draw_icon(canvas, 4, 26, &I_Smile_18x18);
canvas_set_font(canvas, FontBigNumbers);
canvas_draw_str_aligned(canvas, 114, 40, AlignRight, AlignBottom, "0");
canvas_draw_icon(canvas, 117, 26, &I_Percent_10x14);
} else if(model->state.state == BadUsbStateRunning) {
} else if(state == BadUsbStateRunning) {
if(model->anim_frame == 0) {
canvas_draw_icon(canvas, 4, 23, &I_EviSmile1_18x21);
} else {
@@ -105,13 +110,13 @@ static void bad_usb_draw_callback(Canvas* canvas, void* _model) {
canvas, 114, 40, AlignRight, AlignBottom, furi_string_get_cstr(disp_str));
furi_string_reset(disp_str);
canvas_draw_icon(canvas, 117, 26, &I_Percent_10x14);
} else if(model->state.state == BadUsbStateDone) {
} else if(state == BadUsbStateDone) {
canvas_draw_icon(canvas, 4, 23, &I_EviSmile1_18x21);
canvas_set_font(canvas, FontBigNumbers);
canvas_draw_str_aligned(canvas, 114, 40, AlignRight, AlignBottom, "100");
furi_string_reset(disp_str);
canvas_draw_icon(canvas, 117, 26, &I_Percent_10x14);
} else if(model->state.state == BadUsbStateDelay) {
} else if(state == BadUsbStateDelay) {
if(model->anim_frame == 0) {
canvas_draw_icon(canvas, 4, 23, &I_EviWaiting1_18x21);
} else {
@@ -129,6 +134,22 @@ static void bad_usb_draw_callback(Canvas* canvas, void* _model) {
canvas_draw_str_aligned(
canvas, 127, 50, AlignRight, AlignBottom, furi_string_get_cstr(disp_str));
furi_string_reset(disp_str);
} else if((state == BadUsbStatePaused) || (state == BadUsbStateWaitForBtn)) {
if(model->anim_frame == 0) {
canvas_draw_icon(canvas, 4, 23, &I_EviWaiting1_18x21);
} else {
canvas_draw_icon(canvas, 4, 23, &I_EviWaiting2_18x21);
}
canvas_set_font(canvas, FontBigNumbers);
furi_string_printf(
disp_str, "%u", ((model->state.line_cur - 1) * 100) / model->state.line_nb);
canvas_draw_str_aligned(
canvas, 114, 40, AlignRight, AlignBottom, furi_string_get_cstr(disp_str));
furi_string_reset(disp_str);
canvas_draw_icon(canvas, 117, 26, &I_Percent_10x14);
canvas_set_font(canvas, FontSecondary);
canvas_draw_str_aligned(canvas, 127, 50, AlignRight, AlignBottom, "Paused");
furi_string_reset(disp_str);
} else {
canvas_draw_icon(canvas, 4, 26, &I_Clock_18x18);
}
@@ -142,7 +163,27 @@ static bool bad_usb_input_callback(InputEvent* event, void* context) {
bool consumed = false;
if(event->type == InputTypeShort) {
if((event->key == InputKeyLeft) || (event->key == InputKeyOk)) {
if(event->key == InputKeyLeft) {
consumed = true;
furi_assert(bad_usb->callback);
bad_usb->callback(event->key, bad_usb->context);
} else if(event->key == InputKeyOk) {
with_view_model(
bad_usb->view, BadUsbModel * model, { model->pause_wait = false; }, true);
consumed = true;
furi_assert(bad_usb->callback);
bad_usb->callback(event->key, bad_usb->context);
} else if(event->key == InputKeyRight) {
with_view_model(
bad_usb->view,
BadUsbModel * model,
{
if((model->state.state == BadUsbStateRunning) ||
(model->state.state == BadUsbStateDelay)) {
model->pause_wait = true;
}
},
true);
consumed = true;
furi_assert(bad_usb->callback);
bad_usb->callback(event->key, bad_usb->context);
@@ -215,6 +256,9 @@ void bad_usb_set_state(BadUsb* bad_usb, BadUsbState* st) {
{
memcpy(&(model->state), st, sizeof(BadUsbState));
model->anim_frame ^= 1;
if(model->state.state == BadUsbStatePaused) {
model->pause_wait = false;
}
},
true);
}

View File

@@ -11,7 +11,6 @@ void infrared_scene_universal_ac_on_enter(void* context) {
infrared_brute_force_set_db_filename(brute_force, EXT_PATH("infrared/assets/ac.ir"));
//TODO Improve A/C universal remote
button_panel_reserve(button_panel, 2, 3);
uint32_t i = 0;
button_panel_add_item(
@@ -20,77 +19,74 @@ void infrared_scene_universal_ac_on_enter(void* context) {
0,
0,
3,
24,
&I_Power_25x27,
&I_Power_hvr_25x27,
22,
&I_Off_25x27,
&I_Off_hvr_25x27,
infrared_scene_universal_common_item_callback,
context);
infrared_brute_force_add_record(brute_force, i++, "POWER");
infrared_brute_force_add_record(brute_force, i++, "Off");
button_panel_add_item(
button_panel,
i,
1,
0,
36,
24,
&I_Mode_25x27,
&I_Mode_hvr_25x27,
22,
&I_Dehumidify_25x27,
&I_Dehumidify_hvr_25x27,
infrared_scene_universal_common_item_callback,
context);
infrared_brute_force_add_record(brute_force, i++, "MODE");
infrared_brute_force_add_record(brute_force, i++, "Dh");
button_panel_add_item(
button_panel,
i,
0,
1,
3,
66,
&I_Vol_up_25x27,
&I_Vol_up_hvr_25x27,
59,
&I_CoolHi_25x27,
&I_CoolHi_hvr_25x27,
infrared_scene_universal_common_item_callback,
context);
infrared_brute_force_add_record(brute_force, i++, "TEMP+");
infrared_brute_force_add_record(brute_force, i++, "Cool_hi");
button_panel_add_item(
button_panel,
i,
1,
1,
36,
66,
&I_Vol_down_25x27,
&I_Vol_down_hvr_25x27,
59,
&I_HeatHi_25x27,
&I_HeatHi_hvr_25x27,
infrared_scene_universal_common_item_callback,
context);
infrared_brute_force_add_record(brute_force, i++, "TEMP-");
infrared_brute_force_add_record(brute_force, i++, "Heat_hi");
button_panel_add_item(
button_panel,
i,
0,
2,
3,
98,
&I_Swing_25x27,
&I_Swing_hvr_25x27,
91,
&I_CoolLo_25x27,
&I_CoolLo_hvr_25x27,
infrared_scene_universal_common_item_callback,
context);
infrared_brute_force_add_record(brute_force, i++, "SWING");
infrared_brute_force_add_record(brute_force, i++, "Cool_lo");
button_panel_add_item(
button_panel,
i,
1,
2,
36,
98,
&I_Timer_25x27,
&I_Timer_hvr_25x27,
91,
&I_HeatLo_25x27,
&I_HeatLo_hvr_25x27,
infrared_scene_universal_common_item_callback,
context);
infrared_brute_force_add_record(brute_force, i++, "TIMER");
infrared_brute_force_add_record(brute_force, i++, "Heat_lo");
button_panel_add_label(button_panel, 6, 11, FontPrimary, "AC remote");
button_panel_add_label(button_panel, 20, 63, FontSecondary, "Temp");
button_panel_add_label(button_panel, 8, 23, FontSecondary, "Pwr");
button_panel_add_label(button_panel, 40, 23, FontSecondary, "Mod");
button_panel_add_label(button_panel, 6, 10, FontPrimary, "AC remote");
view_set_orientation(view_stack_get_view(infrared->view_stack), ViewOrientationVertical);
view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewStack);

View File

@@ -10,8 +10,8 @@ void infrared_scene_universal_audio_on_enter(void* context) {
InfraredBruteForce* brute_force = infrared->brute_force;
infrared_brute_force_set_db_filename(brute_force, EXT_PATH("infrared/assets/audio.ir"));
//TODO Improve Audio universal remote
button_panel_reserve(button_panel, 2, 2);
button_panel_reserve(button_panel, 2, 4);
uint32_t i = 0;
button_panel_add_item(
button_panel,
@@ -19,51 +19,98 @@ void infrared_scene_universal_audio_on_enter(void* context) {
0,
0,
3,
19,
11,
&I_Power_25x27,
&I_Power_hvr_25x27,
infrared_scene_universal_common_item_callback,
context);
infrared_brute_force_add_record(brute_force, i++, "POWER");
infrared_brute_force_add_record(brute_force, i++, "Power");
button_panel_add_item(
button_panel,
i,
1,
0,
36,
19,
11,
&I_Mute_25x27,
&I_Mute_hvr_25x27,
infrared_scene_universal_common_item_callback,
context);
infrared_brute_force_add_record(brute_force, i++, "MUTE");
infrared_brute_force_add_record(brute_force, i++, "Mute");
button_panel_add_item(
button_panel,
i,
0,
1,
3,
64,
&I_Vol_up_25x27,
&I_Vol_up_hvr_25x27,
41,
&I_Play_25x27,
&I_Play_hvr_25x27,
infrared_scene_universal_common_item_callback,
context);
infrared_brute_force_add_record(brute_force, i++, "VOL+");
infrared_brute_force_add_record(brute_force, i++, "Play");
button_panel_add_item(
button_panel,
i,
1,
1,
36,
64,
41,
&I_Pause_25x27,
&I_Pause_hvr_25x27,
infrared_scene_universal_common_item_callback,
context);
infrared_brute_force_add_record(brute_force, i++, "Pause");
button_panel_add_item(
button_panel,
i,
0,
2,
3,
71,
&I_TrackPrev_25x27,
&I_TrackPrev_hvr_25x27,
infrared_scene_universal_common_item_callback,
context);
infrared_brute_force_add_record(brute_force, i++, "Prev");
button_panel_add_item(
button_panel,
i,
1,
2,
36,
71,
&I_TrackNext_25x27,
&I_TrackNext_hvr_25x27,
infrared_scene_universal_common_item_callback,
context);
infrared_brute_force_add_record(brute_force, i++, "Next");
button_panel_add_item(
button_panel,
i,
0,
3,
3,
101,
&I_Vol_down_25x27,
&I_Vol_down_hvr_25x27,
infrared_scene_universal_common_item_callback,
context);
infrared_brute_force_add_record(brute_force, i++, "VOL-");
infrared_brute_force_add_record(brute_force, i++, "Vol_dn");
button_panel_add_item(
button_panel,
i,
1,
3,
36,
101,
&I_Vol_up_25x27,
&I_Vol_up_hvr_25x27,
infrared_scene_universal_common_item_callback,
context);
infrared_brute_force_add_record(brute_force, i++, "Vol_up");
button_panel_add_label(button_panel, 5, 11, FontSecondary, "Audio remote");
button_panel_add_label(button_panel, 17, 60, FontSecondary, "Volume");
button_panel_add_label(button_panel, 1, 8, FontPrimary, "Mus. remote");
view_set_orientation(view_stack_get_view(infrared->view_stack), ViewOrientationVertical);
view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewStack);

View File

@@ -25,7 +25,7 @@ void infrared_scene_universal_fan_on_enter(void* context) {
&I_Power_hvr_25x27,
infrared_scene_universal_common_item_callback,
context);
infrared_brute_force_add_record(brute_force, i++, "POWER");
infrared_brute_force_add_record(brute_force, i++, "Power");
button_panel_add_item(
button_panel,
i,
@@ -37,7 +37,7 @@ void infrared_scene_universal_fan_on_enter(void* context) {
&I_Mode_hvr_25x27,
infrared_scene_universal_common_item_callback,
context);
infrared_brute_force_add_record(brute_force, i++, "MODE");
infrared_brute_force_add_record(brute_force, i++, "Mode");
button_panel_add_item(
button_panel,
i,
@@ -49,7 +49,7 @@ void infrared_scene_universal_fan_on_enter(void* context) {
&I_Vol_up_hvr_25x27,
infrared_scene_universal_common_item_callback,
context);
infrared_brute_force_add_record(brute_force, i++, "SPEED+");
infrared_brute_force_add_record(brute_force, i++, "Speed_up");
button_panel_add_item(
button_panel,
i,
@@ -61,7 +61,7 @@ void infrared_scene_universal_fan_on_enter(void* context) {
&I_Vol_down_hvr_25x27,
infrared_scene_universal_common_item_callback,
context);
infrared_brute_force_add_record(brute_force, i++, "SPEED-");
infrared_brute_force_add_record(brute_force, i++, "Speed_dn");
button_panel_add_item(
button_panel,
i,
@@ -73,7 +73,7 @@ void infrared_scene_universal_fan_on_enter(void* context) {
&I_Rotate_hvr_25x27,
infrared_scene_universal_common_item_callback,
context);
infrared_brute_force_add_record(brute_force, i++, "ROTATE");
infrared_brute_force_add_record(brute_force, i++, "Rotate");
button_panel_add_item(
button_panel,
i,
@@ -85,7 +85,7 @@ void infrared_scene_universal_fan_on_enter(void* context) {
&I_Timer_hvr_25x27,
infrared_scene_universal_common_item_callback,
context);
infrared_brute_force_add_record(brute_force, i++, "TIMER");
infrared_brute_force_add_record(brute_force, i++, "Timer");
button_panel_add_label(button_panel, 5, 11, FontPrimary, "Fan remote");
button_panel_add_label(button_panel, 20, 63, FontSecondary, "Speed");

View File

@@ -24,7 +24,7 @@ void infrared_scene_universal_projector_on_enter(void* context) {
&I_Power_hvr_25x27,
infrared_scene_universal_common_item_callback,
context);
infrared_brute_force_add_record(brute_force, i++, "POWER");
infrared_brute_force_add_record(brute_force, i++, "Power");
button_panel_add_item(
button_panel,
i,
@@ -36,7 +36,7 @@ void infrared_scene_universal_projector_on_enter(void* context) {
&I_Mute_hvr_25x27,
infrared_scene_universal_common_item_callback,
context);
infrared_brute_force_add_record(brute_force, i++, "MUTE");
infrared_brute_force_add_record(brute_force, i++, "Mute");
button_panel_add_item(
button_panel,
i,
@@ -48,7 +48,7 @@ void infrared_scene_universal_projector_on_enter(void* context) {
&I_Vol_up_hvr_25x27,
infrared_scene_universal_common_item_callback,
context);
infrared_brute_force_add_record(brute_force, i++, "VOL+");
infrared_brute_force_add_record(brute_force, i++, "Vol_up");
button_panel_add_item(
button_panel,
i,
@@ -60,7 +60,7 @@ void infrared_scene_universal_projector_on_enter(void* context) {
&I_Vol_down_hvr_25x27,
infrared_scene_universal_common_item_callback,
context);
infrared_brute_force_add_record(brute_force, i++, "VOL-");
infrared_brute_force_add_record(brute_force, i++, "Vol_dn");
button_panel_add_label(button_panel, 10, 11, FontPrimary, "Projector");
button_panel_add_label(button_panel, 17, 60, FontSecondary, "Volume");

Some files were not shown because too many files have changed in this diff Show More