gid9798 2 лет назад
Родитель
Сommit
3bcb6994ec

+ 3 - 3
helpers/fuzzer_custom_event.h

@@ -13,10 +13,10 @@ typedef enum {
     FuzzerCustomEventViewAttackRunAttack,
     FuzzerCustomEventViewAttackPause,
     FuzzerCustomEventViewAttackIdle, // Setup
-    // FuzzerCustomEventViewAttackEmulateCurrent,
+    FuzzerCustomEventViewAttackEmulateCurrent,
     // FuzzerCustomEventViewAttackSave,
-    // FuzzerCustomEventViewAttackNextUid,
-    // FuzzerCustomEventViewAttackPrevUid,
+    FuzzerCustomEventViewAttackNextUid,
+    FuzzerCustomEventViewAttackPrevUid,
 
     FuzzerCustomEventViewFieldEditorBack,
     FuzzerCustomEventViewFieldEditorOk,

+ 2 - 1
helpers/fuzzer_types.h

@@ -10,7 +10,8 @@ typedef struct {
 typedef enum {
     FuzzerAttackStateOff = 0,
     FuzzerAttackStateIdle,
-    FuzzerAttackStateRunning,
+    FuzzerAttackStateAttacking,
+    FuzzerAttackStateEmulating,
     FuzzerAttackStatePause,
     FuzzerAttackStateEnd,
 

+ 75 - 2
lib/worker/fake_worker.c

@@ -213,7 +213,11 @@ static bool fuzzer_worker_load_key(FuzzerWorker* instance, bool next) {
     switch(instance->attack_type) {
     case FuzzerWorkerAttackTypeDefaultDict:
         if(next) {
-            instance->index++;
+            if(instance->index < (protocol->dict.len - 1)) {
+                instance->index++;
+            } else {
+                break;
+            }
         }
         if(instance->index < protocol->dict.len) {
             memcpy(
@@ -275,7 +279,47 @@ static bool fuzzer_worker_load_key(FuzzerWorker* instance, bool next) {
         break;
     }
 
-    hardware_worker_set_protocol_data(instance, instance->payload);
+    if(res) {
+        hardware_worker_set_protocol_data(instance, instance->payload);
+    }
+
+    return res;
+}
+
+static bool fuzzer_worker_load_previous_key(FuzzerWorker* instance) {
+    furi_assert(instance);
+    furi_assert(instance->protocol);
+    bool res = false;
+
+    const FuzzerProtocol* protocol = instance->protocol;
+
+    switch(instance->attack_type) {
+    case FuzzerWorkerAttackTypeDefaultDict:
+        if(instance->index > 0) {
+            instance->index--;
+            memcpy(
+                instance->payload,
+                &protocol->dict.val[instance->index * protocol->data_size],
+                protocol->data_size);
+            res = true;
+        }
+        break;
+
+    case FuzzerWorkerAttackTypeLoadFile:
+        if(instance->payload[instance->index] != 0x00) {
+            instance->payload[instance->index]--;
+            res = true;
+        }
+
+        break;
+
+    default:
+        break;
+    }
+
+    if(res) {
+        hardware_worker_set_protocol_data(instance, instance->payload);
+    }
 
     return res;
 }
@@ -319,6 +363,20 @@ void fuzzer_worker_get_current_key(FuzzerWorker* instance, FuzzerPayload* output
     memcpy(output_key->data, instance->payload, instance->protocol->data_size);
 }
 
+bool fuzzer_worker_next_key(FuzzerWorker* instance) {
+    furi_assert(instance);
+    furi_assert(instance->protocol);
+
+    return fuzzer_worker_load_key(instance, true);
+}
+
+bool fuzzer_worker_previous_key(FuzzerWorker* instance) {
+    furi_assert(instance);
+    furi_assert(instance->protocol);
+
+    return fuzzer_worker_load_previous_key(instance);
+}
+
 bool fuzzer_worker_init_attack_dict(FuzzerWorker* instance, FuzzerProtocolsID protocol_index) {
     furi_assert(instance);
 
@@ -462,6 +520,21 @@ bool fuzzer_worker_start(FuzzerWorker* instance, uint8_t idle_time, uint8_t emu_
     return false;
 }
 
+void fuzzer_worker_start_emulate(FuzzerWorker* instance) {
+    furi_assert(instance);
+
+    if(!instance->treead_running) {
+        hardware_worker_start_thread(instance);
+
+        FURI_LOG_D(TAG, "Worker Starting");
+        instance->treead_running = true;
+    } else {
+        FURI_LOG_D(TAG, "Worker UnPaused");
+    }
+
+    hardware_worker_emulate_start(instance);
+}
+
 void fuzzer_worker_pause(FuzzerWorker* instance) {
     furi_assert(instance);
 

+ 5 - 0
lib/worker/fake_worker.h

@@ -48,6 +48,8 @@ bool fuzzer_worker_start(FuzzerWorker* instance, uint8_t idle_time, uint8_t emu_
  */
 void fuzzer_worker_stop(FuzzerWorker* instance);
 
+void fuzzer_worker_start_emulate(FuzzerWorker* instance);
+
 /**
  * Suspend emulation
  * 
@@ -100,6 +102,9 @@ bool fuzzer_worker_init_attack_bf_byte(
  */
 void fuzzer_worker_get_current_key(FuzzerWorker* instance, FuzzerPayload* output_key);
 
+bool fuzzer_worker_next_key(FuzzerWorker* instance);
+bool fuzzer_worker_previous_key(FuzzerWorker* instance);
+
 /**
  * Load UID from Flipper Format Key file
  * 

+ 26 - 10
scenes/fuzzer_scene_attack.c

@@ -1,7 +1,7 @@
 #include "../fuzzer_i.h"
 #include "../helpers/fuzzer_custom_event.h"
 
-const NotificationSequence sequence_one_green_50_on_blink_blue = {
+const NotificationSequence sequence_one_red_50_on_blink_blue = {
     &message_red_255,
     &message_delay_50,
     &message_red_0,
@@ -28,37 +28,37 @@ static void fuzzer_scene_attack_set_state(PacsFuzzerApp* app, FuzzerAttackState
     switch(state) {
     case FuzzerAttackStateIdle:
         notification_message(app->notifications, &sequence_blink_stop);
-        fuzzer_view_attack_idle(app->attack_view);
         break;
 
-    case FuzzerAttackStateRunning:
+    case FuzzerAttackStateAttacking:
+        notification_message(app->notifications, &sequence_blink_start_blue);
+        break;
+    case FuzzerAttackStateEmulating:
         notification_message(app->notifications, &sequence_blink_start_blue);
-        fuzzer_view_attack_start(app->attack_view);
         break;
 
     case FuzzerAttackStateEnd:
         notification_message(app->notifications, &sequence_blink_stop);
         notification_message(app->notifications, &sequence_single_vibro);
-        fuzzer_view_attack_end(app->attack_view);
         break;
 
     case FuzzerAttackStateOff:
         notification_message(app->notifications, &sequence_blink_stop);
-        fuzzer_view_attack_stop(app->attack_view);
         break;
 
     case FuzzerAttackStatePause:
         notification_message(app->notifications, &sequence_blink_stop);
-        fuzzer_view_attack_pause(app->attack_view);
         break;
     }
+
+    fuzzer_view_update_state(app->attack_view, state);
 }
 
 void fuzzer_scene_attack_worker_tick_callback(void* context) {
     furi_assert(context);
     PacsFuzzerApp* app = context;
 
-    notification_message(app->notifications, &sequence_one_green_50_on_blink_blue);
+    notification_message(app->notifications, &sequence_one_red_50_on_blink_blue);
     fuzzer_scene_attack_update_uid(app);
 }
 
@@ -117,10 +117,14 @@ bool fuzzer_scene_attack_on_event(void* context, SceneManagerEvent event) {
                    app->worker,
                    fuzzer_view_attack_get_time_delay(app->attack_view),
                    fuzzer_view_attack_get_emu_time(app->attack_view))) {
-                fuzzer_scene_attack_set_state(app, FuzzerAttackStateRunning);
+                fuzzer_scene_attack_set_state(app, FuzzerAttackStateAttacking);
             } else {
                 // Error?
             }
+        } else if(event.event == FuzzerCustomEventViewAttackEmulateCurrent) {
+            fuzzer_worker_start_emulate(app->worker);
+
+            fuzzer_scene_attack_set_state(app, FuzzerAttackStateEmulating);
         } else if(event.event == FuzzerCustomEventViewAttackPause) {
             fuzzer_worker_pause(app->worker);
 
@@ -129,8 +133,20 @@ bool fuzzer_scene_attack_on_event(void* context, SceneManagerEvent event) {
             fuzzer_worker_pause(app->worker);
 
             fuzzer_scene_attack_set_state(app, FuzzerAttackStateIdle);
+        } else if(event.event == FuzzerCustomEventViewAttackNextUid) {
+            if(fuzzer_worker_next_key(app->worker)) {
+                fuzzer_scene_attack_update_uid(app);
+            } else {
+                notification_message(app->notifications, &sequence_blink_red_100);
+            }
+        } else if(event.event == FuzzerCustomEventViewAttackPrevUid) {
+            if(fuzzer_worker_previous_key(app->worker)) {
+                fuzzer_scene_attack_update_uid(app);
+            } else {
+                notification_message(app->notifications, &sequence_blink_red_100);
+            }
         }
-        // OLD
+        // Callback from worker
         else if(event.event == FuzzerCustomEventViewAttackEnd) {
             fuzzer_scene_attack_set_state(app, FuzzerAttackStateEnd);
             consumed = true;

+ 1 - 0
scenes/fuzzer_scene_field_editor.c

@@ -22,6 +22,7 @@ void fuzzer_scene_field_editor_on_enter(void* context) {
         break;
 
     case FuzzerFieldEditorStateEditingOff:
+        memset(app->payload->data, 0x00, app->payload->data_size);
         fuzzer_view_field_editor_reset_data(app->field_editor_view, app->payload, false);
         break;
 

+ 3 - 3
todo.md

@@ -4,7 +4,7 @@
 
 - [ ] Make the "Load File" independent of the current protocol
 - [x] Add pause
-    - [ ] Switching  UIDs if possible
+    - [X] Switching  UIDs if possible
 - [x] Led and sound Notification
     - [x] Led
     - [x] Vibro
@@ -36,9 +36,9 @@
     - [x] `UID_MAX_SIZE`
 - [x] Add pause
     - [x] Fix `Custom dict` attack when ended
-- [ ] Pause V2
+- [X] Pause V2
     - [ ] Save logic
-    - [ ] Switching  UIDs if possible
+    - [X] Switching  UIDs if possible
 - [ ] Worker
     - [ ] Use `prtocol_id` instead of protocol name
     - [x] this can be simplified `fuzzer_proto_items`

+ 140 - 102
views/attack.c

@@ -6,7 +6,12 @@
 
 #define ATTACK_SCENE_MAX_UID_LENGTH 25
 #define UID_MAX_DISPLAYED_LEN (8U)
-#define LIFT_RIGHT_OFFSET (3)
+#define LEFT_RIGHT_OFFSET (3U)
+
+#define LINE_1_Y (12U)
+#define LINE_2_Y (24U)
+#define LINE_3_Y (36U)
+#define LINE_4_Y (48U)
 
 struct FuzzerViewAttack {
     View* view;
@@ -60,64 +65,91 @@ void fuzzer_view_attack_set_uid(FuzzerViewAttack* view, const FuzzerPayload* uid
         true);
 }
 
-void fuzzer_view_attack_start(FuzzerViewAttack* view) {
+void fuzzer_view_update_state(FuzzerViewAttack* view, FuzzerAttackState state) {
     furi_assert(view);
 
     with_view_model(
-        view->view,
-        FuzzerViewAttackModel * model,
-        { model->attack_state = FuzzerAttackStateRunning; },
-        true);
+        view->view, FuzzerViewAttackModel * model, { model->attack_state = state; }, true);
 }
 
-void fuzzer_view_attack_stop(FuzzerViewAttack* view) {
-    furi_assert(view);
+void fuzzer_view_attack_set_callback(
+    FuzzerViewAttack* view_attack,
+    FuzzerViewAttackCallback callback,
+    void* context) {
+    furi_assert(view_attack);
 
-    with_view_model(
-        view->view,
-        FuzzerViewAttackModel * model,
-        { model->attack_state = FuzzerAttackStateOff; },
-        true);
+    view_attack->callback = callback;
+    view_attack->context = context;
 }
 
-void fuzzer_view_attack_pause(FuzzerViewAttack* view) {
-    furi_assert(view);
+static void
+    fuzzer_view_attack_draw_time_delays_line(Canvas* canvas, FuzzerViewAttackModel* model) {
+    char temp_str[25];
+    uint16_t crt;
+    const uint16_t y = LINE_2_Y;
 
-    with_view_model(
-        view->view,
-        FuzzerViewAttackModel * model,
-        { model->attack_state = FuzzerAttackStatePause; },
-        true);
-}
+    canvas_set_font(canvas, FontPrimary);
 
-void fuzzer_view_attack_idle(FuzzerViewAttack* view) {
-    furi_assert(view);
+    if(!model->td_emt_cursor) {
+        canvas_set_font(canvas, FontSecondary);
+        snprintf(temp_str, sizeof(temp_str), "Time delay:");
+        canvas_draw_str_aligned(canvas, LEFT_RIGHT_OFFSET, y, AlignLeft, AlignBottom, temp_str);
+        crt = canvas_string_width(canvas, temp_str);
 
-    with_view_model(
-        view->view,
-        FuzzerViewAttackModel * model,
-        { model->attack_state = FuzzerAttackStateIdle; },
-        true);
-}
+        canvas_set_font(canvas, FontPrimary);
+        snprintf(
+            temp_str, sizeof(temp_str), "%d.%d", model->time_delay / 10, model->time_delay % 10);
+        canvas_draw_str_aligned(
+            canvas, crt + LEFT_RIGHT_OFFSET + 3, y, AlignLeft, AlignBottom, temp_str);
 
-void fuzzer_view_attack_end(FuzzerViewAttack* view) {
-    furi_assert(view);
+        canvas_set_font(canvas, FontSecondary);
+        snprintf(
+            temp_str, sizeof(temp_str), "EmT: %d.%d", model->emu_time / 10, model->emu_time % 10);
+        canvas_draw_str_aligned(
+            canvas, 128 - LEFT_RIGHT_OFFSET, y, AlignRight, AlignBottom, temp_str);
+    } else {
+        canvas_set_font(canvas, FontSecondary);
+        snprintf(
+            temp_str,
+            sizeof(temp_str),
+            "TD: %d.%d",
+            model->time_delay / 10,
+            model->time_delay % 10);
 
-    with_view_model(
-        view->view,
-        FuzzerViewAttackModel * model,
-        { model->attack_state = FuzzerAttackStateEnd; },
-        true);
+        canvas_draw_str_aligned(canvas, LEFT_RIGHT_OFFSET, y, AlignLeft, AlignBottom, temp_str);
+
+        canvas_set_font(canvas, FontPrimary);
+        snprintf(temp_str, sizeof(temp_str), "%d.%d", model->emu_time / 10, model->emu_time % 10);
+        canvas_draw_str_aligned(
+            canvas, 128 - LEFT_RIGHT_OFFSET, y, AlignRight, AlignBottom, temp_str);
+        crt = canvas_string_width(canvas, temp_str);
+
+        canvas_set_font(canvas, FontSecondary);
+        snprintf(temp_str, sizeof(temp_str), "Emulation time:");
+        canvas_draw_str_aligned(
+            canvas, 128 - LEFT_RIGHT_OFFSET - crt - 3, y, AlignRight, AlignBottom, temp_str);
+    }
 }
 
-void fuzzer_view_attack_set_callback(
-    FuzzerViewAttack* view_attack,
-    FuzzerViewAttackCallback callback,
-    void* context) {
-    furi_assert(view_attack);
+static void fuzzer_view_attack_draw_time_delays_str(Canvas* canvas, FuzzerViewAttackModel* model) {
+    char temp_str[20];
+    uint16_t crt;
+    const uint16_t y = LINE_2_Y;
 
-    view_attack->callback = callback;
-    view_attack->context = context;
+    canvas_set_font(canvas, FontSecondary);
+    snprintf(
+        temp_str,
+        sizeof(temp_str),
+        "TD: %d.%d Emt: %d.%d",
+        model->time_delay / 10,
+        model->time_delay % 10,
+        model->emu_time / 10,
+        model->emu_time % 10);
+
+    crt = canvas_string_width(canvas, temp_str);
+
+    canvas_draw_str_aligned(
+        canvas, 128 - LEFT_RIGHT_OFFSET - crt, y, AlignLeft, AlignBottom, temp_str);
 }
 
 static void fuzzer_view_attack_draw_idle(Canvas* canvas, FuzzerViewAttackModel* model) {
@@ -134,7 +166,8 @@ static void fuzzer_view_attack_draw_idle(Canvas* canvas, FuzzerViewAttackModel*
 
 static void fuzzer_view_attack_draw_running(Canvas* canvas, FuzzerViewAttackModel* model) {
     UNUSED(model);
-    elements_button_center(canvas, "Stop");
+    elements_button_left(canvas, "Stop");
+    elements_button_center(canvas, "Pause");
 }
 
 static void fuzzer_view_attack_draw_end(Canvas* canvas, FuzzerViewAttackModel* model) {
@@ -144,76 +177,75 @@ static void fuzzer_view_attack_draw_end(Canvas* canvas, FuzzerViewAttackModel* m
 }
 
 void fuzzer_view_attack_draw(Canvas* canvas, FuzzerViewAttackModel* model) {
-    char temp_str[50];
-
     canvas_clear(canvas);
     canvas_set_color(canvas, ColorBlack);
 
+    // Header - Attack name
     canvas_set_font(canvas, FontPrimary);
-    canvas_draw_str_aligned(canvas, 64, 2, AlignCenter, AlignTop, model->attack_name);
-
-    uint16_t crt;
-    canvas_set_font(canvas, FontPrimary);
+    canvas_draw_str_aligned(canvas, 64, LINE_1_Y, AlignCenter, AlignBottom, model->attack_name);
 
-    if(!model->td_emt_cursor) {
-        canvas_set_font(canvas, FontSecondary);
-        snprintf(temp_str, sizeof(temp_str), "Time delay:");
-        canvas_draw_str_aligned(canvas, LIFT_RIGHT_OFFSET, 21, AlignLeft, AlignBottom, temp_str);
-        crt = canvas_string_width(canvas, temp_str);
+    // Time delays line or Status line
+    switch(model->attack_state) {
+    case FuzzerAttackStateIdle:
+        fuzzer_view_attack_draw_time_delays_line(canvas, model);
+        break;
 
+    case FuzzerAttackStateAttacking:
         canvas_set_font(canvas, FontPrimary);
-        snprintf(
-            temp_str, sizeof(temp_str), "%d.%d", model->time_delay / 10, model->time_delay % 10);
-        canvas_draw_str_aligned(
-            canvas, crt + LIFT_RIGHT_OFFSET + 3, 21, AlignLeft, AlignBottom, temp_str);
+        canvas_draw_str(canvas, LEFT_RIGHT_OFFSET, LINE_2_Y, "Attacking");
+        fuzzer_view_attack_draw_time_delays_str(canvas, model);
 
-        canvas_set_font(canvas, FontSecondary);
-        snprintf(
-            temp_str, sizeof(temp_str), "EmT: %d.%d", model->emu_time / 10, model->emu_time % 10);
-        canvas_draw_str_aligned(
-            canvas, 128 - LIFT_RIGHT_OFFSET, 21, AlignRight, AlignBottom, temp_str);
-    } else {
-        canvas_set_font(canvas, FontSecondary);
-        snprintf(
-            temp_str,
-            sizeof(temp_str),
-            "TD: %d.%d",
-            model->time_delay / 10,
-            model->time_delay % 10);
+        break;
+
+    case FuzzerAttackStateEmulating:
+        canvas_set_font(canvas, FontPrimary);
+        canvas_draw_str_aligned(canvas, 64, LINE_2_Y, AlignCenter, AlignBottom, "Emulating:");
 
-        canvas_draw_str_aligned(canvas, LIFT_RIGHT_OFFSET, 21, AlignLeft, AlignBottom, temp_str);
+        break;
 
+    case FuzzerAttackStatePause:
         canvas_set_font(canvas, FontPrimary);
-        snprintf(temp_str, sizeof(temp_str), "%d.%d", model->emu_time / 10, model->emu_time % 10);
-        canvas_draw_str_aligned(
-            canvas, 128 - LIFT_RIGHT_OFFSET, 21, AlignRight, AlignBottom, temp_str);
-        crt = canvas_string_width(canvas, temp_str);
+        canvas_draw_str(canvas, LEFT_RIGHT_OFFSET, LINE_2_Y, "Paused");
 
         canvas_set_font(canvas, FontSecondary);
-        snprintf(temp_str, sizeof(temp_str), "Emulation time:");
-        canvas_draw_str_aligned(
-            canvas, 128 - LIFT_RIGHT_OFFSET - crt - 3, 21, AlignRight, AlignBottom, temp_str);
+        canvas_draw_icon_ex(canvas, 62, LINE_2_Y - 9, &I_Pin_arrow_up_7x9, IconRotation180);
+        canvas_draw_icon(canvas, 69, LINE_2_Y - 9, &I_Pin_arrow_up_7x9);
+        canvas_draw_str(canvas, 79, LINE_2_Y, "Change UID");
+        break;
+
+    case FuzzerAttackStateEnd:
+        canvas_set_font(canvas, FontPrimary);
+        canvas_draw_str_aligned(canvas, 64, LINE_2_Y, AlignCenter, AlignBottom, "Attack is over");
+
+        break;
+
+    default:
+        break;
     }
 
+    // Protocol name
     canvas_set_font(canvas, FontSecondary);
-    canvas_draw_str_aligned(canvas, 64, 26, AlignCenter, AlignTop, model->protocol_name);
+    canvas_draw_str_aligned(canvas, 64, LINE_3_Y, AlignCenter, AlignBottom, model->protocol_name);
 
+    // Current UID
     canvas_set_font(canvas, FontPrimary);
     if(128 < canvas_string_width(canvas, furi_string_get_cstr(model->uid_str))) {
         canvas_set_font(canvas, FontSecondary);
     }
     canvas_draw_str_aligned(
-        canvas, 64, 38, AlignCenter, AlignTop, furi_string_get_cstr(model->uid_str));
+        canvas, 64, LINE_4_Y, AlignCenter, AlignBottom, furi_string_get_cstr(model->uid_str));
 
+    // Btns
     canvas_set_font(canvas, FontSecondary);
-    if(model->attack_state == FuzzerAttackStateRunning) {
+    if(model->attack_state == FuzzerAttackStateAttacking ||
+       model->attack_state == FuzzerAttackStateEmulating) {
         fuzzer_view_attack_draw_running(canvas, model);
     } else if(model->attack_state == FuzzerAttackStateIdle) {
         fuzzer_view_attack_draw_idle(canvas, model);
     } else if(model->attack_state == FuzzerAttackStatePause) {
-        elements_button_left(canvas, "Prev");
-        elements_button_right(canvas, "Next");
-        elements_button_center(canvas, "Try"); // XXX
+        elements_button_left(canvas, "Back");
+        // elements_button_right(canvas, "Save"); // XXX
+        elements_button_center(canvas, "Emu");
     } else if(model->attack_state == FuzzerAttackStateEnd) {
         fuzzer_view_attack_draw_end(canvas, model);
     }
@@ -236,7 +268,7 @@ static bool fuzzer_view_attack_input_idle(
                 if(model->time_delay > model->time_delay_min) {
                     model->time_delay--;
                 }
-            } else if(event->type == InputTypeLong) {
+            } else if(event->type == InputTypeLong || event->type == InputTypeRepeat) {
                 if((model->time_delay - 10) >= model->time_delay_min) {
                     model->time_delay -= 10;
                 } else {
@@ -249,7 +281,7 @@ static bool fuzzer_view_attack_input_idle(
                 if(model->emu_time > model->emu_time_min) {
                     model->emu_time--;
                 }
-            } else if(event->type == InputTypeLong) {
+            } else if(event->type == InputTypeLong || event->type == InputTypeRepeat) {
                 if((model->emu_time - 10) >= model->emu_time_min) {
                     model->emu_time -= 10;
                 } else {
@@ -265,7 +297,7 @@ static bool fuzzer_view_attack_input_idle(
                 if(model->time_delay < FUZZ_TIME_DELAY_MAX) {
                     model->time_delay++;
                 }
-            } else if(event->type == InputTypeLong) {
+            } else if(event->type == InputTypeLong || event->type == InputTypeRepeat) {
                 model->time_delay += 10;
                 if(model->time_delay > FUZZ_TIME_DELAY_MAX) {
                     model->time_delay = FUZZ_TIME_DELAY_MAX;
@@ -277,7 +309,7 @@ static bool fuzzer_view_attack_input_idle(
                 if(model->emu_time < FUZZ_TIME_DELAY_MAX) {
                     model->emu_time++;
                 }
-            } else if(event->type == InputTypeLong) {
+            } else if(event->type == InputTypeLong || event->type == InputTypeRepeat) {
                 model->emu_time += 10;
                 if(model->emu_time > FUZZ_TIME_DELAY_MAX) {
                     model->emu_time = FUZZ_TIME_DELAY_MAX;
@@ -303,13 +335,8 @@ static bool fuzzer_view_attack_input_end(
     InputEvent* event,
     FuzzerViewAttackModel* model) {
     UNUSED(model);
-    if(event->key == InputKeyBack && event->type == InputTypeShort) {
-        view_attack->callback(FuzzerCustomEventViewAttackExit, view_attack->context);
-        return true;
-        // } else if(event->key == InputKeyOk && event->type == InputTypeShort) {
-        //     view_attack->callback(FuzzerCustomEventViewAttackOk, view_attack->context);
-        //     return true;
-    } else if(event->key == InputKeyLeft && event->type == InputTypeShort) {
+    if((event->key == InputKeyBack || event->key == InputKeyLeft) &&
+       event->type == InputTypeShort) {
         // Exit if Ended
         view_attack->callback(FuzzerCustomEventViewAttackExit, view_attack->context);
     }
@@ -341,18 +368,29 @@ bool fuzzer_view_attack_input(InputEvent* event, void* context) {
                 fuzzer_view_attack_input_end(view_attack, event, model);
                 break;
 
-            case FuzzerAttackStateRunning:
-                if(event->key == InputKeyBack && event->type == InputTypeShort) {
+            case FuzzerAttackStateAttacking:
+            case FuzzerAttackStateEmulating:
+                if((event->key == InputKeyBack || event->key == InputKeyLeft) &&
+                   event->type == InputTypeShort) {
                     view_attack->callback(FuzzerCustomEventViewAttackIdle, view_attack->context);
                 } else if(event->key == InputKeyOk && event->type == InputTypeShort) {
-                    view_attack->callback(FuzzerCustomEventViewAttackIdle, view_attack->context);
-                    // view_attack->callback(FuzzerCustomEventViewAttackPause, view_attack->context);
+                    view_attack->callback(FuzzerCustomEventViewAttackPause, view_attack->context);
                 }
                 break;
 
             case FuzzerAttackStatePause:
-                if(event->key == InputKeyBack && event->type == InputTypeShort) {
+                if((event->key == InputKeyBack || event->key == InputKeyLeft) &&
+                   event->type == InputTypeShort) {
                     view_attack->callback(FuzzerCustomEventViewAttackIdle, view_attack->context);
+                } else if(event->key == InputKeyOk && event->type == InputTypeShort) {
+                    view_attack->callback(
+                        FuzzerCustomEventViewAttackEmulateCurrent, view_attack->context);
+                } else if(event->key == InputKeyUp && event->type == InputTypeShort) {
+                    view_attack->callback(
+                        FuzzerCustomEventViewAttackPrevUid, view_attack->context);
+                } else if(event->key == InputKeyDown && event->type == InputTypeShort) {
+                    view_attack->callback(
+                        FuzzerCustomEventViewAttackNextUid, view_attack->context);
                 }
                 break;
 

+ 1 - 9
views/attack.h

@@ -29,15 +29,7 @@ void fuzzer_view_attack_reset_data(
 
 void fuzzer_view_attack_set_uid(FuzzerViewAttack* view, const FuzzerPayload* uid);
 
-void fuzzer_view_attack_start(FuzzerViewAttack* view);
-
-void fuzzer_view_attack_stop(FuzzerViewAttack* view);
-
-void fuzzer_view_attack_pause(FuzzerViewAttack* view);
-
-void fuzzer_view_attack_idle(FuzzerViewAttack* view);
-
-void fuzzer_view_attack_end(FuzzerViewAttack* view);
+void fuzzer_view_update_state(FuzzerViewAttack* view, FuzzerAttackState state);
 
 uint8_t fuzzer_view_attack_get_time_delay(FuzzerViewAttack* view);