[FL-2045] SubGhz: new protocol (GSN , Beninca/Allmatic, Elmes) and validator (#958)
* SubGhz: add new method of obtaining a manufactory code subghz_protocol_keeloq_common_magic_xor_type1_learning * TextInput: checking for a lock on a file with the same name * TextInput: fix checking for a lock on a file with the same name * Assets: rename and recompile * TextInput: added picture and timer to turn off blob * TextInput: Fix graphics * TextInput: fix validator * Validators: Add validator is file * TextInput: fix callback validator_is_file_alloc * SubGhz: add propocol GNS (dimamic), Beninca/Alcatic, Elmes * SubGhz: fix function description * Gui: correct timer routine on deallocation * Format sources Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
		
							parent
							
								
									32c92a80ea
								
							
						
					
					
						commit
						d4d87aa6a8
					
				| @ -4,6 +4,7 @@ | ||||
| 
 | ||||
| struct TextInput { | ||||
|     View* view; | ||||
|     osTimerId_t timer; | ||||
| }; | ||||
| 
 | ||||
| typedef struct { | ||||
| @ -23,6 +24,11 @@ typedef struct { | ||||
| 
 | ||||
|     uint8_t selected_row; | ||||
|     uint8_t selected_column; | ||||
| 
 | ||||
|     TextInputValidatorCallback validator_callback; | ||||
|     void* validator_callback_context; | ||||
|     string_t validator_text; | ||||
|     bool valadator_message_visible; | ||||
| } TextInputModel; | ||||
| 
 | ||||
| static const uint8_t keyboard_origin_x = 1; | ||||
| @ -236,6 +242,17 @@ static void text_input_view_draw_callback(Canvas* canvas, void* _model) { | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     if(model->valadator_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, string_get_cstr(model->validator_text)); | ||||
|         canvas_set_font(canvas, FontKeyboard); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| static void text_input_handle_up(TextInput* text_input) { | ||||
| @ -295,7 +312,13 @@ static void text_input_handle_ok(TextInput* text_input) { | ||||
|             uint8_t text_length = strlen(model->text_buffer); | ||||
| 
 | ||||
|             if(selected == ENTER_KEY) { | ||||
|                 if(model->callback != 0 && text_length > 0) { | ||||
|                 if(model->validator_callback && (!model->validator_callback( | ||||
|                                                     model->text_buffer, | ||||
|                                                     model->validator_text, | ||||
|                                                     model->validator_callback_context))) { | ||||
|                     model->valadator_message_visible = true; | ||||
|                     osTimerStart(text_input->timer, osKernelGetTickFreq() * 4); | ||||
|                 } else if(model->callback != 0 && text_length > 0) { | ||||
|                     model->callback(model->callback_context); | ||||
|                 } | ||||
|             } else if(selected == BACKSPACE_KEY) { | ||||
| @ -321,6 +344,16 @@ static bool text_input_view_input_callback(InputEvent* event, void* context) { | ||||
|     bool consumed = false; | ||||
| 
 | ||||
|     if(event->type == InputTypeShort || event->type == InputTypeRepeat) { | ||||
|         with_view_model( | ||||
|             text_input->view, (TextInputModel * model) { | ||||
|                 if(model->valadator_message_visible) { | ||||
|                     if(event->key == InputKeyBack) { | ||||
|                         consumed = true; | ||||
|                     } | ||||
|                 } | ||||
|                 model->valadator_message_visible = false; | ||||
|                 return false; | ||||
|             }); | ||||
|         switch(event->key) { | ||||
|         case InputKeyUp: | ||||
|             text_input_handle_up(text_input); | ||||
| @ -351,7 +384,11 @@ static bool text_input_view_input_callback(InputEvent* event, void* context) { | ||||
|        event->key == InputKeyBack) { | ||||
|         with_view_model( | ||||
|             text_input->view, (TextInputModel * model) { | ||||
|                 if(model->valadator_message_visible) { | ||||
|                     model->valadator_message_visible = false; | ||||
|                 } else { | ||||
|                     text_input_backspace_cb(model); | ||||
|                 } | ||||
|                 return true; | ||||
|             }); | ||||
| 
 | ||||
| @ -361,6 +398,17 @@ static bool text_input_view_input_callback(InputEvent* event, void* context) { | ||||
|     return consumed; | ||||
| } | ||||
| 
 | ||||
| void text_input_timer_callback(void* context) { | ||||
|     furi_assert(context); | ||||
|     TextInput* text_input = context; | ||||
| 
 | ||||
|     with_view_model( | ||||
|         text_input->view, (TextInputModel * model) { | ||||
|             model->valadator_message_visible = false; | ||||
|             return true; | ||||
|         }); | ||||
| } | ||||
| 
 | ||||
| TextInput* text_input_alloc() { | ||||
|     TextInput* text_input = furi_alloc(sizeof(TextInput)); | ||||
|     text_input->view = view_alloc(); | ||||
| @ -369,6 +417,14 @@ TextInput* text_input_alloc() { | ||||
|     view_set_draw_callback(text_input->view, text_input_view_draw_callback); | ||||
|     view_set_input_callback(text_input->view, text_input_view_input_callback); | ||||
| 
 | ||||
|     text_input->timer = osTimerNew(text_input_timer_callback, osTimerOnce, text_input, NULL); | ||||
| 
 | ||||
|     with_view_model( | ||||
|         text_input->view, (TextInputModel * model) { | ||||
|             string_init(model->validator_text); | ||||
|             return false; | ||||
|         }); | ||||
| 
 | ||||
|     text_input_clean(text_input); | ||||
| 
 | ||||
|     return text_input; | ||||
| @ -376,7 +432,21 @@ TextInput* text_input_alloc() { | ||||
| 
 | ||||
| void text_input_free(TextInput* text_input) { | ||||
|     furi_assert(text_input); | ||||
|     with_view_model( | ||||
|         text_input->view, (TextInputModel * model) { | ||||
|             string_clear(model->validator_text); | ||||
|             return false; | ||||
|         }); | ||||
| 
 | ||||
|     // Send stop command
 | ||||
|     osTimerStop(text_input->timer); | ||||
|     // Wait till timer stop
 | ||||
|     while(osTimerIsRunning(text_input->timer)) osDelay(1); | ||||
|     // Release allocated memory
 | ||||
|     osTimerDelete(text_input->timer); | ||||
| 
 | ||||
|     view_free(text_input->view); | ||||
| 
 | ||||
|     free(text_input); | ||||
| } | ||||
| 
 | ||||
| @ -393,6 +463,10 @@ void text_input_clean(TextInput* text_input) { | ||||
|             model->text_buffer_size = 0; | ||||
|             model->callback = NULL; | ||||
|             model->callback_context = NULL; | ||||
|             model->validator_callback = NULL; | ||||
|             model->validator_callback_context = NULL; | ||||
|             string_reset(model->validator_text); | ||||
|             model->valadator_message_visible = false; | ||||
|             return true; | ||||
|         }); | ||||
| } | ||||
| @ -425,6 +499,38 @@ void text_input_set_result_callback( | ||||
|         }); | ||||
| } | ||||
| 
 | ||||
| void text_input_set_validator( | ||||
|     TextInput* text_input, | ||||
|     TextInputValidatorCallback callback, | ||||
|     void* callback_context) { | ||||
|     with_view_model( | ||||
|         text_input->view, (TextInputModel * model) { | ||||
|             model->validator_callback = callback; | ||||
|             model->validator_callback_context = callback_context; | ||||
|             return true; | ||||
|         }); | ||||
| } | ||||
| 
 | ||||
| TextInputValidatorCallback text_input_get_validator_callback(TextInput* text_input) { | ||||
|     TextInputValidatorCallback validator_callback = NULL; | ||||
|     with_view_model( | ||||
|         text_input->view, (TextInputModel * model) { | ||||
|             validator_callback = model->validator_callback; | ||||
|             return false; | ||||
|         }); | ||||
|     return validator_callback; | ||||
| } | ||||
| 
 | ||||
| void* text_input_get_validator_callback_context(TextInput* text_input) { | ||||
|     void* validator_callback_context = NULL; | ||||
|     with_view_model( | ||||
|         text_input->view, (TextInputModel * model) { | ||||
|             validator_callback_context = model->validator_callback_context; | ||||
|             return false; | ||||
|         }); | ||||
|     return validator_callback_context; | ||||
| } | ||||
| 
 | ||||
| void text_input_set_header_text(TextInput* text_input, const char* text) { | ||||
|     with_view_model( | ||||
|         text_input->view, (TextInputModel * model) { | ||||
|  | ||||
| @ -6,6 +6,8 @@ | ||||
| #pragma once | ||||
| 
 | ||||
| #include <gui/view.h> | ||||
| #include "validators.h" | ||||
| #include <m-string.h> | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| extern "C" { | ||||
| @ -14,6 +16,7 @@ extern "C" { | ||||
| /** Text input anonymous structure */ | ||||
| typedef struct TextInput TextInput; | ||||
| typedef void (*TextInputCallback)(void* context); | ||||
| typedef bool (*TextInputValidatorCallback)(const char* text, string_t error, void* context); | ||||
| 
 | ||||
| /** Allocate and initialize text input 
 | ||||
|  *  | ||||
| @ -63,6 +66,15 @@ void text_input_set_result_callback( | ||||
|     size_t text_buffer_size, | ||||
|     bool clear_default_text); | ||||
| 
 | ||||
| void text_input_set_validator( | ||||
|     TextInput* text_input, | ||||
|     TextInputValidatorCallback callback, | ||||
|     void* callback_context); | ||||
| 
 | ||||
| TextInputValidatorCallback text_input_get_validator_callback(TextInput* text_input); | ||||
| 
 | ||||
| void* text_input_get_validator_callback_context(TextInput* text_input); | ||||
| 
 | ||||
| /** Set text input header text
 | ||||
|  * | ||||
|  * @param      text_input  TextInput instance | ||||
|  | ||||
							
								
								
									
										42
									
								
								applications/gui/modules/validators.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								applications/gui/modules/validators.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,42 @@ | ||||
| #include <furi.h> | ||||
| #include "validators.h" | ||||
| #include "applications/storage/storage.h" | ||||
| 
 | ||||
| struct ValidatorIsFile { | ||||
|     const char* app_path_folder; | ||||
|     const char* app_extension; | ||||
| }; | ||||
| 
 | ||||
| bool validator_is_file_callback(const char* text, string_t error, void* context) { | ||||
|     furi_assert(context); | ||||
|     ValidatorIsFile* instance = context; | ||||
|     bool ret = true; | ||||
|     string_t path; | ||||
|     string_init_printf(path, "%s/%s%s", instance->app_path_folder, text, instance->app_extension); | ||||
|     Storage* storage = furi_record_open("storage"); | ||||
|     if(storage_common_stat(storage, string_get_cstr(path), NULL) == FSE_OK) { | ||||
|         ret = false; | ||||
|         string_printf(error, "This name\nexists!\nChoose\nanother one."); | ||||
|     } else { | ||||
|         ret = true; | ||||
|     } | ||||
|     string_clear(path); | ||||
|     furi_record_close("storage"); | ||||
| 
 | ||||
|     return ret; | ||||
| } | ||||
| 
 | ||||
| ValidatorIsFile* | ||||
|     validator_is_file_alloc_init(const char* app_path_folder, const char* app_extension) { | ||||
|     ValidatorIsFile* instance = furi_alloc(sizeof(ValidatorIsFile)); | ||||
| 
 | ||||
|     instance->app_path_folder = app_path_folder; | ||||
|     instance->app_extension = app_extension; | ||||
| 
 | ||||
|     return instance; | ||||
| } | ||||
| 
 | ||||
| void validator_is_file_free(ValidatorIsFile* instance) { | ||||
|     furi_assert(instance); | ||||
|     free(instance); | ||||
| } | ||||
							
								
								
									
										20
									
								
								applications/gui/modules/validators.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								applications/gui/modules/validators.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,20 @@ | ||||
| #pragma once | ||||
| 
 | ||||
| // #include <gui/view.h>
 | ||||
| #include <m-string.h> | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| extern "C" { | ||||
| #endif | ||||
| typedef struct ValidatorIsFile ValidatorIsFile; | ||||
| 
 | ||||
| ValidatorIsFile* | ||||
|     validator_is_file_alloc_init(const char* app_path_folder, const char* app_extension); | ||||
| 
 | ||||
| void validator_is_file_free(ValidatorIsFile* instance); | ||||
| 
 | ||||
| bool validator_is_file_callback(const char* text, string_t error, void* context); | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| } | ||||
| #endif | ||||
| @ -1,10 +1,11 @@ | ||||
| #include "../subghz_i.h" | ||||
| #include <lib/toolbox/random_name.h> | ||||
| #include "file_worker.h" | ||||
| #include "../helpers/subghz_custom_event.h" | ||||
| #include <lib/subghz/protocols/subghz_protocol_raw.h> | ||||
| #include <gui/modules/validators.h> | ||||
| 
 | ||||
| void subghz_scene_save_name_text_input_callback(void* context) { | ||||
|     furi_assert(context); | ||||
|     SubGhz* subghz = context; | ||||
|     view_dispatcher_send_custom_event(subghz->view_dispatcher, SubghzCustomEventSceneSaveName); | ||||
| } | ||||
| @ -37,6 +38,11 @@ void subghz_scene_save_name_on_enter(void* context) { | ||||
|         subghz->file_name, | ||||
|         22, //Max len name
 | ||||
|         dev_name_empty); | ||||
| 
 | ||||
|     ValidatorIsFile* validator_is_file = | ||||
|         validator_is_file_alloc_init(SUBGHZ_APP_PATH_FOLDER, SUBGHZ_APP_EXTENSION); | ||||
|     text_input_set_validator(text_input, validator_is_file_callback, validator_is_file); | ||||
| 
 | ||||
|     view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewTextInput); | ||||
| } | ||||
| 
 | ||||
| @ -50,7 +56,9 @@ bool subghz_scene_save_name_on_event(void* context, SceneManagerEvent event) { | ||||
|         if(event.event == SubghzCustomEventSceneSaveName) { | ||||
|             if(strcmp(subghz->file_name, "")) { | ||||
|                 if(strcmp(subghz->file_name_tmp, "")) { | ||||
|                     subghz_rename_file(subghz); | ||||
|                     if(!subghz_rename_file(subghz)) { | ||||
|                         return false; | ||||
|                     } | ||||
|                 } else { | ||||
|                     subghz_save_protocol_to_file(subghz, subghz->file_name); | ||||
|                 } | ||||
| @ -79,6 +87,10 @@ void subghz_scene_save_name_on_exit(void* context) { | ||||
|     SubGhz* subghz = context; | ||||
| 
 | ||||
|     // Clear view
 | ||||
|     void* validator_context = text_input_get_validator_callback_context(subghz->text_input); | ||||
|     text_input_set_validator(subghz->text_input, NULL, NULL); | ||||
|     validator_is_file_free(validator_context); | ||||
| 
 | ||||
|     text_input_clean(subghz->text_input); | ||||
|     scene_manager_set_scene_state( | ||||
|         subghz->scene_manager, SubGhzSceneReadRAW, SubghzCustomEventManagerNoSet); | ||||
|  | ||||
| @ -421,7 +421,7 @@ bool subghz_rename_file(SubGhz* subghz) { | ||||
|     FS_Error fs_result = | ||||
|         storage_common_rename(storage, string_get_cstr(old_path), string_get_cstr(new_path)); | ||||
| 
 | ||||
|     if(fs_result != FSE_OK && fs_result != FSE_EXIST) { | ||||
|     if(fs_result != FSE_OK) { | ||||
|         dialog_message_show_storage_error(subghz->dialogs, "Cannot rename\n file/directory"); | ||||
|         ret = false; | ||||
|     } | ||||
|  | ||||
| @ -245,6 +245,9 @@ const uint8_t *_I_ArrowUpEmpty_14x15[] = {_I_ArrowUpEmpty_14x15_0}; | ||||
| const uint8_t _I_ArrowUpFilled_14x15_0[] = {0x00,0xC0,0x00,0x20,0x01,0xD0,0x02,0xE8,0x05,0xF4,0x0B,0xFA,0x17,0x61,0x21,0xAF,0x3D,0x68,0x05,0xA8,0x05,0x68,0x05,0xA8,0x05,0xE8,0x05,0x08,0x04,0xF8,0x07,}; | ||||
| const uint8_t *_I_ArrowUpFilled_14x15[] = {_I_ArrowUpFilled_14x15_0}; | ||||
| 
 | ||||
| const uint8_t _I_Back3_45x8_0[] = {0x00,0x04,0x00,0x10,0x00,0x40,0x00,0x06,0x00,0x18,0x00,0x60,0x00,0x7F,0x00,0xFC,0x01,0xF0,0x07,0x86,0x20,0x18,0x82,0x60,0x08,0x04,0x71,0x10,0xC4,0x41,0x10,0x00,0x21,0x00,0x84,0x00,0x10,0x80,0x00,0x00,0x02,0x00,0x08,0x7E,0x00,0xF8,0x01,0xE0,0x07,}; | ||||
| const uint8_t *_I_Back3_45x8[] = {_I_Back3_45x8_0}; | ||||
| 
 | ||||
| const uint8_t _I_DoorLeft_70x55_0[] = {0x01,0x00,0x19,0x01,0x00,0x2c,0x32,0x01,0x03,0x04,0x2c,0x18,0x10,0xf0,0x40,0x47,0x82,0x06,0x81,0x03,0xff,0x80,0x08,0x1a,0x20,0x82,0x15,0x28,0x21,0x87,0x82,0x08,0x6f,0xc0,0xb1,0xe6,0x10,0x10,0x8b,0x46,0x20,0x43,0x55,0x8f,0x82,0x10,0x32,0x73,0x0a,0x09,0x89,0x6c,0x1e,0x09,0x00,0x18,0x60,0xf0,0x0c,0x84,0x93,0x82,0x03,0x18,0x0c,0x02,0x1d,0x00,0x90,0x52,0x70,0x50,0x1e,0x00,0x58,0x63,0x90,0x0a,0x06,0x4a,0x09,0x03,0xb0,0x02,0x06,0x70,0x62,0x49,0xf8,0x0c,0x66,0x3f,0xf0,0x41,0x63,0x04,0x43,0x00,0x99,0x60,0x00,0x85,0xc8,0x06,0x14,0xd0,0x80,0x3f,0xc8,0x0d,0xb8,0x10,0x70,0xf8,0x34,0x13,0x03,0x39,0x04,0x1c,0x42,0x19,0xf8,0xa0,0xc2,0x01,0x07,0xef,0x02,0x8c,0x80,0x10,0x9d,0x00,0x43,0xec,0x00,0xa3,0x10,0x04,0x25,0xce,0x19,0xfc,0x88,0x82,0x12,0x0c,0x35,0x10,0x42,0x4c,0xa1,0x90,0x3f,0xc0,0x21,0x22,0x39,0x82,0xc8,0x88,0xd2,0x11,0xf0,0x01,0x88,0xd5,0x18,0xe2,0x08,0x68,0x10,0x0c,0xa8,0x00,0x83,0x81,0xcc,0xd5,0xc3,0x80,0x84,0x82,0x0e,0xcc,0xc0,0x15,0x79,0x02,0x0b,0x98,0xf8,0x11,0x88,0x82,0x0f,0x31,0x19,0x02,0x08,0x2c,0x9f,0x6a,0x1d,0x20,0x41,0x31,0x4c,0x10,0x8d,0x73,0x04,0x23,0xa4,0xc4,0x6c,0xde,0x20,0x42,0xcc,0x01,0x07,0x07,0xff,0x80,0x06,0x3e,0x08,0x38,0x70,0x20,0xa1,0xe0,0x83,0x8e,0x01,0x0c,0xf0,0x73,0x80,0x43,0x70,0x05,0x08,0x00,0x2c,0x04,0xc4,0x46,0x53,0x09,0x98,0x24,0x80,0x65,0x80,0xb0,0xd9,0x84,0x65,0x32,0x06,0x17,0x0f,0x98,0x23,0x63,0xe1,0x88,0xc4,0x08,0x5f,0xc1,0x30,0x9d,0x84,0x4e,0x66,0x94,0x11,0x98,0x75,0x26,0x00,}; | ||||
| const uint8_t *_I_DoorLeft_70x55[] = {_I_DoorLeft_70x55_0}; | ||||
| 
 | ||||
| @ -263,6 +266,9 @@ const uint8_t *_I_PassportBottom_128x17[] = {_I_PassportBottom_128x17_0}; | ||||
| const uint8_t _I_PassportLeft_6x47_0[] = {0x01,0x00,0x1c,0x00,0x9e,0x40,0xa3,0x32,0x59,0x2c,0x66,0x03,0x01,0x82,0xc2,0x62,0x32,0x50,0x16,0xc8,0x60,0x30,0x28,0x24,0x32,0x39,0x3c,0x9e,0x4d,0x25,0x80,0x1a,}; | ||||
| const uint8_t *_I_PassportLeft_6x47[] = {_I_PassportLeft_6x47_0}; | ||||
| 
 | ||||
| const uint8_t _I_WarningDolphin_45x42_0[] = {0x01,0x00,0xc6,0x00,0x00,0x1c,0x22,0x04,0x05,0x7f,0xfc,0x1e,0x20,0x05,0x1e,0x04,0x02,0x30,0x05,0x29,0x84,0x02,0xc1,0x20,0x02,0x8c,0x22,0x01,0x80,0x02,0x94,0x10,0x32,0x30,0x10,0x10,0x87,0xca,0x84,0x03,0x10,0x42,0x81,0x48,0x28,0x38,0x08,0x04,0x3e,0x01,0x84,0x83,0xe0,0x30,0x11,0x08,0x05,0xa2,0x11,0x40,0xa0,0x4b,0xc6,0xc5,0x40,0xd0,0x56,0xe0,0x10,0x60,0x29,0x54,0xf0,0x10,0x18,0xf0,0x14,0x6b,0xf6,0x0c,0x04,0x3e,0x40,0x05,0x12,0x80,0xc1,0xe4,0x01,0xd2,0xf8,0x40,0xe4,0x18,0x09,0xf4,0x03,0xf1,0x01,0x90,0x40,0x28,0x30,0x0f,0xe4,0x00,0x16,0x24,0x11,0xbf,0x01,0x44,0xee,0x53,0xf0,0x29,0xf0,0x3e,0x02,0x91,0x3b,0x8c,0xc3,0x81,0x13,0x90,0x48,0x20,0x3f,0xf9,0xfc,0x42,0x60,0x05,0x10,0x98,0x81,0x56,0x11,0x38,0x02,0x9c,0x1a,0x31,0x1e,0x02,0x8f,0x02,0x03,0x1c,0x90,0xc0,0x7c,0x02,0xf1,0xce,0x02,0x07,0x01,0x1f,0x80,0x63,0xa8,0x08,0x71,0x3c,0x8e,0x39,0x24,0x40,0x51,0xc7,0x81,0x53,0x0f,0x3c,0x02,0x9d,0x1e,0x38,0x29,0x10,0x29,0x17,0xc8,0x0a,0x32,0x3a,0x00,0x14,0x4b,0xa2,0x05,0x58,0x98,0x15,0x22,0x20,0x54,0x84,0x81,0x50,}; | ||||
| const uint8_t *_I_WarningDolphin_45x42[] = {_I_WarningDolphin_45x42_0}; | ||||
| 
 | ||||
| const uint8_t _I_Back_15x10_0[] = {0x00,0x04,0x00,0x06,0x00,0xFF,0x0F,0x06,0x10,0x04,0x20,0x00,0x40,0x00,0x40,0x00,0x20,0x00,0x10,0xFE,0x0F,}; | ||||
| const uint8_t *_I_Back_15x10[] = {_I_Back_15x10_0}; | ||||
| 
 | ||||
| @ -748,12 +754,14 @@ const Icon I_ArrowDownEmpty_14x15 = {.width=14,.height=15,.frame_count=1,.frame_ | ||||
| const Icon I_ArrowDownFilled_14x15 = {.width=14,.height=15,.frame_count=1,.frame_rate=0,.frames=_I_ArrowDownFilled_14x15}; | ||||
| const Icon I_ArrowUpEmpty_14x15 = {.width=14,.height=15,.frame_count=1,.frame_rate=0,.frames=_I_ArrowUpEmpty_14x15}; | ||||
| const Icon I_ArrowUpFilled_14x15 = {.width=14,.height=15,.frame_count=1,.frame_rate=0,.frames=_I_ArrowUpFilled_14x15}; | ||||
| const Icon I_Back3_45x8 = {.width=45,.height=8,.frame_count=1,.frame_rate=0,.frames=_I_Back3_45x8}; | ||||
| const Icon I_DoorLeft_70x55 = {.width=70,.height=55,.frame_count=1,.frame_rate=0,.frames=_I_DoorLeft_70x55}; | ||||
| const Icon I_DoorLocked_10x56 = {.width=10,.height=56,.frame_count=1,.frame_rate=0,.frames=_I_DoorLocked_10x56}; | ||||
| const Icon I_DoorRight_70x55 = {.width=70,.height=55,.frame_count=1,.frame_rate=0,.frames=_I_DoorRight_70x55}; | ||||
| const Icon I_LockPopup_100x49 = {.width=100,.height=49,.frame_count=1,.frame_rate=0,.frames=_I_LockPopup_100x49}; | ||||
| const Icon I_PassportBottom_128x17 = {.width=128,.height=17,.frame_count=1,.frame_rate=0,.frames=_I_PassportBottom_128x17}; | ||||
| const Icon I_PassportLeft_6x47 = {.width=6,.height=47,.frame_count=1,.frame_rate=0,.frames=_I_PassportLeft_6x47}; | ||||
| const Icon I_WarningDolphin_45x42 = {.width=45,.height=42,.frame_count=1,.frame_rate=0,.frames=_I_WarningDolphin_45x42}; | ||||
| const Icon I_Back_15x10 = {.width=15,.height=10,.frame_count=1,.frame_rate=0,.frames=_I_Back_15x10}; | ||||
| const Icon I_DolphinReadingSuccess_59x63 = {.width=59,.height=63,.frame_count=1,.frame_rate=0,.frames=_I_DolphinReadingSuccess_59x63}; | ||||
| const Icon I_Down_25x27 = {.width=25,.height=27,.frame_count=1,.frame_rate=0,.frames=_I_Down_25x27}; | ||||
|  | ||||
| @ -82,12 +82,14 @@ extern const Icon I_ArrowDownEmpty_14x15; | ||||
| extern const Icon I_ArrowDownFilled_14x15; | ||||
| extern const Icon I_ArrowUpEmpty_14x15; | ||||
| extern const Icon I_ArrowUpFilled_14x15; | ||||
| extern const Icon I_Back3_45x8; | ||||
| extern const Icon I_DoorLeft_70x55; | ||||
| extern const Icon I_DoorLocked_10x56; | ||||
| extern const Icon I_DoorRight_70x55; | ||||
| extern const Icon I_LockPopup_100x49; | ||||
| extern const Icon I_PassportBottom_128x17; | ||||
| extern const Icon I_PassportLeft_6x47; | ||||
| extern const Icon I_WarningDolphin_45x42; | ||||
| extern const Icon I_Back_15x10; | ||||
| extern const Icon I_DolphinReadingSuccess_59x63; | ||||
| extern const Icon I_Down_25x27; | ||||
|  | ||||
							
								
								
									
										
											BIN
										
									
								
								assets/icons/Interface/Back3_45x8.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								assets/icons/Interface/Back3_45x8.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 3.5 KiB | 
							
								
								
									
										
											BIN
										
									
								
								assets/icons/Interface/WarningDolphin_45x42.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								assets/icons/Interface/WarningDolphin_45x42.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 1.1 KiB | 
| @ -1,38 +1,40 @@ | ||||
| Filetype: Flipper SubGhz Keystore File | ||||
| Version: 0 | ||||
| Encryption: 1 | ||||
| IV: 7A 44 FE 5D C3 B3 65 13 73 A6 F4 2D 1E B6 7D F0 | ||||
| 89153B35033574AAA06D7E792CB92A486B37A2CCDF0B0152BF1A563E321518C8 | ||||
| F6583A3E4148439E8A8D7ED6A095ACC0C3E22A48F1637E78DF023CAC9272934E | ||||
| AA0439E6B76CD43F3FCC27CF69C5F3B6508E8103B164E4ECDDF8B2FB222D46FF | ||||
| A9826C663033D25AE21CB8790406997ADCE84360B258F2B989D967009659859C | ||||
| 3474E7BBFA0173928F414CFD5EE19B27A558D9C171D96FE7B7840A01323A7E7446FAE3E98EA9A8C69B4A6B781BD7906A | ||||
| 2873939A8E0EAC16D748967E987BB0F1079C106E4235B7D35B4BF37F54B21F8E | ||||
| EF6F1DC0201FCB8CEBC5642A5194A1FDCFBE1FA772A79CEAD54D2F0DA3AC4F6C | ||||
| 3F595EAA0E81E96C5D6DB41799D314E3E81E7F4197E19A3341C55592B1B6C4B0 | ||||
| 7B2D75FE11B27E99CA7610E47D712C8CFB619EC69EBC976A70CFD9574C9F4FF8 | ||||
| 39735CF1D009D132A33B9C546D95FA6D3E69BF3A57EF219392E57C9560E7B037 | ||||
| D56FDDFB0C4E808143D3ED5F15D6FF47F6EDEBD01192FC7ACF3ACCE9FD5162FC297D0089D65ED2CBE3CE05DDA7B96446 | ||||
| 2750D4F0650061C3AF72C88FD080BE241F2BDD8D8C1B0EFE781120EBEFFE2C72D0EECC42CDDED50CFE4AC51C48AE68C6 | ||||
| F8CE64921CB73015F2672A9EF0A8359269CAE0E515D6DBB3130CFC9E5E1A98AD | ||||
| ACF6ADB9E02D67B44EB6C6F126BF64BDAB37926B8BE39E27F323E8F5A0F8FC38 | ||||
| FBB1302D697F94ECED681CE047819001EDE6E013850258F61E97091DD37D24F2 | ||||
| D8CD53AB5A94898EB53D4FF46546ADBAA24691181A396052A58AAC657D6817AB | ||||
| 43200E08C21747CABC59538888A259238E782545732A1A6EEE00A6929EC9DD97A8BA9812372374046AC66652CC561D60 | ||||
| C38CBE29F22D0E83E58A52E94AA2485DA8E702FBDB89D27249473CB8A19AEF61 | ||||
| 9F0EB580F7474985E8460E1682451E213778B77A9CAB4734B75C5386851050BF | ||||
| 2364EBB8237363B21226565675B9F47819C5BBC7E917C761BA3652D0A6ED7D3273EB8F3B7FBA68DE4143FB15BBEC35FB | ||||
| CCDE559A2901A8290D6B2E8EDF66612E4C90E2E7C63643C8C5F244E30874B41039E078089E2253DA73B3A6DD821A84CD | ||||
| 33B239455FBE7AB8CE833C3B9C063EFEAE1FC7AC876AF3294C67D5B08BF7E9EC | ||||
| F0FBBCEFE99D25104022CD3621B21B5F84FFBC9A5E21B0AED2B1560B39524A5B | ||||
| E15B0614D9ECA17784E994652755559B7A3DA4B53CE6E63108BCFCD8024761DD | ||||
| 9E244C80E72937274DD6B2787F1A75F278A2DF7CB3B89F7C2BF7CC8DBBF2A3F0 | ||||
| 689DCA188A40DFDD3575A9BD9D7AF2427D0CE707F591029463AEC6B8679969AC | ||||
| 25D9B04D10AF541925901F55D8D7FA9C87523995F53183FB04F00C6023D5930A | ||||
| D11F70508485C019AFC5FDBE5FD7223710033483C803FC7C2C69BAAD6ACB7CA7 | ||||
| C081A0ACEA8210AB117028EDFF15641EE287CB1CFF8332A9D208B7324523129E | ||||
| 4C5B7C959C00A30F39A431B20EA1FEBDFB1C71C01CCC45DD883CD511360479BE | ||||
| ECC0A8237E19D3883A06C5A700647860B3D9E570976D3606A11A4005424FD935 | ||||
| 8F5D7B39696F6F5C2100FFDF71D1C8ECAD98BD1D4CEE7BA8C793815747CE6FD5 | ||||
| 52ED6DE1583093E8D8AB8D16C912F7E89F78A24CE36ED53D3E06D3F81BF62ED1 | ||||
| 416015A128EA3A008573DE760C6AE05BD958BFCB46351F614B617CEE55C5E294 | ||||
| IV: 2A 44 FE 5A A3 63 F5 11 83 A6 FE DA 1E B7 3D F1 | ||||
| BF22677F79DF533C83FFE485B5F9CFABA24352FDEBED14B6FFA16EE9F00D6AC4 | ||||
| B9343EDBB8B8C6EEFDA7AE9934445E27B04950DBB4F31ECCD1735CCB8C1600DE | ||||
| 54CC71AF6794D47FFC49823DA6C4CCAD94EC5540515FD6F537A078BFD736105C | ||||
| 4A3A12125D4F1186369B3B0ECB86B28A6EE4A0AF49DD4C42743A5C2C9BD1F5FC | ||||
| 190D7746CDC7782157E95532070BCFE8637CF9A7BE03F9382A435ACAAA7A5F5E6BEB8E34A320BDB6E492D793E470CAB4 | ||||
| 59ABF9B68B31BF9CCF2CCCC0A6B3182FA2772691A400B2BFB5E2490DA2BCD2A4 | ||||
| 304DF68472EC9C78341218C10242DC3D62887A5281B52061BC0C9D117CDE1185 | ||||
| D146050F90D30FA166615706FBC8D5B3573BDCB081E2445930CE1B71F5BDB7AE | ||||
| 9386C94D044CCCBEE7972319191933328A06B20138C432B86C76EB909BB06019 | ||||
| CFC23206853E9D01C3986FD849908686A2442287277C06574928A362F988CE1B | ||||
| 534B351BE03A98B56ED622D37B9BBCD871CA76EB6EF250B1615105FA496E991C8F195293F83EE38AE5831D95F45238E3 | ||||
| AFF90EC99CF4278D79DA9B1163FF07C83203AD34F9C4228423B4B58FF3F6978C605CC282FB1E37C0946D86C51809222C | ||||
| 44C9EF18971905D2207F62D3365CB4A31D449FA215F950CEB67368D13181959C | ||||
| 0CF10950D8A3EDEEEEA9AA4E41354373584FBFE6BB2E8A52C3149757C133445C | ||||
| 4FBE939E87B8438AFC86773DADA39FE3856A3518A5159C9BF6B2EFA752F5B3F5 | ||||
| CBFD648024823A33481B8A7381CD28930765265A1CA9BBDE1879F0827273A860 | ||||
| 8D3C70EF2E4ED2EF23752046538BF30F6DA8266F2B10A4BAD8549B3D20298F08EF9E6C21F78DDA9CA6EBB1E3CDF82C78 | ||||
| D31EBB7C994C397776777D4904661C6F8DF5CDA9F828CA19378CAA397555F8C0 | ||||
| FDA58BA7B0CD5C9090FE891029A3773EA16DB77EB5FA06A4C443C01B537B2615 | ||||
| 5CEE7A27D0D1B1AB5BAAC93D78121BC6D5FCD589C093A22C71E81C390045C85FDE98C202340FDD2046FF906A035E31E9 | ||||
| C3121624E5B91EDCF651B8A89C2EEF4379876D0E0D918596F3E5CED9F3C92AB689D609AA1FB5362F57738A0AF62E3C92 | ||||
| 25F715B4CEA880E4879C6C03DC61875A43FB314AB4F21AE1CF7C933172B4A29D | ||||
| 574166A278E2FA4AB8A09078152929E631E4E182E20CCF803250A0A2D4BB62F3 | ||||
| B0D1C7AA1752135BA7627D8F65EC9651B810EC29BA01C8D9BC5B3EB20B1A0939 | ||||
| E3E9D30E4F7003E63917DF3B5FC4E03863E37AFD6C5987CCFEC8129C692474EF | ||||
| 67A35F2E3C400953EC1CD1874A35A4734D3E9F116F7E334276BF898E48C21AFE | ||||
| BC8D612FA363AB364BB9D2701273C4FA587B2F8D8CD039DEFB72BAD00360149F | ||||
| 9A88BBDA111C9185EE5BBA610574D46A4D53EC79B63D5FB57BAB5A6609F2160F | ||||
| 9512A1F77A4C46BD7F79D792B1578AC1FA41F15F6D7C72BC952BD89262C85327 | ||||
| 182685E3E0A23055025F7218AB16F7AE3A7F9DD71761AAE3B5E4AB85E2EFBF929D640258AEBC9F0BB167985A1E4B132D | ||||
| 1DD9156B6BF97424DC639708ACEE21DD1D64FC5BC0DD5252DDDDE7832C2B7B6F | ||||
| 109BB4D660897DB00676093B585535D267426310CDE81F05793ACB46B9F6176E | ||||
| D7A2D468DF76A8E5C495D5280524B2996254B94458485B11CCAB36CD1EE3918F | ||||
| 9F445C93FF382433015BEAE6D78F70AE2C02E0C961E1B9576D66E64978D984D0 | ||||
| 195CB755E6AC710B5AF10761AC2B13F8CA57355443B593BC59AAF3A819070568028BBAE75C0DA4BA6B90D63E679098B7 | ||||
| C6ECD39EC47DFFD1ABC55F47AC8E2C26A8DB5EB8184153746F7D9AD5F0015E85 | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| # for adding manufacture keys | ||||
| # AABBCCDDEEFFAABB:X:NAME\r\n | ||||
| # AABBCCDDEEFFAABB - man 64 bit | ||||
| # X - encryption method 1 - Simple Learning, 2 - Normal_Learning, 3 - Secure_Learning  | ||||
| # X - encryption method 1 - Simple Learning, 2 - Normal_Learning, 3 - Secure_Learning,  4 - Magic_xor_type1 Learning | ||||
| #   	0 - iterates over both previous and man in direct and reverse byte sequence | ||||
| # NAME - name (string without spaces) max 64 characters long | ||||
| Filetype: Flipper SubGhz Keystore File | ||||
|  | ||||
| @ -115,6 +115,15 @@ uint8_t subghz_protocol_keeloq_check_remote_controller_selector( | ||||
|                     return 1; | ||||
|                 } | ||||
|                 break; | ||||
|             case KEELOQ_LEARNING_MAGIC_XOR_TYPE_1: | ||||
|                 man_learning = subghz_protocol_keeloq_common_magic_xor_type1_learning( | ||||
|                     fix, manufacture_code->key); | ||||
|                 decrypt = subghz_protocol_keeloq_common_decrypt(hop, man_learning); | ||||
|                 if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { | ||||
|                     instance->manufacture_name = string_get_cstr(manufacture_code->name); | ||||
|                     return 1; | ||||
|                 } | ||||
|                 break; | ||||
|             case KEELOQ_LEARNING_UNKNOWN: | ||||
|                 // Simple Learning
 | ||||
|                 decrypt = subghz_protocol_keeloq_common_decrypt(hop, manufacture_code->key); | ||||
| @ -144,6 +153,8 @@ uint8_t subghz_protocol_keeloq_check_remote_controller_selector( | ||||
|                     instance->manufacture_name = string_get_cstr(manufacture_code->name); | ||||
|                     return 1; | ||||
|                 } | ||||
| 
 | ||||
|                 // Check for mirrored man
 | ||||
|                 man_learning = subghz_protocol_keeloq_common_normal_learning(fix, man_rev); | ||||
|                 decrypt = subghz_protocol_keeloq_common_decrypt(hop, man_learning); | ||||
|                 if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { | ||||
| @ -161,13 +172,30 @@ uint8_t subghz_protocol_keeloq_check_remote_controller_selector( | ||||
|                 } | ||||
| 
 | ||||
|                 // Check for mirrored man
 | ||||
| 
 | ||||
|                 man_learning = subghz_protocol_keeloq_common_secure_learning(fix, seed, man_rev); | ||||
|                 decrypt = subghz_protocol_keeloq_common_decrypt(hop, man_learning); | ||||
|                 if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { | ||||
|                     instance->manufacture_name = string_get_cstr(manufacture_code->name); | ||||
|                     return 1; | ||||
|                 } | ||||
| 
 | ||||
|                 // Magic xor type1 learning
 | ||||
|                 man_learning = subghz_protocol_keeloq_common_magic_xor_type1_learning( | ||||
|                     fix, manufacture_code->key); | ||||
|                 decrypt = subghz_protocol_keeloq_common_decrypt(hop, man_learning); | ||||
|                 if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { | ||||
|                     instance->manufacture_name = string_get_cstr(manufacture_code->name); | ||||
|                     return 1; | ||||
|                 } | ||||
| 
 | ||||
|                 // Check for mirrored man
 | ||||
|                 man_learning = | ||||
|                     subghz_protocol_keeloq_common_magic_xor_type1_learning(fix, man_rev); | ||||
|                 decrypt = subghz_protocol_keeloq_common_decrypt(hop, man_learning); | ||||
|                 if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { | ||||
|                     instance->manufacture_name = string_get_cstr(manufacture_code->name); | ||||
|                     return 1; | ||||
|                 } | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
| @ -198,6 +226,7 @@ void subghz_protocol_keeloq_check_remote_controller(SubGhzProtocolKeeloq* instan | ||||
|     } else { | ||||
|         subghz_protocol_keeloq_check_remote_controller_selector(instance, key_fix, key_hop); | ||||
|     } | ||||
| 
 | ||||
|     instance->common.serial = key_fix & 0x0FFFFFFF; | ||||
|     instance->common.btn = key_fix >> 28; | ||||
| } | ||||
|  | ||||
| @ -53,7 +53,7 @@ inline uint64_t subghz_protocol_keeloq_common_normal_learning(uint32_t data, con | ||||
| 
 | ||||
| /** Secure Learning
 | ||||
|  * @param data - serial number (28bit) | ||||
|  * @param seed - serial number (32bit) | ||||
|  * @param seed - seed number (32bit) | ||||
|  * @param key - manufacture (64bit) | ||||
|  * @return manufacture for this serial number (64bit) | ||||
|  */ | ||||
| @ -70,3 +70,15 @@ inline uint64_t subghz_protocol_keeloq_common_secure_learning( | ||||
| 
 | ||||
|     return ((uint64_t)k1 << 32) | k2; | ||||
| } | ||||
| 
 | ||||
| /** Magic_xor_type1 Learning
 | ||||
|  * @param data - serial number (28bit) | ||||
|  * @param xor - magic xor (64bit) | ||||
|  * @return manufacture for this serial number (64bit) | ||||
|  */ | ||||
| 
 | ||||
| inline uint64_t | ||||
|     subghz_protocol_keeloq_common_magic_xor_type1_learning(uint32_t data, uint64_t xor) { | ||||
|     data &= 0x0FFFFFFF; | ||||
|     return (((uint64_t)data << 32) | data) ^ xor; | ||||
| } | ||||
| @ -24,6 +24,7 @@ | ||||
| #define KEELOQ_LEARNING_SIMPLE 1u | ||||
| #define KEELOQ_LEARNING_NORMAL 2u | ||||
| #define KEELOQ_LEARNING_SECURE 3u | ||||
| #define KEELOQ_LEARNING_MAGIC_XOR_TYPE_1 4u | ||||
| 
 | ||||
| /** Simple Learning Encrypt
 | ||||
|  * @param data - 0xBSSSCCCC, B(4bit) key, S(10bit) serial&0x3FF, C(16bit) counter | ||||
| @ -48,10 +49,18 @@ uint64_t subghz_protocol_keeloq_common_normal_learning(uint32_t data, const uint | ||||
| 
 | ||||
| /** Secure Learning
 | ||||
|  * @param data - serial number (28bit) | ||||
|  * @param seed - serial number (32bit) | ||||
|  * @param seed - seed number (32bit) | ||||
|  * @param key - manufacture (64bit) | ||||
|  * @return manufacture for this serial number (64bit) | ||||
|  */ | ||||
| 
 | ||||
| uint64_t | ||||
|     subghz_protocol_keeloq_common_secure_learning(uint32_t data, uint32_t seed, const uint64_t key); | ||||
| 
 | ||||
| /** Magic_xor_type1 Learning
 | ||||
|  * @param data - serial number (28bit) | ||||
|  * @param xor - magic xor (64bit) | ||||
|  * @return manufacture for this serial number (64bit) | ||||
|  */ | ||||
| 
 | ||||
| uint64_t subghz_protocol_keeloq_common_magic_xor_type1_learning(uint32_t data, uint64_t xor); | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Skorpionm
						Skorpionm