derskythe 3 лет назад
Родитель
Сommit
406cbff116

+ 0 - 0
gui_top_buttons.c → helpers/gui_top_buttons.c


+ 0 - 0
gui_top_buttons.h → helpers/gui_top_buttons.h


+ 19 - 9
helpers/subbrute_worker.c

@@ -96,8 +96,11 @@ bool subbrute_worker_init_default_attack(
     instance->te = protocol->te;
     instance->te = protocol->te;
     instance->repeat = protocol->repeat + extra_repeats;
     instance->repeat = protocol->repeat + extra_repeats;
     instance->load_index = 0;
     instance->load_index = 0;
-    instance->file_key = NULL;
-    instance->max_value = subbrute_protocol_calc_max_value(instance->attack, instance->bits);
+    instance->file_key = 0;
+    instance->two_bytes = false;
+
+    instance->max_value =
+        subbrute_protocol_calc_max_value(instance->attack, instance->bits, instance->two_bytes);
 
 
     instance->initiated = true;
     instance->initiated = true;
     instance->state = SubBruteWorkerStateReady;
     instance->state = SubBruteWorkerStateReady;
@@ -122,9 +125,10 @@ bool subbrute_worker_init_file_attack(
     SubBruteWorker* instance,
     SubBruteWorker* instance,
     uint64_t step,
     uint64_t step,
     uint8_t load_index,
     uint8_t load_index,
-    const char* file_key,
+    uint64_t file_key,
     SubBruteProtocol* protocol,
     SubBruteProtocol* protocol,
-    uint8_t extra_repeats) {
+    uint8_t extra_repeats,
+    bool two_bytes) {
     furi_assert(instance);
     furi_assert(instance);
 
 
     if(instance->worker_running) {
     if(instance->worker_running) {
@@ -142,7 +146,10 @@ bool subbrute_worker_init_file_attack(
     instance->load_index = load_index;
     instance->load_index = load_index;
     instance->repeat = protocol->repeat + extra_repeats;
     instance->repeat = protocol->repeat + extra_repeats;
     instance->file_key = file_key;
     instance->file_key = file_key;
-    instance->max_value = subbrute_protocol_calc_max_value(instance->attack, instance->bits);
+    instance->two_bytes = two_bytes;
+
+    instance->max_value =
+        subbrute_protocol_calc_max_value(instance->attack, instance->bits, instance->two_bytes);
 
 
     instance->initiated = true;
     instance->initiated = true;
     instance->state = SubBruteWorkerStateReady;
     instance->state = SubBruteWorkerStateReady;
@@ -150,14 +157,15 @@ bool subbrute_worker_init_file_attack(
 #ifdef FURI_DEBUG
 #ifdef FURI_DEBUG
     FURI_LOG_I(
     FURI_LOG_I(
         TAG,
         TAG,
-        "subbrute_worker_init_file_attack: %s, bits: %d, preset: %s, file: %s, te: %d, repeat: %d, max_value: %lld",
+        "subbrute_worker_init_file_attack: %s, bits: %d, preset: %s, file: %s, te: %d, repeat: %d, max_value: %lld, key: %llX",
         subbrute_protocol_name(instance->attack),
         subbrute_protocol_name(instance->attack),
         instance->bits,
         instance->bits,
         subbrute_protocol_preset(instance->preset),
         subbrute_protocol_preset(instance->preset),
         subbrute_protocol_file(instance->file),
         subbrute_protocol_file(instance->file),
         instance->te,
         instance->te,
         instance->repeat,
         instance->repeat,
-        instance->max_value);
+        instance->max_value,
+        instance->file_key);
 #endif
 #endif
 
 
     return true;
     return true;
@@ -244,7 +252,8 @@ bool subbrute_worker_transmit_current_key(SubBruteWorker* instance, uint64_t ste
             instance->te,
             instance->te,
             instance->repeat,
             instance->repeat,
             instance->load_index,
             instance->load_index,
-            instance->file_key);
+            instance->file_key,
+            instance->two_bytes);
     } else {
     } else {
         subbrute_protocol_default_payload(
         subbrute_protocol_default_payload(
             stream, step, instance->bits, instance->te, instance->repeat);
             stream, step, instance->bits, instance->te, instance->repeat);
@@ -373,7 +382,8 @@ int32_t subbrute_worker_thread(void* context) {
                 instance->te,
                 instance->te,
                 instance->repeat,
                 instance->repeat,
                 instance->load_index,
                 instance->load_index,
-                instance->file_key);
+                instance->file_key,
+                instance->two_bytes);
         } else {
         } else {
             subbrute_protocol_default_payload(
             subbrute_protocol_default_payload(
                 stream, instance->step, instance->bits, instance->te, instance->repeat);
                 stream, instance->step, instance->bits, instance->te, instance->repeat);

+ 3 - 2
helpers/subbrute_worker.h

@@ -28,9 +28,10 @@ bool subbrute_worker_init_file_attack(
     SubBruteWorker* instance,
     SubBruteWorker* instance,
     uint64_t step,
     uint64_t step,
     uint8_t load_index,
     uint8_t load_index,
-    const char* file_key,
+    uint64_t file_key,
     SubBruteProtocol* protocol,
     SubBruteProtocol* protocol,
-    uint8_t extra_repeats);
+    uint8_t extra_repeats,
+    bool two_bytes);
 bool subbrute_worker_start(SubBruteWorker* instance);
 bool subbrute_worker_start(SubBruteWorker* instance);
 void subbrute_worker_stop(SubBruteWorker* instance);
 void subbrute_worker_stop(SubBruteWorker* instance);
 bool subbrute_worker_transmit_current_key(SubBruteWorker* instance, uint64_t step);
 bool subbrute_worker_transmit_current_key(SubBruteWorker* instance, uint64_t step);

+ 2 - 1
helpers/subbrute_worker_private.h

@@ -31,8 +31,9 @@ struct SubBruteWorker {
     uint8_t te;
     uint8_t te;
     uint8_t repeat;
     uint8_t repeat;
     uint8_t load_index; // Index of group to bruteforce in loaded file
     uint8_t load_index; // Index of group to bruteforce in loaded file
-    const char* file_key;
+    uint64_t file_key;
     uint64_t max_value; // Max step
     uint64_t max_value; // Max step
+    bool two_bytes;
 
 
     // Manual transmit
     // Manual transmit
     uint32_t last_time_tx_data;
     uint32_t last_time_tx_data;

+ 4 - 3
scenes/subbrute_scene_load_file.c

@@ -44,10 +44,11 @@ void subbrute_scene_load_file_on_enter(void* context) {
                 if(!subbrute_worker_init_file_attack(
                 if(!subbrute_worker_init_file_attack(
                        instance->worker,
                        instance->worker,
                        instance->device->current_step,
                        instance->device->current_step,
-                       instance->device->current_step,
-                       instance->device->file_key,
+                       instance->device->bit_index,
+                       instance->device->key_from_file,
                        instance->device->file_protocol_info,
                        instance->device->file_protocol_info,
-                       extra_repeats)) {
+                       extra_repeats,
+                       instance->device->two_bytes)) {
                     furi_crash("Invalid attack set!");
                     furi_crash("Invalid attack set!");
                 }
                 }
                 // Ready to run!
                 // Ready to run!

+ 18 - 6
scenes/subbrute_scene_load_select.c

@@ -20,7 +20,8 @@ void subbrute_scene_load_select_on_enter(void* context) {
 
 
     instance->current_view = SubBruteViewMain;
     instance->current_view = SubBruteViewMain;
     subbrute_main_view_set_callback(view, subbrute_scene_load_select_callback, instance);
     subbrute_main_view_set_callback(view, subbrute_scene_load_select_callback, instance);
-    subbrute_main_view_set_index(view, 7, true, instance->device->file_key);
+    subbrute_main_view_set_index(
+        view, 7, true, instance->device->two_bytes, instance->device->key_from_file);
 
 
     view_dispatcher_switch_to_view(instance->view_dispatcher, instance->current_view);
     view_dispatcher_switch_to_view(instance->view_dispatcher, instance->current_view);
 }
 }
@@ -42,22 +43,33 @@ bool subbrute_scene_load_select_on_event(void* context, SceneManagerEvent event)
             view_dispatcher_stop(instance->view_dispatcher);
             view_dispatcher_stop(instance->view_dispatcher);
             consumed = true;
             consumed = true;
 #else*/
 #else*/
-            instance->device->current_step = subbrute_main_view_get_index(instance->view_main);
+            instance->device->current_step = 0;
+            instance->device->bit_index = subbrute_main_view_get_index(instance->view_main);
+            instance->device->two_bytes = subbrute_main_view_get_two_bytes(instance->view_main);
             uint8_t extra_repeats = subbrute_main_view_get_extra_repeats(instance->view_main);
             uint8_t extra_repeats = subbrute_main_view_get_extra_repeats(instance->view_main);
+            instance->device->max_value = subbrute_protocol_calc_max_value(
+                instance->device->attack,
+                instance->device->bit_index,
+                instance->device->two_bytes);
 
 
             if(!subbrute_worker_init_file_attack(
             if(!subbrute_worker_init_file_attack(
                    instance->worker,
                    instance->worker,
                    instance->device->current_step,
                    instance->device->current_step,
-                   instance->device->current_step,
-                   instance->device->file_key,
+                   instance->device->bit_index,
+                   instance->device->key_from_file,
                    instance->device->file_protocol_info,
                    instance->device->file_protocol_info,
-                   extra_repeats)) {
+                   extra_repeats,
+                   instance->device->two_bytes)) {
                 furi_crash("Invalid attack set!");
                 furi_crash("Invalid attack set!");
             }
             }
             scene_manager_next_scene(instance->scene_manager, SubBruteSceneSetupAttack);
             scene_manager_next_scene(instance->scene_manager, SubBruteSceneSetupAttack);
             /*#endif*/
             /*#endif*/
             consumed = true;
             consumed = true;
-        }
+        } /* else if(event.event == SubBruteCustomEventTypeChangeStepUp) {
+            instance->device->two_bytes = true;
+        } else if(event.event == SubBruteCustomEventTypeChangeStepDown) {
+            instance->device->two_bytes = false;
+        }*/
     } else if(event.type == SceneManagerEventTypeBack) {
     } else if(event.type == SceneManagerEventTypeBack) {
         if(!scene_manager_search_and_switch_to_previous_scene(
         if(!scene_manager_search_and_switch_to_previous_scene(
                instance->scene_manager, SubBruteSceneStart)) {
                instance->scene_manager, SubBruteSceneStart)) {

+ 2 - 1
scenes/subbrute_scene_start.c

@@ -23,7 +23,8 @@ void subbrute_scene_start_on_enter(void* context) {
 
 
     instance->current_view = SubBruteViewMain;
     instance->current_view = SubBruteViewMain;
     subbrute_main_view_set_callback(view, subbrute_scene_start_callback, instance);
     subbrute_main_view_set_callback(view, subbrute_scene_start_callback, instance);
-    subbrute_main_view_set_index(view, instance->device->attack, false, NULL);
+    subbrute_main_view_set_index(
+        view, instance->device->attack, false, instance->device->two_bytes, 0);
 
 
     view_dispatcher_switch_to_view(instance->view_dispatcher, instance->current_view);
     view_dispatcher_switch_to_view(instance->view_dispatcher, instance->current_view);
 
 

+ 102 - 108
subbrute_device.c

@@ -175,8 +175,8 @@ SubBruteFileResult subbrute_device_attack_set(
             protocol_check_result = SubBruteFileResultOk;
             protocol_check_result = SubBruteFileResultOk;
 
 
             // Calc max value
             // Calc max value
-            instance->max_value =
-                subbrute_protocol_calc_max_value(instance->attack, instance->protocol_info->bits);
+            instance->max_value = subbrute_protocol_calc_max_value(
+                instance->attack, instance->protocol_info->bits, instance->two_bytes);
         }
         }
 #ifdef FURI_DEBUG
 #ifdef FURI_DEBUG
         bits = instance->protocol_info->bits;
         bits = instance->protocol_info->bits;
@@ -190,8 +190,8 @@ SubBruteFileResult subbrute_device_attack_set(
         protocol_check_result = SubBruteFileResultOk;
         protocol_check_result = SubBruteFileResultOk;
 
 
         // Calc max value
         // Calc max value
-        instance->max_value =
-            subbrute_protocol_calc_max_value(instance->attack, instance->file_protocol_info->bits);
+        instance->max_value = subbrute_protocol_calc_max_value(
+            instance->attack, instance->file_protocol_info->bits, instance->two_bytes);
 #ifdef FURI_DEBUG
 #ifdef FURI_DEBUG
         bits = instance->file_protocol_info->bits;
         bits = instance->file_protocol_info->bits;
         te = instance->file_protocol_info->te;
         te = instance->file_protocol_info->te;
@@ -258,25 +258,24 @@ uint8_t subbrute_device_load_from_file(SubBruteDevice* instance, const char* fil
         }
         }
 
 
         // Frequency
         // Frequency
-        if(flipper_format_read_uint32(fff_data_file, "Frequency", &temp_data32, 1)) {
-            instance->file_protocol_info->frequency = temp_data32;
-            if(!furi_hal_subghz_is_tx_allowed(instance->file_protocol_info->frequency)) {
-                result = SubBruteFileResultFrequencyNotAllowed;
-                break;
-            }
-        } else {
+        if(!flipper_format_read_uint32(fff_data_file, "Frequency", &temp_data32, 1)) {
             FURI_LOG_E(TAG, "Missing or incorrect Frequency");
             FURI_LOG_E(TAG, "Missing or incorrect Frequency");
             result = SubBruteFileResultMissingOrIncorrectFrequency;
             result = SubBruteFileResultMissingOrIncorrectFrequency;
             break;
             break;
         }
         }
+        instance->file_protocol_info->frequency = temp_data32;
+        if(!furi_hal_subghz_is_tx_allowed(instance->file_protocol_info->frequency)) {
+            result = SubBruteFileResultFrequencyNotAllowed;
+            break;
+        }
 
 
         // Preset
         // Preset
         if(!flipper_format_read_string(fff_data_file, "Preset", temp_str)) {
         if(!flipper_format_read_string(fff_data_file, "Preset", temp_str)) {
             FURI_LOG_E(TAG, "Preset FAIL");
             FURI_LOG_E(TAG, "Preset FAIL");
             result = SubBruteFileResultPresetInvalid;
             result = SubBruteFileResultPresetInvalid;
-        } else {
-            instance->file_protocol_info->preset = subbrute_protocol_convert_preset(temp_str);
+            break;
         }
         }
+        instance->file_protocol_info->preset = subbrute_protocol_convert_preset(temp_str);
 
 
         const char* protocol_file = NULL;
         const char* protocol_file = NULL;
         // Protocol
         // Protocol
@@ -284,13 +283,12 @@ uint8_t subbrute_device_load_from_file(SubBruteDevice* instance, const char* fil
             FURI_LOG_E(TAG, "Missing Protocol");
             FURI_LOG_E(TAG, "Missing Protocol");
             result = SubBruteFileResultMissingProtocol;
             result = SubBruteFileResultMissingProtocol;
             break;
             break;
-        } else {
-            instance->file_protocol_info->file = subbrute_protocol_file_protocol_name(temp_str);
-            protocol_file = subbrute_protocol_file(instance->file_protocol_info->file);
+        }
+        instance->file_protocol_info->file = subbrute_protocol_file_protocol_name(temp_str);
+        protocol_file = subbrute_protocol_file(instance->file_protocol_info->file);
 #ifdef FURI_DEBUG
 #ifdef FURI_DEBUG
-            FURI_LOG_D(TAG, "Protocol: %s", protocol_file);
+        FURI_LOG_D(TAG, "Protocol: %s", protocol_file);
 #endif
 #endif
-        }
 
 
         instance->decoder_result = subghz_receiver_search_decoder_base_by_name(
         instance->decoder_result = subghz_receiver_search_decoder_base_by_name(
             instance->receiver, furi_string_get_cstr(temp_str));
             instance->receiver, furi_string_get_cstr(temp_str));
@@ -308,9 +306,7 @@ uint8_t subbrute_device_load_from_file(SubBruteDevice* instance, const char* fil
             break;
             break;
         }
         }
 #ifdef FURI_DEBUG
 #ifdef FURI_DEBUG
-        else {
-            FURI_LOG_D(TAG, "Decoder: %s", instance->decoder_result->protocol->name);
-        }
+        FURI_LOG_D(TAG, "Decoder: %s", instance->decoder_result->protocol->name);
 #endif
 #endif
 
 
         // Bit
         // Bit
@@ -318,12 +314,11 @@ uint8_t subbrute_device_load_from_file(SubBruteDevice* instance, const char* fil
             FURI_LOG_E(TAG, "Missing or incorrect Bit");
             FURI_LOG_E(TAG, "Missing or incorrect Bit");
             result = SubBruteFileResultMissingOrIncorrectBit;
             result = SubBruteFileResultMissingOrIncorrectBit;
             break;
             break;
-        } else {
-            instance->file_protocol_info->bits = temp_data32;
+        }
+        instance->file_protocol_info->bits = temp_data32;
 #ifdef FURI_DEBUG
 #ifdef FURI_DEBUG
-            FURI_LOG_D(TAG, "Bit: %d", instance->file_protocol_info->bits);
+        FURI_LOG_D(TAG, "Bit: %d", instance->file_protocol_info->bits);
 #endif
 #endif
-        }
 
 
         // TODO: Delete this
         // TODO: Delete this
         // Key
         // Key
@@ -333,12 +328,12 @@ uint8_t subbrute_device_load_from_file(SubBruteDevice* instance, const char* fil
         //             break;
         //             break;
         //         } else {
         //         } else {
         //             snprintf(
         //             snprintf(
-        //                 instance->file_key,
-        //                 sizeof(instance->file_key),
+        //                 instance->current_key_from_file,
+        //                 sizeof(instance->current_key_from_file),
         //                 "%s",
         //                 "%s",
         //                 furi_string_get_cstr(temp_str));
         //                 furi_string_get_cstr(temp_str));
         // #ifdef FURI_DEBUG
         // #ifdef FURI_DEBUG
-        //             FURI_LOG_D(TAG, "Key: %s", instance->file_key);
+        //             FURI_LOG_D(TAG, "Key: %s", instance->current_key_from_file);
         // #endif
         // #endif
         //         }
         //         }
         //
         //
@@ -354,85 +349,85 @@ uint8_t subbrute_device_load_from_file(SubBruteDevice* instance, const char* fil
         for(uint8_t i = 0; i < sizeof(uint64_t); i++) {
         for(uint8_t i = 0; i < sizeof(uint64_t); i++) {
             data = (data << 8) | key_data[i];
             data = (data << 8) | key_data[i];
         }
         }
+#if FURI_DEBUG
+        FURI_LOG_D(TAG, "Key: %.16llX", data);
+#endif
         instance->key_from_file = data;
         instance->key_from_file = data;
 
 
-        uint16_t add_value = 0x0001;
-        uint8_t bit_index = 7;
-        bool two_bytes = true;
-
-        uint8_t p[8];
-        for(int i = 0; i < 8; i++) {
-            p[i] = (uint8_t)(instance->key_from_file >> 8 * (7 - i)) & 0xFF;
-        }
-        uint16_t num = two_bytes ? (p[bit_index - 1] << 8) | p[bit_index] : p[bit_index];
-        FURI_LOG_D(TAG, "num: 0x%04X", num);
-        num += add_value;
-        FURI_LOG_D(TAG, "num added: 0x%04X", num);
-        uint8_t low_byte = num & (0xff);
-        uint8_t high_byte = (num >> 8) & 0xff;
-
-        data = 0;
-        for(uint8_t i = 0; i < sizeof(uint64_t); i++) {
-            if(i == bit_index - 1 && two_bytes) {
-                data = (data << 8) | high_byte;
-                data = (data << 8) | low_byte;
-                i++;
-            } else if(i == bit_index) {
-                data = (data << 8) | low_byte;
-            } else {
-                data = (data << 8) | p[i];
-            }
-        }
-
-        furi_string_printf(temp_str, "Key: %lX", (uint32_t)(data & 0xFFFFFFFF));
-        FURI_LOG_D(
-            TAG, "H: 0x%02X, L: 0x%02X, %s", high_byte, low_byte, furi_string_get_cstr(temp_str));
-
-        flipper_format_rewind(fff_data_file);
-
-        uint8_t key_data[sizeof(uint64_t)] = {0};
-        if(!flipper_format_read_hex(fff_data_file, "Key", key_data, sizeof(uint64_t))) {
-            FURI_LOG_E(TAG, "Missing Key");
-            result = SubBruteFileResultMissingOrIncorrectKey;
-            break;
-        }
-        uint64_t data = 0;
-        for(uint8_t i = 0; i < sizeof(uint64_t); i++) {
-            data = (data << 8) | key_data[i];
-        }
-        instance->key_from_file = data;
-
-        uint16_t add_value = 0x0001;
-        uint8_t bit_index = 7;
-        bool two_bytes = true;
-
-        uint8_t p[8];
-        for(int i = 0; i < 8; i++) {
-            p[i] = (uint8_t)(instance->key_from_file >> 8 * (7 - i)) & 0xFF;
-        }
-        uint16_t num = two_bytes ? (p[bit_index - 1] << 8) | p[bit_index] : p[bit_index];
-        FURI_LOG_D(TAG, "num: 0x%04X", num);
-        num += add_value;
-        FURI_LOG_D(TAG, "num added: 0x%04X", num);
-        uint8_t low_byte = num & (0xff);
-        uint8_t high_byte = (num >> 8) & 0xff;
-
-        data = 0;
-        for(uint8_t i = 0; i < sizeof(uint64_t); i++) {
-            if(i == bit_index - 1 && two_bytes) {
-                data = (data << 8) | high_byte;
-                data = (data << 8) | low_byte;
-                i++;
-            } else if(i == bit_index) {
-                data = (data << 8) | low_byte;
-            } else {
-                data = (data << 8) | p[i];
-            }
-        }
-
-        furi_string_printf(temp_str, "Key: %lX", (uint32_t)(data & 0xFFFFFFFF));
-        FURI_LOG_D(
-            TAG, "H: 0x%02X, L: 0x%02X, %s", high_byte, low_byte, furi_string_get_cstr(temp_str));
+        //         uint16_t add_value = 0x0001;
+        //         uint8_t bit_index = 7;
+        //         bool two_bytes = true;
+        //         uint8_t p[8];
+        //         for(int i = 0; i < 8; i++) {
+        //             p[i] = (uint8_t)(instance->key_from_file >> 8 * (7 - i)) & 0xFF;
+        //         }
+        //         uint16_t num = two_bytes ? (p[bit_index - 1] << 8) | p[bit_index] : p[bit_index];
+        //         FURI_LOG_D(TAG, "num: 0x%04X", num);
+        //         num += add_value;
+        //         FURI_LOG_D(TAG, "num added: 0x%04X", num);
+        //         uint8_t low_byte = num & (0xff);
+        //         uint8_t high_byte = (num >> 8) & 0xff;
+
+        //         data = 0;
+        //         for(uint8_t i = 0; i < sizeof(uint64_t); i++) {
+        //             if(i == bit_index - 1 && two_bytes) {
+        //                 data = (data << 8) | high_byte;
+        //                 data = (data << 8) | low_byte;
+        //                 i++;
+        //             } else if(i == bit_index) {
+        //                 data = (data << 8) | low_byte;
+        //             } else {
+        //                 data = (data << 8) | p[i];
+        //             }
+        //         }
+        // #if FURI_DEBUG
+        //         furi_string_printf(temp_str, "Key: %lX", (uint32_t)(data & 0xFFFFFFFF));
+        //         FURI_LOG_D(
+        //             TAG, "H: 0x%02X, L: 0x%02X, %s", high_byte, low_byte, furi_string_get_cstr(temp_str));
+        // #endif
+        // uint8_t key_data[sizeof(uint64_t)] = {0};
+        // if(!flipper_format_read_hex(fff_data_file, "Key", key_data, sizeof(uint64_t))) {
+        //     FURI_LOG_E(TAG, "Missing Key");
+        //     result = SubBruteFileResultMissingOrIncorrectKey;
+        //     break;
+        // }
+        // uint64_t data = 0;
+        // for(uint8_t i = 0; i < sizeof(uint64_t); i++) {
+        //     data = (data << 8) | key_data[i];
+        // }
+        // instance->key_from_file = data;
+
+        // uint16_t add_value = 0x0001;
+        // uint8_t bit_index = 7;
+        // bool two_bytes = true;
+
+        // uint8_t p[8];
+        // for(int i = 0; i < 8; i++) {
+        //     p[i] = (uint8_t)(instance->key_from_file >> 8 * (7 - i)) & 0xFF;
+        // }
+        // uint16_t num = two_bytes ? (p[bit_index - 1] << 8) | p[bit_index] : p[bit_index];
+        // FURI_LOG_D(TAG, "num: 0x%04X", num);
+        // num += add_value;
+        // FURI_LOG_D(TAG, "num added: 0x%04X", num);
+        // uint8_t low_byte = num & (0xff);
+        // uint8_t high_byte = (num >> 8) & 0xff;
+
+        // data = 0;
+        // for(uint8_t i = 0; i < sizeof(uint64_t); i++) {
+        //     if(i == bit_index - 1 && two_bytes) {
+        //         data = (data << 8) | high_byte;
+        //         data = (data << 8) | low_byte;
+        //         i++;
+        //     } else if(i == bit_index) {
+        //         data = (data << 8) | low_byte;
+        //     } else {
+        //         data = (data << 8) | p[i];
+        //     }
+        // }
+
+        // furi_string_printf(temp_str, "Key: %lX", (uint32_t)(data & 0xFFFFFFFF));
+        // FURI_LOG_D(
+        //     TAG, "H: 0x%02X, L: 0x%02X, %s", high_byte, low_byte, furi_string_get_cstr(temp_str));
 
 
         // TE
         // TE
         if(!flipper_format_read_uint32(fff_data_file, "TE", &temp_data32, 1)) {
         if(!flipper_format_read_uint32(fff_data_file, "TE", &temp_data32, 1)) {
@@ -495,9 +490,8 @@ void subbrute_device_attack_set_default_values(
     memset(instance->current_key, 0, sizeof(instance->current_key));
     memset(instance->current_key, 0, sizeof(instance->current_key));
 
 
     if(default_attack != SubBruteAttackLoadFile) {
     if(default_attack != SubBruteAttackLoadFile) {
-        memset(instance->file_key, 0, sizeof(instance->file_key));
-
-        instance->max_value = (uint64_t)0x00;
+        instance->max_value = subbrute_protocol_calc_max_value(
+            instance->attack, instance->bit_index, instance->two_bytes);
     }
     }
 }
 }
 
 

+ 0 - 1
subbrute_device.h

@@ -50,7 +50,6 @@ typedef struct {
 
 
     // Loaded info for attack type
     // Loaded info for attack type
     char current_key[SUBBRUTE_PAYLOAD_SIZE];
     char current_key[SUBBRUTE_PAYLOAD_SIZE];
-    char file_key[SUBBRUTE_MAX_LEN_NAME];
     uint64_t key_from_file;
     uint64_t key_from_file;
     uint64_t current_key_from_file;
     uint64_t current_key_from_file;
     bool two_bytes;
     bool two_bytes;

+ 1 - 1
subbrute_i.h

@@ -30,7 +30,7 @@
 #include "views/subbrute_main_view.h"
 #include "views/subbrute_main_view.h"
 
 
 #ifdef FURI_DEBUG
 #ifdef FURI_DEBUG
-#define SUBBRUTE_FAST_TRACK true
+//#define SUBBRUTE_FAST_TRACK false
 #endif
 #endif
 
 
 typedef enum {
 typedef enum {

+ 70 - 42
subbrute_protocols.c

@@ -326,6 +326,66 @@ SubBruteFileProtocol subbrute_protocol_file_protocol_name(FuriString* name) {
     return UnknownFileProtocol;
     return UnknownFileProtocol;
 }
 }
 
 
+void subbrute_protocol_create_candidate_for_existing_file(
+    FuriString* candidate,
+    uint64_t step,
+    uint8_t bit_index,
+    uint64_t file_key,
+    bool two_bytes) {
+    uint8_t p[8];
+    for(int i = 0; i < 8; i++) {
+        p[i] = (uint8_t)(file_key >> 8 * (7 - i)) & 0xFF;
+    }
+    uint8_t low_byte = step & (0xff);
+    uint8_t high_byte = (step >> 8) & 0xff;
+
+    size_t size = sizeof(uint64_t);
+    for(uint8_t i = 0; i < size; i++) {
+        if(i == bit_index - 1 && two_bytes) {
+            furi_string_cat_printf(candidate, "%02X %02X", high_byte, low_byte);
+            i++;
+        } else if(i == bit_index) {
+            furi_string_cat_printf(candidate, "%02X", low_byte);
+        } else if(p[i] != 0) {
+            furi_string_cat_printf(candidate, "%02X", p[i]);
+        } else {
+            furi_string_cat_printf(candidate, "%s", "00");
+        }
+
+        if(i < size - 1) {
+            furi_string_push_back(candidate, ' ');
+        }
+    }
+
+#ifdef FURI_DEBUG
+    FURI_LOG_D(TAG, "file candidate: %s, step: %lld", furi_string_get_cstr(candidate), step);
+#endif
+}
+
+void subbrute_protocol_create_candidate_for_default(FuriString* candidate, uint64_t step) {
+    uint8_t p[8];
+    for(int i = 0; i < 8; i++) {
+        p[i] = (uint8_t)(step >> 8 * (7 - i)) & 0xFF;
+    }
+
+    size_t size = sizeof(uint64_t);
+    for(uint8_t i = 0; i < size; i++) {
+        if(p[i] != 0) {
+            furi_string_cat_printf(candidate, "%02X", p[i]);
+        } else {
+            furi_string_cat_printf(candidate, "%s", "00");
+        }
+
+        if(i < size - 1) {
+            furi_string_push_back(candidate, ' ');
+        }
+    }
+
+#ifdef FURI_DEBUG
+    FURI_LOG_D(TAG, "candidate: %s, step: %lld", furi_string_get_cstr(candidate), step);
+#endif
+}
+
 void subbrute_protocol_default_payload(
 void subbrute_protocol_default_payload(
     Stream* stream,
     Stream* stream,
     uint64_t step,
     uint64_t step,
@@ -380,13 +440,12 @@ void subbrute_protocol_file_payload(
     uint8_t bits,
     uint8_t bits,
     uint8_t te,
     uint8_t te,
     uint8_t repeat,
     uint8_t repeat,
-    uint8_t load_index,
-    const char* file_key) {
+    uint8_t bit_index,
+    uint64_t file_key,
+    bool two_bytes) {
     FuriString* candidate = furi_string_alloc();
     FuriString* candidate = furi_string_alloc();
-    char subbrute_payload_byte[4];
-    furi_string_set_str(candidate, file_key);
-    snprintf(subbrute_payload_byte, 4, "%02X ", (uint8_t)step);
-    furi_string_replace_at(candidate, load_index * 3, 3, subbrute_payload_byte);
+    subbrute_protocol_create_candidate_for_existing_file(
+        candidate, step, bit_index, file_key, two_bytes);
 
 
 #ifdef FURI_DEBUG
 #ifdef FURI_DEBUG
     FURI_LOG_D(
     FURI_LOG_D(
@@ -486,41 +545,9 @@ void subbrute_protocol_file_generate_file(
     FuriString* candidate = furi_string_alloc();
     FuriString* candidate = furi_string_alloc();
     // char subbrute_payload_byte[8];
     // char subbrute_payload_byte[8];
     //furi_string_set_str(candidate, file_key);
     //furi_string_set_str(candidate, file_key);
+    subbrute_protocol_create_candidate_for_existing_file(
+        candidate, step, bit_index, file_key, two_bytes);
 
 
-    uint8_t p[8];
-    for(int i = 0; i < 8; i++) {
-        p[i] = (uint8_t)(file_key >> 8 * (7 - i)) & 0xFF;
-    }
-    uint16_t num = two_bytes ? (p[bit_index - 1] << 8) | p[bit_index] : p[bit_index];
-#ifdef FURI_DEBUG
-    FURI_LOG_D(TAG, "num: 0x%04X", num);
-#endif
-    num += step;
-#ifdef FURI_DEBUG
-    FURI_LOG_D(TAG, "num added: 0x%04X", num);
-#endif
-    uint8_t low_byte = num & (0xff);
-    uint8_t high_byte = (num >> 8) & 0xff;
-
-    size_t size = sizeof(uint64_t);
-    for(uint8_t i = 0; i < size; i++) {
-        if(i == bit_index - 1 && two_bytes) {
-            furi_string_cat_printf(candidate, "%02X %02X", high_byte, low_byte);
-            i++;
-        } else if(i == bit_index) {
-            furi_string_cat_printf(candidate, "%02X", low_byte);
-        } else {
-            furi_string_cat_printf(candidate, "%02X", p[i]);
-        }
-
-        if(i < size - 1) {
-            furi_string_push_back(candidate, ' ');
-        }
-    }
-
-#ifdef FURI_DEBUG
-    FURI_LOG_D(TAG, "candidate: %s, step: %lld", furi_string_get_cstr(candidate), step);
-#endif
     stream_clean(stream);
     stream_clean(stream);
     if(te) {
     if(te) {
         stream_write_format(
         stream_write_format(
@@ -548,10 +575,11 @@ void subbrute_protocol_file_generate_file(
     furi_string_free(candidate);
     furi_string_free(candidate);
 }
 }
 
 
-uint64_t subbrute_protocol_calc_max_value(SubBruteAttacks attack_type, uint8_t bits) {
+uint64_t
+    subbrute_protocol_calc_max_value(SubBruteAttacks attack_type, uint8_t bits, bool two_bytes) {
     uint64_t max_value;
     uint64_t max_value;
     if(attack_type == SubBruteAttackLoadFile) {
     if(attack_type == SubBruteAttackLoadFile) {
-        max_value = 0xFFFF;
+        max_value = two_bytes ? 0xFFFF : 0xFF;
     } else {
     } else {
         FuriString* max_value_s;
         FuriString* max_value_s;
         max_value_s = furi_string_alloc();
         max_value_s = furi_string_alloc();

+ 5 - 3
subbrute_protocols.h

@@ -74,8 +74,9 @@ void subbrute_protocol_file_payload(
     uint8_t bits,
     uint8_t bits,
     uint8_t te,
     uint8_t te,
     uint8_t repeat,
     uint8_t repeat,
-    uint8_t load_index,
-    const char* file_key);
+    uint8_t bit_index,
+    uint64_t file_key,
+    bool two_bytes);
 void subbrute_protocol_default_generate_file(
 void subbrute_protocol_default_generate_file(
     Stream* stream,
     Stream* stream,
     uint32_t frequency,
     uint32_t frequency,
@@ -97,4 +98,5 @@ void subbrute_protocol_file_generate_file(
     uint8_t bit_index,
     uint8_t bit_index,
     uint64_t file_key,
     uint64_t file_key,
     bool two_bytes);
     bool two_bytes);
-uint64_t subbrute_protocol_calc_max_value(SubBruteAttacks attack_type, uint8_t bits);
+uint64_t
+    subbrute_protocol_calc_max_value(SubBruteAttacks attack_type, uint8_t bits, bool two_bytes);

+ 22 - 4
views/subbrute_attack_view.c

@@ -1,7 +1,7 @@
 #include "subbrute_attack_view.h"
 #include "subbrute_attack_view.h"
 #include "../subbrute_i.h"
 #include "../subbrute_i.h"
 #include "../subbrute_protocols.h"
 #include "../subbrute_protocols.h"
-#include "../gui_top_buttons.h"
+#include "../helpers/gui_top_buttons.h"
 
 
 #include <input/input.h>
 #include <input/input.h>
 #include <gui/elements.h>
 #include <gui/elements.h>
@@ -272,9 +272,27 @@ void subbrute_attack_view_draw(Canvas* canvas, void* context) {
     }
     }
 
 
     // Current Step / Max value
     // Current Step / Max value
-    canvas_set_font(canvas, FontBigNumbers);
-    snprintf(buffer, sizeof(buffer), "%04d/%04d", (int)model->current_step, (int)model->max_value);
-    canvas_draw_str_aligned(canvas, 64, 17, AlignCenter, AlignTop, buffer);
+    const uint8_t y_frequency = 17;
+    if(model->max_value > 9999) {
+        canvas_set_font(canvas, FontBigNumbers);
+        snprintf(buffer, sizeof(buffer), "%05d/", (int)model->current_step);
+        canvas_draw_str_aligned(canvas, 5, y_frequency, AlignLeft, AlignTop, buffer);
+
+        // Second part with another font, because BigNumber is out of screen bounds
+        canvas_set_font(canvas, FontPrimary);
+        snprintf(buffer, sizeof(buffer), "%05d", (int)model->max_value);
+        canvas_draw_str_aligned(canvas, 107, y_frequency + 13, AlignRight, AlignBottom, buffer);
+    } else if(model->max_value <= 0xFF) {
+        canvas_set_font(canvas, FontBigNumbers);
+        snprintf(
+            buffer, sizeof(buffer), "%03d/%03d", (int)model->current_step, (int)model->max_value);
+        canvas_draw_str_aligned(canvas, 64, y_frequency, AlignCenter, AlignTop, buffer);
+    } else {
+        canvas_set_font(canvas, FontBigNumbers);
+        snprintf(
+            buffer, sizeof(buffer), "%04d/%04d", (int)model->current_step, (int)model->max_value);
+        canvas_draw_str_aligned(canvas, 64, y_frequency, AlignCenter, AlignTop, buffer);
+    }
     canvas_set_font(canvas, FontSecondary);
     canvas_set_font(canvas, FontSecondary);
 
 
     memset(buffer, 0, sizeof(buffer));
     memset(buffer, 0, sizeof(buffer));

+ 135 - 83
views/subbrute_main_view.c

@@ -1,7 +1,7 @@
 #include "subbrute_main_view.h"
 #include "subbrute_main_view.h"
 #include "../subbrute_i.h"
 #include "../subbrute_i.h"
 #include "../subbrute_protocols.h"
 #include "../subbrute_protocols.h"
-#include "../gui_top_buttons.h"
+#include "../helpers/gui_top_buttons.h"
 
 
 #include <input/input.h>
 #include <input/input.h>
 #include <gui/elements.h>
 #include <gui/elements.h>
@@ -11,6 +11,15 @@
 #define TAG "SubBruteMainView"
 #define TAG "SubBruteMainView"
 
 
 #define ITEMS_ON_SCREEN 3
 #define ITEMS_ON_SCREEN 3
+#define ITEMS_INTERVAL 1
+#define ITEM_WIDTH 14
+#define ITEM_Y 27
+#define ITEM_HEIGHT 13
+#define TEXT_X 6
+#define TEXT_Y 37
+#define TEXT_INTERVAL 3
+#define TEXT_WIDTH 12
+#define ITEM_FRAME_RADIUS 2
 
 
 struct SubBruteMainView {
 struct SubBruteMainView {
     View* view;
     View* view;
@@ -18,7 +27,8 @@ struct SubBruteMainView {
     void* context;
     void* context;
     uint8_t index;
     uint8_t index;
     bool is_select_byte;
     bool is_select_byte;
-    const char* key_field;
+    bool two_bytes;
+    uint64_t key_from_file;
     uint8_t extra_repeats;
     uint8_t extra_repeats;
     uint8_t window_position;
     uint8_t window_position;
 };
 };
@@ -28,7 +38,8 @@ typedef struct {
     uint8_t extra_repeats;
     uint8_t extra_repeats;
     uint8_t window_position;
     uint8_t window_position;
     bool is_select_byte;
     bool is_select_byte;
-    const char* key_field;
+    bool two_bytes;
+    uint64_t key_from_file;
 } SubBruteMainViewModel;
 } SubBruteMainViewModel;
 
 
 void subbrute_main_view_set_callback(
 void subbrute_main_view_set_callback(
@@ -42,79 +53,83 @@ void subbrute_main_view_set_callback(
     instance->context = context;
     instance->context = context;
 }
 }
 
 
-FuriString* center_displayed_key(const char* key_cstr, uint8_t index) {
-    uint8_t str_index = (index * 3);
-
-    char display_menu[] = {
-        'X', 'X', ' ', 'X', 'X', ' ', '<', 'X', 'X', '>', ' ', 'X', 'X', ' ', 'X', 'X', '\0'};
-
-    if(key_cstr == NULL) {
-        return furi_string_alloc_set(display_menu);
-    }
-    if(index > 1) {
-        display_menu[0] = key_cstr[str_index - 6];
-        display_menu[1] = key_cstr[str_index - 5];
-    } else {
-        display_menu[0] = ' ';
-        display_menu[1] = ' ';
-    }
-
-    if(index > 0) {
-        display_menu[3] = key_cstr[str_index - 3];
-        display_menu[4] = key_cstr[str_index - 2];
-    } else {
-        display_menu[3] = ' ';
-        display_menu[4] = ' ';
-    }
-
-    display_menu[7] = key_cstr[str_index];
-    display_menu[8] = key_cstr[str_index + 1];
-    uint8_t key_len = (uint8_t)strlen(key_cstr);
-
-    if((str_index + 4) <= key_len) {
-        display_menu[11] = key_cstr[str_index + 3];
-        display_menu[12] = key_cstr[str_index + 4];
-    } else {
-        display_menu[11] = ' ';
-        display_menu[12] = ' ';
-    }
-
-    if((str_index + 8) <= key_len) {
-        display_menu[14] = key_cstr[str_index + 6];
-        display_menu[15] = key_cstr[str_index + 7];
-    } else {
-        display_menu[14] = ' ';
-        display_menu[15] = ' ';
+void subbrute_main_view_center_displayed_key(
+    Canvas* canvas,
+    uint64_t key,
+    uint8_t index,
+    bool two_bytes) {
+    uint8_t text_x = TEXT_X;
+    uint8_t item_x = TEXT_X - ITEMS_INTERVAL;
+    canvas_set_font(canvas, FontSecondary);
+
+    for(int i = 0; i < 8; i++) {
+        char current_value[3] = {0};
+        uint8_t byte_value = (uint8_t)(key >> 8 * (7 - i)) & 0xFF;
+        snprintf(current_value, sizeof(current_value), "%02X", byte_value);
+
+        // For two bytes we need to select prev location
+        if(!two_bytes && i == index) {
+            canvas_set_color(canvas, ColorBlack);
+            canvas_draw_rbox(
+                canvas, item_x - 1, ITEM_Y, ITEM_WIDTH + 1, ITEM_HEIGHT, ITEM_FRAME_RADIUS);
+            canvas_set_color(canvas, ColorWhite);
+            canvas_draw_str(canvas, text_x, TEXT_Y, current_value);
+        } else if(two_bytes && (i == index || i == index - 1)) {
+            if(i == index) {
+                canvas_set_color(canvas, ColorBlack);
+                canvas_draw_rbox(
+                    canvas,
+                    item_x - ITEMS_INTERVAL - ITEM_WIDTH - 1,
+                    ITEM_Y,
+                    ITEM_WIDTH * 2 + ITEMS_INTERVAL * 2 + 1,
+                    ITEM_HEIGHT,
+                    ITEM_FRAME_RADIUS);
+
+                canvas_set_color(canvas, ColorWhite);
+                canvas_draw_str(canvas, text_x, TEXT_Y, current_value);
+
+                // Redraw prev element with white
+                memset(current_value, 0, sizeof(current_value));
+                byte_value = (uint8_t)(key >> 8 * (7 - i + 1)) & 0xFF;
+                snprintf(current_value, sizeof(current_value), "%02X", byte_value);
+                canvas_draw_str(
+                    canvas, text_x - (TEXT_WIDTH + TEXT_INTERVAL), TEXT_Y, current_value);
+            } else {
+                canvas_set_color(canvas, ColorWhite);
+                canvas_draw_str(canvas, text_x, TEXT_Y, current_value);
+            }
+        } else {
+            canvas_set_color(canvas, ColorBlack);
+            canvas_draw_str(canvas, text_x, TEXT_Y, current_value);
+        }
+        text_x = text_x + TEXT_WIDTH + TEXT_INTERVAL;
+        item_x = item_x + ITEM_WIDTH + ITEMS_INTERVAL;
     }
     }
 
 
-    return furi_string_alloc_set(display_menu);
+    // Return normal color
+    canvas_set_color(canvas, ColorBlack);
 }
 }
 
 
 void subbrute_main_view_draw(Canvas* canvas, SubBruteMainViewModel* model) {
 void subbrute_main_view_draw(Canvas* canvas, SubBruteMainViewModel* model) {
-    // Title
-    canvas_set_font(canvas, FontPrimary);
-    canvas_draw_box(canvas, 0, 0, canvas_width(canvas), STATUS_BAR_Y_SHIFT);
-    canvas_invert_color(canvas);
-    canvas_draw_str_aligned(canvas, 64, 3, AlignCenter, AlignTop, "Sub-GHz BruteForcer 3.3");
-    canvas_invert_color(canvas);
-
     uint16_t screen_width = canvas_width(canvas);
     uint16_t screen_width = canvas_width(canvas);
     uint16_t screen_height = canvas_height(canvas);
     uint16_t screen_height = canvas_height(canvas);
 
 
     if(model->is_select_byte) {
     if(model->is_select_byte) {
 #ifdef FURI_DEBUG
 #ifdef FURI_DEBUG
-        //FURI_LOG_D(TAG, "key_field: %s", model->key_field);
+        //FURI_LOG_D(TAG, "key_from_file: %s", model->key_from_file);
 #endif
 #endif
-        char msg_index[18];
-        snprintf(msg_index, sizeof(msg_index), "Field index: %d", model->index);
-        canvas_draw_str_aligned(canvas, 64, 20, AlignCenter, AlignTop, msg_index);
-
-        FuriString* menu_items;
-
-        menu_items = center_displayed_key(model->key_field, model->index);
+        //char msg_index[18];
+        //snprintf(msg_index, sizeof(msg_index), "Field index: %d", model->index);
         canvas_set_font(canvas, FontSecondary);
         canvas_set_font(canvas, FontSecondary);
         canvas_draw_str_aligned(
         canvas_draw_str_aligned(
-            canvas, 64, 40, AlignCenter, AlignTop, furi_string_get_cstr(menu_items));
+            canvas, 64, 17, AlignCenter, AlignTop, "Please select values to calc:");
+
+        subbrute_main_view_center_displayed_key(
+            canvas, model->key_from_file, model->index, model->two_bytes);
+        //const char* line = furi_string_get_cstr(menu_items);
+        //canvas_set_font(canvas, FontSecondary);
+        //canvas_draw_str_aligned(
+        //    canvas, 64, 37, AlignCenter, AlignTop, furi_string_get_cstr(menu_items));
 
 
         elements_button_center(canvas, "Select");
         elements_button_center(canvas, "Select");
         if(model->index > 0) {
         if(model->index > 0) {
@@ -123,9 +138,20 @@ void subbrute_main_view_draw(Canvas* canvas, SubBruteMainViewModel* model) {
         if(model->index < 7) {
         if(model->index < 7) {
             elements_button_right(canvas, " ");
             elements_button_right(canvas, " ");
         }
         }
-        furi_string_reset(menu_items);
-        furi_string_free(menu_items);
+        // Switch to another mode
+        if(model->two_bytes) {
+            elements_button_top_left(canvas, "One byte");
+        } else {
+            elements_button_top_left(canvas, "Two bytes");
+        }
     } else {
     } else {
+        // Title
+        canvas_set_font(canvas, FontPrimary);
+        canvas_draw_box(canvas, 0, 0, canvas_width(canvas), STATUS_BAR_Y_SHIFT);
+        canvas_invert_color(canvas);
+        canvas_draw_str_aligned(canvas, 64, 3, AlignCenter, AlignTop, "Sub-GHz BruteForcer 3.3");
+        canvas_invert_color(canvas);
+
         // Menu
         // Menu
         canvas_set_color(canvas, ColorBlack);
         canvas_set_color(canvas, ColorBlack);
         canvas_set_font(canvas, FontSecondary);
         canvas_set_font(canvas, FontSecondary);
@@ -264,17 +290,33 @@ bool subbrute_main_view_input(InputEvent* event, void* context) {
                 }
                 }
             }
             }
         }
         }
-    } else if (is_short) {
+    } else if(is_short) {
         if(event->key == InputKeyLeft) {
         if(event->key == InputKeyLeft) {
-            if(instance->index > 0) {
+            if((instance->index > 0 && !instance->two_bytes) ||
+               (instance->two_bytes && instance->index > 1)) {
                 instance->index--;
                 instance->index--;
             }
             }
             updated = true;
             updated = true;
+            consumed = true;
         } else if(event->key == InputKeyRight) {
         } else if(event->key == InputKeyRight) {
             if(instance->index < 7) {
             if(instance->index < 7) {
                 instance->index++;
                 instance->index++;
             }
             }
             updated = true;
             updated = true;
+            consumed = true;
+        } else if(event->key == InputKeyUp) {
+            instance->two_bytes = !instance->two_bytes;
+            // Because index is changing
+            if(instance->two_bytes && instance->index < 7) {
+                instance->index++;
+            }
+            // instance->callback(
+            //     instance->two_bytes ? SubBruteCustomEventTypeChangeStepUp :
+            //                           SubBruteCustomEventTypeChangeStepDown,
+            //     instance->context);
+
+            updated = true;
+            consumed = true;
         } else if(event->key == InputKeyOk) {
         } else if(event->key == InputKeyOk) {
             instance->callback(SubBruteCustomEventTypeIndexSelected, instance->context);
             instance->callback(SubBruteCustomEventTypeIndexSelected, instance->context);
             consumed = true;
             consumed = true;
@@ -289,8 +331,9 @@ bool subbrute_main_view_input(InputEvent* event, void* context) {
             {
             {
                 model->index = instance->index;
                 model->index = instance->index;
                 model->window_position = instance->window_position;
                 model->window_position = instance->window_position;
-                model->key_field = instance->key_field;
+                model->key_from_file = instance->key_from_file;
                 model->is_select_byte = instance->is_select_byte;
                 model->is_select_byte = instance->is_select_byte;
+                model->two_bytes = instance->two_bytes;
                 model->extra_repeats = instance->extra_repeats;
                 model->extra_repeats = instance->extra_repeats;
             },
             },
             true);
             true);
@@ -325,24 +368,25 @@ SubBruteMainView* subbrute_main_view_alloc() {
     view_set_enter_callback(instance->view, subbrute_main_view_enter);
     view_set_enter_callback(instance->view, subbrute_main_view_enter);
     view_set_exit_callback(instance->view, subbrute_main_view_exit);
     view_set_exit_callback(instance->view, subbrute_main_view_exit);
 
 
+    instance->index = 0;
+    instance->window_position = 0;
+    instance->key_from_file = 0;
+    instance->is_select_byte = false;
+    instance->two_bytes = false;
+    instance->extra_repeats = 0;
     with_view_model(
     with_view_model(
         instance->view,
         instance->view,
         SubBruteMainViewModel * model,
         SubBruteMainViewModel * model,
         {
         {
-            model->index = 0;
-            model->window_position = 0;
-            model->key_field = NULL;
-            model->is_select_byte = false;
-            model->extra_repeats = 0;
+            model->index = instance->index;
+            model->window_position = instance->window_position;
+            model->key_from_file = instance->key_from_file;
+            model->is_select_byte = instance->is_select_byte;
+            model->two_bytes = instance->two_bytes;
+            model->extra_repeats = instance->extra_repeats;
         },
         },
         true);
         true);
 
 
-    instance->index = 0;
-    instance->window_position = 0;
-    instance->key_field = NULL;
-    instance->is_select_byte = false;
-    instance->extra_repeats = 0;
-
     return instance;
     return instance;
 }
 }
 
 
@@ -362,14 +406,16 @@ void subbrute_main_view_set_index(
     SubBruteMainView* instance,
     SubBruteMainView* instance,
     uint8_t idx,
     uint8_t idx,
     bool is_select_byte,
     bool is_select_byte,
-    const char* key_field) {
+    bool two_bytes,
+    uint64_t key_from_file) {
     furi_assert(instance);
     furi_assert(instance);
     furi_assert(idx < SubBruteAttackTotalCount);
     furi_assert(idx < SubBruteAttackTotalCount);
 #ifdef FURI_DEBUG
 #ifdef FURI_DEBUG
-    FURI_LOG_I(TAG, "Set index: %d, IS_SELECT_BYTE: %d", idx, is_select_byte);
+    FURI_LOG_I(TAG, "Set index: %d, is_select_byte: %d", idx, is_select_byte);
 #endif
 #endif
     instance->is_select_byte = is_select_byte;
     instance->is_select_byte = is_select_byte;
-    instance->key_field = key_field;
+    instance->two_bytes = two_bytes;
+    instance->key_from_file = key_from_file;
     instance->index = idx;
     instance->index = idx;
     instance->window_position = idx;
     instance->window_position = idx;
 
 
@@ -393,8 +439,9 @@ void subbrute_main_view_set_index(
         {
         {
             model->index = instance->index;
             model->index = instance->index;
             model->window_position = instance->window_position;
             model->window_position = instance->window_position;
-            model->key_field = instance->key_field;
+            model->key_from_file = instance->key_from_file;
             model->is_select_byte = instance->is_select_byte;
             model->is_select_byte = instance->is_select_byte;
+            model->two_bytes = instance->two_bytes;
             model->extra_repeats = instance->extra_repeats;
             model->extra_repeats = instance->extra_repeats;
         },
         },
         true);
         true);
@@ -408,4 +455,9 @@ SubBruteAttacks subbrute_main_view_get_index(SubBruteMainView* instance) {
 uint8_t subbrute_main_view_get_extra_repeats(SubBruteMainView* instance) {
 uint8_t subbrute_main_view_get_extra_repeats(SubBruteMainView* instance) {
     furi_assert(instance);
     furi_assert(instance);
     return instance->extra_repeats;
     return instance->extra_repeats;
+}
+
+bool subbrute_main_view_get_two_bytes(SubBruteMainView* instance) {
+    furi_assert(instance);
+    return instance->two_bytes;
 }
 }

+ 3 - 1
views/subbrute_main_view.h

@@ -21,9 +21,11 @@ void subbrute_main_view_set_index(
     SubBruteMainView* instance,
     SubBruteMainView* instance,
     uint8_t idx,
     uint8_t idx,
     bool is_select_byte,
     bool is_select_byte,
-    const char* key_field);
+    bool two_bytes,
+    uint64_t file_key);
 SubBruteAttacks subbrute_main_view_get_index(SubBruteMainView* instance);
 SubBruteAttacks subbrute_main_view_get_index(SubBruteMainView* instance);
 uint8_t subbrute_main_view_get_extra_repeats(SubBruteMainView* instance);
 uint8_t subbrute_main_view_get_extra_repeats(SubBruteMainView* instance);
+bool subbrute_main_view_get_two_bytes(SubBruteMainView* instance);
 void subbrute_attack_view_enter(void* context);
 void subbrute_attack_view_enter(void* context);
 void subbrute_attack_view_exit(void* context);
 void subbrute_attack_view_exit(void* context);
 bool subbrute_attack_view_input(InputEvent* event, void* context);
 bool subbrute_attack_view_input(InputEvent* event, void* context);