Willy-JL %!s(int64=2) %!d(string=hai) anos
pai
achega
311b0a9c74

+ 1 - 0
magspoof/.gitsubtree

@@ -1 +1,2 @@
+https://github.com/hummusec/magspoof_flipper main /
 https://github.com/xMasterX/all-the-plugins dev non_catalog_apps/magspoof_flipper
 https://github.com/xMasterX/all-the-plugins dev non_catalog_apps/magspoof_flipper

+ 10 - 1
magspoof/README.md

@@ -1,8 +1,17 @@
-# magspoof_flipper
+# magspoof_flipper by Zachary Weiss
 WIP of MagSpoof for the Flipper Zero. Basic TX of saved files confirmed working against an MSR90 with an external H-bridge module mirroring Samy Kamkar's design. RFID coil output weaker; able to be picked up/detected by more compact mag readers such as Square, but yet to have success with it being decoded/parsed properly. Additional investigation into alternate internal TX options (CC1101, ST25R3916, piezo) underway; tentatively, RFID coil + speaker (`LF + P` config setting) results in the strongest internal TX tested to date but still weaker than a dedicated external module or an actual card swipe (and sounds like a dial-up modem from hell). Sample files with test data are included in `assets` for anyone wishing to experiment.
 WIP of MagSpoof for the Flipper Zero. Basic TX of saved files confirmed working against an MSR90 with an external H-bridge module mirroring Samy Kamkar's design. RFID coil output weaker; able to be picked up/detected by more compact mag readers such as Square, but yet to have success with it being decoded/parsed properly. Additional investigation into alternate internal TX options (CC1101, ST25R3916, piezo) underway; tentatively, RFID coil + speaker (`LF + P` config setting) results in the strongest internal TX tested to date but still weaker than a dedicated external module or an actual card swipe (and sounds like a dial-up modem from hell). Sample files with test data are included in `assets` for anyone wishing to experiment.
 
 
 Disclaimer: use responsibly, and at your own risk. While in my testing, I've seen no reason to believe this could damage the RFID (or other) hardware, this is inherently driving the coil in ways it was not designed or intended for; I take no responsibility for fried/bricked Flippers. Similarly, please only use this with magstripe cards and mag readers you own — this is solely meant as a proof of concept for educational purposes. I neither condone nor am sympathetic to malicious uses of my code.
 Disclaimer: use responsibly, and at your own risk. While in my testing, I've seen no reason to believe this could damage the RFID (or other) hardware, this is inherently driving the coil in ways it was not designed or intended for; I take no responsibility for fried/bricked Flippers. Similarly, please only use this with magstripe cards and mag readers you own — this is solely meant as a proof of concept for educational purposes. I neither condone nor am sympathetic to malicious uses of my code.
 
 
+## Hummus's Fork
+I made this fork initially to add reading capability using UART magnetic card readers.
+
+Things that changed in this fork:
+- Added a basic card reading ability
+- Added a function to parse a new MagDevice from a Card String (%Track1?;Track2;Track3?;)
+- Swapped the pins between A6 to A7 on the card that I'm using, might add this to configuration scene later on
+- Adapted some of the APIs to the most recent firmware changes.
+
 ## Optional GPIO TX Module
 ## Optional GPIO TX Module
 For those desiring better TX than the internal RFID coil can offer, one can build the module below, consisting of an H-bridge, a capacitor, and a coil.
 For those desiring better TX than the internal RFID coil can offer, one can build the module below, consisting of an H-bridge, a capacitor, and a coil.
 
 

+ 4 - 2
magspoof/application.fam

@@ -1,6 +1,6 @@
 App(
 App(
-    appid="mag",
-    name="MagSpoof",
+    appid="magspoof",
+    name="[MAG] MagSpoof",
     apptype=FlipperAppType.EXTERNAL,
     apptype=FlipperAppType.EXTERNAL,
     entry_point="mag_app",
     entry_point="mag_app",
     cdefines=["APP_MAG"],
     cdefines=["APP_MAG"],
@@ -10,12 +10,14 @@ App(
         "notification",
         "notification",
         "dialogs",
         "dialogs",
     ],
     ],
+    resources="resources",
     provides=[],
     provides=[],
     stack_size=6 * 1024,
     stack_size=6 * 1024,
     order=64,  # keep it at the bottom of the list while still WIP
     order=64,  # keep it at the bottom of the list while still WIP
     fap_icon="icons/mag_10px.png",
     fap_icon="icons/mag_10px.png",
     fap_category="GPIO",
     fap_category="GPIO",
     fap_icon_assets="icons",
     fap_icon_assets="icons",
+    fap_icon_assets_symbol="mag",
     fap_version=(0, 5),  # major, minor
     fap_version=(0, 5),  # major, minor
     fap_description="WIP MagSpoof port using the RFID subsystem",
     fap_description="WIP MagSpoof port using the RFID subsystem",
     fap_author="Zachary Weiss",
     fap_author="Zachary Weiss",

+ 0 - 583
magspoof/helpers/mag_text_input.c

@@ -1,583 +0,0 @@
-#include "mag_text_input.h"
-#include <gui/elements.h>
-#include <assets_icons.h>
-#include <furi.h>
-
-struct Mag_TextInput {
-    View* view;
-    FuriTimer* timer;
-};
-
-typedef struct {
-    const char text;
-    const uint8_t x;
-    const uint8_t y;
-} Mag_TextInputKey;
-
-typedef struct {
-    const char* header;
-    char* text_buffer;
-    size_t text_buffer_size;
-    bool clear_default_text;
-
-    Mag_TextInputCallback callback;
-    void* callback_context;
-
-    uint8_t selected_row;
-    uint8_t selected_column;
-
-    // Mag_TextInputValidatorCallback validator_callback;
-    // void* validator_callback_context;
-    // FuriString* validator_text;
-    // bool validator_message_visible;
-} Mag_TextInputModel;
-
-static const uint8_t keyboard_origin_x = 1;
-static const uint8_t keyboard_origin_y = 29;
-static const uint8_t keyboard_row_count = 3;
-
-#define ENTER_KEY '\r'
-#define BACKSPACE_KEY '\b'
-
-static const Mag_TextInputKey keyboard_keys_row_1[] = {
-    {'q', 1, 8},
-    {'w', 9, 8},
-    {'e', 17, 8},
-    {'r', 25, 8},
-    {'t', 33, 8},
-    {'y', 41, 8},
-    {'u', 49, 8},
-    {'i', 57, 8},
-    {'o', 65, 8},
-    {'p', 73, 8},
-    {'0', 81, 8},
-    {'1', 89, 8},
-    {'2', 97, 8},
-    {'3', 105, 8},
-    {'%', 113, 8},
-    {'^', 120, 8},
-};
-
-static const Mag_TextInputKey keyboard_keys_row_2[] = {
-    {'a', 1, 20},
-    {'s', 9, 20},
-    {'d', 18, 20},
-    {'f', 25, 20},
-    {'g', 33, 20},
-    {'h', 41, 20},
-    {'j', 49, 20},
-    {'k', 57, 20},
-    {'l', 65, 20},
-    {BACKSPACE_KEY, 72, 12},
-    {'4', 89, 20},
-    {'5', 97, 20},
-    {'6', 105, 20},
-    {'/', 113, 20},
-    {'?', 120, 20},
-
-};
-
-static const Mag_TextInputKey keyboard_keys_row_3[] = {
-    {'z', 1, 32},
-    {'x', 9, 32},
-    {'c', 18, 32},
-    {'v', 25, 32},
-    {'b', 33, 32},
-    {'n', 41, 32},
-    {'m', 49, 32},
-    {'_', 57, 32},
-    {ENTER_KEY, 64, 23},
-    {'7', 89, 32},
-    {'8', 97, 32},
-    {'9', 105, 32},
-    {';', 113, 32},
-    {'=', 120, 32},
-};
-
-static uint8_t get_row_size(uint8_t row_index) {
-    uint8_t row_size = 0;
-
-    switch(row_index + 1) {
-    case 1:
-        row_size = sizeof(keyboard_keys_row_1) / sizeof(Mag_TextInputKey);
-        break;
-    case 2:
-        row_size = sizeof(keyboard_keys_row_2) / sizeof(Mag_TextInputKey);
-        break;
-    case 3:
-        row_size = sizeof(keyboard_keys_row_3) / sizeof(Mag_TextInputKey);
-        break;
-    }
-
-    return row_size;
-}
-
-static const Mag_TextInputKey* get_row(uint8_t row_index) {
-    const Mag_TextInputKey* row = NULL;
-
-    switch(row_index + 1) {
-    case 1:
-        row = keyboard_keys_row_1;
-        break;
-    case 2:
-        row = keyboard_keys_row_2;
-        break;
-    case 3:
-        row = keyboard_keys_row_3;
-        break;
-    }
-
-    return row;
-}
-
-static char get_selected_char(Mag_TextInputModel* model) {
-    return get_row(model->selected_row)[model->selected_column].text;
-}
-
-static bool char_is_lowercase(char letter) {
-    return (letter >= 0x61 && letter <= 0x7A);
-}
-
-static char char_to_uppercase(const char letter) {
-    if(letter == '_') {
-        return 0x20;
-    } else if(isalpha(letter)) {
-        return (letter - 0x20);
-    } else {
-        return letter;
-    }
-}
-
-static void mag_text_input_backspace_cb(Mag_TextInputModel* model) {
-    uint8_t text_length = model->clear_default_text ? 1 : strlen(model->text_buffer);
-    if(text_length > 0) {
-        model->text_buffer[text_length - 1] = 0;
-    }
-}
-
-static void mag_text_input_view_draw_callback(Canvas* canvas, void* _model) {
-    Mag_TextInputModel* model = _model;
-    // uint8_t text_length = model->text_buffer ? strlen(model->text_buffer) : 0;
-    uint8_t needed_string_width = canvas_width(canvas) - 8;
-    uint8_t start_pos = 4;
-
-    const char* text = model->text_buffer;
-
-    canvas_clear(canvas);
-    canvas_set_color(canvas, ColorBlack);
-
-    canvas_draw_str(canvas, 2, 8, model->header);
-    elements_slightly_rounded_frame(canvas, 1, 12, 126, 15);
-
-    if(canvas_string_width(canvas, text) > needed_string_width) {
-        canvas_draw_str(canvas, start_pos, 22, "...");
-        start_pos += 6;
-        needed_string_width -= 8;
-    }
-
-    while(text != 0 && canvas_string_width(canvas, text) > needed_string_width) {
-        text++;
-    }
-
-    if(model->clear_default_text) {
-        elements_slightly_rounded_box(
-            canvas, start_pos - 1, 14, canvas_string_width(canvas, text) + 2, 10);
-        canvas_set_color(canvas, ColorWhite);
-    } else {
-        canvas_draw_str(canvas, start_pos + canvas_string_width(canvas, text) + 1, 22, "|");
-        canvas_draw_str(canvas, start_pos + canvas_string_width(canvas, text) + 2, 22, "|");
-    }
-    canvas_draw_str(canvas, start_pos, 22, text);
-
-    canvas_set_font(canvas, FontKeyboard);
-
-    for(uint8_t row = 0; row <= keyboard_row_count; row++) {
-        const uint8_t column_count = get_row_size(row);
-        const Mag_TextInputKey* keys = get_row(row);
-
-        for(size_t column = 0; column < column_count; column++) {
-            if(keys[column].text == ENTER_KEY) {
-                canvas_set_color(canvas, ColorBlack);
-                if(model->selected_row == row && model->selected_column == column) {
-                    canvas_draw_icon(
-                        canvas,
-                        keyboard_origin_x + keys[column].x,
-                        keyboard_origin_y + keys[column].y,
-                        &I_KeySaveSelected_24x11);
-                } else {
-                    canvas_draw_icon(
-                        canvas,
-                        keyboard_origin_x + keys[column].x,
-                        keyboard_origin_y + keys[column].y,
-                        &I_KeySave_24x11);
-                }
-            } else if(keys[column].text == BACKSPACE_KEY) {
-                canvas_set_color(canvas, ColorBlack);
-                if(model->selected_row == row && model->selected_column == column) {
-                    canvas_draw_icon(
-                        canvas,
-                        keyboard_origin_x + keys[column].x,
-                        keyboard_origin_y + keys[column].y,
-                        &I_KeyBackspaceSelected_16x9);
-                } else {
-                    canvas_draw_icon(
-                        canvas,
-                        keyboard_origin_x + keys[column].x,
-                        keyboard_origin_y + keys[column].y,
-                        &I_KeyBackspace_16x9);
-                }
-            } else {
-                if(model->selected_row == row && model->selected_column == column) {
-                    canvas_set_color(canvas, ColorBlack);
-                    canvas_draw_box(
-                        canvas,
-                        keyboard_origin_x + keys[column].x - 1,
-                        keyboard_origin_y + keys[column].y - 8,
-                        7,
-                        10);
-                    canvas_set_color(canvas, ColorWhite);
-                } else {
-                    canvas_set_color(canvas, ColorBlack);
-                }
-
-                if(model->clear_default_text || (char_is_lowercase(keys[column].text))) {
-                    canvas_draw_glyph(
-                        canvas,
-                        keyboard_origin_x + keys[column].x,
-                        keyboard_origin_y + keys[column].y,
-                        char_to_uppercase(keys[column].text));
-                    //keys[column].text);
-                } else {
-                    canvas_draw_glyph(
-                        canvas,
-                        keyboard_origin_x + keys[column].x,
-                        keyboard_origin_y + keys[column].y,
-                        keys[column].text);
-                }
-            }
-        }
-    }
-    /*if(model->validator_message_visible) {
-        canvas_set_font(canvas, FontSecondary);
-        canvas_set_color(canvas, ColorWhite);
-        canvas_draw_box(canvas, 8, 10, 110, 48);
-        canvas_set_color(canvas, ColorBlack);
-        canvas_draw_icon(canvas, 10, 14, &I_WarningDolphin_45x42);
-        canvas_draw_rframe(canvas, 8, 8, 112, 50, 3);
-        canvas_draw_rframe(canvas, 9, 9, 110, 48, 2);
-        elements_multiline_text(canvas, 62, 20, furi_string_get_cstr(model->validator_text));
-        canvas_set_font(canvas, FontKeyboard);
-    }*/
-}
-
-static void mag_text_input_handle_up(Mag_TextInput* mag_text_input, Mag_TextInputModel* model) {
-    UNUSED(mag_text_input);
-    if(model->selected_row > 0) {
-        model->selected_row--;
-        if(model->selected_column > get_row_size(model->selected_row) - 6) {
-            model->selected_column = model->selected_column + 1;
-        }
-    }
-}
-
-static void mag_text_input_handle_down(Mag_TextInput* mag_text_input, Mag_TextInputModel* model) {
-    UNUSED(mag_text_input);
-    if(model->selected_row < keyboard_row_count - 1) {
-        model->selected_row++;
-        if(model->selected_column > get_row_size(model->selected_row) - 4) {
-            model->selected_column = model->selected_column - 1;
-        }
-    }
-}
-
-static void mag_text_input_handle_left(Mag_TextInput* mag_text_input, Mag_TextInputModel* model) {
-    UNUSED(mag_text_input);
-    if(model->selected_column > 0) {
-        model->selected_column--;
-    } else {
-        model->selected_column = get_row_size(model->selected_row) - 1;
-    }
-}
-
-static void mag_text_input_handle_right(Mag_TextInput* mag_text_input, Mag_TextInputModel* model) {
-    UNUSED(mag_text_input);
-    if(model->selected_column < get_row_size(model->selected_row) - 1) {
-        model->selected_column++;
-    } else {
-        model->selected_column = 0;
-    }
-}
-
-static void
-    mag_text_input_handle_ok(Mag_TextInput* mag_text_input, Mag_TextInputModel* model, bool shift) {
-    UNUSED(mag_text_input);
-
-    char selected = get_selected_char(model);
-    uint8_t text_length = strlen(model->text_buffer);
-
-    if(shift) {
-        selected = char_to_uppercase(selected);
-    }
-
-    if(selected == ENTER_KEY) {
-        /*if(model->validator_callback &&
-           (!model->validator_callback(
-               model->text_buffer, model->validator_text, model->validator_callback_context))) {
-            model->validator_message_visible = true;
-            furi_timer_start(mag_text_input->timer, furi_kernel_get_tick_frequency() * 4);
-        } else*/
-        if(model->callback != 0 && text_length > 0) {
-            model->callback(model->callback_context);
-        }
-    } else if(selected == BACKSPACE_KEY) {
-        mag_text_input_backspace_cb(model);
-    } else {
-        if(model->clear_default_text) {
-            text_length = 0;
-        }
-        if(text_length < (model->text_buffer_size - 1)) {
-            if(char_is_lowercase(selected)) {
-                selected = char_to_uppercase(selected);
-            }
-            model->text_buffer[text_length] = selected;
-            model->text_buffer[text_length + 1] = 0;
-        }
-    }
-    model->clear_default_text = false;
-}
-
-static bool mag_text_input_view_input_callback(InputEvent* event, void* context) {
-    Mag_TextInput* mag_text_input = context;
-    furi_assert(mag_text_input);
-
-    bool consumed = false;
-
-    // Acquire model
-    Mag_TextInputModel* model = view_get_model(mag_text_input->view);
-
-    /* if((!(event->type == InputTypePress) && !(event->type == InputTypeRelease)) &&
-       model->validator_message_visible) {
-        model->validator_message_visible = false;
-        consumed = true;
-    } else*/
-    if(event->type == InputTypeShort) {
-        consumed = true;
-        switch(event->key) {
-        case InputKeyUp:
-            mag_text_input_handle_up(mag_text_input, model);
-            break;
-        case InputKeyDown:
-            mag_text_input_handle_down(mag_text_input, model);
-            break;
-        case InputKeyLeft:
-            mag_text_input_handle_left(mag_text_input, model);
-            break;
-        case InputKeyRight:
-            mag_text_input_handle_right(mag_text_input, model);
-            break;
-        case InputKeyOk:
-            mag_text_input_handle_ok(mag_text_input, model, false);
-            break;
-        default:
-            consumed = false;
-            break;
-        }
-    } else if(event->type == InputTypeLong) {
-        consumed = true;
-        switch(event->key) {
-        case InputKeyUp:
-            mag_text_input_handle_up(mag_text_input, model);
-            break;
-        case InputKeyDown:
-            mag_text_input_handle_down(mag_text_input, model);
-            break;
-        case InputKeyLeft:
-            mag_text_input_handle_left(mag_text_input, model);
-            break;
-        case InputKeyRight:
-            mag_text_input_handle_right(mag_text_input, model);
-            break;
-        case InputKeyOk:
-            mag_text_input_handle_ok(mag_text_input, model, true);
-            break;
-        case InputKeyBack:
-            mag_text_input_backspace_cb(model);
-            break;
-        default:
-            consumed = false;
-            break;
-        }
-    } else if(event->type == InputTypeRepeat) {
-        consumed = true;
-        switch(event->key) {
-        case InputKeyUp:
-            mag_text_input_handle_up(mag_text_input, model);
-            break;
-        case InputKeyDown:
-            mag_text_input_handle_down(mag_text_input, model);
-            break;
-        case InputKeyLeft:
-            mag_text_input_handle_left(mag_text_input, model);
-            break;
-        case InputKeyRight:
-            mag_text_input_handle_right(mag_text_input, model);
-            break;
-        case InputKeyBack:
-            mag_text_input_backspace_cb(model);
-            break;
-        default:
-            consumed = false;
-            break;
-        }
-    }
-
-    // Commit model
-    view_commit_model(mag_text_input->view, consumed);
-
-    return consumed;
-}
-
-void mag_text_input_timer_callback(void* context) {
-    furi_assert(context);
-    Mag_TextInput* mag_text_input = context;
-    UNUSED(mag_text_input);
-
-    /*with_view_model(
-        mag_text_input->view,
-        Mag_TextInputModel * model,
-        { model->validator_message_visible = false; },
-        true);*/
-}
-
-Mag_TextInput* mag_text_input_alloc() {
-    Mag_TextInput* mag_text_input = malloc(sizeof(Mag_TextInput));
-    mag_text_input->view = view_alloc();
-    view_set_context(mag_text_input->view, mag_text_input);
-    view_allocate_model(mag_text_input->view, ViewModelTypeLocking, sizeof(Mag_TextInputModel));
-    view_set_draw_callback(mag_text_input->view, mag_text_input_view_draw_callback);
-    view_set_input_callback(mag_text_input->view, mag_text_input_view_input_callback);
-
-    mag_text_input->timer =
-        furi_timer_alloc(mag_text_input_timer_callback, FuriTimerTypeOnce, mag_text_input);
-
-    /*with_view_model(
-        mag_text_input->view,
-        Mag_TextInputModel * model,
-        { model->validator_text = furi_string_alloc(); },
-        false);*/
-
-    mag_text_input_reset(mag_text_input);
-
-    return mag_text_input;
-}
-
-void mag_text_input_free(Mag_TextInput* mag_text_input) {
-    furi_assert(mag_text_input);
-    /*with_view_model(
-        mag_text_input->view,
-        Mag_TextInputModel * model,
-        { furi_string_free(model->validator_text); },
-        false);*/
-
-    // Send stop command
-    furi_timer_stop(mag_text_input->timer);
-    // Release allocated memory
-    furi_timer_free(mag_text_input->timer);
-
-    view_free(mag_text_input->view);
-
-    free(mag_text_input);
-}
-
-void mag_text_input_reset(Mag_TextInput* mag_text_input) {
-    furi_assert(mag_text_input);
-    with_view_model(
-        mag_text_input->view,
-        Mag_TextInputModel * model,
-        {
-            model->text_buffer_size = 0;
-            model->header = "";
-            model->selected_row = 0;
-            model->selected_column = 0;
-            model->clear_default_text = false;
-            model->text_buffer = NULL;
-            model->text_buffer_size = 0;
-            model->callback = NULL;
-            model->callback_context = NULL;
-            /*model->validator_callback = NULL;
-            model->validator_callback_context = NULL;
-            furi_string_reset(model->validator_text);
-            model->validator_message_visible = false;*/
-        },
-        true);
-}
-
-View* mag_text_input_get_view(Mag_TextInput* mag_text_input) {
-    furi_assert(mag_text_input);
-    return mag_text_input->view;
-}
-
-void mag_text_input_set_result_callback(
-    Mag_TextInput* mag_text_input,
-    Mag_TextInputCallback callback,
-    void* callback_context,
-    char* text_buffer,
-    size_t text_buffer_size,
-    bool clear_default_text) {
-    with_view_model(
-        mag_text_input->view,
-        Mag_TextInputModel * model,
-        {
-            model->callback = callback;
-            model->callback_context = callback_context;
-            model->text_buffer = text_buffer;
-            model->text_buffer_size = text_buffer_size;
-            model->clear_default_text = clear_default_text;
-            if(text_buffer && text_buffer[0] != '\0') {
-                // Set focus on Save
-                model->selected_row = 2;
-                model->selected_column = 8;
-            }
-        },
-        true);
-}
-
-/* void mag_text_input_set_validator(
-    Mag_TextInput* mag_text_input,
-    Mag_TextInputValidatorCallback callback,
-    void* callback_context) {
-    with_view_model(
-        mag_text_input->view,
-        Mag_TextInputModel * model,
-        {
-            model->validator_callback = callback;
-            model->validator_callback_context = callback_context;
-        },
-        true);
-}
-
-Mag_TextInputValidatorCallback
-    mag_text_input_get_validator_callback(Mag_TextInput* mag_text_input) {
-    Mag_TextInputValidatorCallback validator_callback = NULL;
-    with_view_model(
-        mag_text_input->view,
-        Mag_TextInputModel * model,
-        { validator_callback = model->validator_callback; },
-        false);
-    return validator_callback;
-}
-
-void* mag_text_input_get_validator_callback_context(Mag_TextInput* mag_text_input) {
-    void* validator_callback_context = NULL;
-    with_view_model(
-        mag_text_input->view,
-        Mag_TextInputModel * model,
-        { validator_callback_context = model->validator_callback_context; },
-        false);
-    return validator_callback_context;
-}*/
-
-void mag_text_input_set_header_text(Mag_TextInput* mag_text_input, const char* text) {
-    with_view_model(
-        mag_text_input->view, Mag_TextInputModel * model, { model->header = text; }, true);
-}

+ 0 - 82
magspoof/helpers/mag_text_input.h

@@ -1,82 +0,0 @@
-#pragma once
-
-#include <gui/view.h>
-// #include "mag_validators.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** Text input anonymous structure */
-typedef struct Mag_TextInput Mag_TextInput;
-typedef void (*Mag_TextInputCallback)(void* context);
-// typedef bool (*Mag_TextInputValidatorCallback)(const char* text, FuriString* error, void* context);
-
-/** Allocate and initialize text input 
- * 
- * This text input is used to enter string
- *
- * @return     Mag_TextInput instance
- */
-Mag_TextInput* mag_text_input_alloc();
-
-/** Deinitialize and free text input
- *
- * @param      mag_text_input  Mag_TextInput instance
- */
-void mag_text_input_free(Mag_TextInput* mag_text_input);
-
-/** Clean text input view Note: this function does not free memory
- *
- * @param      mag_text_input  Text input instance
- */
-void mag_text_input_reset(Mag_TextInput* mag_text_input);
-
-/** Get text input view
- *
- * @param      mag_text_input  Mag_TextInput instance
- *
- * @return     View instance that can be used for embedding
- */
-View* mag_text_input_get_view(Mag_TextInput* mag_text_input);
-
-/** Set text input result callback
- *
- * @param      mag_text_input          Mag_TextInput instance
- * @param      callback            callback fn
- * @param      callback_context    callback context
- * @param      text_buffer         pointer to YOUR text buffer, that we going
- *                                 to modify
- * @param      text_buffer_size    YOUR text buffer size in bytes. Max string
- *                                 length will be text_buffer_size-1.
- * @param      clear_default_text  clear text from text_buffer on first OK
- *                                 event
- */
-void mag_text_input_set_result_callback(
-    Mag_TextInput* mag_text_input,
-    Mag_TextInputCallback callback,
-    void* callback_context,
-    char* text_buffer,
-    size_t text_buffer_size,
-    bool clear_default_text);
-
-/* void mag_text_input_set_validator(
-    Mag_TextInput* mag_text_input,
-    Mag_TextInputValidatorCallback callback,
-    void* callback_context);
-
-Mag_TextInputValidatorCallback
-    mag_text_input_get_validator_callback(Mag_TextInput* mag_text_input);
-
-void* mag_text_input_get_validator_callback_context(Mag_TextInput* mag_text_input); */
-
-/** Set text input header text
- *
- * @param      mag_text_input  Mag_TextInput instance
- * @param      text        text to be shown
- */
-void mag_text_input_set_header_text(Mag_TextInput* mag_text_input, const char* text);
-
-#ifdef __cplusplus
-}
-#endif

+ 0 - 2
magspoof/helpers/mag_types.h

@@ -12,7 +12,6 @@ typedef enum {
     MagViewWidget,
     MagViewWidget,
     MagViewVariableItemList,
     MagViewVariableItemList,
     MagViewTextInput,
     MagViewTextInput,
-    MagViewMagTextInput,
 } MagView;
 } MagView;
 
 
 typedef enum {
 typedef enum {
@@ -37,7 +36,6 @@ typedef enum {
     MagTxCC1101_868,
     MagTxCC1101_868,
 } MagTxState;
 } MagTxState;
 
 
-
 typedef enum {
 typedef enum {
     UART_TerminalEventRefreshConsoleOutput = 0,
     UART_TerminalEventRefreshConsoleOutput = 0,
     UART_TerminalEventStartConsole,
     UART_TerminalEventStartConsole,

BIN=BIN
magspoof/icons/DolphinMafia_115x62.png


BIN=BIN
magspoof/icons/DolphinNice_96x59.png


BIN=BIN
magspoof/icons/KeyBackspaceSelected_16x9.png


BIN=BIN
magspoof/icons/KeyBackspace_16x9.png


BIN=BIN
magspoof/icons/KeySaveSelected_24x11.png


BIN=BIN
magspoof/icons/KeySave_24x11.png


+ 0 - 9
magspoof/mag.c

@@ -92,11 +92,6 @@ static Mag* mag_alloc() {
     view_dispatcher_add_view(
     view_dispatcher_add_view(
         mag->view_dispatcher, MagViewTextInput, text_input_get_view(mag->text_input));
         mag->view_dispatcher, MagViewTextInput, text_input_get_view(mag->text_input));
 
 
-    // Custom Mag Text Input
-    mag->mag_text_input = mag_text_input_alloc();
-    view_dispatcher_add_view(
-        mag->view_dispatcher, MagViewMagTextInput, mag_text_input_get_view(mag->mag_text_input));
-
     return mag;
     return mag;
 }
 }
 
 
@@ -148,10 +143,6 @@ static void mag_free(Mag* mag) {
     view_dispatcher_remove_view(mag->view_dispatcher, MagViewTextInput);
     view_dispatcher_remove_view(mag->view_dispatcher, MagViewTextInput);
     text_input_free(mag->text_input);
     text_input_free(mag->text_input);
 
 
-    // Custom Mag TextInput
-    view_dispatcher_remove_view(mag->view_dispatcher, MagViewMagTextInput);
-    mag_text_input_free(mag->mag_text_input);
-
     // View Dispatcher
     // View Dispatcher
     view_dispatcher_free(mag->view_dispatcher);
     view_dispatcher_free(mag->view_dispatcher);
 
 

+ 4 - 5
magspoof/mag_device.c

@@ -251,7 +251,7 @@ bool mag_device_parse_card_string(MagDevice* mag_dev, FuriString* f_card_str) {
         return false;
         return false;
     }
     }
     size_t track1_len = track1_end - track1_start;
     size_t track1_len = track1_end - track1_start;
-    
+
     FURI_LOG_D(TAG, "Track 1: %.*s", track1_len, track1_start);
     FURI_LOG_D(TAG, "Track 1: %.*s", track1_len, track1_start);
 
 
     mag_dev->dev_data.track[0].len = track1_len;
     mag_dev->dev_data.track[0].len = track1_len;
@@ -259,7 +259,7 @@ bool mag_device_parse_card_string(MagDevice* mag_dev, FuriString* f_card_str) {
 
 
     // Track 2
     // Track 2
     const char* track2_start = strchr(track1_end, ';');
     const char* track2_start = strchr(track1_end, ';');
-    if (!track2_start) {
+    if(!track2_start) {
         FURI_LOG_D(TAG, "Could not find track 2 start");
         FURI_LOG_D(TAG, "Could not find track 2 start");
         return true;
         return true;
     }
     }
@@ -279,7 +279,7 @@ bool mag_device_parse_card_string(MagDevice* mag_dev, FuriString* f_card_str) {
 
 
     // Track 3
     // Track 3
     const char* track3_start = strchr(track2_end, ';');
     const char* track3_start = strchr(track2_end, ';');
-    if (!track3_start) {
+    if(!track3_start) {
         FURI_LOG_D(TAG, "Could not find track 3 start");
         FURI_LOG_D(TAG, "Could not find track 3 start");
         return true;
         return true;
     }
     }
@@ -296,11 +296,10 @@ bool mag_device_parse_card_string(MagDevice* mag_dev, FuriString* f_card_str) {
 
 
     mag_dev->dev_data.track[2].len = track3_len;
     mag_dev->dev_data.track[2].len = track3_len;
     furi_string_printf(mag_dev->dev_data.track[2].str, "%%%.*s?", track3_len, track3_start);
     furi_string_printf(mag_dev->dev_data.track[2].str, "%%%.*s?", track3_len, track3_start);
-    
+
     return true;
     return true;
 }
 }
 
 
-
 void mag_device_set_loading_callback(
 void mag_device_set_loading_callback(
     MagDevice* mag_dev,
     MagDevice* mag_dev,
     MagLoadingCallback callback,
     MagLoadingCallback callback,

+ 3 - 1
magspoof/mag_device.h

@@ -7,10 +7,12 @@
 
 
 #include "mag_icons.h"
 #include "mag_icons.h"
 
 
+#include <assets_icons.h>
+
 #define MAG_DEV_NAME_MAX_LEN 22
 #define MAG_DEV_NAME_MAX_LEN 22
 #define MAG_DEV_TRACKS 3
 #define MAG_DEV_TRACKS 3
 
 
-#define MAG_APP_FOLDER ANY_PATH("mag")
+#define MAG_APP_FOLDER STORAGE_APP_DATA_PATH_PREFIX
 #define MAG_APP_EXTENSION ".mag"
 #define MAG_APP_EXTENSION ".mag"
 
 
 typedef void (*MagLoadingCallback)(void* context, bool state);
 typedef void (*MagLoadingCallback)(void* context, bool state);

+ 1 - 6
magspoof/mag_i.h

@@ -2,7 +2,6 @@
 
 
 #include "mag_device.h"
 #include "mag_device.h"
 //#include "helpers/mag_helpers.h"
 //#include "helpers/mag_helpers.h"
-#include "helpers/mag_text_input.h"
 #include "helpers/mag_types.h"
 #include "helpers/mag_types.h"
 
 
 #include <furi.h>
 #include <furi.h>
@@ -51,7 +50,6 @@ typedef struct {
     uint32_t us_interpacket;
     uint32_t us_interpacket;
 } MagSetting;
 } MagSetting;
 
 
-
 typedef struct {
 typedef struct {
     ViewDispatcher* view_dispatcher;
     ViewDispatcher* view_dispatcher;
     Gui* gui;
     Gui* gui;
@@ -76,15 +74,12 @@ typedef struct {
     Widget* widget;
     Widget* widget;
     VariableItemList* variable_item_list;
     VariableItemList* variable_item_list;
 
 
-    // Custom views
-    Mag_TextInput* mag_text_input;
-
     // UART
     // UART
     FuriThread* uart_rx_thread;
     FuriThread* uart_rx_thread;
     FuriStreamBuffer* uart_rx_stream;
     FuriStreamBuffer* uart_rx_stream;
     uint8_t uart_rx_buf[UART_RX_BUF_SIZE + 1];
     uint8_t uart_rx_buf[UART_RX_BUF_SIZE + 1];
     void (*handle_rx_data_cb)(uint8_t* buf, size_t len, void* context);
     void (*handle_rx_data_cb)(uint8_t* buf, size_t len, void* context);
-    
+
     char uart_text_input_store[UART_TERMINAL_TEXT_INPUT_STORE_SIZE + 1];
     char uart_text_input_store[UART_TERMINAL_TEXT_INPUT_STORE_SIZE + 1];
     FuriString* uart_text_box_store;
     FuriString* uart_text_box_store;
     size_t uart_text_box_store_strlen;
     size_t uart_text_box_store_strlen;

+ 0 - 0
magspoof/assets/SamyExampleImage.mag → magspoof/resources/apps_data/magspoof/SamyExampleImage.mag


+ 0 - 0
magspoof/assets/SamyExpiredCard.mag → magspoof/resources/apps_data/magspoof/SamyExpiredCard.mag


+ 0 - 0
magspoof/assets/TestMagstripe.mag → magspoof/resources/apps_data/magspoof/TestMagstripe.mag


+ 7 - 5
magspoof/scenes/mag_scene_input_value.c

@@ -2,16 +2,18 @@
 
 
 void mag_scene_input_value_on_enter(void* context) {
 void mag_scene_input_value_on_enter(void* context) {
     Mag* mag = context;
     Mag* mag = context;
-    Mag_TextInput* mag_text_input = mag->mag_text_input;
+    TextInput* text_input = mag->text_input;
 
 
     // TODO: retrieve stored/existing data if editing rather than adding anew?
     // TODO: retrieve stored/existing data if editing rather than adding anew?
     mag_text_store_set(mag, furi_string_get_cstr(mag->mag_dev->dev_data.track[1].str));
     mag_text_store_set(mag, furi_string_get_cstr(mag->mag_dev->dev_data.track[1].str));
 
 
-    mag_text_input_set_header_text(mag_text_input, "Enter track data (WIP)");
-    mag_text_input_set_result_callback(
-        mag_text_input, mag_text_input_callback, mag, mag->text_store, MAG_TEXT_STORE_SIZE, true);
+    text_input_set_header_text(text_input, "Enter track data (WIP)");
+    text_input_set_result_callback(
+        text_input, mag_text_input_callback, mag, mag->text_store, MAG_TEXT_STORE_SIZE, true);
 
 
-    view_dispatcher_switch_to_view(mag->view_dispatcher, MagViewMagTextInput);
+    text_input_add_illegal_symbols(text_input);
+
+    view_dispatcher_switch_to_view(mag->view_dispatcher, MagViewTextInput);
 }
 }
 
 
 bool mag_scene_input_value_on_event(void* context, SceneManagerEvent event) {
 bool mag_scene_input_value_on_event(void* context, SceneManagerEvent event) {

+ 1 - 1
magspoof/scenes/mag_scene_read.c

@@ -182,4 +182,4 @@ void mag_scene_read_on_exit(void* context) {
     // furi_hal_console_enable();
     // furi_hal_console_enable();
 
 
     notification_message(mag->notifications, &sequence_blink_stop);
     notification_message(mag->notifications, &sequence_blink_stop);
-}
+}

+ 0 - 1
magspoof/scenes/mag_scene_read.h

@@ -17,5 +17,4 @@ typedef enum {
     UARTEventRxData = 100,
     UARTEventRxData = 100,
 } UARTEvents;
 } UARTEvents;
 
 
-
 #define WORKER_ALL_RX_EVENTS (WorkerEvtStop | WorkerEvtRxDone)
 #define WORKER_ALL_RX_EVENTS (WorkerEvtStop | WorkerEvtRxDone)