From 065c62166ac8d66a7e6c292b7e3d2a38941119fa Mon Sep 17 00:00:00 2001 From: RogueMaster Date: Fri, 10 May 2024 17:29:22 -0400 Subject: [PATCH] Squashed 'applications/external/' changes from 54870d87b75..b481757d003 b481757d003 Save cache for clean merges 058e2daafed Merge subghz_bruteforcer from https://github.com/DarkFlippers/flipperzero-subbrute cf9b9e4e481 Format 002502741ca Merge picopass from https://gitlab.com/bettse/picopass a07de342c75 Picopass moved 3227a82e19b Merge pull request #75 from derskythe/master 0c69d335775 Merge pull request #9 from derskythe/fix-typo 48deea4c44e fix: README.md 5a706106859 Merge subghz_bruteforcer from https://github.com/DarkFlippers/flipperzero-subbrute 797bd846323 Merge qrcode from https://github.com/bmatcuk/flipperzero-qrcode 6bac51db640 Merge magspoof from https://github.com/zacharyweiss/magspoof_flipper d26b9c1c9f4 Merge gps_nmea from https://github.com/ezod/flipperzero-gps 9b94ae65a75 Merge pull request #74 from DarkFlippers/feat-add-318--to-9bit-chamber-linear 7c5b5485e96 feat: Update Sub-GHz BruteForcer version to 3.C a52d0255738 Delay between repeats 08781c79aad Add "repeat" setting ebd7d2018ae Merge pull request #30 from lekkas/quectel-l80-support 8c8bd786377 Document support for Quectel L80 14a4e0b0ad0 Merge branch 'save_as_legacy' into 'main' 60d2c641cc0 Save as legacy 4ffa01764a6 update to firmware 0.101.2 c6581bee461 Fix plugin path @Willy-JL 2659fec833f Fix changelog 250bf0c8fc5 changelog d7bd70643f2 v1.14 29405af1d9a Add plugin submodule back 9cc6fb0c17f picopass: Add wiegand parsing plugin (#205) ae4ce84f174 Picopass cleanup (#201) 471e8db1565 Picopass: enum to track auth method (#198) 3768efef3e0 Picopass: saved card save as lfrfid (#195) 86c31c23541 Picopass: add subheader to loclass UI (#197) 97423fc3653 Picopass: Save unknown blocks with ?? (#196) 5e7ae5b2185 Picopass block tracking (#125) 6c5074796ef Picopass: update with latest API (#165) adff1263a82 Picopass save written key (#126) d6f32ef64fc picopass: apply card to back view (#118) 9a26cf8f766 Picopass: rename AA1 to card_data (#119) e55f8919d07 picopass: remove backticks in changelog (#116) 8ff393b3afa Update changelog and bump version (#114) 808e36db4f8 Picopass read improvements (#109) 7b24843ef6b Add circuit to picopass readme (#110) a125d70dab7 Picopass nr mac improvements (#108) 95ae7f2b991 picopass: Add support for non-secure cards (#106) efe1a388005 Picopass: Create seader directory if needed (#101) d8303dc86ec Picopass: handle NR-MAC auth for legacy cards (#95) ef3333a0aed Fix markdown headings in the picopass README (#93) ea1e5bfadce Picopass: NR-MAC instructions (#92) e6ba05569d4 Picopass config se problem (#90) 1a6da3dac54 Add additional keys to elite dict (#89) 9012d97c2fe Picopass: update working with keys (#88) e95daa16790 Picopass: More info view (raw bytes) (#86) cf16630fd92 Picopass: detect config card (#87) 7958963cec0 Picopass save partial (#85) 8a135f2c57f PicoPass: Fix name buffer size issues (#84) c8d2411aec7 Picopass save as seader (#81) 6ff62d7715c Picopass read card using nr-mac (#79) 83535bedcc8 Picopass: Update loclass notes (#80) a465f998bcf Picopass: Create folder before loclass (#78) 93f32a14ed9 Picopass: typo (#76) 55f43bb5da5 FreeRTOS API fixes (#73) 6ccba6c73e0 [FL-3593] Picopass rework. Part 1 (#68) 77e776a8e79 Picopass: rename RFAL_PICOPASS_BLOCK_LEN (#63) 692dc973483 Picopass: check if HID CSN if read fails (#61) 242578c2eea Picopass: bump version + changelog (#56) 2888b9e1c7b Picopass: Add haptics to loclass (#53) eaeee879374 Picopass: populate key change input with first key of user dictionary (#54) b349f4c86d4 Picopass more bit formats (#47) d561b02154d Improve loclass logic for readers doing keyrolling. (#50) 83e7c4c3b4c Picopass: Remove elite user dictionary from Read Card (#48) 4af84c85145 Picopass: allow zero keys (#44) bf2f50c4099 Picopass: one more readme fix (#42) d576e77bc9e Picopass readme fix (#41) c92d22845ba revamp picopass readme and add loclass (#39) 90bdf475c3a New random file name API fix (#40) 7b3170a1cdd Optimise picopass crypto to fix timing issues with newer readers. (#34) 2bf5b807316 Picopass standard key (#32) c82a9822fbd picopass: clean up UI, espeicially for SR cards (#31) 322cb82b363 Picopass remove sentinel (#29) 885f01fd1d2 Picopass, music player version bump (#28) 2bf8d616f51 Picopass: allow write immediately after read (#26) 95891406149 Music player, picopass: assets integration (#23) 7caee8fd939 Picopass: Rename option (#25) 3812f9b76c7 Added fap_version field to all apps (#15) e1a8f9dae6e Add descriptions for all the faps (#13) 0e4e711ab3d Fixes failure to read picopass cards immediately after emulating. (#10) bbf0cf4e87e Merge pull request #9 from bettse/custom_key git-subtree-dir: applications/external git-subtree-split: b481757d0031408c9c45fc076118c1375cea0b31 --- .utils/.subtree-subdir-helper.sh | 7 +- gps_nmea/README.md | 2 + magspoof/application.fam | 2 +- magspoof/helpers/mag_helpers.c | 62 +++++---- magspoof/helpers/mag_types.h | 2 + magspoof/mag_state.c | 20 ++- magspoof/mag_state.h | 4 +- magspoof/scenes/mag_scene_emulate_config.c | 41 ++++-- magspoof/scenes/mag_scene_settings.c | 118 +++++++++++++++++- picopass/.catalog/changelog.md | 3 + picopass/.gitsubtree | 2 +- picopass/application.fam | 2 +- picopass/icons/Nfc_10px.png | Bin 0 -> 304 bytes picopass/icons/RFIDDolphinReceive_97x61.png | Bin 0 -> 1421 bytes picopass/icons/RFIDDolphinSend_97x61.png | Bin 0 -> 1418 bytes picopass/picopass_device.c | 22 +++- picopass/picopass_device.h | 3 +- picopass/picopass_i.h | 2 - picopass/scenes/picopass_scene_card_menu.c | 21 +++- picopass/views/dict_attack.h | 2 - qrcode/.github/workflows/release.yml | 2 +- subghz_bruteforcer/LICENSE | 2 +- subghz_bruteforcer/README.md | 31 +++-- .../helpers/subbrute_radio_device_loader.c | 1 + subghz_bruteforcer/helpers/subbrute_worker.c | 35 +----- .../scenes/subbrute_scene_load_file.c | 1 + .../scenes/subbrute_scene_save_name.c | 1 + .../scenes/subbrute_scene_save_success.c | 1 + .../scenes/subbrute_scene_setup_extra.c | 14 +-- subghz_bruteforcer/subbrute_device.c | 5 +- subghz_bruteforcer/subbrute_i.h | 2 +- subghz_bruteforcer/subbrute_protocols.c | 15 ++- subghz_bruteforcer/subbrute_protocols.h | 2 + .../views/subbrute_attack_view.c | 7 +- subghz_bruteforcer/views/subbrute_main_view.c | 27 ++-- 35 files changed, 324 insertions(+), 137 deletions(-) create mode 100644 picopass/icons/Nfc_10px.png create mode 100644 picopass/icons/RFIDDolphinReceive_97x61.png create mode 100644 picopass/icons/RFIDDolphinSend_97x61.png diff --git a/.utils/.subtree-subdir-helper.sh b/.utils/.subtree-subdir-helper.sh index a90cddabe25..e7c79d91cab 100644 --- a/.utils/.subtree-subdir-helper.sh +++ b/.utils/.subtree-subdir-helper.sh @@ -49,8 +49,13 @@ else prevhead="$(git rev-parse HEAD)" exec {capture}>&1 result="$(git subtree "${action}" -P "${path}" "${split}" -m "${action^} ${path} from ${repo}" 2>&1 | tee /proc/self/fd/$capture)" + cleanmerge=false + if git diff --quiet && git diff --cached --quiet && git merge HEAD &> /dev/null; then + cleanmerge=true + fi bash .utils/.check-merge.sh "${path}" "${repo}" "${result}" - if [ "${prevhead}" = "$(git rev-parse HEAD)" ]; then + if [ "${prevhead}" = "$(git rev-parse HEAD)" ] && ! $cleanmerge; then + # Not a clean merge, and merge was aborted, don't save cache ok=false fi fi diff --git a/gps_nmea/README.md b/gps_nmea/README.md index 9cdc619e14d..5cc350fb58e 100644 --- a/gps_nmea/README.md +++ b/gps_nmea/README.md @@ -61,6 +61,7 @@ the hardware setup. * [u-Blox NEO-6M] * [u-Blox NEO-7M] * [Uputronics u-blox MAX-M8C Pico] +* [Quectel L80] If you have verified this application working with a module not listed here, please submit a PR adding it to the list. @@ -78,3 +79,4 @@ of the repository. [u-Blox NEO-7M]: https://www.u-blox.com/en/product/neo-7-series [uFBT]: https://github.com/flipperdevices/flipperzero-ufbt [Uputronics u-blox MAX-M8C Pico]: https://store.uputronics.com/index.php?route=product/product&product_id=72 +[Quectel L80]: https://www.quectel.com/ProductDownload/L80.html diff --git a/magspoof/application.fam b/magspoof/application.fam index 7d68ce32cbd..f51ffd2bf26 100644 --- a/magspoof/application.fam +++ b/magspoof/application.fam @@ -17,7 +17,7 @@ App( fap_category="GPIO", fap_icon_assets="icons", fap_icon_assets_symbol="mag", - fap_version=(0, 7), # major, minor + fap_version=(0, 8), # major, minor fap_description="Enables wireless transmission of magstripe data", fap_author="Zachary Weiss", fap_weburl="https://github.com/zacharyweiss/magspoof_flipper", diff --git a/magspoof/helpers/mag_helpers.c b/magspoof/helpers/mag_helpers.c index 83bf6c322dc..269606545c5 100644 --- a/magspoof/helpers/mag_helpers.c +++ b/magspoof/helpers/mag_helpers.c @@ -5,6 +5,7 @@ #define ZERO_PREFIX 25 // n zeros prefix #define ZERO_BETWEEN 53 // n zeros between tracks #define ZERO_SUFFIX 25 // n zeros suffix +#define REPEAT_DELAY_MS 50 // bits per char on a given track const uint8_t bitlen[] = {7, 5, 5}; @@ -331,40 +332,49 @@ void mag_spoof(Mag* mag) { if(!tx_init(state)) return; - FURI_CRITICAL_ENTER(); - for(uint16_t i = 0; i < (ZERO_PREFIX * 2); i++) { - // is this right? - if(!!(i % 2)) bit ^= 1; - play_halfbit(bit, state); - furi_delay_us(state->us_clock); - } + uint8_t i = 0; + do { + FURI_CRITICAL_ENTER(); + for(uint16_t i = 0; i < (ZERO_PREFIX * 2); i++) { + // is this right? + if(!!(i % 2)) bit ^= 1; + play_halfbit(bit, state); + furi_delay_us(state->us_clock); + } + + if((state->track == MagTrackStateOneAndTwo) || (state->track == MagTrackStateOne)) + play_track((uint8_t*)bits_t1_manchester, bits_t1_count, state, false); - if((state->track == MagTrackStateOneAndTwo) || (state->track == MagTrackStateOne)) - play_track((uint8_t*)bits_t1_manchester, bits_t1_count, state, false); + if((state->track == MagTrackStateOneAndTwo)) + for(uint16_t i = 0; i < (ZERO_BETWEEN * 2); i++) { + if(!!(i % 2)) bit ^= 1; + play_halfbit(bit, state); + furi_delay_us(state->us_clock); + } - if((state->track == MagTrackStateOneAndTwo)) - for(uint16_t i = 0; i < (ZERO_BETWEEN * 2); i++) { + if((state->track == MagTrackStateOneAndTwo) || (state->track == MagTrackStateTwo)) + play_track( + (uint8_t*)bits_t2_manchester, + bits_t2_count, + state, + (state->reverse == MagReverseStateOn)); + + if((state->track == MagTrackStateThree)) + play_track((uint8_t*)bits_t3_manchester, bits_t3_count, state, false); + + for(uint16_t i = 0; i < (ZERO_SUFFIX * 2); i++) { if(!!(i % 2)) bit ^= 1; play_halfbit(bit, state); furi_delay_us(state->us_clock); } + FURI_CRITICAL_EXIT(); - if((state->track == MagTrackStateOneAndTwo) || (state->track == MagTrackStateTwo)) - play_track( - (uint8_t*)bits_t2_manchester, - bits_t2_count, - state, - (state->reverse == MagReverseStateOn)); - - if((state->track == MagTrackStateThree)) - play_track((uint8_t*)bits_t3_manchester, bits_t3_count, state, false); + i++; + FURI_LOG_D( + TAG, "TX %u (n_repeats: %u, repeat_mode: %u)", i, state->n_repeats, state->repeat_mode); + furi_delay_ms(REPEAT_DELAY_MS); - for(uint16_t i = 0; i < (ZERO_SUFFIX * 2); i++) { - if(!!(i % 2)) bit ^= 1; - play_halfbit(bit, state); - furi_delay_us(state->us_clock); - } - FURI_CRITICAL_EXIT(); + } while((i < state->n_repeats) && state->repeat_mode); free(data1); free(data2); diff --git a/magspoof/helpers/mag_types.h b/magspoof/helpers/mag_types.h index 898f876f82c..0d2593572af 100644 --- a/magspoof/helpers/mag_types.h +++ b/magspoof/helpers/mag_types.h @@ -46,6 +46,8 @@ typedef enum { #define MAG_STATE_DEFAULT_PIN_OUTPUT MagPinA6 #define MAG_STATE_DEFAULT_PIN_ENABLE MagPinA4 #define MAG_STATE_DEFAULT_ALLOW_UART false +#define MAG_STATE_DEFAULT_N_REPEATS 3 +#define MAG_STATE_DEFAULT_REPEAT_MODE true typedef enum { MagViewSubmenu, diff --git a/magspoof/mag_state.c b/magspoof/mag_state.c index f1e4d89608b..13e051d0608 100644 --- a/magspoof/mag_state.c +++ b/magspoof/mag_state.c @@ -53,12 +53,15 @@ bool mag_state_load(MagState* out_state) { if(tmp != MAG_STATE_VER) break; if(!flipper_format_read_uint32(file, "pin_input", &tmp, 1)) break; - state.pin_input = tmp; + state.pin_input = (MagPin)tmp; if(!flipper_format_read_uint32(file, "pin_output", &tmp, 1)) break; - state.pin_output = tmp; + state.pin_output = (MagPin)tmp; if(!flipper_format_read_uint32(file, "pin_enable", &tmp, 1)) break; - state.pin_enable = tmp; + state.pin_enable = (MagPin)tmp; if(!flipper_format_read_bool(file, "allow_uart", &state.allow_uart, 1)) break; + if(!flipper_format_read_uint32(file, "n_repeats", &tmp, 1)) break; + state.n_repeats = (uint8_t)tmp; + if(!flipper_format_read_bool(file, "repeat_mode", &state.repeat_mode, 1)) break; loaded_from_file = true; } while(0); @@ -76,6 +79,8 @@ bool mag_state_load(MagState* out_state) { if(!loaded_from_file) { state.allow_uart = MAG_STATE_DEFAULT_ALLOW_UART; + state.n_repeats = MAG_STATE_DEFAULT_N_REPEATS; + state.repeat_mode = MAG_STATE_DEFAULT_REPEAT_MODE; } // set defaults we don't save @@ -102,13 +107,16 @@ void mag_state_save(MagState* state) { if(!flipper_format_file_open_always(file, MAG_STATE_PATH)) break; if(!flipper_format_write_header_cstr(file, MAG_STATE_HEADER, MAG_STATE_VER)) break; - tmp = state->pin_input; + tmp = (uint32_t)state->pin_input; if(!flipper_format_write_uint32(file, "pin_input", &tmp, 1)) break; - tmp = state->pin_output; + tmp = (uint32_t)state->pin_output; if(!flipper_format_write_uint32(file, "pin_output", &tmp, 1)) break; - tmp = state->pin_enable; + tmp = (uint32_t)state->pin_enable; if(!flipper_format_write_uint32(file, "pin_enable", &tmp, 1)) break; if(!flipper_format_write_bool(file, "allow_uart", &state->allow_uart, 1)) break; + tmp = (uint32_t)state->n_repeats; + if(!flipper_format_write_uint32(file, "n_repeats", &tmp, 1)) break; + if(!flipper_format_write_bool(file, "repeat_mode", &state->repeat_mode, 1)) break; } while(0); flipper_format_free(file); diff --git a/magspoof/mag_state.h b/magspoof/mag_state.h index b2e26623bfc..e7f1b8a3868 100644 --- a/magspoof/mag_state.h +++ b/magspoof/mag_state.h @@ -14,7 +14,7 @@ #include "helpers/mag_types.h" #define MAG_STATE_HEADER "Mag State" -#define MAG_STATE_VER 1 +#define MAG_STATE_VER 2 #define MAG_STATE_DIR STORAGE_APP_DATA_PATH_PREFIX #define MAG_STATE_PATH MAG_STATE_DIR "/mag_state.txt" @@ -29,6 +29,8 @@ typedef struct { MagPin pin_enable; bool allow_uart; bool is_debug; + uint8_t n_repeats; + bool repeat_mode; } MagState; const GpioPin* mag_state_enum_to_pin(MagPin pin); diff --git a/magspoof/scenes/mag_scene_emulate_config.c b/magspoof/scenes/mag_scene_emulate_config.c index 5c2e048f886..cd5106ab052 100644 --- a/magspoof/scenes/mag_scene_emulate_config.c +++ b/magspoof/scenes/mag_scene_emulate_config.c @@ -3,11 +3,12 @@ #define TAG "MagSceneEmulateConfig" enum MagEmulateConfigIndex { - MagEmulateConfigIndexTx, + MagEmulateConfigIndexClock, MagEmulateConfigIndexTrack, MagEmulateConfigIndexReverse, - MagEmulateConfigIndexClock, - MagEmulateConfigIndexInterpacket, + MagEmulateConfigIndexRepeat, + MagEmulateConfigIndexTx, + // MagEmulateConfigIndexInterpacket, }; #define TX_COUNT 7 @@ -163,6 +164,14 @@ static void mag_scene_emulate_config_set_reverse(VariableItem* item) { } }; +static void mag_scene_emulate_config_set_repeat_mode(VariableItem* item) { + Mag* mag = variable_item_get_context(item); + uint8_t index = variable_item_get_current_value_index(item); + variable_item_set_current_value_text(item, reverse_text[index]); + + mag->state.repeat_mode = (bool)index; +} + static void mag_scene_emulate_config_set_clock(VariableItem* item) { Mag* mag = variable_item_get_context(item); uint8_t index = variable_item_get_current_value_index(item); @@ -190,7 +199,7 @@ void mag_scene_emulate_config_on_enter(void* context) { item = variable_item_list_add( mag->variable_item_list, "Clock:", CLOCK_COUNT, mag_scene_emulate_config_set_clock, mag); value_index = value_index_uint32(mag->state.us_clock, clock_value, CLOCK_COUNT); - scene_manager_set_scene_state(mag->scene_manager, MagSceneEmulateConfig, (uint32_t)item); + // scene_manager_set_scene_state(mag->scene_manager, MagSceneEmulateConfig, (uint32_t)item); variable_item_set_current_value_index(item, value_index); variable_item_set_current_value_text(item, clock_text[value_index]); @@ -198,7 +207,7 @@ void mag_scene_emulate_config_on_enter(void* context) { item = variable_item_list_add( mag->variable_item_list, "Track:", TRACK_COUNT, mag_scene_emulate_config_set_track, mag); value_index = value_index_uint32(mag->state.track, track_value, TRACK_COUNT); - scene_manager_set_scene_state(mag->scene_manager, MagSceneEmulateConfig, (uint32_t)item); + //scene_manager_set_scene_state(mag->scene_manager, MagSceneEmulateConfig, (uint32_t)item); variable_item_set_current_value_index(item, value_index); variable_item_set_current_value_text(item, track_text[value_index]); @@ -211,7 +220,19 @@ void mag_scene_emulate_config_on_enter(void* context) { mag_scene_emulate_config_set_reverse, mag); value_index = value_index_uint32(mag->state.reverse, reverse_value, REVERSE_COUNT); - scene_manager_set_scene_state(mag->scene_manager, MagSceneEmulateConfig, (uint32_t)item); + //scene_manager_set_scene_state(mag->scene_manager, MagSceneEmulateConfig, (uint32_t)item); + variable_item_set_current_value_index(item, value_index); + variable_item_set_current_value_text(item, reverse_text[value_index]); + + // Repeated TX + item = variable_item_list_add( + mag->variable_item_list, + "Repeat:", + REVERSE_COUNT, + mag_scene_emulate_config_set_repeat_mode, + mag); + value_index = (uint32_t)mag->state.repeat_mode; + //scene_manager_set_scene_state(mag->scene_manager, MagSceneEmulateConfig, (uint32_t)item); variable_item_set_current_value_index(item, value_index); variable_item_set_current_value_text(item, reverse_text[value_index]); @@ -222,7 +243,7 @@ void mag_scene_emulate_config_on_enter(void* context) { item = variable_item_list_add( mag->variable_item_list, "TX via:", TX_COUNT, mag_scene_emulate_config_set_tx, mag); value_index = value_index_uint32(mag->state.tx, tx_value, TX_COUNT); - scene_manager_set_scene_state(mag->scene_manager, MagSceneEmulateConfig, (uint32_t)item); + //scene_manager_set_scene_state(mag->scene_manager, MagSceneEmulateConfig, (uint32_t)item); variable_item_set_current_value_index(item, value_index); variable_item_set_current_value_text(item, tx_text[value_index]); #ifdef FW_ORIGIN_Official @@ -245,6 +266,10 @@ void mag_scene_emulate_config_on_enter(void* context) { variable_item_set_current_value_text(item, interpacket_text[value_index]);*/ UNUSED(mag_scene_emulate_config_set_interpacket); + variable_item_list_set_selected_item( + mag->variable_item_list, + scene_manager_get_scene_state(mag->scene_manager, MagSceneEmulateConfig)); + view_dispatcher_switch_to_view(mag->view_dispatcher, MagViewVariableItemList); } @@ -264,6 +289,4 @@ void mag_scene_emulate_config_on_exit(void* context) { Mag* mag = context; variable_item_list_set_selected_item(mag->variable_item_list, 0); variable_item_list_reset(mag->variable_item_list); - // mag_last_settings_save? - // scene_manager_set_scene_state? Using subghz_scene_reciever_config as framework/inspo } \ No newline at end of file diff --git a/magspoof/scenes/mag_scene_settings.c b/magspoof/scenes/mag_scene_settings.c index e920de34cd7..30b6e7a6b41 100644 --- a/magspoof/scenes/mag_scene_settings.c +++ b/magspoof/scenes/mag_scene_settings.c @@ -8,6 +8,8 @@ enum VarItemListIndex { VarItemListIndexPinInput, VarItemListIndexPinOutput, VarItemListIndexPinEnable, + VarItemListIndexNRepeats, + VarItemListIndexRepeatModeOn, #ifndef FW_ORIGIN_Official VarItemListIndexAllowUART, #endif @@ -27,6 +29,38 @@ const uint8_t GPIO_COUNT = COUNT_OF(gpio); // static const char* uart_pins[] = {[DapUartTypeUSART1] = "13,14", [DapUartTypeLPUART1] = "15,16"}; // static const char* uart_swap[] = {[DapUartTXRXNormal] = "No", [DapUartTXRXSwap] = "Yes"}; +#define N_REPEATS_COUNT 10 +const char* const n_repeats_text[N_REPEATS_COUNT] = { + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "10", + "20", +}; +const uint32_t n_repeats_value[N_REPEATS_COUNT] = { + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 20, +}; + +#define OFF_ON_COUNT 2 +const char* const off_on_text[OFF_ON_COUNT] = { + "OFF", + "ON", +}; + void mag_scene_settings_var_item_list_callback(void* context, uint32_t index) { Mag* mag = context; view_dispatcher_send_custom_event(mag->view_dispatcher, index); @@ -53,6 +87,55 @@ static void mag_scene_settings_set_gpio_enable(VariableItem* item) { mag_scene_settings_set_gpio(item, &mag->state.pin_enable); }; +static void mag_scene_settings_set_n_repeats(VariableItem* item) { + Mag* mag = variable_item_get_context(item); + uint8_t index = variable_item_get_current_value_index(item); + variable_item_set_current_value_text(item, n_repeats_text[index]); + mag->state.n_repeats = n_repeats_value[index]; +} + +static void mag_scene_settings_set_bool(VariableItem* item, bool* bool_out) { + uint8_t index = variable_item_get_current_value_index(item); + variable_item_set_current_value_text(item, off_on_text[index]); + *bool_out = (bool)index; +} + +static void mag_scene_settings_set_repeat_mode(VariableItem* item) { + Mag* mag = variable_item_get_context(item); + mag_scene_settings_set_bool(item, &mag->state.repeat_mode); +} + +/* +static void mag_scene_settings_set_allow_uart(VariableItem* item) { + Mag* mag = variable_item_get_context(item); + + bool rising = !(mag->state.allow_uart); + // trigger dialog only on rising change + if(rising) { + DialogMessage* msg = dialog_message_alloc(); + dialog_message_set_header(msg, "UART MSR", 64, 0, AlignCenter, AlignTop); + dialog_message_set_buttons(msg, "No", NULL, "Yes"); + dialog_message_set_text( + msg, + "This option requires a\nUART-compatible mag reader.\nIs it installed?\n", + 64, + 32, + AlignCenter, + AlignCenter); + DialogMessageButton res = dialog_message_show(furi_record_open(RECORD_DIALOGS), msg); + if(res != DialogMessageButtonRight) { + // if not "Yes", reset index + variable_item_set_current_value_index(item, (uint32_t)mag->state.allow_uart); + } + dialog_message_free(msg); + furi_record_close(RECORD_DIALOGS); + } + + // set value & text based on current varitem index + mag_scene_settings_set_bool(item, &mag->state.allow_uart); +} +*/ + static void mag_pin_variable_item_list_add( Mag* mag, const char* label, @@ -64,9 +147,30 @@ static void mag_pin_variable_item_list_add( variable_item_set_current_value_text(item, gpio[pin]); } +static void mag_bool_variable_item_list_add( + Mag* mag, + const char* label, + bool value, + VariableItemChangeCallback change_callback) { + VariableItem* item = + variable_item_list_add(mag->variable_item_list, label, OFF_ON_COUNT, change_callback, mag); + uint32_t value_index = (uint32_t)value; + variable_item_set_current_value_index(item, value_index); + variable_item_set_current_value_text(item, off_on_text[value_index]); +} + void mag_scene_settings_on_enter(void* context) { Mag* mag = context; VariableItemList* var_item_list = mag->variable_item_list; + VariableItem* item; + uint32_t value_index; + + // reload state in the event temporary changes have been + // made on the emulate config screen + // only changes made in this scene should be saved, and this scene + // should always represent the saved settings, not the transient ones for + // a given emulation. + mag_state_load(&mag->state); mag_pin_variable_item_list_add( mag, "Input pin:", mag->state.pin_input, mag_scene_settings_set_gpio_input); @@ -75,11 +179,23 @@ void mag_scene_settings_on_enter(void* context) { mag_pin_variable_item_list_add( mag, "Enable pin:", mag->state.pin_enable, mag_scene_settings_set_gpio_enable); + mag_bool_variable_item_list_add( + mag, "Repeat default:", mag->state.repeat_mode, mag_scene_settings_set_repeat_mode); + + item = variable_item_list_add( + var_item_list, "# repeats: ", N_REPEATS_COUNT, mag_scene_settings_set_n_repeats, mag); + value_index = value_index_uint32(mag->state.n_repeats, n_repeats_value, N_REPEATS_COUNT); + variable_item_set_current_value_index(item, value_index); + variable_item_set_current_value_text(item, n_repeats_text[value_index]); + #ifndef FW_ORIGIN_Official - VariableItem* item = variable_item_list_add(var_item_list, "UART MSR: ", 1, NULL, mag); + item = variable_item_list_add(var_item_list, "UART MSR: ", 1, NULL, mag); variable_item_set_current_value_text(item, mag->state.allow_uart ? "ON" : "OFF"); #endif + //mag_bool_variable_item_list_add( + // mag, "UART MSR:", mag->state.allow_uart, mag_scene_settings_set_allow_uart); + variable_item_list_set_enter_callback( var_item_list, mag_scene_settings_var_item_list_callback, mag); diff --git a/picopass/.catalog/changelog.md b/picopass/.catalog/changelog.md index 3cb46eb2582..fd8b8c2f701 100644 --- a/picopass/.catalog/changelog.md +++ b/picopass/.catalog/changelog.md @@ -1,3 +1,6 @@ +## 1.14 + - Add plugin to parse some wiegand formats + - Store unknown blocks in picopass file with '??' ## 1.13 - Rework loclass writer with datetime lib ## 1.12 diff --git a/picopass/.gitsubtree b/picopass/.gitsubtree index de6ea5bde4f..47523116b85 100644 --- a/picopass/.gitsubtree +++ b/picopass/.gitsubtree @@ -1,2 +1,2 @@ https://github.com/xMasterX/all-the-plugins dev base_pack/picopass -https://github.com/flipperdevices/flipperzero-good-faps dev picopass +https://gitlab.com/bettse/picopass main / diff --git a/picopass/application.fam b/picopass/application.fam index 937387bdc2d..f03be3d8d96 100644 --- a/picopass/application.fam +++ b/picopass/application.fam @@ -14,7 +14,7 @@ App( ], stack_size=4 * 1024, fap_description="App to communicate with NFC tags using the PicoPass(iClass) format", - fap_version="1.13", + fap_version="1.14", fap_icon="125_10px.png", fap_category="NFC", fap_libs=["mbedtls"], diff --git a/picopass/icons/Nfc_10px.png b/picopass/icons/Nfc_10px.png new file mode 100644 index 0000000000000000000000000000000000000000..6bc027111a7517a8cd53bb511c064b834027c5a9 GIT binary patch literal 304 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2xkYHHq`AGmsv7|ftIx;Y9?C1WI$O_~uBzpw; zGB8xBF)%c=FfjZA3N^f7U???UV0e|lz+g3lfkC`r&aOZkpafHrx4R1i<>&pI=m5)b(dHL6nbwD9yPZ!4!j_b)k${QZ;XFmLn zjqNsD+YPq1J8W%_*aXBie!OR3*tC!PwU_7Q9H4U564!{5l*E!$tK_0oAjM#0U}UIk zV5)0q5@Kj%Wo%$&Y@uynU}a#izM}XGiiX_$l+3hBs0L%8o)7~QD^p9LQiz6svOM}g O4Gf;HelF{r5}E+GUQp8j literal 0 HcmV?d00001 diff --git a/picopass/icons/RFIDDolphinReceive_97x61.png b/picopass/icons/RFIDDolphinReceive_97x61.png new file mode 100644 index 0000000000000000000000000000000000000000..e1f5f9f8017b49ab1ea78a9394ed8ea7684e3083 GIT binary patch literal 1421 zcmaJ>eQXnD7{Agv#{x2p_yIvKhl^r%z3;AfTbW%yMuEcUiZn{X?&IxtS=&4BZnPU= zlx>i)WI>$aQvw7<5XB`bIuRj@1WD9@Lr2D(5=YPwGc*zsSTf&kEAj{7lDqeL-}m`F zpTFm}Rj;U;Sva>4L6DijCB86RMfkc4?C{(9_MQ1~dCu}jtr{(6r9=ZD9z~M?8cc|F zAPhvM>5U7Z96{_EH4?R=q2+?CB^+W_$B|Cx5RD+^6=_|R8-RsMpiWJ?vC&g!FjQ6C z*cvWGhIB8eSC=#!pr(06L~d@7c?GLjjFzVbXdnSB5ltuJNmEF>u?f2Zl(WYKhEAwh z4Q^~QsA#Af^=bw{oemP0Nz#dy@(x9mL|KwbP@1GEf@BGb#Ys|Nc!6cnsRx7Z3?(Ln zeSs-waOcMAElU>&B9%%xQj9}0>IjPGd4i+~n#Q39ZZ;(?F^wn9g*gj8V9JK7TdI~s zvlc~3YqZ=L40SSxgdPgrH=H!5Dg|psq(z;e93+uQWD}dvHmxxDKa7WJn~^3R5Mf|y zjfM;x5?h!9!{R;KQC1N~Bdj!3*cCDE)8xhkNLoRk8-q6vMO6faWjLq8D>(0>TsY@s zOL2+gT{ut5lFP+&G;q>6I}gJ}uK`3$Ga{N6&(WZ|Ub8f_Uei&p7kz1snpCuuxhUJA$%K8tP}c(` zU}y<+qQrvwF!u}>V`HR<(=n36VBt1B^`_fx&WPzU_AMY;oo7=&mIg2tu^u1f5 z)@y#lGg2HF{icooYxXeey6HJl+%===Q-Yg*f$J(< z+gbGCvVprluc__jmS6m=F>l7JjJ;Cb^sMdho~B4w{1|(u#k_H5R;4;`zs)u0gC*%S zI_>C5rsHbY>U}-r=8b&^Mh7zat>Eaqs$E;p%^t}^&M*C`d_!V*2g<#^ZLQq9;N6x= zv^)OzpYh#+OwHKfQ+kHHZreNi()*6Nw&PX5?kxF@U2EB*+}LH?toC1`{oRjksXb78 zx8u;V!Qv~6!ySjp4u16f-y8F;3}d=*b!=ao^)Gw)nS({6qa!CbyuwrWMvi?_zz4rL rb-KI#{JuTj%qEZPotyLfwj*}ruaRky;O7Gyvp>k7e}(TvWo_$!Vg&g_ literal 0 HcmV?d00001 diff --git a/picopass/icons/RFIDDolphinSend_97x61.png b/picopass/icons/RFIDDolphinSend_97x61.png new file mode 100644 index 0000000000000000000000000000000000000000..380a970d9004cba5520560fd9aa24aa42924e2a1 GIT binary patch literal 1418 zcmaJ>eQXnD7{6`EHeeAZ8ii;s2g4C}y=!}S>mBQswzrLLl$EYRfoyOe?`_T2-g$Sk z9pb2CPQ(a0XM$+dKhO~O0nx;1L}kUOGdh8Ve-^?LG)CD7lOfXp&bQl&{IPJ!-TS=n z`~05I-*YefH&^B@S+xW~kUZ~3J^)t%zRsL1_&wM?{Wx46Gs{C}t*V$YK?jISRz-k% zBSHfR06}hjW(brZNLC^o44EO{CQec#79pi$iAOYuMv#)SxF$$Vz(hsR5RN*rYhQeg zp<&sHZKHjpPxFAr@WwqlsNJ(UDD7#ISQ#rTMN8rwG!Ox%fW{-uQG<&+v01wulvBq9 zhR&*(O-^hssF2T(dQ=^tjD^G{l4Q_g)*=g{AcBJ%MzrGu-R~^fg7z+Q;6eHV@=uu4-82U zYi3xDqA81lsJ56+42C+FLqzlW?i!97^Ob@%BjSQaSS=(GiKG&n)i%rk_&3wK+`#f1_%uMx&~s9uHc$EgY5An6W<9p}B;4 zpogCYa)qu&(Ag4m;RW0?c3PnnQowBrN#lw@*>TY-L0(ZbMKQG9>QDeSkC*Q$-5f{Z z2~0stN5WYZfssX-#AS)L;{r{IxG2~K90(F6+7!i3SxJn5ArdLp+{2>u5u|2HygL+d zb9byj6wZ} zqrIB@aESUiV~B&zwY0sUci%;mf;cmkA+7cD0^$ih9{f{w;v_DJ`sY;R`f3( z?7BXf_vMbW zuU1_w753GAG_~{axB58aI?KM!#N|b)zyZV)ZU9QaOj9KuN$fX{&>fy=f`f8Io+CbZIMpovDCx1HL z?$&C^=R1DyispWLc%|FSKGs*ccUMOLz=7=zt7r7(!|y7;X08;c-@aJ>V5pwIR`S;) wTk7+73`}?J{<7dJ@~ literal 0 HcmV?d00001 diff --git a/picopass/picopass_device.c b/picopass/picopass_device.c index ea8352f5d04..42b5012c0bc 100644 --- a/picopass/picopass_device.c +++ b/picopass/picopass_device.c @@ -4,8 +4,6 @@ #include #include -#include - #include #include #include @@ -195,7 +193,8 @@ static bool picopass_device_save_file( furi_string_printf(temp_str, "%s/%s%s", folder, dev_name, extension); } - if(dev->format == PicopassDeviceSaveFormatHF || + if(dev->format == PicopassDeviceSaveFormatOriginal || + dev->format == PicopassDeviceSaveFormatLegacy || dev->format == PicopassDeviceSaveFormatPartial) { // Open file if(!flipper_format_file_open_always(file, furi_string_get_cstr(temp_str))) break; @@ -217,6 +216,12 @@ static bool picopass_device_save_file( for(size_t i = 0; i < app_limit; i++) { furi_string_printf(temp_str, "Block %d", i); if(card_data[i].valid) { + if(dev->format == PicopassDeviceSaveFormatLegacy) { + if(i == PICOPASS_ICLASS_PACS_CFG_BLOCK_INDEX) { + card_data[i].data[0] = 0x03; + } + } + if(!flipper_format_write_hex( file, furi_string_get_cstr(temp_str), @@ -251,7 +256,7 @@ static bool picopass_device_save_file( } bool picopass_device_save(PicopassDevice* dev, const char* dev_name) { - if(dev->format == PicopassDeviceSaveFormatHF) { + if(dev->format == PicopassDeviceSaveFormatOriginal) { return picopass_device_save_file( dev, dev_name, STORAGE_APP_DATA_PATH_PREFIX, PICOPASS_APP_EXTENSION, true); } else if(dev->format == PicopassDeviceSaveFormatLF) { @@ -262,6 +267,11 @@ bool picopass_device_save(PicopassDevice* dev, const char* dev_name) { } else if(dev->format == PicopassDeviceSaveFormatPartial) { return picopass_device_save_file( dev, dev_name, STORAGE_APP_DATA_PATH_PREFIX, PICOPASS_APP_EXTENSION, true); + } else if(dev->format == PicopassDeviceSaveFormatLegacy) { + return picopass_device_save_file( + dev, dev_name, STORAGE_APP_DATA_PATH_PREFIX, PICOPASS_APP_EXTENSION, true); + } else { + FURI_LOG_E(TAG, "Unknown format"); } return false; @@ -384,7 +394,7 @@ void picopass_device_clear(PicopassDevice* dev) { picopass_device_data_clear(&dev->dev_data); memset(&dev->dev_data, 0, sizeof(dev->dev_data)); - dev->format = PicopassDeviceSaveFormatHF; + dev->format = PicopassDeviceSaveFormatOriginal; furi_string_reset(dev->load_path); } @@ -443,7 +453,7 @@ void picopass_device_data_clear(PicopassDeviceData* dev_data) { bool picopass_device_delete(PicopassDevice* dev, bool use_load_path) { furi_assert(dev); - if(dev->format != PicopassDeviceSaveFormatHF) { + if(dev->format != PicopassDeviceSaveFormatOriginal) { // Never delete other formats (LF, Seader, etc) return false; } diff --git a/picopass/picopass_device.h b/picopass/picopass_device.h index 78ed6645c09..ea0ec6c911e 100644 --- a/picopass/picopass_device.h +++ b/picopass/picopass_device.h @@ -68,7 +68,8 @@ typedef enum { } PicopassEncryption; typedef enum { - PicopassDeviceSaveFormatHF, + PicopassDeviceSaveFormatOriginal, + PicopassDeviceSaveFormatLegacy, PicopassDeviceSaveFormatLF, PicopassDeviceSaveFormatSeader, PicopassDeviceSaveFormatPartial, diff --git a/picopass/picopass_i.h b/picopass/picopass_i.h index a2eb79f77ea..0dd687dc170 100644 --- a/picopass/picopass_i.h +++ b/picopass/picopass_i.h @@ -29,8 +29,6 @@ #include #include -#include - #include #include #include "protocol/picopass_poller.h" diff --git a/picopass/scenes/picopass_scene_card_menu.c b/picopass/scenes/picopass_scene_card_menu.c index 9d44f5642d9..7d643d8ec06 100644 --- a/picopass/scenes/picopass_scene_card_menu.c +++ b/picopass/scenes/picopass_scene_card_menu.c @@ -9,6 +9,7 @@ enum SubmenuIndex { SubmenuIndexWrite, SubmenuIndexEmulate, SubmenuIndexSavePartial, + SubmenuIndexSaveLegacy, }; void picopass_scene_card_menu_submenu_callback(void* context, uint32_t index) { @@ -27,7 +28,8 @@ void picopass_scene_card_menu_on_enter(void* context) { bool SE = card_data[PICOPASS_ICLASS_PACS_CFG_BLOCK_INDEX].valid && 0x30 == card_data[PICOPASS_ICLASS_PACS_CFG_BLOCK_INDEX].data[0]; - bool SR = card_data[10].valid && 0x30 == card_data[10].data[0]; + bool SR = card_data[PICOPASS_ICLASS_PACS_CFG_BLOCK_INDEX].data[0] == 0xA3 && + card_data[10].valid && 0x30 == card_data[10].data[0]; bool has_sio = SE || SR; bool secured = (card_data[PICOPASS_CONFIG_BLOCK_INDEX].data[7] & PICOPASS_FUSE_CRYPT10) != PICOPASS_FUSE_CRYPT0; @@ -62,6 +64,15 @@ void picopass_scene_card_menu_on_enter(void* context) { picopass_scene_card_menu_submenu_callback, picopass); + if(SR) { + submenu_add_item( + submenu, + "Save as Legacy", + SubmenuIndexSaveLegacy, + picopass_scene_card_menu_submenu_callback, + picopass); + } + if(plugin) { // Convert from byte array to uint64_t uint64_t credential = 0; @@ -119,7 +130,7 @@ bool picopass_scene_card_menu_on_event(void* context, SceneManagerEvent event) { scene_manager_set_scene_state( picopass->scene_manager, PicopassSceneCardMenu, SubmenuIndexSave); scene_manager_next_scene(picopass->scene_manager, PicopassSceneSaveName); - picopass->dev->format = PicopassDeviceSaveFormatHF; + picopass->dev->format = PicopassDeviceSaveFormatOriginal; consumed = true; } else if(event.event == SubmenuIndexSavePartial) { scene_manager_set_scene_state( @@ -155,6 +166,12 @@ bool picopass_scene_card_menu_on_event(void* context, SceneManagerEvent event) { picopass->scene_manager, PicopassSceneCardMenu, SubmenuIndexParse); scene_manager_next_scene(picopass->scene_manager, PicopassSceneFormats); consumed = true; + } else if(event.event == SubmenuIndexSaveLegacy) { + scene_manager_set_scene_state( + picopass->scene_manager, PicopassSceneCardMenu, SubmenuIndexSaveLegacy); + picopass->dev->format = PicopassDeviceSaveFormatLegacy; + scene_manager_next_scene(picopass->scene_manager, PicopassSceneSaveName); + consumed = true; } } else if(event.type == SceneManagerEventTypeBack) { consumed = scene_manager_search_and_switch_to_previous_scene( diff --git a/picopass/views/dict_attack.h b/picopass/views/dict_attack.h index 9cd6af569a9..998ac295e20 100644 --- a/picopass/views/dict_attack.h +++ b/picopass/views/dict_attack.h @@ -4,8 +4,6 @@ #include #include -#include - typedef struct DictAttack DictAttack; typedef void (*DictAttackCallback)(void* context); diff --git a/qrcode/.github/workflows/release.yml b/qrcode/.github/workflows/release.yml index c4ff8a01519..1e30a2a43f3 100644 --- a/qrcode/.github/workflows/release.yml +++ b/qrcode/.github/workflows/release.yml @@ -6,7 +6,7 @@ on: - 'v[0-9]+.[0-9]+.[0-9]+' env: - firmware_version: '0.100.3' + firmware_version: '0.101.2' jobs: build: diff --git a/subghz_bruteforcer/LICENSE b/subghz_bruteforcer/LICENSE index 8fb0d138897..0a456052c07 100644 --- a/subghz_bruteforcer/LICENSE +++ b/subghz_bruteforcer/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2023 DerSkythe +Copyright (c) 2024 DerSkythe Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/subghz_bruteforcer/README.md b/subghz_bruteforcer/README.md index ad8453fff0e..b7fd8caa4ac 100644 --- a/subghz_bruteforcer/README.md +++ b/subghz_bruteforcer/README.md @@ -14,32 +14,36 @@ We do not condone illegal activity and strongly encourage keeping transmissions ## Installation -The application is included in the standard firmware package of [Unleashed Firmware](https://github.com/DarkFlippers/unleashed-firmware). +The application is included in the standard firmware package of [Unleashed Firmware](https://github.com/DarkFlippers/unleashed-firmware). You just need to install the [latest firmware](https://github.com/DarkFlippers/unleashed-firmware/releases/latest).
You can also download the [release](https://github.com/derskythe/flipperzero-subbrute/releases/latest) and unzip/untar it to the `SD Card/apps/Sub-GHz` directory.
> [!WARNING] -> +> > The application is not compatible with the official firmware version. > Also, it has not been tested on other firmware versions other than [Unleashed Firmware](https://github.com/DarkFlippers/unleashed-firmware) and [OFW](https://github.com/flipperdevices/flipperzero-firmware). +--- + ## User Guide ### Main Menu ![image](https://github.com/DarkFlippers/flipperzero-subbrute/assets/31771569/9f428d6e-59fd-4517-895d-fb185f8d884f) -Here you can select the protocol and frequency that will be used for bruteforce. -According to our observations, `CAME 12bit 433MHz` is the most common protocol, so it is selected by default. -To identify other devices and protocols, you should inspect the device. -According to the protocol, when probe a key, each value is sent 3 times. -Most of the devices this works but there are devices that don't work and more repetitions are needed. -The number of repetitions can be increased with the right button, the left button decreases the value. -The negative side of increasing the number of repetitions will be a longer key find time. +

Here you can select the protocol and frequency that will be used for bruteforce.

+

According to our observations, `CAME 12bit 433MHz` is the most common protocol, so it is selected by default. +To identify other devices and protocols, you should inspect the device.

+

According to the protocol, when probe a key, each value is sent 3 times.

+

Most of the devices this works but there are devices that don't work and more repetitions are needed.

+

The number of repetitions can be increased with the right button, the left button decreases the value.

+

The negative side of increasing the number of repetitions will be a longer key find time.

![image](https://github.com/DarkFlippers/flipperzero-subbrute/assets/31771569/a17695d0-833d-44ce-a0d0-ead8366cb4fe) +--- + #### Buttons | Button | Action | @@ -51,6 +55,8 @@ The negative side of increasing the number of repetitions will be a longer key f | :record_button: | Select protocol | | :leftwards_arrow_with_hook: | Close application | +--- + ## Supported Protocols ![image](https://github.com/DarkFlippers/flipperzero-subbrute/assets/31771569/1f14b5eb-7e66-4b37-b816-34fab63db70c) @@ -88,6 +94,7 @@ The negative side of increasing the number of repetitions will be a longer key f - Chamberlain 9bit 300MHz - Chamberlain 9bit 315MHz +- Chamberlain 9bit 318MHz - Chamberlain 9bit 390MHz - Chamberlain 9bit 433MHz - Chamberlain 8bit 300MHz @@ -106,7 +113,7 @@ The negative side of increasing the number of repetitions will be a longer key f ### UNILARM > [!NOTE] -> +> > Only dip switch combinations, not full 25bit bruteforce - UNILARM 25bit 330MHz (TE: 209μs) @@ -115,7 +122,7 @@ The negative side of increasing the number of repetitions will be a longer key f ### SMC5326 > [!NOTE] -> +> > Only dip switch combinations, not full 25bit bruteforce - SMC5326 25bit 330MHz (TE: 320μs) @@ -124,7 +131,7 @@ The negative side of increasing the number of repetitions will be a longer key f ### PT2260 > [!NOTE] -> +> > Only for 8 dip switch remote, not full 24bit bruteforce - PT2260 24bit 315MHz (TE: 286μs) diff --git a/subghz_bruteforcer/helpers/subbrute_radio_device_loader.c b/subghz_bruteforcer/helpers/subbrute_radio_device_loader.c index 6fcfde8726f..9a7a1fe24d5 100644 --- a/subghz_bruteforcer/helpers/subbrute_radio_device_loader.c +++ b/subghz_bruteforcer/helpers/subbrute_radio_device_loader.c @@ -46,6 +46,7 @@ bool subbrute_radio_device_loader_is_connect_external(const char* name) { if(!is_otg_enabled) { subbrute_radio_device_loader_power_off(); } + return is_connect; } diff --git a/subghz_bruteforcer/helpers/subbrute_worker.c b/subghz_bruteforcer/helpers/subbrute_worker.c index 2061f7c8187..4cf2104ea8e 100644 --- a/subghz_bruteforcer/helpers/subbrute_worker.c +++ b/subghz_bruteforcer/helpers/subbrute_worker.c @@ -72,6 +72,7 @@ bool subbrute_worker_set_step(SubBruteWorker* instance, uint64_t step) { furi_assert(instance); if(!subbrute_worker_can_manual_transmit(instance)) { FURI_LOG_W(TAG, "Cannot set step during running mode"); + return false; } @@ -264,21 +265,14 @@ bool subbrute_worker_transmit_current_key(SubBruteWorker* instance, uint64_t ste stream, instance->file, step, instance->bits, instance->te, instance->repeat); } - // size_t written = stream_write_string(stream, payload); - // if(written <= 0) { - // FURI_LOG_W(TAG, "Error creating packet! EXIT"); - // result = false; - // } else { subbrute_worker_subghz_transmit(instance, flipper_format); result = true; #if FURI_DEBUG FURI_LOG_D(TAG, "Manual transmit done"); #endif - // } flipper_format_free(flipper_format); - // furi_string_free(payload); return result; } @@ -366,11 +360,13 @@ int32_t subbrute_worker_thread(void* context) { if(!instance->worker_running) { FURI_LOG_W(TAG, "Worker is not set to running state!"); + return -1; } if(instance->state != SubBruteWorkerStateReady && instance->state != SubBruteWorkerStateFinished) { FURI_LOG_W(TAG, "Invalid state for running worker! State: %d", instance->state); + return -2; } #ifdef FURI_DEBUG @@ -411,15 +407,6 @@ int32_t subbrute_worker_thread(void* context) { //furi_delay_ms(SUBBRUTE_MANUAL_TRANSMIT_INTERVAL / 4); #endif - // size_t written = stream_write_stream_write_string(stream, payload); - // if(written <= 0) { - // FURI_LOG_W(TAG, "Error creating packet! BREAK"); - // instance->worker_running = false; - // local_state = SubBruteWorkerStateIDLE; - // furi_string_free(payload); - // break; - // } - subbrute_worker_subghz_transmit(instance, flipper_format); if(instance->step + 1 > instance->max_value) { @@ -427,12 +414,11 @@ int32_t subbrute_worker_thread(void* context) { FURI_LOG_I(TAG, "Worker finished to end"); #endif local_state = SubBruteWorkerStateFinished; - // furi_string_free(payload); + break; } instance->step++; - // furi_string_free(payload); furi_delay_ms(instance->tx_timeout_ms); } @@ -446,6 +432,7 @@ int32_t subbrute_worker_thread(void* context) { #ifdef FURI_DEBUG FURI_LOG_I(TAG, "Worker stop"); #endif + return 0; } @@ -473,18 +460,6 @@ void subbrute_worker_set_te(SubBruteWorker* instance, uint32_t te) { instance->te = te; } -// void subbrute_worker_timeout_inc(SubBruteWorker* instance) { -// if(instance->tx_timeout_ms < 255) { -// instance->tx_timeout_ms++; -// } -// } - -// void subbrute_worker_timeout_dec(SubBruteWorker* instance) { -// if(instance->tx_timeout_ms > 0) { -// instance->tx_timeout_ms--; -// } -// } - bool subbrute_worker_is_tx_allowed(SubBruteWorker* instance, uint32_t value) { furi_assert(instance); bool res = false; diff --git a/subghz_bruteforcer/scenes/subbrute_scene_load_file.c b/subghz_bruteforcer/scenes/subbrute_scene_load_file.c index 391001a54a9..aa787694071 100644 --- a/subghz_bruteforcer/scenes/subbrute_scene_load_file.c +++ b/subghz_bruteforcer/scenes/subbrute_scene_load_file.c @@ -91,5 +91,6 @@ void subbrute_scene_load_file_on_exit(void* context) { bool subbrute_scene_load_file_on_event(void* context, SceneManagerEvent event) { UNUSED(context); UNUSED(event); + return false; } diff --git a/subghz_bruteforcer/scenes/subbrute_scene_save_name.c b/subghz_bruteforcer/scenes/subbrute_scene_save_name.c index 7628a477a8c..4a82ff95319 100644 --- a/subghz_bruteforcer/scenes/subbrute_scene_save_name.c +++ b/subghz_bruteforcer/scenes/subbrute_scene_save_name.c @@ -76,6 +76,7 @@ bool subbrute_scene_save_name_on_event(void* context, SceneManagerEvent event) { instance->scene_manager, SubBruteSceneSetupAttack); } } + return consumed; } diff --git a/subghz_bruteforcer/scenes/subbrute_scene_save_success.c b/subghz_bruteforcer/scenes/subbrute_scene_save_success.c index 127f3a0aa1f..ef33456efc0 100644 --- a/subghz_bruteforcer/scenes/subbrute_scene_save_success.c +++ b/subghz_bruteforcer/scenes/subbrute_scene_save_success.c @@ -31,6 +31,7 @@ bool subbrute_scene_save_success_on_event(void* context, SceneManagerEvent event return true; } } + return false; } diff --git a/subghz_bruteforcer/scenes/subbrute_scene_setup_extra.c b/subghz_bruteforcer/scenes/subbrute_scene_setup_extra.c index 5e8e05bc9ba..ef26b5d99de 100644 --- a/subghz_bruteforcer/scenes/subbrute_scene_setup_extra.c +++ b/subghz_bruteforcer/scenes/subbrute_scene_setup_extra.c @@ -22,7 +22,7 @@ static void setup_extra_td_callback(VariableItem* item) { furi_assert(item); SubBruteState* instance = variable_item_get_context(item); furi_assert(instance); - char buf[6]; + char buf[6] = {0}; const uint8_t index = variable_item_get_current_value_index(item); uint8_t val = subbrute_worker_get_timeout(instance->worker); @@ -76,7 +76,7 @@ static void setup_extra_rep_callback(VariableItem* item) { furi_assert(item); SubBruteState* instance = variable_item_get_context(item); furi_assert(instance); - char buf[6]; + char buf[6] = {0}; const uint8_t index = variable_item_get_current_value_index(item); uint8_t val = subbrute_worker_get_repeats(instance->worker); @@ -130,7 +130,7 @@ static void setup_extra_te_callback(VariableItem* item) { furi_assert(item); SubBruteState* instance = variable_item_get_context(item); furi_assert(instance); - char buf[6]; + char buf[6] = {0}; const uint8_t index = variable_item_get_current_value_index(item); uint32_t val = subbrute_worker_get_te(instance->worker); @@ -182,7 +182,7 @@ static void setup_extra_te_callback(VariableItem* item) { static void subbrute_scene_setup_extra_init_var_list(SubBruteState* instance, bool on_extra) { furi_assert(instance); - char str[6]; + char str[6] = {0}; VariableItem* item; static bool extra = false; if(on_extra) { @@ -254,7 +254,7 @@ static void subbrute_scene_setup_extra_init_var_list(SubBruteState* instance, bo static void setup_extra_enter_callback(void* context, uint32_t index) { furi_assert(context); - SubBruteState* instance = context; + SubBruteState* instance = (SubBruteState*)context; if(index == SubBruteVarListIndexRepeatOrOnExtra) { subbrute_scene_setup_extra_init_var_list(instance, true); @@ -263,14 +263,14 @@ static void setup_extra_enter_callback(void* context, uint32_t index) { void subbrute_scene_setup_extra_on_enter(void* context) { furi_assert(context); - SubBruteState* instance = context; + SubBruteState* instance = (SubBruteState*)context; subbrute_scene_setup_extra_init_var_list(instance, false); } void subbrute_scene_setup_extra_on_exit(void* context) { furi_assert(context); - SubBruteState* instance = context; + SubBruteState* instance = (SubBruteState*)context; variable_item_list_reset(instance->var_list); } diff --git a/subghz_bruteforcer/subbrute_device.c b/subghz_bruteforcer/subbrute_device.c index bc0c754a8bf..ec854d63218 100644 --- a/subghz_bruteforcer/subbrute_device.c +++ b/subghz_bruteforcer/subbrute_device.c @@ -21,11 +21,8 @@ SubBruteDevice* subbrute_device_alloc(const SubGhzDevice* radio_device) { instance->radio_device = radio_device; - //#ifdef FURI_DEBUG - // subbrute_device_attack_set_default_values(instance, SubBruteAttackLoadFile); - //#else subbrute_device_attack_set_default_values(instance, SubBruteAttackCAME12bit433); - //#endif + return instance; } diff --git a/subghz_bruteforcer/subbrute_i.h b/subghz_bruteforcer/subbrute_i.h index 54bf2cef7e2..cae53bdbfb5 100644 --- a/subghz_bruteforcer/subbrute_i.h +++ b/subghz_bruteforcer/subbrute_i.h @@ -33,7 +33,7 @@ #include "views/subbrute_attack_view.h" #include "views/subbrute_main_view.h" -#define SUBBRUTEFORCER_VER "Sub-GHz BruteForcer 3.B" +#define SUBBRUTEFORCER_VER "Sub-GHz BruteForcer 3.C" #ifdef FURI_DEBUG //#define SUBBRUTE_FAST_TRACK false diff --git a/subghz_bruteforcer/subbrute_protocols.c b/subghz_bruteforcer/subbrute_protocols.c index 8ca5bb51869..8c69b2fb58d 100644 --- a/subghz_bruteforcer/subbrute_protocols.c +++ b/subghz_bruteforcer/subbrute_protocols.c @@ -146,6 +146,17 @@ const SubBruteProtocol subbrute_protocol_chamberlain_9bit_315 = { .preset = FuriHalSubGhzPresetOok650Async, .file = ChamberlainFileProtocol}; +/** + * Chamberlain 9bit 318MHz + */ +const SubBruteProtocol subbrute_protocol_chamberlain_9bit_318 = { + .frequency = 318000000, + .bits = 9, + .te = 0, + .repeat = 3, + .preset = FuriHalSubGhzPresetOok650Async, + .file = ChamberlainFileProtocol}; + /** * Chamberlain 9bit 390MHz */ @@ -435,6 +446,7 @@ static const char* subbrute_protocol_names[] = { [SubBruteAttackHoltek12bitAM915] = "Holtek AM 12bit 915MHz", [SubBruteAttackChamberlain9bit300] = "Chamberlain 9bit 300MHz", [SubBruteAttackChamberlain9bit315] = "Chamberlain 9bit 315MHz", + [SubBruteAttackChamberlain9bit318] = "Chamberlain 9bit 318MHz", [SubBruteAttackChamberlain9bit390] = "Chamberlain 9bit 390MHz", [SubBruteAttackChamberlain9bit433] = "Chamberlain 9bit 433MHz", [SubBruteAttackChamberlain8bit300] = "Chamberlain 8bit 300MHz", @@ -487,6 +499,7 @@ const SubBruteProtocol* subbrute_protocol_registry[] = { [SubBruteAttackHoltek12bitAM915] = &subbrute_protocol_holtek_12bit_am_915, [SubBruteAttackChamberlain9bit300] = &subbrute_protocol_chamberlain_9bit_300, [SubBruteAttackChamberlain9bit315] = &subbrute_protocol_chamberlain_9bit_315, + [SubBruteAttackChamberlain9bit318] = &subbrute_protocol_chamberlain_9bit_318, [SubBruteAttackChamberlain9bit390] = &subbrute_protocol_chamberlain_9bit_390, [SubBruteAttackChamberlain9bit433] = &subbrute_protocol_chamberlain_9bit_433, [SubBruteAttackChamberlain8bit300] = &subbrute_protocol_chamberlain_8bit_300, @@ -828,8 +841,6 @@ void subbrute_protocol_file_generate_file( uint64_t file_key, bool two_bytes) { FuriString* candidate = furi_string_alloc(); - // char subbrute_payload_byte[8]; - //furi_string_set_str(candidate, file_key); subbrute_protocol_create_candidate_for_existing_file( candidate, step, bit_index, file_key, two_bytes); diff --git a/subghz_bruteforcer/subbrute_protocols.h b/subghz_bruteforcer/subbrute_protocols.h index 1fe4ef2a94a..0dfa1a91208 100644 --- a/subghz_bruteforcer/subbrute_protocols.h +++ b/subghz_bruteforcer/subbrute_protocols.h @@ -90,6 +90,7 @@ typedef enum { * - `SubBruteAttackHoltek12bitAM915`: Holtek 12-bit AM 915 MHz sub-brute attack. * - `SubBruteAttackChamberlain9bit300`: Chamberlain 9-bit 300 MHz sub-brute attack. * - `SubBruteAttackChamberlain9bit315`: Chamberlain 9-bit 315 MHz sub-brute attack. + * - `SubBruteAttackChamberlain9bit318`: Chamberlain 9-bit 318 MHz sub-brute attack. * - `SubBruteAttackChamberlain9bit390`: Chamberlain 9-bit 390 MHz sub-brute attack. * - `SubBruteAttackChamberlain9bit433`: Chamberlain 9-bit 433 MHz sub-brute attack. * - `SubBruteAttackChamberlain8bit300`: Chamberlain 8-bit 300 MHz sub-brute attack. @@ -131,6 +132,7 @@ typedef enum { SubBruteAttackHoltek12bitAM915, SubBruteAttackChamberlain9bit300, SubBruteAttackChamberlain9bit315, + SubBruteAttackChamberlain9bit318, SubBruteAttackChamberlain9bit390, SubBruteAttackChamberlain9bit433, SubBruteAttackChamberlain8bit300, diff --git a/subghz_bruteforcer/views/subbrute_attack_view.c b/subghz_bruteforcer/views/subbrute_attack_view.c index b41ff7635c6..24ce12cbcf7 100644 --- a/subghz_bruteforcer/views/subbrute_attack_view.c +++ b/subghz_bruteforcer/views/subbrute_attack_view.c @@ -195,9 +195,7 @@ View* subbrute_attack_view_get_view(SubBruteAttackView* instance) { void subbrute_attack_view_set_current_step(SubBruteAttackView* instance, uint64_t current_step) { furi_assert(instance); -#ifdef FURI_DEBUG - //FURI_LOG_D(TAG, "Set step: %d", current_step); -#endif + instance->current_step = current_step; with_view_model( instance->view, @@ -228,7 +226,6 @@ void subbrute_attack_view_init_values( instance->max_value = max_value; instance->current_step = current_step; instance->is_attacking = is_attacking; - // instance->extra_repeats = extra_repeats; with_view_model( instance->view, @@ -264,7 +261,7 @@ void subbrute_attack_view_exit(void* context) { void subbrute_attack_view_draw(Canvas* canvas, void* context) { furi_assert(context); SubBruteAttackViewModel* model = (SubBruteAttackViewModel*)context; - char buffer[64]; + char buffer[64] = {0}; const char* attack_name = NULL; attack_name = subbrute_protocol_name(model->attack_type); diff --git a/subghz_bruteforcer/views/subbrute_main_view.c b/subghz_bruteforcer/views/subbrute_main_view.c index de40670b6d7..454024c344c 100644 --- a/subghz_bruteforcer/views/subbrute_main_view.c +++ b/subghz_bruteforcer/views/subbrute_main_view.c @@ -109,9 +109,6 @@ void subbrute_main_view_center_displayed_key( } void subbrute_main_view_draw_is_byte_selected(Canvas* canvas, SubBruteMainViewModel* model) { -#ifdef FURI_DEBUG - //FURI_LOG_D(TAG, "key_from_file: %s", model->key_from_file); -#endif canvas_set_font(canvas, FontSecondary); canvas_draw_str_aligned( canvas, 64, 17, AlignCenter, AlignTop, "Please select values to calc:"); @@ -152,9 +149,6 @@ void subbrute_main_view_draw_is_ordinary_selected(Canvas* canvas, SubBruteMainVi const uint8_t item_height = 16; const uint8_t string_height_offset = 9; -#ifdef FURI_DEBUG - //FURI_LOG_D(TAG, "window_position: %d, index: %d", model->window_position, model->index); -#endif for(size_t position = 0; position < SubBruteAttackTotalCount; ++position) { uint8_t item_position = position - model->window_position; @@ -189,7 +183,7 @@ void subbrute_main_view_draw_is_ordinary_selected(Canvas* canvas, SubBruteMainVi #else canvas_set_font(canvas, FontBatteryPercent); #endif - char buffer[10]; + char buffer[10] = {0}; snprintf(buffer, sizeof(buffer), "x%d", current_repeat_count); uint8_t temp_x_offset_repeats = current_repeat_count <= SUBBRUTE_PROTOCOL_MAX_REPEATS ? 15 : 18; @@ -230,11 +224,13 @@ bool subbrute_main_view_input_file_protocol(InputEvent* event, SubBruteMainView* (instance->two_bytes && instance->index > 1)) { instance->index--; } + updated = true; } else if(event->key == InputKeyRight) { if(instance->index < 7) { instance->index++; } + updated = true; } else if(event->key == InputKeyUp) { instance->two_bytes = !instance->two_bytes; @@ -242,14 +238,11 @@ bool subbrute_main_view_input_file_protocol(InputEvent* event, SubBruteMainView* if(instance->two_bytes && instance->index < 7) { instance->index++; } - // instance->callback( - // instance->two_bytes ? SubBruteCustomEventTypeChangeStepUp : - // SubBruteCustomEventTypeChangeStepDown, - // instance->context); updated = true; } else if(event->key == InputKeyOk) { instance->callback(SubBruteCustomEventTypeIndexSelected, instance->context); + updated = true; } return updated; @@ -273,7 +266,7 @@ bool subbrute_main_view_input_ordinary_protocol( } else { instance->index = CLAMP(index - 1, correct_total, min_value); } - //instance->repeat_values = 0; + updated = true; } else if(event->key == InputKeyDown && is_short) { if(index == correct_total) { @@ -281,7 +274,7 @@ bool subbrute_main_view_input_ordinary_protocol( } else { instance->index = CLAMP(index + 1, correct_total, min_value); } - //instance->repeat_values = 0; + updated = true; } else if(event->key == InputKeyLeft && is_short) { instance->repeat_values[index] = CLAMP(current_repeats - 1, max_repeats, min_repeats); @@ -297,6 +290,7 @@ bool subbrute_main_view_input_ordinary_protocol( } else { instance->callback(SubBruteCustomEventTypeMenuSelected, instance->context); } + updated = true; } @@ -322,7 +316,7 @@ bool subbrute_main_view_input(InputEvent* event, void* context) { furi_assert(event); furi_assert(context); - SubBruteMainView* instance = context; + SubBruteMainView* instance = (SubBruteMainView*)context; if(event->key == InputKeyBack && event->type == InputTypeShort) { #ifdef FURI_DEBUG @@ -417,6 +411,7 @@ void subbrute_main_view_free(SubBruteMainView* instance) { View* subbrute_main_view_get_view(SubBruteMainView* instance) { furi_assert(instance); + return instance->view; } @@ -460,6 +455,7 @@ void subbrute_main_view_set_index( model->key_from_file = instance->key_from_file; model->is_select_byte = instance->is_select_byte; model->two_bytes = instance->two_bytes; + for(size_t i = 0; i < SubBruteAttackTotalCount; i++) { model->repeat_values[i] = repeats[i]; } @@ -469,15 +465,18 @@ void subbrute_main_view_set_index( SubBruteAttacks subbrute_main_view_get_index(SubBruteMainView* instance) { furi_assert(instance); + return instance->index; } const uint8_t* subbrute_main_view_get_repeats(SubBruteMainView* instance) { furi_assert(instance); + return instance->repeat_values; } bool subbrute_main_view_get_two_bytes(SubBruteMainView* instance) { furi_assert(instance); + return instance->two_bytes; }