From 0a8a944e100c79432773ef3b6e749ab065e46cd1 Mon Sep 17 00:00:00 2001 From: Skorpionm <85568270+Skorpionm@users.noreply.github.com> Date: Sat, 28 Aug 2021 17:51:48 +0400 Subject: [PATCH] Skorp subghz signal archive (#667) * SubGhz: Add millis() furi, add subghz history struct * SubGhz: Fix subghz history * Gubghz: Fix code repeat history, add clean history * SubGhz: reading and adding keys to history * Gui: Renaming Sub 1-Ghz -> SubGhz * Archive: Renaming Sub 1-Ghz -> SubGhz * SubGhz: Add menu history, modified button for sending a signal, changed output of data about accepted protocol * Archive: Fix name subghz * SubGhz: Menu navigation * Assets: Add assets/SubGHz/icon.png * Assets: add new icons for subghz * SubGhz: Fix name Add manually scene * SubGhz: Fix load icon Read scene. rename encoder struct, rename protocol function load from file, add load raw data protocol, add info pleasant signals all protocol * SubGhz: fix memory leak * SubGhz: change of receiving frequency for read scene * SubGhz: Add save/load frequency and preset, add automatic configuration of transmit/receive to the desired frequency and modulation, add button "save" config scene * SubGhz: Fix frequency and preset, fix frequency add manualli scene, fix re-executing the parser * Furi-hal-subghz: add 2-FSK config, fix ook config 650KHz BW Tx filter * Fix formatting and release build * SubGhz: Delete read scene * SubGhz: Fix frequency add manualli scene, refactoring code * SubGhz: 2 profiles for OOK, fix broken build. * SubGhz: Add passing static codes from read scene, add notification read scene, refactoring code * SubGhz: fix assert on worker double stop. Co-authored-by: Aleksandr Kutuzov --- applications/applications.c | 2 +- applications/archive/archive_i.h | 14 +- applications/archive/archive_views.c | 4 +- applications/archive/archive_views.h | 4 +- .../subghz/scenes/subghz_scene_config.h | 1 - .../subghz/scenes/subghz_scene_read.c | 62 --- .../subghz/scenes/subghz_scene_receiver.c | 49 +- .../subghz/scenes/subghz_scene_save_name.c | 2 +- .../subghz/scenes/subghz_scene_saved.c | 2 +- .../subghz/scenes/subghz_scene_set_type.c | 16 +- .../subghz/scenes/subghz_scene_start.c | 5 +- .../subghz/scenes/subghz_scene_transmitter.c | 2 + applications/subghz/subghz_cli.c | 10 +- applications/subghz/subghz_history.c | 155 +++++++ applications/subghz/subghz_history.h | 22 + applications/subghz/subghz_i.c | 128 +++++- applications/subghz/subghz_i.h | 16 +- applications/subghz/views/subghz_analyze.c | 4 +- applications/subghz/views/subghz_receiver.c | 435 ++++++++++++++++-- applications/subghz/views/subghz_receiver.h | 19 +- applications/subghz/views/subghz_static.c | 2 +- .../subghz/views/subghz_test_carrier.c | 2 +- .../subghz/views/subghz_test_packet.c | 2 +- .../subghz/views/subghz_transmitter.c | 60 ++- .../subghz/views/subghz_transmitter.h | 4 + assets/compiled/assets_icons.c | 24 + assets/compiled/assets_icons.h | 6 + assets/icons/GubGHz/Broadcast_dolph_67-61.png | Bin 0 -> 3894 bytes assets/icons/GubGHz/Scanning_dolph_67-61.png | Bin 0 -> 3518 bytes assets/icons/GubGHz/Top-frame_128-13.png | Bin 0 -> 3610 bytes assets/icons/GubGHz/lock_7x8.png | Bin 0 -> 3597 bytes assets/icons/GubGHz/quest_7x8.png | Bin 0 -> 3675 bytes assets/icons/GubGHz/unlock_7x8.png | Bin 0 -> 3598 bytes firmware/targets/f6/furi-hal/furi-hal-delay.c | 4 + firmware/targets/f6/furi-hal/furi-hal-irda.c | 2 + .../targets/f6/furi-hal/furi-hal-subghz.c | 136 +++++- .../targets/furi-hal-include/furi-hal-delay.h | 3 + .../furi-hal-include/furi-hal-subghz.h | 4 +- lib/irda/worker/irda_worker.c | 8 +- lib/subghz/protocols/subghz_protocol.c | 143 ++++-- lib/subghz/protocols/subghz_protocol_came.c | 28 +- lib/subghz/protocols/subghz_protocol_came.h | 7 +- lib/subghz/protocols/subghz_protocol_common.c | 10 +- lib/subghz/protocols/subghz_protocol_common.h | 53 ++- .../protocols/subghz_protocol_faac_slh.c | 23 +- .../protocols/subghz_protocol_faac_slh.h | 2 + .../protocols/subghz_protocol_gate_tx.c | 29 +- .../protocols/subghz_protocol_gate_tx.h | 7 +- lib/subghz/protocols/subghz_protocol_ido.c | 101 ++-- lib/subghz/protocols/subghz_protocol_ido.h | 1 + lib/subghz/protocols/subghz_protocol_keeloq.c | 94 ++-- lib/subghz/protocols/subghz_protocol_keeloq.h | 9 +- .../protocols/subghz_protocol_nero_sketch.c | 28 +- .../protocols/subghz_protocol_nero_sketch.h | 7 +- .../protocols/subghz_protocol_nice_flo.c | 30 +- .../protocols/subghz_protocol_nice_flo.h | 7 +- .../protocols/subghz_protocol_nice_flor_s.c | 21 +- .../protocols/subghz_protocol_nice_flor_s.h | 1 + .../protocols/subghz_protocol_princeton.c | 75 +-- .../protocols/subghz_protocol_princeton.h | 28 +- .../protocols/subghz_protocol_star_line.c | 38 +- .../protocols/subghz_protocol_star_line.h | 3 + lib/subghz/subghz_worker.c | 5 + lib/subghz/subghz_worker.h | 6 + 64 files changed, 1563 insertions(+), 402 deletions(-) delete mode 100644 applications/subghz/scenes/subghz_scene_read.c create mode 100644 applications/subghz/subghz_history.c create mode 100644 applications/subghz/subghz_history.h create mode 100644 assets/icons/GubGHz/Broadcast_dolph_67-61.png create mode 100644 assets/icons/GubGHz/Scanning_dolph_67-61.png create mode 100644 assets/icons/GubGHz/Top-frame_128-13.png create mode 100644 assets/icons/GubGHz/lock_7x8.png create mode 100644 assets/icons/GubGHz/quest_7x8.png create mode 100644 assets/icons/GubGHz/unlock_7x8.png diff --git a/applications/applications.c b/applications/applications.c index 786b8f35..36751e09 100644 --- a/applications/applications.c +++ b/applications/applications.c @@ -148,7 +148,7 @@ const FlipperApplication FLIPPER_APPS[] = { #endif #ifdef APP_SUBGHZ - {.app = subghz_app, .name = "Sub-1 GHz", .stack_size = 2048, .icon = &A_Sub1ghz_14}, + {.app = subghz_app, .name = "Sub-GHz", .stack_size = 2048, .icon = &A_Sub1ghz_14}, #endif #ifdef APP_LF_RFID diff --git a/applications/archive/archive_i.h b/applications/archive/archive_i.h index 79105704..a7c3a901 100644 --- a/applications/archive/archive_i.h +++ b/applications/archive/archive_i.h @@ -30,7 +30,7 @@ typedef enum { static const char* flipper_app_name[] = { [ArchiveFileTypeIButton] = "iButton", [ArchiveFileTypeNFC] = "NFC", - [ArchiveFileTypeSubOne] = "Sub-1 GHz", + [ArchiveFileTypeSubGhz] = "Sub-GHz", [ArchiveFileTypeLFRFID] = "125 kHz RFID", [ArchiveFileTypeIrda] = "Infrared", }; @@ -38,7 +38,7 @@ static const char* flipper_app_name[] = { static const char* known_ext[] = { [ArchiveFileTypeIButton] = ".ibtn", [ArchiveFileTypeNFC] = ".nfc", - [ArchiveFileTypeSubOne] = ".sub", + [ArchiveFileTypeSubGhz] = ".sub", [ArchiveFileTypeLFRFID] = ".rfid", [ArchiveFileTypeIrda] = ".ir", }; @@ -47,7 +47,7 @@ static const char* tab_default_paths[] = { [ArchiveTabFavorites] = "/any/favorites", [ArchiveTabIButton] = "/any/ibutton", [ArchiveTabNFC] = "/any/nfc", - [ArchiveTabSubOne] = "/any/subghz/saved", + [ArchiveTabSubGhz] = "/any/subghz/saved", [ArchiveTabLFRFID] = "/any/lfrfid", [ArchiveTabIrda] = "/any/irda", [ArchiveTabBrowser] = "/any", @@ -59,8 +59,8 @@ static inline const char* get_tab_ext(ArchiveTabEnum tab) { return known_ext[ArchiveFileTypeIButton]; case ArchiveTabNFC: return known_ext[ArchiveFileTypeNFC]; - case ArchiveTabSubOne: - return known_ext[ArchiveFileTypeSubOne]; + case ArchiveTabSubGhz: + return known_ext[ArchiveFileTypeSubGhz]; case ArchiveTabLFRFID: return known_ext[ArchiveFileTypeLFRFID]; case ArchiveTabIrda: @@ -76,8 +76,8 @@ static inline const char* get_default_path(ArchiveFileTypeEnum type) { return tab_default_paths[ArchiveTabIButton]; case ArchiveFileTypeNFC: return tab_default_paths[ArchiveTabNFC]; - case ArchiveFileTypeSubOne: - return tab_default_paths[ArchiveTabSubOne]; + case ArchiveFileTypeSubGhz: + return tab_default_paths[ArchiveTabSubGhz]; case ArchiveFileTypeLFRFID: return tab_default_paths[ArchiveTabLFRFID]; case ArchiveFileTypeIrda: diff --git a/applications/archive/archive_views.c b/applications/archive/archive_views.c index 4268e95f..00f4d0f3 100644 --- a/applications/archive/archive_views.c +++ b/applications/archive/archive_views.c @@ -4,7 +4,7 @@ static const char* ArchiveTabNames[] = { [ArchiveTabFavorites] = "Favorites", [ArchiveTabIButton] = "iButton", [ArchiveTabNFC] = "NFC", - [ArchiveTabSubOne] = "SubGhz", + [ArchiveTabSubGhz] = "Sub-GHz", [ArchiveTabLFRFID] = "RFID LF", [ArchiveTabIrda] = "Infrared", [ArchiveTabBrowser] = "Browser"}; @@ -12,7 +12,7 @@ static const char* ArchiveTabNames[] = { static const Icon* ArchiveItemIcons[] = { [ArchiveFileTypeIButton] = &I_ibutt_10px, [ArchiveFileTypeNFC] = &I_Nfc_10px, - [ArchiveFileTypeSubOne] = &I_sub1_10px, + [ArchiveFileTypeSubGhz] = &I_sub1_10px, [ArchiveFileTypeLFRFID] = &I_125_10px, [ArchiveFileTypeIrda] = &I_ir_10px, [ArchiveFileTypeFolder] = &I_dir_10px, diff --git a/applications/archive/archive_views.h b/applications/archive/archive_views.h index ca7772d4..9c9cd8f6 100644 --- a/applications/archive/archive_views.h +++ b/applications/archive/archive_views.h @@ -14,7 +14,7 @@ typedef enum { ArchiveFileTypeIButton, ArchiveFileTypeNFC, - ArchiveFileTypeSubOne, + ArchiveFileTypeSubGhz, ArchiveFileTypeLFRFID, ArchiveFileTypeIrda, ArchiveFileTypeFolder, @@ -25,7 +25,7 @@ typedef enum { typedef enum { ArchiveTabFavorites, ArchiveTabLFRFID, - ArchiveTabSubOne, + ArchiveTabSubGhz, ArchiveTabNFC, ArchiveTabIButton, ArchiveTabIrda, diff --git a/applications/subghz/scenes/subghz_scene_config.h b/applications/subghz/scenes/subghz_scene_config.h index 460001d2..514abd38 100644 --- a/applications/subghz/scenes/subghz_scene_config.h +++ b/applications/subghz/scenes/subghz_scene_config.h @@ -1,6 +1,5 @@ ADD_SCENE(subghz, start, Start) ADD_SCENE(subghz, analyze, Analyze) -ADD_SCENE(subghz, read, Read) ADD_SCENE(subghz, receiver, Receiver) ADD_SCENE(subghz, save_name, SaveName) ADD_SCENE(subghz, save_success, SaveSuccess) diff --git a/applications/subghz/scenes/subghz_scene_read.c b/applications/subghz/scenes/subghz_scene_read.c deleted file mode 100644 index 7cab340d..00000000 --- a/applications/subghz/scenes/subghz_scene_read.c +++ /dev/null @@ -1,62 +0,0 @@ -#include "../subghz_i.h" - -#define GUBGHZ_READ_CUSTOM_EVENT (10UL) - -void subghz_read_protocol_callback(SubGhzProtocolCommon* parser, void* context) { - furi_assert(context); - SubGhz* subghz = context; - subghz->protocol_result = parser; - view_dispatcher_send_custom_event(subghz->view_dispatcher, GUBGHZ_READ_CUSTOM_EVENT); -} -void subghz_scene_read_callback(DialogExResult result, void* context) { - SubGhz* subghz = context; - view_dispatcher_send_custom_event(subghz->view_dispatcher, result); -} - -const void subghz_scene_read_on_enter(void* context) { - SubGhz* subghz = context; - - // Setup view - DialogEx* dialog_ex = subghz->dialog_ex; - - dialog_ex_set_header(dialog_ex, "SubGhz 433.92", 36, 6, AlignLeft, AlignCenter); - dialog_ex_set_icon(dialog_ex, 10, 12, &I_RFIDDolphinReceive_97x61); - - //Start CC1101 rx - subghz_begin(FuriHalSubGhzPresetOokAsync); - subghz_rx(433920000); - - furi_hal_subghz_start_async_rx(subghz_worker_rx_callback, subghz->worker); - subghz_worker_start(subghz->worker); - subghz_protocol_enable_dump(subghz->protocol, subghz_read_protocol_callback, subghz); - - view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewDialogEx); -} - -const bool subghz_scene_read_on_event(void* context, SceneManagerEvent event) { - SubGhz* subghz = context; - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == GUBGHZ_READ_CUSTOM_EVENT) { - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneReceiver); - notification_message(subghz->notifications, &sequence_success); - return true; - } - } else if(event.type == SceneManagerEventTypeTick) { - notification_message(subghz->notifications, &sequence_blink_blue_10); - return true; - } - return false; -} - -const void subghz_scene_read_on_exit(void* context) { - SubGhz* subghz = context; - - // Stop CC1101 - subghz_worker_stop(subghz->worker); - furi_hal_subghz_stop_async_rx(); - subghz_end(); - - DialogEx* dialog_ex = subghz->dialog_ex; - dialog_ex_set_header(dialog_ex, NULL, 0, 0, AlignCenter, AlignCenter); - dialog_ex_set_icon(dialog_ex, 0, 0, NULL); -} diff --git a/applications/subghz/scenes/subghz_scene_receiver.c b/applications/subghz/scenes/subghz_scene_receiver.c index 1fe9a466..f0607f17 100644 --- a/applications/subghz/scenes/subghz_scene_receiver.c +++ b/applications/subghz/scenes/subghz_scene_receiver.c @@ -13,7 +13,9 @@ const void subghz_scene_receiver_on_enter(void* context) { subghz_receiver_set_callback(subghz_receiver, subghz_scene_receiver_callback, subghz); - subghz_receiver_set_protocol(subghz_receiver, subghz->protocol_result); + subghz_receiver_set_protocol(subghz_receiver, subghz->protocol_result, subghz->protocol); + subghz_receiver_set_worker(subghz_receiver, subghz->worker); + subghz->state_notifications = NOTIFICATION_RX_STATE; view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewReceiver); } @@ -21,12 +23,53 @@ const bool subghz_scene_receiver_on_event(void* context, SceneManagerEvent event SubGhz* subghz = context; if(event.type == SceneManagerEventTypeCustom) { - if(event.event == SubghzReceverEventSave) { + switch(event.event) { + case SubghzReceverEventSave: + subghz->state_notifications = NOTIFICATION_IDLE_STATE; + subghz->frequency = subghz_receiver_get_frequency(subghz->subghz_receiver); + subghz->preset = subghz_receiver_get_preset(subghz->subghz_receiver); + subghz->protocol_result = subghz_receiver_get_protocol(subghz->subghz_receiver); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaveName); return true; - } else if(event.event == SubghzReceverEventBack) { + break; + case SubghzReceverEventBack: scene_manager_previous_scene(subghz->scene_manager); return true; + break; + case SubghzReceverEventSendStart: + subghz->state_notifications = NOTIFICATION_TX_STATE; + subghz->frequency = subghz_receiver_get_frequency(subghz->subghz_receiver); + subghz->preset = subghz_receiver_get_preset(subghz->subghz_receiver); + subghz->protocol_result = subghz_receiver_get_protocol(subghz->subghz_receiver); + subghz_transmitter_tx_start(subghz); + return true; + break; + case SubghzReceverEventSendStop: + subghz->state_notifications = NOTIFICATION_IDLE_STATE; + subghz_transmitter_tx_stop(subghz); + return true; + break; + case SubghzReceverEventMain: + subghz->state_notifications = NOTIFICATION_RX_STATE; + return true; + break; + case SubghzReceverEventConfig: + subghz->state_notifications = NOTIFICATION_IDLE_STATE; + return true; + break; + default: + break; + } + } else if(event.type == SceneManagerEventTypeTick) { + switch(subghz->state_notifications) { + case NOTIFICATION_TX_STATE: + notification_message(subghz->notifications, &sequence_blink_red_10); + break; + case NOTIFICATION_RX_STATE: + notification_message(subghz->notifications, &sequence_blink_blue_10); + break; + default: + break; } } return false; diff --git a/applications/subghz/scenes/subghz_scene_save_name.c b/applications/subghz/scenes/subghz_scene_save_name.c index 5a3452f8..fba0c622 100644 --- a/applications/subghz/scenes/subghz_scene_save_name.c +++ b/applications/subghz/scenes/subghz_scene_save_name.c @@ -19,7 +19,7 @@ const void subghz_scene_save_name_on_enter(void* context) { set_random_name(subghz->text_store, sizeof(subghz->text_store)); dev_name_empty = true; - text_input_set_header_text(text_input, "Name the KEY"); + text_input_set_header_text(text_input, "Name signal"); text_input_set_result_callback( text_input, subghz_scene_save_name_text_input_callback, diff --git a/applications/subghz/scenes/subghz_scene_saved.c b/applications/subghz/scenes/subghz_scene_saved.c index 09b7a4ac..3bfec82a 100644 --- a/applications/subghz/scenes/subghz_scene_saved.c +++ b/applications/subghz/scenes/subghz_scene_saved.c @@ -3,7 +3,7 @@ const void subghz_scene_saved_on_enter(void* context) { SubGhz* subghz = context; - if(subghz_saved_protocol_select(subghz)) { + if(subghz_load_protocol_from_file(subghz)) { scene_manager_next_scene(subghz->scene_manager, SubGhzSceneTransmitter); } else { scene_manager_search_and_switch_to_previous_scene(subghz->scene_manager, SubGhzSceneStart); diff --git a/applications/subghz/scenes/subghz_scene_set_type.c b/applications/subghz/scenes/subghz_scene_set_type.c index d3c36f54..8948f06e 100644 --- a/applications/subghz/scenes/subghz_scene_set_type.c +++ b/applications/subghz/scenes/subghz_scene_set_type.c @@ -32,31 +32,31 @@ const void subghz_scene_set_type_on_enter(void* context) { submenu_add_item( subghz->submenu, - "Pricenton", + "Princeton_433", SubmenuIndexPricenton, subghz_scene_set_type_submenu_callback, subghz); submenu_add_item( subghz->submenu, - "Nice Flo 12bit", + "Nice Flo 12bit_433", SubmenuIndexNiceFlo12bit, subghz_scene_set_type_submenu_callback, subghz); submenu_add_item( subghz->submenu, - "Nice Flo 24bit", + "Nice Flo 24bit_433", SubmenuIndexNiceFlo24bit, subghz_scene_set_type_submenu_callback, subghz); submenu_add_item( subghz->submenu, - "CAME 12bit", + "CAME 12bit_433", SubmenuIndexCAME12bit, subghz_scene_set_type_submenu_callback, subghz); submenu_add_item( subghz->submenu, - "CAME 24bit", + "CAME 24bit_433", SubmenuIndexCAME24bit, subghz_scene_set_type_submenu_callback, subghz); @@ -64,13 +64,13 @@ const void subghz_scene_set_type_on_enter(void* context) { // subghz->submenu, "Nero Sketch", SubmenuIndexNeroSketch, subghz_scene_set_type_submenu_callback, subghz); submenu_add_item( subghz->submenu, - "Gate TX", + "Gate TX_433", SubmenuIndexGateTX, subghz_scene_set_type_submenu_callback, subghz); submenu_add_item( subghz->submenu, - "DoorHan", + "DoorHan_433", SubmenuIndexDoorHan, subghz_scene_set_type_submenu_callback, subghz); @@ -159,6 +159,8 @@ const bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event break; } if(generated_protocol) { + subghz->frequency = subghz_frequencies[subghz_frequencies_433_92]; + subghz->preset = FuriHalSubGhzPresetOok650Async; scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaveName); return true; } diff --git a/applications/subghz/scenes/subghz_scene_start.c b/applications/subghz/scenes/subghz_scene_start.c index d30536a5..64e50d6a 100644 --- a/applications/subghz/scenes/subghz_scene_start.c +++ b/applications/subghz/scenes/subghz_scene_start.c @@ -56,9 +56,12 @@ const bool subghz_scene_start_on_event(void* context, SceneManagerEvent event) { scene_manager_next_scene(subghz->scene_manager, SubGhzSceneAnalyze); return true; } else if(event.event == SubmenuIndexRead) { + // scene_manager_set_scene_state( + // subghz->scene_manager, SubGhzSceneStart, SubmenuIndexRead); + // scene_manager_next_scene(subghz->scene_manager, SubGhzSceneRead); scene_manager_set_scene_state( subghz->scene_manager, SubGhzSceneStart, SubmenuIndexRead); - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneRead); + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneReceiver); return true; } else if(event.event == SubmenuIndexSaved) { scene_manager_set_scene_state( diff --git a/applications/subghz/scenes/subghz_scene_transmitter.c b/applications/subghz/scenes/subghz_scene_transmitter.c index e28e6d88..3ce3ad2d 100644 --- a/applications/subghz/scenes/subghz_scene_transmitter.c +++ b/applications/subghz/scenes/subghz_scene_transmitter.c @@ -13,6 +13,7 @@ const void subghz_scene_transmitter_on_enter(void* context) { subghz_transmitter_set_callback(subghz_transmitter, subghz_scene_transmitter_callback, subghz); subghz_transmitter_set_protocol(subghz_transmitter, subghz->protocol_result); + subghz_transmitter_set_frequency_preset(subghz_transmitter, subghz->frequency, subghz->preset); view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewTransmitter); @@ -30,6 +31,7 @@ const bool subghz_scene_transmitter_on_event(void* context, SceneManagerEvent ev } else if(event.event == SubghzTransmitterEventSendStop) { subghz->state_notifications = NOTIFICATION_IDLE_STATE; subghz_transmitter_tx_stop(subghz); + subghz_sleep(); return true; } else if(event.event == SubghzTransmitterEventBack) { subghz->state_notifications = NOTIFICATION_IDLE_STATE; diff --git a/applications/subghz/subghz_cli.c b/applications/subghz/subghz_cli.c index 0e4eb7fe..3031fec1 100644 --- a/applications/subghz/subghz_cli.c +++ b/applications/subghz/subghz_cli.c @@ -42,7 +42,7 @@ void subghz_cli_command_tx_carrier(Cli* cli, string_t args, void* context) { } furi_hal_subghz_reset(); - furi_hal_subghz_load_preset(FuriHalSubGhzPresetOokAsync); + furi_hal_subghz_load_preset(FuriHalSubGhzPresetOok650Async); frequency = furi_hal_subghz_set_frequency_and_path(frequency); hal_gpio_init(&gpio_cc1101_g0, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); @@ -79,7 +79,7 @@ void subghz_cli_command_rx_carrier(Cli* cli, string_t args, void* context) { } furi_hal_subghz_reset(); - furi_hal_subghz_load_preset(FuriHalSubGhzPresetOokAsync); + furi_hal_subghz_load_preset(FuriHalSubGhzPresetOok650Async); frequency = furi_hal_subghz_set_frequency_and_path(frequency); printf("Receiving at frequency %lu Hz\r\n", frequency); printf("Press CTRL+C to stop\r\n"); @@ -134,12 +134,12 @@ void subghz_cli_command_tx(Cli* cli, string_t args, void* context) { protocol->common.code_last_found = key; protocol->common.code_last_count_bit = 24; - SubGhzProtocolEncoderCommon* encoder = subghz_protocol_encoder_common_alloc(); + SubGhzProtocolCommonEncoder* encoder = subghz_protocol_encoder_common_alloc(); encoder->repeat = repeat; subghz_protocol_princeton_send_key(protocol, encoder); furi_hal_subghz_reset(); - furi_hal_subghz_load_preset(FuriHalSubGhzPresetOokAsync); + furi_hal_subghz_load_preset(FuriHalSubGhzPresetOok650Async); frequency = furi_hal_subghz_set_frequency_and_path(frequency); furi_hal_subghz_start_async_tx(subghz_protocol_encoder_common_yield, encoder); @@ -212,7 +212,7 @@ void subghz_cli_command_rx(Cli* cli, string_t args, void* context) { // Configure radio furi_hal_subghz_reset(); - furi_hal_subghz_load_preset(FuriHalSubGhzPresetOokAsync); + furi_hal_subghz_load_preset(FuriHalSubGhzPresetOok650Async); frequency = furi_hal_subghz_set_frequency_and_path(frequency); hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow); diff --git a/applications/subghz/subghz_history.c b/applications/subghz/subghz_history.c new file mode 100644 index 00000000..1aacdea6 --- /dev/null +++ b/applications/subghz/subghz_history.c @@ -0,0 +1,155 @@ +#include "subghz_history.h" +#include +#include +#include + +#include +#include + +#define SUBGHZ_HISTORY_MAX 20 + +typedef struct SubGhzHistoryStruct SubGhzHistoryStruct; + +struct SubGhzHistoryStruct { + const char* name; + const char* manufacture_name; + uint8_t type_protocol; + uint8_t code_count_bit; + uint64_t code_found; + uint16_t te; + FuriHalSubGhzPreset preset; + uint32_t real_frequency; +}; + +struct SubGhzHistory { + uint32_t last_update_timestamp; + uint16_t last_index_write; + uint64_t code_last_found; + SubGhzHistoryStruct history[SUBGHZ_HISTORY_MAX]; + SubGhzProtocolCommonLoad data; +}; + +SubGhzHistory* subghz_history_alloc(void) { + SubGhzHistory* instance = furi_alloc(sizeof(SubGhzHistory)); + return instance; +} + +void subghz_history_free(SubGhzHistory* instance) { + furi_assert(instance); + free(instance); +} + +void subghz_history_set_frequency_preset( + SubGhzHistory* instance, + uint16_t idx, + uint32_t frequency, + FuriHalSubGhzPreset preset) { + furi_assert(instance); + if(instance->last_index_write >= SUBGHZ_HISTORY_MAX) return; + instance->history[idx].preset = preset; + instance->history[idx].real_frequency = frequency; +} + +uint32_t subghz_history_get_frequency(SubGhzHistory* instance, uint16_t idx) { + furi_assert(instance); + return instance->history[idx].real_frequency; +} + +FuriHalSubGhzPreset subghz_history_get_preset(SubGhzHistory* instance, uint16_t idx) { + furi_assert(instance); + return instance->history[idx].preset; +} + +void subghz_history_clean(SubGhzHistory* instance) { + furi_assert(instance); + instance->last_index_write = 0; + instance->code_last_found = 0; +} + +uint16_t subghz_history_get_item(SubGhzHistory* instance) { + furi_assert(instance); + return instance->last_index_write; +} + +uint8_t subghz_history_get_type_protocol(SubGhzHistory* instance, uint16_t idx) { + furi_assert(instance); + return instance->history[idx].type_protocol; +} + +const char* subghz_history_get_name(SubGhzHistory* instance, uint16_t idx) { + furi_assert(instance); + return instance->history[idx].name; +} + +SubGhzProtocolCommonLoad* subghz_history_get_raw_data(SubGhzHistory* instance, uint16_t idx) { + furi_assert(instance); + instance->data.code_found = instance->history[idx].code_found; + instance->data.code_count_bit = instance->history[idx].code_count_bit; + instance->data.param1 = instance->history[idx].te; + return &instance->data; +} + +void subghz_history_get_text_item_menu(SubGhzHistory* instance, string_t output, uint16_t idx) { + if(instance->history[idx].code_count_bit < 33) { + string_printf( + output, + "%s %lX", + instance->history[idx].name, + (uint32_t)(instance->history[idx].code_found & 0xFFFFFFFF)); + } else { + string_t str_buff; + string_init(str_buff); + if(strcmp(instance->history[idx].name, "KeeLoq") == 0) { + string_set(str_buff, "KL "); + string_cat(str_buff, instance->history[idx].manufacture_name); + } else if(strcmp(instance->history[idx].name, "Star Line") == 0) { + string_set(str_buff, "SL "); + string_cat(str_buff, instance->history[idx].manufacture_name); + } else { + string_set(str_buff, instance->history[idx].name); + } + + string_printf( + output, + "%s %lX%08lX", + string_get_cstr(str_buff), + (uint32_t)(instance->history[idx].code_found >> 32), + (uint32_t)(instance->history[idx].code_found & 0xFFFFFFFF)); + string_clear(str_buff); + } +} + +void subghz_history_add_to_history(SubGhzHistory* instance, void* context) { + furi_assert(instance); + furi_assert(context); + SubGhzProtocolCommon* protocol = context; + + if(instance->last_index_write >= SUBGHZ_HISTORY_MAX) return; + if((instance->code_last_found == (protocol->code_last_found & 0xFFFF0FFFFFFFFFFF)) && + ((millis() - instance->last_update_timestamp) < 500)) { + instance->last_update_timestamp = millis(); + return; + } + + instance->code_last_found = protocol->code_last_found & 0xFFFF0FFFFFFFFFFF; + instance->last_update_timestamp = millis(); + + instance->history[instance->last_index_write].te = 0; + instance->history[instance->last_index_write].manufacture_name = NULL; + instance->history[instance->last_index_write].name = protocol->name; + instance->history[instance->last_index_write].code_count_bit = protocol->code_last_count_bit; + instance->history[instance->last_index_write].code_found = protocol->code_last_found; + if(strcmp(protocol->name, "KeeLoq") == 0) { + instance->history[instance->last_index_write].manufacture_name = + subghz_protocol_keeloq_get_manufacture_name(protocol); + } else if(strcmp(protocol->name, "Star Line") == 0) { + instance->history[instance->last_index_write].manufacture_name = + subghz_protocol_star_line_get_manufacture_name(protocol); + } else if(strcmp(protocol->name, "Princeton") == 0) { + instance->history[instance->last_index_write].te = + subghz_protocol_princeton_get_te(protocol); + } + instance->history[instance->last_index_write].type_protocol = protocol->type_protocol; + + instance->last_index_write++; +} \ No newline at end of file diff --git a/applications/subghz/subghz_history.h b/applications/subghz/subghz_history.h new file mode 100644 index 00000000..a0964fa0 --- /dev/null +++ b/applications/subghz/subghz_history.h @@ -0,0 +1,22 @@ +#pragma once + +#include + +typedef struct SubGhzHistory SubGhzHistory; + +SubGhzHistory* subghz_history_alloc(void); +void subghz_history_free(SubGhzHistory* instance); +void subghz_history_clean(SubGhzHistory* instance); +void subghz_history_set_frequency_preset( + SubGhzHistory* instance, + uint16_t idx, + uint32_t frequency, + FuriHalSubGhzPreset preset); +uint32_t subghz_history_get_frequency(SubGhzHistory* instance, uint16_t idx); +FuriHalSubGhzPreset subghz_history_get_preset(SubGhzHistory* instance, uint16_t idx); +uint16_t subghz_history_get_item(SubGhzHistory* instance); +uint8_t subghz_history_get_type_protocol(SubGhzHistory* instance, uint16_t idx); +const char* subghz_history_get_name(SubGhzHistory* instance, uint16_t idx); +void subghz_history_get_text_item_menu(SubGhzHistory* instance, string_t output, uint16_t idx); +void subghz_history_add_to_history(SubGhzHistory* instance, void* context); +SubGhzProtocolCommonLoad* subghz_history_get_raw_data(SubGhzHistory* instance, uint16_t idx); diff --git a/applications/subghz/subghz_i.c b/applications/subghz/subghz_i.c index 03ebbc26..a339edfb 100644 --- a/applications/subghz/subghz_i.c +++ b/applications/subghz/subghz_i.c @@ -8,6 +8,7 @@ #include #include "file-worker.h" #include "../notification/notification.h" +#include "views/subghz_receiver.h" void subghz_begin(FuriHalSubGhzPreset preset) { furi_hal_subghz_reset(); @@ -16,30 +17,59 @@ void subghz_begin(FuriHalSubGhzPreset preset) { hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow); } -void subghz_rx(uint32_t frequency) { +uint32_t subghz_rx(void* context, uint32_t frequency) { + furi_assert(context); + SubGhzWorker* worker = context; + furi_hal_subghz_idle(); - furi_hal_subghz_set_frequency_and_path(frequency); + uint32_t value = furi_hal_subghz_set_frequency_and_path(frequency); hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow); furi_hal_subghz_flush_rx(); furi_hal_subghz_rx(); + + furi_hal_subghz_start_async_rx(subghz_worker_rx_callback, worker); + subghz_worker_start(worker); + return value; } -void subghz_tx(uint32_t frequency) { +uint32_t subghz_tx(uint32_t frequency) { furi_hal_subghz_idle(); - furi_hal_subghz_set_frequency_and_path(frequency); + uint32_t value = furi_hal_subghz_set_frequency_and_path(frequency); hal_gpio_init(&gpio_cc1101_g0, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); hal_gpio_write(&gpio_cc1101_g0, true); furi_hal_subghz_tx(); + return value; } void subghz_idle(void) { furi_hal_subghz_idle(); } -void subghz_end(void) { +void subghz_rx_end(void* context) { + furi_assert(context); + SubGhzWorker* worker = context; + + if(subghz_worker_is_running(worker)) { + subghz_worker_stop(worker); + furi_hal_subghz_stop_async_rx(); + } +} + +void subghz_sleep(void) { furi_hal_subghz_sleep(); } +void subghz_frequency_preset_to_str(void* context, string_t output) { + furi_assert(context); + SubGhz* subghz = context; + string_cat_printf( + output, + "Frequency: %d\n" + "Preset: %d\n", + (int)subghz->frequency, + (int)subghz->preset); +} + void subghz_transmitter_tx_start(void* context) { SubGhz* subghz = context; subghz->encoder = subghz_protocol_encoder_common_alloc(); @@ -47,8 +77,17 @@ void subghz_transmitter_tx_start(void* context) { //get upload if(subghz->protocol_result->get_upload_protocol) { if(subghz->protocol_result->get_upload_protocol(subghz->protocol_result, subghz->encoder)) { - subghz_begin(FuriHalSubGhzPresetOokAsync); - subghz_tx(433920000); + if(subghz->preset) { + subghz_begin(subghz->preset); + } else { + subghz_begin(FuriHalSubGhzPresetOok650Async); + } + if(subghz->frequency) { + subghz_tx(subghz->frequency); + } else { + subghz_tx(433920000); + } + //Start TX furi_hal_subghz_start_async_tx(subghz_protocol_encoder_common_yield, subghz->encoder); } @@ -59,7 +98,6 @@ void subghz_transmitter_tx_stop(void* context) { SubGhz* subghz = context; //Stop TX furi_hal_subghz_stop_async_tx(); - subghz_end(); subghz_protocol_encoder_common_free(subghz->encoder); //if protocol dynamic then we save the last upload if(subghz->protocol_result->type_protocol == TYPE_PROTOCOL_DYNAMIC) { @@ -79,12 +117,35 @@ bool subghz_key_load(SubGhz* subghz, const char* file_path) { string_init_set_str(path, file_path); string_t temp_str; string_init(temp_str); + int res = 0; + int data = 0; do { if(!file_worker_open(file_worker, string_get_cstr(path), FSAM_READ, FSOM_OPEN_EXISTING)) { break; } - // Read and parse name protocol from 1st line + + // Read and parse frequency from 1st line + if(!file_worker_read_until(file_worker, temp_str, '\n')) { + break; + } + res = sscanf(string_get_cstr(temp_str), "Frequency: %d\n", &data); + if(res != 1) { + break; + } + subghz->frequency = (uint32_t)data; + + // Read and parse preset from 2st line + if(!file_worker_read_until(file_worker, temp_str, '\n')) { + break; + } + res = sscanf(string_get_cstr(temp_str), "Preset: %d\n", &data); + if(res != 1) { + break; + } + subghz->preset = (FuriHalSubGhzPreset)data; + + // Read and parse name protocol from 2st line if(!file_worker_read_until(file_worker, temp_str, '\n')) { break; } @@ -93,16 +154,18 @@ bool subghz_key_load(SubGhz* subghz, const char* file_path) { subghz->protocol_result = subghz_protocol_get_by_name(subghz->protocol, string_get_cstr(temp_str)); if(subghz->protocol_result == NULL) { - file_worker_show_error(file_worker, "Cannot parse\nfile"); break; } - if(!subghz->protocol_result->to_load_protocol(file_worker, subghz->protocol_result)) { - file_worker_show_error(file_worker, "Cannot parse\nfile"); + if(!subghz->protocol_result->to_load_protocol_from_file( + file_worker, subghz->protocol_result)) { break; } loaded = true; } while(0); + if(!loaded) { + file_worker_show_error(file_worker, "Cannot parse\nfile"); + } string_clear(temp_str); string_clear(path); file_worker_close(file_worker); @@ -113,6 +176,7 @@ bool subghz_key_load(SubGhz* subghz, const char* file_path) { bool subghz_save_protocol_to_file(void* context, const char* dev_name) { SubGhz* subghz = context; + furi_assert(subghz->protocol_result); FileWorker* file_worker = file_worker_alloc(false); string_t dev_file_name; string_init(dev_file_name); @@ -140,6 +204,11 @@ bool subghz_save_protocol_to_file(void* context, const char* dev_name) { file_worker, string_get_cstr(dev_file_name), FSAM_WRITE, FSOM_CREATE_ALWAYS)) { break; } + //Get string frequency preset protocol + subghz_frequency_preset_to_str(subghz, temp_str); + if(!file_worker_write(file_worker, string_get_cstr(temp_str), string_size(temp_str))) { + break; + } //Get string save subghz->protocol_result->to_save_string(subghz->protocol_result, temp_str); // Prepare and write data to file @@ -157,7 +226,7 @@ bool subghz_save_protocol_to_file(void* context, const char* dev_name) { return saved; } -bool subghz_saved_protocol_select(SubGhz* subghz) { +bool subghz_load_protocol_from_file(SubGhz* subghz) { furi_assert(subghz); FileWorker* file_worker = file_worker_alloc(false); @@ -165,6 +234,8 @@ bool subghz_saved_protocol_select(SubGhz* subghz) { string_init(protocol_file_name); string_t temp_str; string_init(temp_str); + int sscanf_res = 0; + int data = 0; // Input events and views are managed by file_select bool res = file_worker_file_select( @@ -197,7 +268,27 @@ bool subghz_saved_protocol_select(SubGhz* subghz) { file_worker, string_get_cstr(protocol_file_name), FSAM_READ, FSOM_OPEN_EXISTING)) { break; } - // Read and parse name protocol from 1st line + // Read and parse frequency from 1st line + if(!file_worker_read_until(file_worker, temp_str, '\n')) { + break; + } + sscanf_res = sscanf(string_get_cstr(temp_str), "Frequency: %d\n", &data); + if(sscanf_res != 1) { + break; + } + subghz->frequency = (uint32_t)data; + + // Read and parse preset from 2st line + if(!file_worker_read_until(file_worker, temp_str, '\n')) { + break; + } + sscanf_res = sscanf(string_get_cstr(temp_str), "Preset: %d\n", &data); + if(sscanf_res != 1) { + break; + } + subghz->preset = (FuriHalSubGhzPreset)data; + + // Read and parse name protocol from 3st line if(!file_worker_read_until(file_worker, temp_str, '\n')) { break; } @@ -206,16 +297,19 @@ bool subghz_saved_protocol_select(SubGhz* subghz) { subghz->protocol_result = subghz_protocol_get_by_name(subghz->protocol, string_get_cstr(temp_str)); if(subghz->protocol_result == NULL) { - file_worker_show_error(file_worker, "Cannot parse\nfile"); break; } - if(!subghz->protocol_result->to_load_protocol(file_worker, subghz->protocol_result)) { - file_worker_show_error(file_worker, "Cannot parse\nfile"); + if(!subghz->protocol_result->to_load_protocol_from_file( + file_worker, subghz->protocol_result)) { break; } res = true; } while(0); + if(!res) { + file_worker_show_error(file_worker, "Cannot parse\nfile"); + } + string_clear(temp_str); string_clear(protocol_file_name); diff --git a/applications/subghz/subghz_i.h b/applications/subghz/subghz_i.h index 8149363d..8b084209 100644 --- a/applications/subghz/subghz_i.h +++ b/applications/subghz/subghz_i.h @@ -25,12 +25,14 @@ #include #include #include +#include "subghz_history.h" #define SUBGHZ_TEXT_STORE_SIZE 128 #define NOTIFICATION_STARTING_STATE 0u #define NOTIFICATION_IDLE_STATE 1u #define NOTIFICATION_TX_STATE 2u +#define NOTIFICATION_RX_STATE 3u extern const uint32_t subghz_frequencies[]; extern const uint32_t subghz_frequencies_count; @@ -43,10 +45,11 @@ struct SubGhz { SubGhzWorker* worker; SubGhzProtocol* protocol; SubGhzProtocolCommon* protocol_result; - SubGhzProtocolEncoderCommon* encoder; + SubGhzProtocolCommonEncoder* encoder; + uint32_t frequency; + FuriHalSubGhzPreset preset; SceneManager* scene_manager; - ViewDispatcher* view_dispatcher; Submenu* submenu; @@ -81,13 +84,14 @@ typedef enum { } SubGhzView; void subghz_begin(FuriHalSubGhzPreset preset); -void subghz_rx(uint32_t frequency); -void subghz_tx(uint32_t frequency); +uint32_t subghz_rx(void* context, uint32_t frequency); +uint32_t subghz_tx(uint32_t frequency); void subghz_idle(void); -void subghz_end(void); +void subghz_rx_end(void* context); +void subghz_sleep(void); void subghz_transmitter_tx_start(void* context); void subghz_transmitter_tx_stop(void* context); bool subghz_key_load(SubGhz* subghz, const char* file_path); bool subghz_save_protocol_to_file(void* context, const char* dev_name); -bool subghz_saved_protocol_select(SubGhz* subghz); +bool subghz_load_protocol_from_file(SubGhz* subghz); uint32_t subghz_random_serial(void); diff --git a/applications/subghz/views/subghz_analyze.c b/applications/subghz/views/subghz_analyze.c index 7380a026..cef72303 100644 --- a/applications/subghz/views/subghz_analyze.c +++ b/applications/subghz/views/subghz_analyze.c @@ -58,7 +58,7 @@ void subghz_analyze_draw(Canvas* canvas, SubghzAnalyzeModel* model) { default: canvas_set_font(canvas, FontSecondary); - elements_multiline_text(canvas, 0, 20, string_get_cstr(model->text)); + elements_multiline_text(canvas, 0, 18, string_get_cstr(model->text)); break; } } @@ -144,7 +144,7 @@ void subghz_analyze_enter(void* context) { furi_hal_subghz_reset(); furi_hal_subghz_idle(); - furi_hal_subghz_load_preset(FuriHalSubGhzPresetOokAsync); + furi_hal_subghz_load_preset(FuriHalSubGhzPresetOok650Async); with_view_model( subghz_analyze->view, (SubghzAnalyzeModel * model) { diff --git a/applications/subghz/views/subghz_receiver.c b/applications/subghz/views/subghz_receiver.c index a4d9aef7..147811dc 100644 --- a/applications/subghz/views/subghz_receiver.c +++ b/applications/subghz/views/subghz_receiver.c @@ -1,25 +1,55 @@ #include "subghz_receiver.h" #include "../subghz_i.h" - #include #include #include #include #include #include +#include #include +#define FRAME_HEIGHT 12 +#define MAX_LEN_PX 100 +#define MENU_ITEMS 4 + +typedef enum { + ReceiverSceneStart, + ReceiverSceneMain, + ReceiverSceneConfig, + ReceiverSceneInfo, +} SubghzReceiverScene; + +static const Icon* ReceiverItemIcons[] = { + [TYPE_PROTOCOL_UNKNOWN] = &I_quest_7x8, + [TYPE_PROTOCOL_STATIC] = &I_unlock_7x8, + [TYPE_PROTOCOL_DYNAMIC] = &I_lock_7x8, +}; + struct SubghzReceiver { View* view; SubghzReceiverCallback callback; void* context; + SubGhzWorker* worker; + SubGhzProtocol* protocol; }; typedef struct { string_t text; uint16_t scene; - SubGhzProtocolCommon* protocol; + SubGhzProtocolCommon* protocol_result; + SubGhzHistory* history; + uint8_t frequency; + uint8_t temp_frequency; + uint32_t real_frequency; + + uint8_t tab_idx; + uint8_t menu_idx; + uint16_t idx; + uint16_t list_offset; + uint16_t history_item; + bool menu; } SubghzReceiverModel; void subghz_receiver_set_callback( @@ -32,50 +62,323 @@ void subghz_receiver_set_callback( subghz_receiver->context = context; } -void subghz_receiver_set_protocol(SubghzReceiver* subghz_receiver, SubGhzProtocolCommon* protocol) { +void subghz_receiver_set_protocol( + SubghzReceiver* subghz_receiver, + SubGhzProtocolCommon* protocol_result, + SubGhzProtocol* protocol) { + furi_assert(subghz_receiver); with_view_model( subghz_receiver->view, (SubghzReceiverModel * model) { - model->protocol = protocol; + model->protocol_result = protocol_result; + return true; + }); + subghz_receiver->protocol = protocol; +} + +SubGhzProtocolCommon* subghz_receiver_get_protocol(SubghzReceiver* subghz_receiver) { + furi_assert(subghz_receiver); + SubGhzProtocolCommon* result = NULL; + with_view_model( + subghz_receiver->view, (SubghzReceiverModel * model) { + result = model->protocol_result; + return false; + }); + return result; +} + +void subghz_receiver_set_worker(SubghzReceiver* subghz_receiver, SubGhzWorker* worker) { + furi_assert(subghz_receiver); + subghz_receiver->worker = worker; +} + +static void subghz_receiver_update_offset(SubghzReceiver* subghz_receiver) { + furi_assert(subghz_receiver); + + with_view_model( + subghz_receiver->view, (SubghzReceiverModel * model) { + size_t history_item = model->history_item; + uint16_t bounds = history_item > 3 ? 2 : history_item; + + if(history_item > 3 && model->idx >= history_item - 1) { + model->list_offset = model->idx - 3; + } else if(model->list_offset < model->idx - bounds) { + model->list_offset = CLAMP(model->list_offset + 1, history_item - bounds, 0); + } else if(model->list_offset > model->idx - bounds) { + model->list_offset = CLAMP(model->idx - 1, history_item - bounds, 0); + } return true; }); } +static void subghz_receiver_draw_frame(Canvas* canvas, uint16_t idx, bool scrollbar) { + canvas_set_color(canvas, ColorBlack); + canvas_draw_box(canvas, 0, 0 + idx * FRAME_HEIGHT, scrollbar ? 122 : 127, FRAME_HEIGHT); + + canvas_set_color(canvas, ColorWhite); + canvas_draw_dot(canvas, 0, 0 + idx * FRAME_HEIGHT); + canvas_draw_dot(canvas, 1, 0 + idx * FRAME_HEIGHT); + canvas_draw_dot(canvas, 0, (0 + idx * FRAME_HEIGHT) + 1); + + canvas_draw_dot(canvas, 0, (0 + idx * FRAME_HEIGHT) + 11); + canvas_draw_dot(canvas, scrollbar ? 121 : 126, 0 + idx * FRAME_HEIGHT); + canvas_draw_dot(canvas, scrollbar ? 121 : 126, (0 + idx * FRAME_HEIGHT) + 11); +} + void subghz_receiver_draw(Canvas* canvas, SubghzReceiverModel* model) { + bool scrollbar = model->history_item > 4; + string_t str_buff; + char buffer[64]; + string_init(str_buff); + canvas_clear(canvas); canvas_set_color(canvas, ColorBlack); - canvas_set_font(canvas, FontSecondary); - elements_multiline_text(canvas, 0, 10, string_get_cstr(model->text)); - elements_button_left(canvas, "Back"); - if(model->protocol && model->protocol->to_save_string && - strcmp(model->protocol->name, "KeeLoq")) { - elements_button_right(canvas, "Save"); + switch(model->scene) { + case ReceiverSceneMain: + for(size_t i = 0; i < MIN(model->history_item, MENU_ITEMS); ++i) { + size_t idx = CLAMP(i + model->list_offset, model->history_item, 0); + subghz_history_get_text_item_menu(model->history, str_buff, idx); + elements_string_fit_width(canvas, str_buff, scrollbar ? MAX_LEN_PX - 6 : MAX_LEN_PX); + if(model->idx == idx) { + subghz_receiver_draw_frame(canvas, i, scrollbar); + } else { + canvas_set_color(canvas, ColorBlack); + } + canvas_draw_icon( + canvas, + 1, + 2 + i * FRAME_HEIGHT, + ReceiverItemIcons[subghz_history_get_type_protocol(model->history, idx)]); + canvas_draw_str(canvas, 15, 9 + i * FRAME_HEIGHT, string_get_cstr(str_buff)); + string_clean(str_buff); + } + if(scrollbar) { + elements_scrollbar_pos(canvas, 126, 0, 49, model->idx, model->history_item); + } + canvas_set_color(canvas, ColorBlack); + canvas_set_font(canvas, FontPrimary); + snprintf( + buffer, + sizeof(buffer), + "%03ld.%03ld OOK", + model->real_frequency / 1000000 % 1000, + model->real_frequency / 1000 % 1000); + canvas_draw_str(canvas, 60, 61, buffer); + elements_button_left(canvas, "Config"); + break; + + case ReceiverSceneStart: + canvas_draw_icon(canvas, 0, 0, &I_RFIDDolphinReceive_97x61); + canvas_invert_color(canvas); + canvas_draw_box(canvas, 80, 2, 20, 20); + canvas_invert_color(canvas); + canvas_draw_icon(canvas, 75, 8, &I_sub1_10px); + canvas_set_font(canvas, FontPrimary); + canvas_draw_str(canvas, 63, 40, "Scanning..."); + canvas_set_color(canvas, ColorBlack); + canvas_set_font(canvas, FontPrimary); + snprintf( + buffer, + sizeof(buffer), + "%03ld.%03ld OOK", + model->real_frequency / 1000000 % 1000, + model->real_frequency / 1000 % 1000); + canvas_draw_str(canvas, 60, 61, buffer); + elements_button_left(canvas, "Config"); + break; + + case ReceiverSceneConfig: + snprintf( + buffer, + sizeof(buffer), + "Frequency: < %03ld.%03ldMHz >", + model->real_frequency / 1000000 % 1000, + model->real_frequency / 1000 % 1000); + canvas_draw_str(canvas, 0, 8, buffer); + elements_button_center(canvas, "Save"); + break; + + case ReceiverSceneInfo: + canvas_set_font(canvas, FontSecondary); + elements_multiline_text(canvas, 0, 8, string_get_cstr(model->text)); + snprintf( + buffer, + sizeof(buffer), + "%03ld.%03ld", + subghz_history_get_frequency(model->history, model->idx) / 1000000 % 1000, + subghz_history_get_frequency(model->history, model->idx) / 1000 % 1000); + canvas_draw_str(canvas, 90, 8, buffer); + if(model->protocol_result && model->protocol_result->to_save_string && + strcmp(model->protocol_result->name, "KeeLoq")) { + elements_button_right(canvas, "Save"); + elements_button_center(canvas, "Send"); + } + break; + + default: + + break; } + + string_clear(str_buff); } bool subghz_receiver_input(InputEvent* event, void* context) { furi_assert(context); + + uint8_t scene = 0; SubghzReceiver* subghz_receiver = context; - - if(event->type != InputTypeShort) return false; - - bool can_be_saved = false; with_view_model( subghz_receiver->view, (SubghzReceiverModel * model) { - can_be_saved = - (model->protocol && model->protocol->to_save_string && - strcmp(model->protocol->name, "KeeLoq")); + scene = model->scene; return false; }); - if(event->key == InputKeyBack) { - return false; - } else if(event->key == InputKeyLeft) { - subghz_receiver->callback(SubghzReceverEventBack, subghz_receiver->context); - } else if(can_be_saved && event->key == InputKeyRight) { - subghz_receiver->callback(SubghzReceverEventSave, subghz_receiver->context); + if(scene != ReceiverSceneInfo && event->type != InputTypeShort) return false; + + bool can_be_saved = false; + + switch(scene) { + case ReceiverSceneMain: + if(event->key == InputKeyBack) { + return false; + } else if(event->key == InputKeyUp) { + with_view_model( + subghz_receiver->view, (SubghzReceiverModel * model) { + if(model->idx != 0) model->idx--; + return true; + }); + } else if(event->key == InputKeyDown) { + with_view_model( + subghz_receiver->view, (SubghzReceiverModel * model) { + if(model->idx != subghz_history_get_item(model->history) - 1) model->idx++; + return true; + }); + } else if(event->key == InputKeyLeft) { + with_view_model( + subghz_receiver->view, (SubghzReceiverModel * model) { + model->scene = ReceiverSceneConfig; + model->temp_frequency = model->frequency; + return true; + }); + subghz_receiver->callback(SubghzReceverEventConfig, subghz_receiver->context); + } else if(event->key == InputKeyOk) { + with_view_model( + subghz_receiver->view, (SubghzReceiverModel * model) { + string_clean(model->text); + model->protocol_result = subghz_protocol_get_by_name( + subghz_receiver->protocol, + subghz_history_get_name(model->history, model->idx)); + if(model->protocol_result->to_load_protocol != NULL) { + model->protocol_result->to_load_protocol( + model->protocol_result, + subghz_history_get_raw_data(model->history, model->idx)); + model->protocol_result->to_string(model->protocol_result, model->text); + model->scene = ReceiverSceneInfo; + } + return true; + }); + } + break; + + case ReceiverSceneInfo: + with_view_model( + subghz_receiver->view, (SubghzReceiverModel * model) { + can_be_saved = + (model->protocol_result && model->protocol_result->to_save_string && + strcmp(model->protocol_result->name, "KeeLoq")); + return false; + }); + if(event->key == InputKeyBack && event->type == InputTypeShort) { + with_view_model( + subghz_receiver->view, (SubghzReceiverModel * model) { + subghz_rx_end(subghz_receiver->worker); + model->real_frequency = + subghz_rx(subghz_receiver->worker, subghz_frequencies[model->frequency]); + model->scene = ReceiverSceneMain; + return true; + }); + subghz_receiver->callback(SubghzReceverEventMain, subghz_receiver->context); + } else if(can_be_saved && event->key == InputKeyRight) { + subghz_receiver->callback(SubghzReceverEventSave, subghz_receiver->context); + return false; + } else if(can_be_saved && event->key == InputKeyOk && event->type == InputTypePress) { + subghz_rx_end(subghz_receiver->worker); + subghz_receiver->callback(SubghzReceverEventSendStart, subghz_receiver->context); + return true; + } else if(can_be_saved && event->key == InputKeyOk && event->type == InputTypeRelease) { + subghz_receiver->callback(SubghzReceverEventSendStop, subghz_receiver->context); + return true; + } + break; + + case ReceiverSceneConfig: + if(event->key == InputKeyBack) { + with_view_model( + subghz_receiver->view, (SubghzReceiverModel * model) { + model->frequency = model->temp_frequency; + model->real_frequency = subghz_frequencies[model->frequency]; + if(subghz_history_get_item(model->history) == 0) { + model->scene = ReceiverSceneStart; + } else { + model->scene = ReceiverSceneMain; + } + return true; + }); + subghz_receiver->callback(SubghzReceverEventMain, subghz_receiver->context); + } else if(event->key == InputKeyOk) { + with_view_model( + subghz_receiver->view, (SubghzReceiverModel * model) { + subghz_rx_end(subghz_receiver->worker); + model->real_frequency = + subghz_rx(subghz_receiver->worker, subghz_frequencies[model->frequency]); + if(subghz_history_get_item(model->history) == 0) { + model->scene = ReceiverSceneStart; + } else { + model->scene = ReceiverSceneMain; + } + return true; + }); + subghz_receiver->callback(SubghzReceverEventMain, subghz_receiver->context); + } else { + with_view_model( + subghz_receiver->view, (SubghzReceiverModel * model) { + bool model_updated = false; + + if(event->key == InputKeyLeft) { + if(model->frequency > 0) model->frequency--; + model_updated = true; + } else if(event->key == InputKeyRight) { + if(model->frequency < subghz_frequencies_count - 1) model->frequency++; + model_updated = true; + } + if(model_updated) { + model->real_frequency = subghz_frequencies[model->frequency]; + } + return model_updated; + }); + } + break; + + case ReceiverSceneStart: + if(event->key == InputKeyBack) { + return false; + } else if(event->key == InputKeyLeft) { + with_view_model( + subghz_receiver->view, (SubghzReceiverModel * model) { + model->temp_frequency = model->frequency; + model->scene = ReceiverSceneConfig; + return true; + }); + subghz_receiver->callback(SubghzReceverEventConfig, subghz_receiver->context); + } + break; + + default: + break; } + subghz_receiver_update_offset(subghz_receiver); return true; } @@ -86,19 +389,53 @@ void subghz_receiver_text_callback(string_t text, void* context) { with_view_model( subghz_receiver->view, (SubghzReceiverModel * model) { string_set(model->text, text); - model->scene = 0; + model->scene = ReceiverSceneMain; return true; }); } +void subghz_receiver_protocol_callback(SubGhzProtocolCommon* parser, void* context) { + furi_assert(context); + SubghzReceiver* subghz_receiver = context; + + with_view_model( + subghz_receiver->view, (SubghzReceiverModel * model) { + model->protocol_result = parser; + subghz_history_set_frequency_preset( + model->history, + model->history_item, + model->real_frequency, + FuriHalSubGhzPresetOok650Async); + subghz_history_add_to_history(model->history, parser); + + model->history_item = subghz_history_get_item(model->history); + model->scene = ReceiverSceneMain; + return true; + }); + subghz_protocol_reset(subghz_receiver->protocol); + subghz_receiver_update_offset(subghz_receiver); +} + void subghz_receiver_enter(void* context) { furi_assert(context); SubghzReceiver* subghz_receiver = context; + //Start CC1101 Rx + subghz_begin(FuriHalSubGhzPresetOok650Async); with_view_model( subghz_receiver->view, (SubghzReceiverModel * model) { - model->protocol->to_string(model->protocol, model->text); + subghz_rx_end(subghz_receiver->worker); + model->frequency = subghz_frequencies_433_92; + model->real_frequency = + subghz_rx(subghz_receiver->worker, subghz_frequencies[model->frequency]); + if(subghz_history_get_item(model->history) == 0) { + model->scene = ReceiverSceneStart; + } else { + model->scene = ReceiverSceneMain; + } return true; }); + subghz_protocol_enable_dump( + subghz_receiver->protocol, subghz_receiver_protocol_callback, subghz_receiver); } void subghz_receiver_exit(void* context) { @@ -109,6 +446,9 @@ void subghz_receiver_exit(void* context) { string_clean(model->text); return true; }); + // Stop CC1101 Rx + subghz_rx_end(subghz_receiver->worker); + subghz_sleep(); } SubghzReceiver* subghz_receiver_alloc() { @@ -126,6 +466,7 @@ SubghzReceiver* subghz_receiver_alloc() { with_view_model( subghz_receiver->view, (SubghzReceiverModel * model) { string_init(model->text); + model->history = subghz_history_alloc(); return true; }); return subghz_receiver; @@ -137,7 +478,8 @@ void subghz_receiver_free(SubghzReceiver* subghz_receiver) { with_view_model( subghz_receiver->view, (SubghzReceiverModel * model) { string_clear(model->text); - return true; + subghz_history_free(model->history); + return false; }); view_free(subghz_receiver->view); free(subghz_receiver); @@ -147,3 +489,44 @@ View* subghz_receiver_get_view(SubghzReceiver* subghz_receiver) { furi_assert(subghz_receiver); return subghz_receiver->view; } + +uint32_t subghz_receiver_get_frequency(SubghzReceiver* subghz_receiver) { + furi_assert(subghz_receiver); + uint32_t frequency; + with_view_model( + subghz_receiver->view, (SubghzReceiverModel * model) { + frequency = subghz_history_get_frequency(model->history, model->idx); + return false; + }); + return frequency; +} + +FuriHalSubGhzPreset subghz_receiver_get_preset(SubghzReceiver* subghz_receiver) { + furi_assert(subghz_receiver); + FuriHalSubGhzPreset preset; + with_view_model( + subghz_receiver->view, (SubghzReceiverModel * model) { + preset = subghz_history_get_preset(model->history, model->idx); + return false; + }); + return preset; +} + +void subghz_receiver_frequency_preset_to_str(SubghzReceiver* subghz_receiver, string_t output) { + furi_assert(subghz_receiver); + uint32_t frequency; + uint32_t preset; + with_view_model( + subghz_receiver->view, (SubghzReceiverModel * model) { + frequency = subghz_history_get_frequency(model->history, model->idx); + preset = (uint32_t)subghz_history_get_preset(model->history, model->idx); + return false; + }); + + string_cat_printf( + output, + "Frequency: %d\n" + "Preset: %d\n", + (int)frequency, + (int)preset); +} \ No newline at end of file diff --git a/applications/subghz/views/subghz_receiver.h b/applications/subghz/views/subghz_receiver.h index 924f90b8..b4aa7bbc 100644 --- a/applications/subghz/views/subghz_receiver.h +++ b/applications/subghz/views/subghz_receiver.h @@ -2,10 +2,19 @@ #include #include +#include +#include +#include "../subghz_history.h" typedef enum { + SubghzReceverEventOK, + SubghzReceverEventConfig, + SubghzReceverEventMain, SubghzReceverEventSave, SubghzReceverEventBack, + SubghzReceverEventMore, + SubghzReceverEventSendStart, + SubghzReceverEventSendStop } SubghzReceverEvent; typedef struct SubghzReceiver SubghzReceiver; @@ -23,4 +32,12 @@ void subghz_receiver_free(SubghzReceiver* subghz_receiver); View* subghz_receiver_get_view(SubghzReceiver* subghz_receiver); -void subghz_receiver_set_protocol(SubghzReceiver* subghz_receiver, SubGhzProtocolCommon* protocol); +void subghz_receiver_set_protocol( + SubghzReceiver* subghz_receiver, + SubGhzProtocolCommon* protocol_result, + SubGhzProtocol* protocol); +SubGhzProtocolCommon* subghz_receiver_get_protocol(SubghzReceiver* subghz_receiver); +void subghz_receiver_set_worker(SubghzReceiver* subghz_receiver, SubGhzWorker* worker); +uint32_t subghz_receiver_get_frequency(SubghzReceiver* subghz_receiver); +FuriHalSubGhzPreset subghz_receiver_get_preset(SubghzReceiver* subghz_receiver); +void subghz_receiver_frequency_preset_to_str(SubghzReceiver* subghz_receiver, string_t output); diff --git a/applications/subghz/views/subghz_static.c b/applications/subghz/views/subghz_static.c index 25c9b9b4..bdb11753 100644 --- a/applications/subghz/views/subghz_static.c +++ b/applications/subghz/views/subghz_static.c @@ -112,7 +112,7 @@ void subghz_static_enter(void* context) { SubghzStatic* instance = context; furi_hal_subghz_reset(); - furi_hal_subghz_load_preset(FuriHalSubGhzPresetOokAsync); + furi_hal_subghz_load_preset(FuriHalSubGhzPresetOok650Async); hal_gpio_init(&gpio_cc1101_g0, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); hal_gpio_write(&gpio_cc1101_g0, false); diff --git a/applications/subghz/views/subghz_test_carrier.c b/applications/subghz/views/subghz_test_carrier.c index acd1dacb..82d11650 100644 --- a/applications/subghz/views/subghz_test_carrier.c +++ b/applications/subghz/views/subghz_test_carrier.c @@ -119,7 +119,7 @@ void subghz_test_carrier_enter(void* context) { SubghzTestCarrier* subghz_test_carrier = context; furi_hal_subghz_reset(); - furi_hal_subghz_load_preset(FuriHalSubGhzPresetOokAsync); + furi_hal_subghz_load_preset(FuriHalSubGhzPresetOok650Async); hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow); diff --git a/applications/subghz/views/subghz_test_packet.c b/applications/subghz/views/subghz_test_packet.c index 66a8eeee..f1c48179 100644 --- a/applications/subghz/views/subghz_test_packet.c +++ b/applications/subghz/views/subghz_test_packet.c @@ -166,7 +166,7 @@ void subghz_test_packet_enter(void* context) { SubghzTestPacket* instance = context; furi_hal_subghz_reset(); - furi_hal_subghz_load_preset(FuriHalSubGhzPresetOokAsync); + furi_hal_subghz_load_preset(FuriHalSubGhzPresetOok650Async); with_view_model( instance->view, (SubghzTestPacketModel * model) { diff --git a/applications/subghz/views/subghz_transmitter.c b/applications/subghz/views/subghz_transmitter.c index 1ba76d97..efa35fde 100644 --- a/applications/subghz/views/subghz_transmitter.c +++ b/applications/subghz/views/subghz_transmitter.c @@ -8,7 +8,8 @@ #include #include -#include +//#include +#include struct SubghzTransmitter { View* view; @@ -19,6 +20,8 @@ struct SubghzTransmitter { typedef struct { string_t text; uint16_t scene; + uint32_t real_frequency; + FuriHalSubGhzPreset preset; SubGhzProtocolCommon* protocol; } SubghzTransmitterModel; @@ -42,14 +45,65 @@ void subghz_transmitter_set_protocol( }); } +void subghz_transmitter_set_frequency_preset( + SubghzTransmitter* subghz_transmitter, + uint32_t frequency, + FuriHalSubGhzPreset preset) { + with_view_model( + subghz_transmitter->view, (SubghzTransmitterModel * model) { + model->real_frequency = frequency; + model->preset = preset; + return true; + }); +} + +static void subghz_transmitter_button_right(Canvas* canvas, const char* str) { + const uint8_t button_height = 13; + const uint8_t vertical_offset = 3; + const uint8_t horizontal_offset = 1; + const uint8_t string_width = canvas_string_width(canvas, str); + const Icon* icon = &I_ButtonCenter_7x7; + const uint8_t icon_offset = 3; + const uint8_t icon_width_with_offset = icon->width + icon_offset; + const uint8_t button_width = string_width + horizontal_offset * 2 + icon_width_with_offset; + + const uint8_t x = (canvas_width(canvas) - button_width) / 2 + 40; + const uint8_t y = canvas_height(canvas); + + canvas_draw_box(canvas, x, y - button_height, button_width, button_height); + + canvas_draw_line(canvas, x - 1, y, x - 1, y - button_height + 0); + canvas_draw_line(canvas, x - 2, y, x - 2, y - button_height + 1); + canvas_draw_line(canvas, x - 3, y, x - 3, y - button_height + 2); + + canvas_draw_line(canvas, x + button_width + 0, y, x + button_width + 0, y - button_height + 0); + canvas_draw_line(canvas, x + button_width + 1, y, x + button_width + 1, y - button_height + 1); + canvas_draw_line(canvas, x + button_width + 2, y, x + button_width + 2, y - button_height + 2); + + canvas_invert_color(canvas); + canvas_draw_icon( + canvas, x + horizontal_offset, y - button_height + vertical_offset, &I_ButtonCenter_7x7); + canvas_draw_str( + canvas, x + horizontal_offset + icon_width_with_offset, y - vertical_offset, str); + canvas_invert_color(canvas); +} + void subghz_transmitter_draw(Canvas* canvas, SubghzTransmitterModel* model) { + char buffer[64]; canvas_clear(canvas); canvas_set_color(canvas, ColorBlack); canvas_set_font(canvas, FontSecondary); - elements_multiline_text(canvas, 0, 10, string_get_cstr(model->text)); + elements_multiline_text(canvas, 0, 8, string_get_cstr(model->text)); + snprintf( + buffer, + sizeof(buffer), + "%03ld.%03ld", + model->real_frequency / 1000000 % 1000, + model->real_frequency / 1000 % 1000); + canvas_draw_str(canvas, 90, 8, buffer); if(model->protocol && model->protocol->get_upload_protocol) { - elements_button_center(canvas, "Send"); + subghz_transmitter_button_right(canvas, "Send"); } } diff --git a/applications/subghz/views/subghz_transmitter.h b/applications/subghz/views/subghz_transmitter.h index 2c1f1b72..6f289e4d 100644 --- a/applications/subghz/views/subghz_transmitter.h +++ b/applications/subghz/views/subghz_transmitter.h @@ -27,3 +27,7 @@ View* subghz_transmitter_get_view(SubghzTransmitter* subghz_transmitter); void subghz_transmitter_set_protocol( SubghzTransmitter* subghz_transmitter, SubGhzProtocolCommon* protocol); +void subghz_transmitter_set_frequency_preset( + SubghzTransmitter* subghz_transmitter, + uint32_t frequency, + FuriHalSubGhzPreset preset); diff --git a/assets/compiled/assets_icons.c b/assets/compiled/assets_icons.c index f4cfcab4..af195b64 100644 --- a/assets/compiled/assets_icons.c +++ b/assets/compiled/assets_icons.c @@ -98,6 +98,24 @@ const uint8_t *_I_Flipper_young_80x60[] = {_I_Flipper_young_80x60_0}; const uint8_t _I_DolphinFirstStart3_57x48_0[] = {0x00,0x00,0x00,0x80,0xFF,0x07,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x04,0x00,0x00,0xF8,0x03,0x01,0x00,0x00,0x08,0x00,0x00,0x04,0xBC,0x00,0x00,0x00,0x10,0x00,0x00,0x02,0xC0,0x00,0x00,0x00,0x20,0x00,0x00,0x02,0x00,0x01,0x00,0x00,0x20,0x00,0x00,0x02,0x00,0x02,0x00,0x38,0x40,0x00,0x00,0x02,0x00,0x04,0x00,0x3E,0x40,0x00,0x00,0xF4,0x03,0x08,0x80,0x07,0x80,0x00,0x00,0x5C,0x0D,0x10,0xE0,0x01,0x80,0x00,0x00,0xA8,0x3A,0x20,0xE0,0x00,0x00,0x01,0x00,0x58,0x55,0x00,0xC0,0x01,0x00,0x01,0x00,0xB0,0xAA,0x00,0x80,0x07,0x00,0x01,0x00,0x60,0x55,0x01,0x00,0x1E,0x00,0x01,0x0E,0xC0,0xAA,0x02,0xE0,0x5C,0x00,0x01,0x11,0x80,0x55,0x05,0x00,0xA9,0x00,0x01,0x21,0x00,0xAB,0x0A,0x00,0x56,0x07,0x01,0x41,0x00,0x56,0x15,0x00,0xEC,0x08,0x01,0x81,0x00,0xBF,0x2A,0x00,0x34,0x08,0x01,0x01,0xF1,0xC0,0x57,0x00,0x0C,0x08,0x01,0x02,0x0A,0x00,0xBE,0x00,0x04,0x08,0x01,0x02,0x06,0x00,0x78,0x83,0x02,0x04,0x01,0x02,0x0C,0x00,0xF0,0x7F,0x01,0x04,0x01,0x02,0xF4,0x01,0xFE,0x81,0x00,0x04,0x01,0x04,0x08,0xFF,0x6B,0x40,0x00,0x02,0x01,0x04,0x88,0x55,0x1D,0x40,0x00,0x02,0x01,0x04,0x50,0xAA,0x06,0x20,0x00,0x02,0x01,0x04,0x30,0xD4,0x01,0x20,0x00,0x01,0x01,0x04,0x10,0x68,0x00,0x10,0x00,0x01,0x01,0x04,0x18,0x18,0x00,0x10,0x00,0x01,0x01,0x08,0x18,0x06,0x80,0x10,0x00,0x01,0x01,0x08,0xE8,0x01,0x60,0x08,0x80,0x00,0x01,0x08,0x08,0x00,0x18,0x08,0x80,0x00,0x00,0x08,0x10,0x00,0x06,0x08,0x80,0x00,0x00,0x08,0x60,0xE0,0x01,0x08,0x80,0x00,0x00,0x08,0x80,0x1F,0x00,0x08,0x80,0x00,0x00,0x08,0x80,0x04,0x00,0x04,0x00,0x01,0x00,0x08,0x80,0x04,0x00,0x04,0x00,0x01,0x00,0x10,0x00,0x03,0x00,0x04,0x00,0x01,0x00,0x10,0x00,0x03,0x00,0x04,0x00,0x01,0x00,0x10,0x00,0x01,0x00,0x04,0x00,0x02,0x00,0x10,0x00,0x01,0x00,0x04,0x00,0x02,0x00,0x10,0x80,0x00,0x00,0x04,0x00,0x02,0x00,0x10,0x80,0x00,0x00,0x04,0x00,0x06,0x00,}; const uint8_t *_I_DolphinFirstStart3_57x48[] = {_I_DolphinFirstStart3_57x48_0}; +const uint8_t _I_quest_7x8_0[] = {0x1E,0x33,0x33,0x30,0x18,0x0C,0x00,0x0C,}; +const uint8_t *_I_quest_7x8[] = {_I_quest_7x8_0}; + +const uint8_t _I_unlock_7x8_0[] = {0x1C,0x22,0x02,0x4F,0x67,0x73,0x79,0x3C,}; +const uint8_t *_I_unlock_7x8[] = {_I_unlock_7x8_0}; + +const uint8_t _I_Scanning_dolph_67_61_0[] = {0x00,0x00,0xFE,0x1F,0x00,0x00,0x20,0x00,0x00,0x00,0xC0,0x01,0xE0,0x01,0x00,0x10,0x00,0x00,0x00,0x30,0x00,0x00,0x06,0x00,0x10,0x00,0x00,0x00,0x0C,0x00,0x00,0x18,0x00,0x08,0x00,0x00,0x00,0x02,0x00,0x00,0x20,0x00,0x08,0x08,0x00,0x00,0x01,0x00,0x00,0x40,0x00,0x04,0x04,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x04,0x04,0x00,0x40,0x00,0x00,0x00,0x00,0x01,0x04,0x02,0x00,0x20,0x00,0x00,0x00,0x00,0x02,0x02,0x02,0x00,0x20,0x00,0x00,0x00,0x3C,0x04,0x02,0x81,0x00,0x10,0x00,0x00,0x00,0x42,0x04,0x02,0x41,0x00,0x10,0x00,0x00,0x00,0x81,0x08,0x02,0x41,0x00,0x08,0x06,0x00,0x80,0x18,0x09,0x02,0x41,0x00,0x08,0x09,0x08,0x80,0x24,0x09,0x02,0x41,0x00,0x84,0x10,0x08,0x80,0x24,0x11,0x02,0x41,0x00,0xC4,0x10,0x10,0x80,0x24,0x11,0x02,0x81,0x00,0x44,0x10,0x10,0x80,0x24,0x11,0x02,0x02,0x00,0x46,0x20,0x20,0x80,0x24,0x11,0x04,0x02,0x00,0x2A,0x20,0x20,0x80,0x24,0x11,0x04,0x04,0x00,0x36,0x20,0x40,0x80,0x18,0x11,0x04,0x04,0x00,0x1B,0xE0,0x80,0x00,0x81,0x10,0x08,0x08,0x00,0x0D,0xE0,0x00,0x01,0x42,0x10,0x08,0x00,0x00,0x07,0xE0,0x01,0x00,0x3C,0x18,0x10,0x00,0x00,0x03,0xF0,0x01,0x00,0x00,0x14,0x10,0x00,0x00,0x01,0xF0,0x03,0x00,0x00,0x0A,0x20,0x00,0x00,0x00,0xD0,0xFF,0x01,0x00,0x08,0x00,0x00,0x00,0x00,0xD0,0xFF,0x01,0x00,0x0C,0x00,0x00,0x00,0x00,0x18,0xFF,0x00,0x00,0x0E,0x00,0x00,0x00,0x00,0x08,0x3C,0x00,0x1F,0x0E,0x00,0x00,0x00,0x00,0x18,0x00,0x60,0x80,0x06,0x00,0x00,0x00,0x00,0x0C,0x00,0x08,0x00,0x05,0x00,0x00,0x00,0x00,0x14,0x00,0x02,0x00,0x07,0x00,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x0A,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x0B,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x80,0x05,0x18,0x00,0x00,0x10,0x00,0x00,0x00,0xC0,0x02,0x20,0x00,0x00,0x10,0x00,0x00,0x00,0x40,0x05,0xC0,0x00,0x00,0x20,0x00,0x00,0x00,0xA0,0x02,0x00,0x01,0x00,0x20,0x00,0x00,0x00,0x50,0x01,0x00,0x06,0x00,0x40,0x00,0x00,0x00,0xB0,0x00,0x14,0x08,0x00,0x40,0x00,0x00,0x00,0x58,0x00,0x6A,0x30,0x00,0x40,0x00,0x00,0x00,0xAC,0x00,0xD4,0x41,0x00,0x40,0x00,0x00,0x00,0x54,0x00,0xA8,0x83,0x01,0x40,0x00,0x00,0x00,0x2A,0x00,0x50,0x0F,0x02,0x40,0x00,0x00,0x00,0x15,0x00,0xA0,0x1E,0xFC,0x5F,0x00,0x00,0x00,0x0B,0x00,0x40,0x7D,0x00,0x30,0x00,0x00,0x00,0x01,0x00,0xA0,0xFA,0x01,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x15,0x04,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0xF0,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,}; +const uint8_t *_I_Scanning_dolph_67_61[] = {_I_Scanning_dolph_67_61_0}; + +const uint8_t _I_Broadcast_dolph_67_61_0[] = {0x00,0x00,0xFE,0x1F,0x00,0x00,0x00,0x40,0x00,0x00,0xC0,0x01,0xE0,0x01,0x00,0x00,0x80,0x00,0x00,0x30,0x00,0x00,0x06,0x00,0x00,0x80,0x00,0x00,0x0C,0x00,0x00,0x18,0x00,0x00,0x00,0x01,0x00,0x02,0x00,0x00,0x20,0x00,0x00,0x01,0x01,0x00,0x01,0x00,0x00,0x40,0x00,0x00,0x02,0x02,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x02,0x02,0x40,0x00,0x00,0x00,0x00,0x01,0x00,0x04,0x02,0x20,0x00,0x00,0x00,0x00,0x02,0x00,0x04,0x04,0x20,0x00,0x00,0x00,0x3C,0x04,0x10,0x08,0x04,0x10,0x00,0x00,0x00,0x42,0x04,0x20,0x08,0x04,0x10,0x00,0x00,0x00,0x81,0x08,0x20,0x08,0x04,0x08,0x06,0x00,0x80,0x18,0x09,0x20,0x08,0x04,0x08,0x09,0x08,0x80,0x24,0x09,0x20,0x08,0x04,0x84,0x10,0x08,0x80,0x24,0x11,0x20,0x08,0x04,0xC4,0x10,0x10,0x80,0x24,0x11,0x10,0x08,0x04,0x44,0x10,0x10,0x80,0x24,0x11,0x00,0x04,0x04,0x46,0x20,0x20,0x80,0x24,0x11,0x00,0x04,0x02,0x2A,0x20,0x20,0x80,0x24,0x11,0x00,0x02,0x02,0x36,0x20,0x40,0x80,0x18,0x11,0x00,0x02,0x02,0x1B,0xE0,0x80,0x00,0x81,0x10,0x00,0x01,0x01,0x0D,0xE0,0x00,0x01,0x42,0x10,0x00,0x00,0x01,0x07,0xE0,0x01,0x00,0x3C,0x18,0x00,0x80,0x00,0x03,0xF0,0x01,0x00,0x00,0x14,0x00,0x80,0x00,0x01,0xF0,0x03,0x00,0x00,0x0A,0x00,0x40,0x00,0x00,0xD0,0xFF,0x01,0x00,0x08,0x00,0x00,0x00,0x00,0xD0,0xFF,0x01,0x00,0x0C,0x00,0x00,0x00,0x00,0x18,0xFF,0x00,0x00,0x0E,0x00,0x00,0x00,0x00,0x08,0x3C,0x00,0x1F,0x0E,0x00,0x00,0x00,0x00,0x18,0x00,0x60,0x80,0x06,0x00,0x00,0x00,0x00,0x0C,0x00,0x08,0x00,0x05,0x00,0x00,0x00,0x00,0x14,0x00,0x02,0x00,0x07,0x00,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x0A,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x0B,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x80,0x05,0x18,0x00,0x00,0x10,0x00,0x00,0x00,0xC0,0x02,0x20,0x00,0x00,0x10,0x00,0x00,0x00,0x40,0x05,0xC0,0x00,0x00,0x20,0x00,0x00,0x00,0xA0,0x02,0x00,0x01,0x00,0x20,0x00,0x00,0x00,0x50,0x01,0x00,0x06,0x00,0x40,0x00,0x00,0x00,0xB0,0x00,0x14,0x08,0x00,0x40,0x00,0x00,0x00,0x58,0x00,0x6A,0x30,0x00,0x40,0x00,0x00,0x00,0xAC,0x00,0xD4,0x41,0x00,0x40,0x00,0x00,0x00,0x54,0x00,0xA8,0x83,0x01,0x40,0x00,0x00,0x00,0x2A,0x00,0x50,0x0F,0x02,0x40,0x00,0x00,0x00,0x15,0x00,0xA0,0x1E,0xFC,0x5F,0x00,0x00,0x00,0x0B,0x00,0x40,0x7D,0x00,0x30,0x00,0x00,0x00,0x01,0x00,0xA0,0xFA,0x01,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x15,0x04,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0xF0,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,}; +const uint8_t *_I_Broadcast_dolph_67_61[] = {_I_Broadcast_dolph_67_61_0}; + +const uint8_t _I_lock_7x8_0[] = {0x1C,0x22,0x22,0x7F,0x7F,0x77,0x7F,0x3E,}; +const uint8_t *_I_lock_7x8[] = {_I_lock_7x8_0}; + +const uint8_t _I_Top_frame_128_13_0[] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0xFC,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x3F,}; +const uint8_t *_I_Top_frame_128_13[] = {_I_Top_frame_128_13_0}; + const uint8_t _I_PassportBottom_128x17_0[] = {0x2C,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x8F,0x34,0x00,0x00,0x00,0x00,0x00,0x00,0x58,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x95,0x2C,0x00,0x00,0x00,0x00,0x00,0x00,0xA8,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0x9A,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x58,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x95,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xA8,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0x9A,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x58,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x95,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0xA8,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0x9A,0xF2,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x8F,0xF9,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x0D,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x05,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x05,0xF2,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x3F,0x05,0xFA,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x1F,0x09,0x79,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0xD5,0x80,0x55,0xD5,0x00,0xF3,0xCC,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0x6A,0x00,0xAB,0x6A,0x00,0x06,0x86,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x3F,0x00,0xFE,0x3F,0x00,0xFC,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}; const uint8_t *_I_PassportBottom_128x17[] = {_I_PassportBottom_128x17_0}; @@ -460,6 +478,12 @@ const Icon I_DolphinFirstStart8_56x51 = {.width=56,.height=51,.frame_count=1,.fr const Icon I_DolphinFirstStart7_61x51 = {.width=61,.height=51,.frame_count=1,.frame_rate=0,.frames=_I_DolphinFirstStart7_61x51}; const Icon I_Flipper_young_80x60 = {.width=80,.height=60,.frame_count=1,.frame_rate=0,.frames=_I_Flipper_young_80x60}; const Icon I_DolphinFirstStart3_57x48 = {.width=57,.height=48,.frame_count=1,.frame_rate=0,.frames=_I_DolphinFirstStart3_57x48}; +const Icon I_quest_7x8 = {.width=7,.height=8,.frame_count=1,.frame_rate=0,.frames=_I_quest_7x8}; +const Icon I_unlock_7x8 = {.width=7,.height=8,.frame_count=1,.frame_rate=0,.frames=_I_unlock_7x8}; +const Icon I_Scanning_dolph_67_61 = {.width=67,.height=61,.frame_count=1,.frame_rate=0,.frames=_I_Scanning_dolph_67_61}; +const Icon I_Broadcast_dolph_67_61 = {.width=67,.height=61,.frame_count=1,.frame_rate=0,.frames=_I_Broadcast_dolph_67_61}; +const Icon I_lock_7x8 = {.width=7,.height=8,.frame_count=1,.frame_rate=0,.frames=_I_lock_7x8}; +const Icon I_Top_frame_128_13 = {.width=128,.height=13,.frame_count=1,.frame_rate=0,.frames=_I_Top_frame_128_13}; const Icon I_PassportBottom_128x17 = {.width=128,.height=17,.frame_count=1,.frame_rate=0,.frames=_I_PassportBottom_128x17}; const Icon I_DoorLeft_8x56 = {.width=8,.height=56,.frame_count=1,.frame_rate=0,.frames=_I_DoorLeft_8x56}; const Icon I_DoorLocked_10x56 = {.width=10,.height=56,.frame_count=1,.frame_rate=0,.frames=_I_DoorLocked_10x56}; diff --git a/assets/compiled/assets_icons.h b/assets/compiled/assets_icons.h index faba6981..81cf0232 100644 --- a/assets/compiled/assets_icons.h +++ b/assets/compiled/assets_icons.h @@ -29,6 +29,12 @@ extern const Icon I_DolphinFirstStart8_56x51; extern const Icon I_DolphinFirstStart7_61x51; extern const Icon I_Flipper_young_80x60; extern const Icon I_DolphinFirstStart3_57x48; +extern const Icon I_quest_7x8; +extern const Icon I_unlock_7x8; +extern const Icon I_Scanning_dolph_67_61; +extern const Icon I_Broadcast_dolph_67_61; +extern const Icon I_lock_7x8; +extern const Icon I_Top_frame_128_13; extern const Icon I_PassportBottom_128x17; extern const Icon I_DoorLeft_8x56; extern const Icon I_DoorLocked_10x56; diff --git a/assets/icons/GubGHz/Broadcast_dolph_67-61.png b/assets/icons/GubGHz/Broadcast_dolph_67-61.png new file mode 100644 index 0000000000000000000000000000000000000000..9864e0857d0be3d8e65500c8aef368b6f8bd4185 GIT binary patch literal 3894 zcmaJ@c|26@+dsA%vSnYAG2*Gjj6pFO`!b45W3QAk2E%NPu?&$V6xp&RONtT=X(ic` zeT^ca>?AankgeYF{GOiQ`^VdRKA&^Wbzk@O{a)+2Kj#|yl(_((3?Bdh0v0F}4Et@& zzL6j<_Vcywfdv5IGbR`tqb-b$!BiT>oj}9`K)^t@jlW~^nuOl)8eYiWsDI&cIx!4@ zC^A9K!cKREZvfaU!XgF@kyrWb#l-h!q3r6zd-+h=SI2S>mU|e+Ts;$OcTW48{7}L3 z;6T>={N{(v%IU1>txiUlQ0QI}<)o>*UVsiJQWw!LpJ0uuZ>b996i1D4gN3Ks>O6QF z0APWO5fDNz)!*WHL;*MfYOmS>k*3jK5fx}<2LPM|j6g)D_i!X)fMzw@W-*{y3MjRC z>c$78005D3$p``z2>^57E%bPR{=(!TNudAkzCsWX#{py6c&F;U3C1qjVBI?@h+wK)Of{h}RQU`wuCSWnGJ;RR}B zIf?_QZA7=Hr`)HBtnUqXe|j%aAbJXm!#^vpb8-X1r@B}J7bYkBxTsAWrM@-Zg=c{Q zd%$ye-C1LhH}?$R+raf$hW3`h{+v7LW?i{`e0%oHE4kjOf{n-O{n8kvjKqelvUh(D z1}*>>Zy971*XBiRU&NCAN-*)$ZQMrcka zduYNLYXFd3vz}m}!U1%o=Z^zG@E`n{sXnT!bZC$Lih3AkxDa^wyj03^o!6o5Apyt(Z!4^^~wDr@7v9`Wn1^ATJZsnCsI`*A#LNO}p#eE%R(YGW5mW zg6@-FeCa@NOgt{MTV2ro`bX@!>(Qnz*BoV(nKT`@6S+5UpMLbS)G-E1% zQ`oPNqjdf+LD37zr~`s6HzrQ;DJUhvE%sP=qXto``8N4_J;H=6OXb-_Qp@KF(34Om zI6bK>Q7F;+#%9Z#i83)n!__fM-n$1d`6(hNwD9_q-1lz7jWTkJPInaMyayFsMch7P zLCW<*Lv5l9MKyhIDRpE@7`NrC=Jme4Merc3c|vFC6}+D!_M4`^P4DskvU_HFCgQt4 zzd)2gL=(#OptQGikaU4mnKU%R@;=YI^o(X(*ax_5hR02zn-n|8!>flci6^y+q#{!7 zQ$tdxi)`(D?DTsXMSE-?+6g^8Zy$W$%}{+I-G*Xav+ z)fcwIH*f+^q9V<5qfmLaxUxp+I0cDDIDXO5sE=mPHG9PSrj_g2C+l;TemtA9e$XIG z8)Kg$ccy!id-l}D4i3S_$0G|mAG1z$Ds&2T2B~tX>Z?BP^D1^P4kHDBI}qZOwsA}a=cyT0nZ!_6{gcvo6i1ZO^Vo3D_*=dDP7 zW%aST<&VKMK}Qp%iR#+8h4w_;7w?;d^6rHzqYw7Bc~&IVd**dpQdq;0?Z$2`_>}R&j#q0EDdFNoO zKUNNI#YNsT&1yIido;EwZ6NJZ8&8^5+8Xnwy`DY8e#QO+)1vR(?2%bgp92vs>yXKx ziO6hw@t`=fxZW?5G%PkImT;)&(25OtKz(j&j&JVP+^%_@RqU$LDrvP#u6>_~T;Fl} z@k=ziZ@V9nS~;6Ps`;j{zVOYAgNLlg9iQxFEy?>Q6Wc`6{n90ENChzkZrfiGz8zjr{`@)*z*v0no?1IdKy5+=a=y|{M zPUknP_FF&AQqJjvk(vkV&yG~J1-T&fkob+x87{p>J^e?k$m7VZZt+%7w)h#@4OqLf<^I0C@ljo%Vc`(U{dLQk_7|Y5Bj&`b zjp0WCYj<4VAKwLcvX zHs0`zvNrQ=)Zn$os4$YGZ@g4owz4sUnnx$9ybOEaMlA>w%Pz)E%3dIy_)NbO=(Q5x z@vNh@gG&pmHGj7K1#@ue&e6Qp!0gM;ZT8#656h}QDi8G4eDV)k7L1S+KmM7OGFSOr zCBVVE$~1U|-19B`Q-X}EY(>pf$ft61f9r;vgrIvtyH`zFvtD!xap+M^%@bY{=4jl0 z6oNXL8A=(*oWJG&oO%WHYUkVyWf4S57X6Q}FaK`1b70@h-q0)n>@nx#! zk#doDs#ssH=Vi;Cmou*}`xU}cAIJGNX(c%1?7I;d23vKU!{G!LO}kD?x(rOe{j z+U6Z}OX%ONW{-EX-d*1Cs_pgp@Z*D;^KC{It8q@YjI8`=U%67n$`8NQc}ai1ZXjPC_g}-sqg4DZk!DkM@|ioA)Z3DaIva z%gf6O$W$%4btaD%JSh>qcW>aD3f@|;=}lkyxdmOjvb-6pqqLX( zS1C<5b)?%+-0A*U8XhooqqyS179^|(9)riaF)p^?bpe1&nPBTkceJuZ;3y@gz*DxkKyRFm z8$@3ZtQ&w}6Oiz9EI5EfB>Nx&kdVK55o~!!4TXUJHlceXA^!==(FzSVrqJ-sp+=#3K-G10bf7Re6b@HqTd4Xl$aHLgD%nTzH-ib@2S+1N=>!TH zyu*lfrTEg35O%2l$$>=umzM1FPo3Bmg9c!!P<1ufPENlKt*rikQxfT4YacoW|KE83 zPhuZi1{Dv*;C(2*G#tBg?ut9Es0d>k9!satY$+7t?=qr2DRhdDCxr@z!__pw2d%I; z0(nPs=x>OX6~cn-L&uVFcncFGgiWGGAh;pajp0XiOkqZ5+S*#`>ZV3UaM)234Kp1b zO;b&np$7an)`WudCE>~R-&nW*VvYZZ-5CcGmF?LCPb2u@-OOkd68P_|5rjX-qVq?- zf3R+Uj>YhgSSULf=uU6{SFeAo*aNg9{yVzt#lORkC$lG>#vbht>gjXr&teza($@6X zuU~A@uI^n30C1REm>Ajy49ullkn3Um+;+cy(FM77i#6Ok#1*j*!awEG%|rHT^5p->W@OOv^>5}&SA3&$RZp_d!k*Weq>iYI2aoY9c!2Iy3N%7uaK{$HRifI=$N0ER z+&e)@&YBHG^bqmw-a?R#f*?v)0R8l_AzBJ+1+%&5QLpt8Y*rwhmApIrfY3yz94A!Z xCd`bycQf+D7CfjpVmNF|yzw#&F>W5p0i1Zi(ILuuy0UZhSeTwNDKT;h{~yW1(>4GA literal 0 HcmV?d00001 diff --git a/assets/icons/GubGHz/Scanning_dolph_67-61.png b/assets/icons/GubGHz/Scanning_dolph_67-61.png new file mode 100644 index 0000000000000000000000000000000000000000..4f9ea8d7d2b73faa929df7707673bb8220010ec8 GIT binary patch literal 3518 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 a9|QyVQ~@!E@+ey_4zMz}H7hmoyzn0`d`!~- literal 0 HcmV?d00001 diff --git a/assets/icons/GubGHz/quest_7x8.png b/assets/icons/GubGHz/quest_7x8.png new file mode 100644 index 0000000000000000000000000000000000000000..6825247fbeaf98b4d0d9f8aa15d4f2c5f45dcf3c GIT binary patch literal 3675 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 MrJY5ondim-0h+K&wEzGB literal 0 HcmV?d00001 diff --git a/firmware/targets/f6/furi-hal/furi-hal-delay.c b/firmware/targets/f6/furi-hal/furi-hal-delay.c index e886e23e..52de8715 100644 --- a/firmware/targets/f6/furi-hal/furi-hal-delay.c +++ b/firmware/targets/f6/furi-hal/furi-hal-delay.c @@ -28,3 +28,7 @@ void delay(float milliseconds) { (void)result; furi_assert(result == osOK); } + +uint32_t millis(void){ + return HAL_GetTick(); +} diff --git a/firmware/targets/f6/furi-hal/furi-hal-irda.c b/firmware/targets/f6/furi-hal/furi-hal-irda.c index 7e3d371f..7c5d832b 100644 --- a/firmware/targets/f6/furi-hal/furi-hal-irda.c +++ b/firmware/targets/f6/furi-hal/furi-hal-irda.c @@ -411,7 +411,9 @@ static void furi_hal_irda_tx_fill_buffer_last(uint8_t buf_num) { furi_assert(irda_tim_tx.data_callback); IrdaTxBuf* buffer = &irda_tim_tx.buffer[buf_num]; furi_assert(buffer->data != NULL); + (void)buffer->data; furi_assert(buffer->polarity != NULL); + (void)buffer->polarity; irda_tim_tx.buffer[buf_num].data[0] = 0; // 1 pulse irda_tim_tx.buffer[buf_num].polarity[0] = IRDA_TX_CCMR_LOW; diff --git a/firmware/targets/f6/furi-hal/furi-hal-subghz.c b/firmware/targets/f6/furi-hal/furi-hal-subghz.c index 93331cb7..679eea74 100644 --- a/firmware/targets/f6/furi-hal/furi-hal-subghz.c +++ b/firmware/targets/f6/furi-hal/furi-hal-subghz.c @@ -11,14 +11,14 @@ static volatile SubGhzState furi_hal_subghz_state = SubGhzStateInit; -static const uint8_t furi_hal_subghz_preset_ook_async_regs[][2] = { +static const uint8_t furi_hal_subghz_preset_ook_270khz_async_regs[][2] = { // https://e2e.ti.com/support/wireless-connectivity/sub-1-ghz-group/sub-1-ghz/f/sub-1-ghz-forum/382066/cc1101---don-t-know-the-correct-registers-configuration /* GPIO GD0 */ { CC1101_IOCFG0, 0x0D }, // GD0 as async serial data output/input /* FIFO and internals */ - { CC1101_FIFOTHR, 0x47 }, // The only important bit is ADC_RETENTION + { CC1101_FIFOTHR, 0x47 }, // The only important bit is ADC_RETENTION, FIFO Tx=33 Rx=32 /* Packet engine */ { CC1101_PKTCTRL0, 0x32 }, // Async, continious, no whitening @@ -66,6 +66,116 @@ static const uint8_t furi_hal_subghz_preset_ook_async_regs[][2] = { { 0, 0 }, }; +static const uint8_t furi_hal_subghz_preset_ook_650khz_async_regs[][2] = { + // https://e2e.ti.com/support/wireless-connectivity/sub-1-ghz-group/sub-1-ghz/f/sub-1-ghz-forum/382066/cc1101---don-t-know-the-correct-registers-configuration + + /* GPIO GD0 */ + { CC1101_IOCFG0, 0x0D }, // GD0 as async serial data output/input + + /* FIFO and internals */ + { CC1101_FIFOTHR, 0x07 }, // The only important bit is ADC_RETENTION + + /* Packet engine */ + { CC1101_PKTCTRL0, 0x32 }, // Async, continious, no whitening + + /* Frequency Synthesizer Control */ + { CC1101_FSCTRL1, 0x06 }, // IF = (26*10^6) / (2^10) * 0x06 = 152343.75Hz + + // Modem Configuration + { CC1101_MDMCFG0, 0x00 }, // Channel spacing is 25kHz + { CC1101_MDMCFG1, 0x00 }, // Channel spacing is 25kHz + { CC1101_MDMCFG2, 0x30 }, // Format ASK/OOK, No preamble/sync + { CC1101_MDMCFG3, 0x32 }, // Data rate is 3.79372 kBaud + { CC1101_MDMCFG4, 0x17 }, // Rx BW filter is 650.000kHz + + /* Main Radio Control State Machine */ + { CC1101_MCSM0, 0x18 }, // Autocalibrate on idle-to-rx/tx, PO_TIMEOUT is 64 cycles(149-155us) + + /* Frequency Offset Compensation Configuration */ + { CC1101_FOCCFG, 0x18 }, // no frequency offset compensation, POST_K same as PRE_K, PRE_K is 4K, GATE is off + + /* Automatic Gain Control */ + { CC1101_AGCTRL0, 0x40 }, // 01 - Low hysteresis, small asymmetric dead zone, medium gain; 00 - 8 samples agc; 00 - Normal AGC, 00 - 4dB boundary + { CC1101_AGCTRL1, 0x00 }, // 0; 0 - LNA 2 gain is decreased to minimum before decreasing LNA gain; 00 - Relative carrier sense threshold disabled; 0000 - RSSI to MAIN_TARGET + { CC1101_AGCTRL2, 0x03 }, // 00 - DVGA all; 000 - MAX LNA+LNA2; 011 - MAIN_TARGET 24 dB + + /* Wake on radio and timeouts control */ + { CC1101_WORCTRL, 0xFB }, // WOR_RES is 2^15 periods (0.91 - 0.94 s) 16.5 - 17.2 hours + + /* Frontend configuration */ + { CC1101_FREND0, 0x11 }, // Adjusts current TX LO buffer + high is PATABLE[1] + { CC1101_FREND1, 0xB6 }, // + + /* Frequency Synthesizer Calibration, valid for 433.92 */ + { CC1101_FSCAL3, 0xE9 }, + { CC1101_FSCAL2, 0x2A }, + { CC1101_FSCAL1, 0x00 }, + { CC1101_FSCAL0, 0x1F }, + + /* Magic f4ckery */ + { CC1101_TEST2, 0x88 }, + { CC1101_TEST1, 0x31 }, + { CC1101_TEST0, 0x09 }, // VCO selection calibration stage is disabled + + /* End */ + { 0, 0 }, +}; +static const uint8_t furi_hal_subghz_preset_2fsk_async_regs[][2] = { + // https://e2e.ti.com/support/wireless-connectivity/sub-1-ghz-group/sub-1-ghz/f/sub-1-ghz-forum/382066/cc1101---don-t-know-the-correct-registers-configuration + + /* GPIO GD0 */ + { CC1101_IOCFG0, 0x0D }, // GD0 as async serial data output/input + + /* FIFO and internals */ + { CC1101_FIFOTHR, 0x47 }, // The only important bit is ADC_RETENTION + + /* Packet engine */ + { CC1101_PKTCTRL0, 0x32 }, // Async, continious, no whitening + + /* Frequency Synthesizer Control */ + { CC1101_FSCTRL1, 0x06 }, // IF = (26*10^6) / (2^10) * 0x06 = 152343.75Hz + + // Modem Configuration + { CC1101_MDMCFG0, 0xF8 }, + { CC1101_MDMCFG1, 0x00 }, // No preamble/sync + { CC1101_MDMCFG2, 0x80 }, // Format 2-FSK/FM, No preamble/sync, Disable (current optimized) + { CC1101_MDMCFG3, 0x83 }, // Data rate is 9.59587 kBaud + { CC1101_MDMCFG4, 0x88 }, // Rx BW filter is 203.125000kHz + + { CC1101_DEVIATN, 0x14}, //Deviation 4.760742 khz + + /* Main Radio Control State Machine */ + { CC1101_MCSM0, 0x18 }, // Autocalibrate on idle-to-rx/tx, PO_TIMEOUT is 64 cycles(149-155us) + + /* Frequency Offset Compensation Configuration */ + { CC1101_FOCCFG, 0x18 }, // no frequency offset compensation, POST_K same as PRE_K, PRE_K is 4K, GATE is off + + /* Automatic Gain Control */ + { CC1101_AGCTRL0, 0x40 }, // 01 - Low hysteresis, small asymmetric dead zone, medium gain; 00 - 8 samples agc; 00 - Normal AGC, 00 - 4dB boundary + { CC1101_AGCTRL1, 0x00 }, // 0; 0 - LNA 2 gain is decreased to minimum before decreasing LNA gain; 00 - Relative carrier sense threshold disabled; 0000 - RSSI to MAIN_TARGET + { CC1101_AGCTRL2, 0x03 }, // 00 - DVGA all; 000 - MAX LNA+LNA2; 011 - MAIN_TARGET 24 dB + + /* Wake on radio and timeouts control */ + { CC1101_WORCTRL, 0xFB }, // WOR_RES is 2^15 periods (0.91 - 0.94 s) 16.5 - 17.2 hours + + /* Frontend configuration */ + { CC1101_FREND0, 0x10 }, // Adjusts current TX LO buffer + { CC1101_FREND1, 0xB6 }, // + + /* Frequency Synthesizer Calibration, valid for 433.92 */ + { CC1101_FSCAL3, 0xE9 }, + { CC1101_FSCAL2, 0x2A }, + { CC1101_FSCAL1, 0x00 }, + { CC1101_FSCAL0, 0x1F }, + + /* Magic f4ckery */ + { CC1101_TEST2, 0x81 }, // FIFOTHR ADC_RETENTION=1 matched value + { CC1101_TEST1, 0x35 }, // FIFOTHR ADC_RETENTION=1 matched value + { CC1101_TEST0, 0x09 }, // VCO selection calibration stage is disabled + + /* End */ + { 0, 0 }, +}; static const uint8_t furi_hal_subghz_preset_ook_async_patable[8] = { 0x00, 0xC0, // 10dBm 0xC0, 7dBm 0xC8, 5dBm 0x84, 0dBm 0x60, -10dBm 0x34, -15dBm 0x1D, -20dBm 0x0E, -30dBm 0x12 @@ -76,6 +186,16 @@ static const uint8_t furi_hal_subghz_preset_ook_async_patable[8] = { 0x00, 0x00 }; +static const uint8_t furi_hal_subghz_preset_2fsk_async_patable[8] = { + 0xC0, // 10dBm 0xC0, 7dBm 0xC8, 5dBm 0x84, 0dBm 0x60, -10dBm 0x34, -15dBm 0x1D, -20dBm 0x0E, -30dBm 0x12 + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00 +}; void furi_hal_subghz_init() { furi_assert(furi_hal_subghz_state == SubGhzStateInit); @@ -143,10 +263,16 @@ void furi_hal_subghz_dump_state() { } void furi_hal_subghz_load_preset(FuriHalSubGhzPreset preset) { - if(preset == FuriHalSubGhzPresetOokAsync) { - furi_hal_subghz_load_registers(furi_hal_subghz_preset_ook_async_regs); + if(preset == FuriHalSubGhzPresetOok650Async) { + furi_hal_subghz_load_registers(furi_hal_subghz_preset_ook_650khz_async_regs); furi_hal_subghz_load_patable(furi_hal_subghz_preset_ook_async_patable); - } else { + } else if(preset == FuriHalSubGhzPresetOok270Async){ + furi_hal_subghz_load_registers(furi_hal_subghz_preset_ook_270khz_async_regs); + furi_hal_subghz_load_patable(furi_hal_subghz_preset_ook_async_patable); + } else if(preset == FuriHalSubGhzPreset2FSKAsync){ + furi_hal_subghz_load_registers(furi_hal_subghz_preset_2fsk_async_regs); + furi_hal_subghz_load_patable(furi_hal_subghz_preset_2fsk_async_patable); + }else { furi_check(0); } } diff --git a/firmware/targets/furi-hal-include/furi-hal-delay.h b/firmware/targets/furi-hal-include/furi-hal-delay.h index 0f6c0a76..3ba2836f 100644 --- a/firmware/targets/furi-hal-include/furi-hal-delay.h +++ b/firmware/targets/furi-hal-include/furi-hal-delay.h @@ -17,6 +17,9 @@ void delay(float milliseconds); /** Delay in microseconds */ void delay_us(float microseconds); +/** Get current millisecond */ +uint32_t millis(void); + #ifdef __cplusplus } #endif diff --git a/firmware/targets/furi-hal-include/furi-hal-subghz.h b/firmware/targets/furi-hal-include/furi-hal-subghz.h index bf80d7e1..653a343c 100644 --- a/firmware/targets/furi-hal-include/furi-hal-subghz.h +++ b/firmware/targets/furi-hal-include/furi-hal-subghz.h @@ -11,7 +11,9 @@ extern "C" { /** Radio Presets */ typedef enum { - FuriHalSubGhzPresetOokAsync, /** OOK, asynchronous */ + FuriHalSubGhzPresetOok270Async, /** OOK, bandwidth 270kHz, asynchronous */ + FuriHalSubGhzPresetOok650Async, /** OOK, bandwidth 650kHz, asynchronous */ + FuriHalSubGhzPreset2FSKAsync, /** FM, asynchronous */ } FuriHalSubGhzPreset; /** Switchable Radio Paths */ diff --git a/lib/irda/worker/irda_worker.c b/lib/irda/worker/irda_worker.c index 62d4363f..6d4f0f4b 100644 --- a/lib/irda/worker/irda_worker.c +++ b/lib/irda/worker/irda_worker.c @@ -267,10 +267,10 @@ void irda_worker_rx_stop(IrdaWorker* instance) { osEventFlagsSet(instance->events, IRDA_WORKER_EXIT); furi_thread_join(instance->thread); - BaseType_t xReturn = pdFAIL; - xReturn = xStreamBufferReset(instance->stream); + BaseType_t xReturn = xStreamBufferReset(instance->stream); furi_assert(xReturn == pdPASS); - instance->state = IrdaWorkerStateIdle; + (void)xReturn; + instance->state = IrdaWorkerStateIdle; } @@ -424,6 +424,7 @@ static bool irda_worker_tx_fill_buffer(IrdaWorker* instance) { } uint32_t written_size = xStreamBufferSend(instance->stream, &timing, sizeof(IrdaWorkerTiming), 0); furi_assert(sizeof(IrdaWorkerTiming) == written_size); + (void)written_size; } return new_data_available; @@ -528,6 +529,7 @@ void irda_worker_tx_stop(IrdaWorker* instance) { BaseType_t xReturn = pdFAIL; xReturn = xStreamBufferReset(instance->stream); furi_assert(xReturn == pdPASS); + (void)xReturn; instance->state = IrdaWorkerStateIdle; } diff --git a/lib/subghz/protocols/subghz_protocol.c b/lib/subghz/protocols/subghz_protocol.c index f0b93066..c2e3efec 100644 --- a/lib/subghz/protocols/subghz_protocol.c +++ b/lib/subghz/protocols/subghz_protocol.c @@ -31,7 +31,6 @@ typedef enum { SubGhzProtocolTypeMax, } SubGhzProtocolType; - struct SubGhzProtocol { SubGhzKeystore* keystore; @@ -49,7 +48,7 @@ static void subghz_protocol_text_rx_callback(SubGhzProtocolCommon* parser, void* string_t output; string_init(output); subghz_protocol_common_to_str((SubGhzProtocolCommon*)parser, output); - if (instance->text_callback) { + if(instance->text_callback) { instance->text_callback(output, instance->text_callback_context); } else { printf(string_get_cstr(output)); @@ -59,9 +58,9 @@ static void subghz_protocol_text_rx_callback(SubGhzProtocolCommon* parser, void* static void subghz_protocol_parser_rx_callback(SubGhzProtocolCommon* parser, void* context) { SubGhzProtocol* instance = context; - if (instance->parser_callback) { + if(instance->parser_callback) { instance->parser_callback(parser, instance->parser_callback_context); - } + } } SubGhzProtocol* subghz_protocol_alloc() { @@ -69,16 +68,26 @@ SubGhzProtocol* subghz_protocol_alloc() { instance->keystore = subghz_keystore_alloc(); - instance->protocols[SubGhzProtocolTypeCame] =(SubGhzProtocolCommon*)subghz_protocol_came_alloc(); - instance->protocols[SubGhzProtocolTypeKeeloq] = (SubGhzProtocolCommon*)subghz_protocol_keeloq_alloc(instance->keystore); - instance->protocols[SubGhzProtocolTypePrinceton] = (SubGhzProtocolCommon*)subghz_decoder_princeton_alloc(); - instance->protocols[SubGhzProtocolTypeNiceFlo] = (SubGhzProtocolCommon*)subghz_protocol_nice_flo_alloc(); - instance->protocols[SubGhzProtocolTypeNiceFlorS] = (SubGhzProtocolCommon*)subghz_protocol_nice_flor_s_alloc(); - instance->protocols[SubGhzProtocolTypeGateTX] = (SubGhzProtocolCommon*)subghz_protocol_gate_tx_alloc(); - instance->protocols[SubGhzProtocolTypeIDo] = (SubGhzProtocolCommon*)subghz_protocol_ido_alloc(); - instance->protocols[SubGhzProtocolTypeFaacSLH] = (SubGhzProtocolCommon*)subghz_protocol_faac_slh_alloc(); - instance->protocols[SubGhzProtocolTypeNeroSketch] = (SubGhzProtocolCommon*)subghz_protocol_nero_sketch_alloc(); - instance->protocols[SubGhzProtocolTypeStarLine] = (SubGhzProtocolCommon*)subghz_protocol_star_line_alloc(instance->keystore); + instance->protocols[SubGhzProtocolTypeCame] = + (SubGhzProtocolCommon*)subghz_protocol_came_alloc(); + instance->protocols[SubGhzProtocolTypeKeeloq] = + (SubGhzProtocolCommon*)subghz_protocol_keeloq_alloc(instance->keystore); + instance->protocols[SubGhzProtocolTypePrinceton] = + (SubGhzProtocolCommon*)subghz_decoder_princeton_alloc(); + instance->protocols[SubGhzProtocolTypeNiceFlo] = + (SubGhzProtocolCommon*)subghz_protocol_nice_flo_alloc(); + instance->protocols[SubGhzProtocolTypeNiceFlorS] = + (SubGhzProtocolCommon*)subghz_protocol_nice_flor_s_alloc(); + instance->protocols[SubGhzProtocolTypeGateTX] = + (SubGhzProtocolCommon*)subghz_protocol_gate_tx_alloc(); + instance->protocols[SubGhzProtocolTypeIDo] = + (SubGhzProtocolCommon*)subghz_protocol_ido_alloc(); + instance->protocols[SubGhzProtocolTypeFaacSLH] = + (SubGhzProtocolCommon*)subghz_protocol_faac_slh_alloc(); + instance->protocols[SubGhzProtocolTypeNeroSketch] = + (SubGhzProtocolCommon*)subghz_protocol_nero_sketch_alloc(); + instance->protocols[SubGhzProtocolTypeStarLine] = + (SubGhzProtocolCommon*)subghz_protocol_star_line_alloc(instance->keystore); return instance; } @@ -87,15 +96,23 @@ void subghz_protocol_free(SubGhzProtocol* instance) { furi_assert(instance); subghz_protocol_came_free((SubGhzProtocolCame*)instance->protocols[SubGhzProtocolTypeCame]); - subghz_protocol_keeloq_free((SubGhzProtocolKeeloq*)instance->protocols[SubGhzProtocolTypeKeeloq]); - subghz_decoder_princeton_free((SubGhzDecoderPrinceton*)instance->protocols[SubGhzProtocolTypePrinceton]); - subghz_protocol_nice_flo_free((SubGhzProtocolNiceFlo*)instance->protocols[SubGhzProtocolTypeNiceFlo]); - subghz_protocol_nice_flor_s_free((SubGhzProtocolNiceFlorS*)instance->protocols[SubGhzProtocolTypeNiceFlorS]); - subghz_protocol_gate_tx_free((SubGhzProtocolGateTX*)instance->protocols[SubGhzProtocolTypeGateTX]); + subghz_protocol_keeloq_free( + (SubGhzProtocolKeeloq*)instance->protocols[SubGhzProtocolTypeKeeloq]); + subghz_decoder_princeton_free( + (SubGhzDecoderPrinceton*)instance->protocols[SubGhzProtocolTypePrinceton]); + subghz_protocol_nice_flo_free( + (SubGhzProtocolNiceFlo*)instance->protocols[SubGhzProtocolTypeNiceFlo]); + subghz_protocol_nice_flor_s_free( + (SubGhzProtocolNiceFlorS*)instance->protocols[SubGhzProtocolTypeNiceFlorS]); + subghz_protocol_gate_tx_free( + (SubGhzProtocolGateTX*)instance->protocols[SubGhzProtocolTypeGateTX]); subghz_protocol_ido_free((SubGhzProtocolIDo*)instance->protocols[SubGhzProtocolTypeIDo]); - subghz_protocol_faac_slh_free((SubGhzProtocolFaacSLH*)instance->protocols[SubGhzProtocolTypeFaacSLH]); - subghz_protocol_nero_sketch_free((SubGhzProtocolNeroSketch*)instance->protocols[SubGhzProtocolTypeNeroSketch]); - subghz_protocol_star_line_free((SubGhzProtocolStarLine*)instance->protocols[SubGhzProtocolTypeStarLine]); + subghz_protocol_faac_slh_free( + (SubGhzProtocolFaacSLH*)instance->protocols[SubGhzProtocolTypeFaacSLH]); + subghz_protocol_nero_sketch_free( + (SubGhzProtocolNeroSketch*)instance->protocols[SubGhzProtocolTypeNeroSketch]); + subghz_protocol_star_line_free( + (SubGhzProtocolStarLine*)instance->protocols[SubGhzProtocolTypeStarLine]); subghz_keystore_free(instance->keystore); @@ -115,32 +132,40 @@ SubGhzProtocolCommon* subghz_protocol_get_by_name(SubGhzProtocol* instance, cons return result; } -void subghz_protocol_enable_dump_text(SubGhzProtocol* instance, SubGhzProtocolTextCallback callback, void* context) { +void subghz_protocol_enable_dump_text( + SubGhzProtocol* instance, + SubGhzProtocolTextCallback callback, + void* context) { furi_assert(instance); for(size_t i = 0; i < SubGhzProtocolTypeMax; i++) { - subghz_protocol_common_set_callback(instance->protocols[i], subghz_protocol_text_rx_callback, instance); + subghz_protocol_common_set_callback( + instance->protocols[i], subghz_protocol_text_rx_callback, instance); } instance->text_callback = callback; instance->text_callback_context = context; } -void subghz_protocol_enable_dump(SubGhzProtocol* instance, SubGhzProtocolCommonCallbackDump callback, void* context) { +void subghz_protocol_enable_dump( + SubGhzProtocol* instance, + SubGhzProtocolCommonCallbackDump callback, + void* context) { furi_assert(instance); for(size_t i = 0; i < SubGhzProtocolTypeMax; i++) { - subghz_protocol_common_set_callback(instance->protocols[i], subghz_protocol_parser_rx_callback, instance); + subghz_protocol_common_set_callback( + instance->protocols[i], subghz_protocol_parser_rx_callback, instance); } instance->parser_callback = callback; instance->parser_callback_context = context; } - void subghz_protocol_load_nice_flor_s_file(SubGhzProtocol* instance, const char* file_name) { // subghz_protocol_nice_flor_s_name_file(instance->nice_flor_s, file_name); - subghz_protocol_nice_flor_s_name_file((SubGhzProtocolNiceFlorS*) instance->protocols[SubGhzProtocolTypeNiceFlorS], file_name); + subghz_protocol_nice_flor_s_name_file( + (SubGhzProtocolNiceFlorS*)instance->protocols[SubGhzProtocolTypeNiceFlorS], file_name); } void subghz_protocol_load_keeloq_file(SubGhzProtocol* instance, const char* file_name) { @@ -148,29 +173,51 @@ void subghz_protocol_load_keeloq_file(SubGhzProtocol* instance, const char* file } void subghz_protocol_reset(SubGhzProtocol* instance) { - subghz_protocol_came_reset((SubGhzProtocolCame*)instance->protocols[SubGhzProtocolTypeCame]); - subghz_protocol_keeloq_reset((SubGhzProtocolKeeloq*)instance->protocols[SubGhzProtocolTypeKeeloq]); - subghz_decoder_princeton_reset((SubGhzDecoderPrinceton*)instance->protocols[SubGhzProtocolTypePrinceton]); - subghz_protocol_nice_flo_reset((SubGhzProtocolNiceFlo*)instance->protocols[SubGhzProtocolTypeNiceFlo]); - subghz_protocol_nice_flor_s_reset((SubGhzProtocolNiceFlorS*)instance->protocols[SubGhzProtocolTypeNiceFlorS]); - subghz_protocol_gate_tx_reset((SubGhzProtocolGateTX*)instance->protocols[SubGhzProtocolTypeGateTX]); + subghz_protocol_keeloq_reset( + (SubGhzProtocolKeeloq*)instance->protocols[SubGhzProtocolTypeKeeloq]); + subghz_decoder_princeton_reset( + (SubGhzDecoderPrinceton*)instance->protocols[SubGhzProtocolTypePrinceton]); + subghz_protocol_nice_flo_reset( + (SubGhzProtocolNiceFlo*)instance->protocols[SubGhzProtocolTypeNiceFlo]); + subghz_protocol_nice_flor_s_reset( + (SubGhzProtocolNiceFlorS*)instance->protocols[SubGhzProtocolTypeNiceFlorS]); + subghz_protocol_gate_tx_reset( + (SubGhzProtocolGateTX*)instance->protocols[SubGhzProtocolTypeGateTX]); subghz_protocol_ido_reset((SubGhzProtocolIDo*)instance->protocols[SubGhzProtocolTypeIDo]); - subghz_protocol_faac_slh_reset((SubGhzProtocolFaacSLH*)instance->protocols[SubGhzProtocolTypeFaacSLH]); - subghz_protocol_nero_sketch_reset((SubGhzProtocolNeroSketch*)instance->protocols[SubGhzProtocolTypeNeroSketch]); - subghz_protocol_star_line_reset((SubGhzProtocolStarLine*)instance->protocols[SubGhzProtocolTypeStarLine]); + subghz_protocol_faac_slh_reset( + (SubGhzProtocolFaacSLH*)instance->protocols[SubGhzProtocolTypeFaacSLH]); + subghz_protocol_nero_sketch_reset( + (SubGhzProtocolNeroSketch*)instance->protocols[SubGhzProtocolTypeNeroSketch]); + subghz_protocol_star_line_reset( + (SubGhzProtocolStarLine*)instance->protocols[SubGhzProtocolTypeStarLine]); } void subghz_protocol_parse(SubGhzProtocol* instance, bool level, uint32_t duration) { - - subghz_protocol_came_parse((SubGhzProtocolCame*)instance->protocols[SubGhzProtocolTypeCame], level, duration); - subghz_protocol_keeloq_parse((SubGhzProtocolKeeloq*)instance->protocols[SubGhzProtocolTypeKeeloq], level, duration); - subghz_decoder_princeton_parse((SubGhzDecoderPrinceton*)instance->protocols[SubGhzProtocolTypePrinceton], level, duration); - subghz_protocol_nice_flo_parse((SubGhzProtocolNiceFlo*)instance->protocols[SubGhzProtocolTypeNiceFlo], level, duration); - subghz_protocol_nice_flor_s_parse((SubGhzProtocolNiceFlorS*)instance->protocols[SubGhzProtocolTypeNiceFlorS], level, duration); - subghz_protocol_gate_tx_parse((SubGhzProtocolGateTX*)instance->protocols[SubGhzProtocolTypeGateTX], level, duration); - subghz_protocol_ido_parse((SubGhzProtocolIDo*)instance->protocols[SubGhzProtocolTypeIDo], level, duration); - subghz_protocol_faac_slh_parse((SubGhzProtocolFaacSLH*)instance->protocols[SubGhzProtocolTypeFaacSLH], level, duration); - subghz_protocol_nero_sketch_parse((SubGhzProtocolNeroSketch*)instance->protocols[SubGhzProtocolTypeNeroSketch], level, duration); - subghz_protocol_star_line_parse((SubGhzProtocolStarLine*)instance->protocols[SubGhzProtocolTypeStarLine], level, duration); + subghz_protocol_came_parse( + (SubGhzProtocolCame*)instance->protocols[SubGhzProtocolTypeCame], level, duration); + subghz_protocol_keeloq_parse( + (SubGhzProtocolKeeloq*)instance->protocols[SubGhzProtocolTypeKeeloq], level, duration); + subghz_decoder_princeton_parse( + (SubGhzDecoderPrinceton*)instance->protocols[SubGhzProtocolTypePrinceton], + level, + duration); + subghz_protocol_nice_flo_parse( + (SubGhzProtocolNiceFlo*)instance->protocols[SubGhzProtocolTypeNiceFlo], level, duration); + subghz_protocol_nice_flor_s_parse( + (SubGhzProtocolNiceFlorS*)instance->protocols[SubGhzProtocolTypeNiceFlorS], + level, + duration); + subghz_protocol_gate_tx_parse( + (SubGhzProtocolGateTX*)instance->protocols[SubGhzProtocolTypeGateTX], level, duration); + subghz_protocol_ido_parse( + (SubGhzProtocolIDo*)instance->protocols[SubGhzProtocolTypeIDo], level, duration); + subghz_protocol_faac_slh_parse( + (SubGhzProtocolFaacSLH*)instance->protocols[SubGhzProtocolTypeFaacSLH], level, duration); + subghz_protocol_nero_sketch_parse( + (SubGhzProtocolNeroSketch*)instance->protocols[SubGhzProtocolTypeNeroSketch], + level, + duration); + subghz_protocol_star_line_parse( + (SubGhzProtocolStarLine*)instance->protocols[SubGhzProtocolTypeStarLine], level, duration); } diff --git a/lib/subghz/protocols/subghz_protocol_came.c b/lib/subghz/protocols/subghz_protocol_came.c index 330a1509..5d3e5f4c 100644 --- a/lib/subghz/protocols/subghz_protocol_came.c +++ b/lib/subghz/protocols/subghz_protocol_came.c @@ -23,10 +23,12 @@ SubGhzProtocolCame* subghz_protocol_came_alloc() { instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_protocol_came_to_str; instance->common.to_save_string = (SubGhzProtocolCommonGetStrSave)subghz_protocol_came_to_save_str; - instance->common.to_load_protocol= - (SubGhzProtocolCommonLoad)subghz_protocol_came_to_load_protocol; + instance->common.to_load_protocol_from_file= + (SubGhzProtocolCommonLoadFromFile)subghz_protocol_came_to_load_protocol_from_file; + instance->common.to_load_protocol = + (SubGhzProtocolCommonLoadFromRAW)subghz_decoder_came_to_load_protocol; instance->common.get_upload_protocol = - (SubGhzProtocolEncoderCommonGetUpLoad)subghz_protocol_came_send_key; + (SubGhzProtocolCommonEncoderGetUpLoad)subghz_protocol_came_send_key; return instance; } @@ -36,7 +38,7 @@ void subghz_protocol_came_free(SubGhzProtocolCame* instance) { free(instance); } -bool subghz_protocol_came_send_key(SubGhzProtocolCame* instance, SubGhzProtocolEncoderCommon* encoder){ +bool subghz_protocol_came_send_key(SubGhzProtocolCame* instance, SubGhzProtocolCommonEncoder* encoder){ furi_assert(instance); furi_assert(encoder); size_t index = 0; @@ -142,9 +144,9 @@ void subghz_protocol_came_to_str(SubGhzProtocolCame* instance, string_t output) string_cat_printf( output, - "%s %d Bit\r\n" - " KEY:0x%08lX\r\n" - " YEK:0x%08lX\r\n", + "%s %dbit\r\n" + "Key:0x%08lX\r\n" + "Yek:0x%08lX\r\n", instance->common.name, instance->common.code_last_count_bit, code_found_lo, @@ -163,7 +165,7 @@ void subghz_protocol_came_to_save_str(SubGhzProtocolCame* instance, string_t out (uint32_t)(instance->common.code_last_found & 0x00000000ffffffff)); } -bool subghz_protocol_came_to_load_protocol(FileWorker* file_worker, SubGhzProtocolCame* instance){ +bool subghz_protocol_came_to_load_protocol_from_file(FileWorker* file_worker, SubGhzProtocolCame* instance){ bool loaded = false; string_t temp_str; string_init(temp_str); @@ -199,3 +201,13 @@ bool subghz_protocol_came_to_load_protocol(FileWorker* file_worker, SubGhzProtoc return loaded; } + +void subghz_decoder_came_to_load_protocol( + SubGhzProtocolCame* instance, + void* context) { + furi_assert(context); + furi_assert(instance); + SubGhzProtocolCommonLoad* data = context; + instance->common.code_last_found = data->code_found; + instance->common.code_last_count_bit = data->code_count_bit; +} diff --git a/lib/subghz/protocols/subghz_protocol_came.h b/lib/subghz/protocols/subghz_protocol_came.h index 24810da4..21cd5eca 100644 --- a/lib/subghz/protocols/subghz_protocol_came.h +++ b/lib/subghz/protocols/subghz_protocol_came.h @@ -19,10 +19,10 @@ void subghz_protocol_came_free(SubGhzProtocolCame* instance); /** Get upload protocol * * @param instance - SubGhzProtocolCame instance - * @param encoder - SubGhzProtocolEncoderCommon encoder + * @param encoder - SubGhzProtocolCommonEncoder encoder * @return bool */ -bool subghz_protocol_came_send_key(SubGhzProtocolCame* instance, SubGhzProtocolEncoderCommon* encoder); +bool subghz_protocol_came_send_key(SubGhzProtocolCame* instance, SubGhzProtocolCommonEncoder* encoder); /** Reset internal state * @param instance - SubGhzProtocolCame instance @@ -44,4 +44,5 @@ void subghz_protocol_came_parse(SubGhzProtocolCame* instance, bool level, uint32 void subghz_protocol_came_to_str(SubGhzProtocolCame* instance, string_t output); void subghz_protocol_came_to_save_str(SubGhzProtocolCame* instance, string_t output); -bool subghz_protocol_came_to_load_protocol(FileWorker* file_worker, SubGhzProtocolCame* instance); +bool subghz_protocol_came_to_load_protocol_from_file(FileWorker* file_worker, SubGhzProtocolCame* instance); +void subghz_decoder_came_to_load_protocol(SubGhzProtocolCame* instance, void* context); \ No newline at end of file diff --git a/lib/subghz/protocols/subghz_protocol_common.c b/lib/subghz/protocols/subghz_protocol_common.c index 2c5f4f2e..dc3e4f09 100644 --- a/lib/subghz/protocols/subghz_protocol_common.c +++ b/lib/subghz/protocols/subghz_protocol_common.c @@ -3,27 +3,27 @@ #include -SubGhzProtocolEncoderCommon* subghz_protocol_encoder_common_alloc() { - SubGhzProtocolEncoderCommon* instance = furi_alloc(sizeof(SubGhzProtocolEncoderCommon)); +SubGhzProtocolCommonEncoder* subghz_protocol_encoder_common_alloc() { + SubGhzProtocolCommonEncoder* instance = furi_alloc(sizeof(SubGhzProtocolCommonEncoder)); instance->upload = furi_alloc(SUBGHZ_ENCODER_UPLOAD_MAX_SIZE * sizeof(LevelDuration)); instance->start = true; instance->repeat = 10; //default number of repeat return instance; } -void subghz_protocol_encoder_common_free(SubGhzProtocolEncoderCommon* instance) { +void subghz_protocol_encoder_common_free(SubGhzProtocolCommonEncoder* instance) { furi_assert(instance); free(instance->upload); free(instance); } -size_t subghz_encoder_common_get_repeat_left(SubGhzProtocolEncoderCommon* instance) { +size_t subghz_encoder_common_get_repeat_left(SubGhzProtocolCommonEncoder* instance) { furi_assert(instance); return instance->repeat; } LevelDuration subghz_protocol_encoder_common_yield(void* context) { - SubGhzProtocolEncoderCommon* instance = context; + SubGhzProtocolCommonEncoder* instance = context; if(instance->repeat == 0){ return level_duration_reset(); diff --git a/lib/subghz/protocols/subghz_protocol_common.h b/lib/subghz/protocols/subghz_protocol_common.h index 32a0f923..79c2a2c0 100644 --- a/lib/subghz/protocols/subghz_protocol_common.h +++ b/lib/subghz/protocols/subghz_protocol_common.h @@ -14,30 +14,37 @@ #define SUBGHZ_TX_PIN_LOW() #define DURATION_DIFF(x, y) ((x < y) ? (y - x) : (x - y)) -//#define SUBGHZ_APP_PATH_FOLDER "/ext/subghz/saved" #define SUBGHZ_APP_FOLDER "/any/subghz" #define SUBGHZ_APP_PATH_FOLDER "/any/subghz/saved" #define SUBGHZ_APP_EXTENSION ".sub" -#define SUBGHZ_ENCODER_UPLOAD_MAX_SIZE 512 +#define SUBGHZ_ENCODER_UPLOAD_MAX_SIZE 512 + +enum { + TYPE_PROTOCOL_UNKNOWN, + TYPE_PROTOCOL_STATIC, + TYPE_PROTOCOL_DYNAMIC, +}; -#define TYPE_PROTOCOL_STATIC 1u -#define TYPE_PROTOCOL_DYNAMIC 2u typedef struct SubGhzProtocolCommon SubGhzProtocolCommon; -typedef struct SubGhzProtocolEncoderCommon SubGhzProtocolEncoderCommon; +typedef struct SubGhzProtocolCommonEncoder SubGhzProtocolCommonEncoder; +typedef struct SubGhzProtocolCommonLoad SubGhzProtocolCommonLoad; typedef void (*SubGhzProtocolCommonCallback)(SubGhzProtocolCommon* parser, void* context); typedef void (*SubGhzProtocolCommonToStr)(SubGhzProtocolCommon* instance, string_t output); -//Save +//Get string to save typedef void (*SubGhzProtocolCommonGetStrSave)(SubGhzProtocolCommon* instance, string_t output); -//Load -typedef bool (*SubGhzProtocolCommonLoad)(FileWorker* file_worker, SubGhzProtocolCommon* instance); - +//Load protocol from file +typedef bool (*SubGhzProtocolCommonLoadFromFile)(FileWorker* file_worker, SubGhzProtocolCommon* instance); +//Load protocol +typedef void (*SubGhzProtocolCommonLoadFromRAW)(SubGhzProtocolCommon* instance, void* context); //Get upload encoder protocol -typedef bool (*SubGhzProtocolEncoderCommonGetUpLoad)(SubGhzProtocolCommon* instance, SubGhzProtocolEncoderCommon* encoder); +typedef bool (*SubGhzProtocolCommonEncoderGetUpLoad)( + SubGhzProtocolCommon* instance, + SubGhzProtocolCommonEncoder* encoder); struct SubGhzProtocolCommon { const char* name; @@ -65,13 +72,15 @@ struct SubGhzProtocolCommon { SubGhzProtocolCommonToStr to_string; /* Get string to save */ SubGhzProtocolCommonGetStrSave to_save_string; - /*Load protocol by file*/ - SubGhzProtocolCommonLoad to_load_protocol; - /*Get upload encoder protocol*/ - SubGhzProtocolEncoderCommonGetUpLoad get_upload_protocol; + /* Load protocol from file */ + SubGhzProtocolCommonLoadFromFile to_load_protocol_from_file; + /* Load protocol from RAW data */ + SubGhzProtocolCommonLoadFromRAW to_load_protocol; + /* Get upload encoder protocol */ + SubGhzProtocolCommonEncoderGetUpLoad get_upload_protocol; }; -struct SubGhzProtocolEncoderCommon { +struct SubGhzProtocolCommonEncoder { bool start; size_t repeat; size_t front; @@ -79,9 +88,17 @@ struct SubGhzProtocolEncoderCommon { LevelDuration* upload; }; -SubGhzProtocolEncoderCommon* subghz_protocol_encoder_common_alloc(); -void subghz_protocol_encoder_common_free(SubGhzProtocolEncoderCommon* instance); -size_t subghz_encoder_common_get_repeat_left(SubGhzProtocolEncoderCommon* instance); +struct SubGhzProtocolCommonLoad{ + uint64_t code_found; + uint8_t code_count_bit; + uint32_t param1; + uint32_t param2; + uint32_t param3; +}; + +SubGhzProtocolCommonEncoder* subghz_protocol_encoder_common_alloc(); +void subghz_protocol_encoder_common_free(SubGhzProtocolCommonEncoder* instance); +size_t subghz_encoder_common_get_repeat_left(SubGhzProtocolCommonEncoder* instance); LevelDuration subghz_protocol_encoder_common_yield(void* context); /** Add data bit to code_found diff --git a/lib/subghz/protocols/subghz_protocol_faac_slh.c b/lib/subghz/protocols/subghz_protocol_faac_slh.c index dff5b4fd..ee44ec76 100644 --- a/lib/subghz/protocols/subghz_protocol_faac_slh.c +++ b/lib/subghz/protocols/subghz_protocol_faac_slh.c @@ -15,6 +15,8 @@ SubGhzProtocolFaacSLH* subghz_protocol_faac_slh_alloc(void) { instance->common.te_delta = 100; instance->common.type_protocol = TYPE_PROTOCOL_DYNAMIC; instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_protocol_faac_slh_to_str; + instance->common.to_load_protocol = + (SubGhzProtocolCommonLoadFromRAW)subghz_decoder_faac_slh_to_load_protocol; return instance; } @@ -145,11 +147,11 @@ void subghz_protocol_faac_slh_to_str(SubGhzProtocolFaacSLH* instance, string_t o uint32_t code_hop = (code_found_reverse >>32) & 0xFFFFFFFF; string_cat_printf(output, - "%s, %d Bit\r\n" - " KEY:0x%lX%08lX\r\n" - " FIX:%08lX \r\n" - " HOP:%08lX \r\n" - " SN:%07lX BTN:%lX\r\n", + "%s %dbit\r\n" + "Key:0x%lX%08lX\r\n" + "Fix:%08lX \r\n" + "Hop:%08lX \r\n" + "Sn:%07lX Btn:%lX\r\n", instance->common.name, instance->common.code_last_count_bit, (uint32_t)(instance->common.code_last_found >> 32), @@ -157,4 +159,15 @@ void subghz_protocol_faac_slh_to_str(SubGhzProtocolFaacSLH* instance, string_t o code_fix, code_hop, instance->common.serial, instance->common.btn); +} + +void subghz_decoder_faac_slh_to_load_protocol( + SubGhzProtocolFaacSLH* instance, + void* context) { + furi_assert(context); + furi_assert(instance); + SubGhzProtocolCommonLoad* data = context; + instance->common.code_last_found = data->code_found; + instance->common.code_last_count_bit = data->code_count_bit; + subghz_protocol_faac_slh_check_remote_controller(instance); } \ No newline at end of file diff --git a/lib/subghz/protocols/subghz_protocol_faac_slh.h b/lib/subghz/protocols/subghz_protocol_faac_slh.h index 26b4ac08..43f9d2bf 100644 --- a/lib/subghz/protocols/subghz_protocol_faac_slh.h +++ b/lib/subghz/protocols/subghz_protocol_faac_slh.h @@ -49,3 +49,5 @@ void subghz_protocol_faac_slh_parse(SubGhzProtocolFaacSLH* instance, bool level, * @param output - output string */ void subghz_protocol_faac_slh_to_str(SubGhzProtocolFaacSLH* instance, string_t output); + +void subghz_decoder_faac_slh_to_load_protocol(SubGhzProtocolFaacSLH* instance, void* context); diff --git a/lib/subghz/protocols/subghz_protocol_gate_tx.c b/lib/subghz/protocols/subghz_protocol_gate_tx.c index d850d741..8e10d5f8 100644 --- a/lib/subghz/protocols/subghz_protocol_gate_tx.c +++ b/lib/subghz/protocols/subghz_protocol_gate_tx.c @@ -17,10 +17,12 @@ SubGhzProtocolGateTX* subghz_protocol_gate_tx_alloc(void) { instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_protocol_gate_tx_to_str; instance->common.to_save_string = (SubGhzProtocolCommonGetStrSave)subghz_protocol_gate_tx_to_save_str; - instance->common.to_load_protocol= - (SubGhzProtocolCommonLoad)subghz_protocol_gate_tx_to_load_protocol; + instance->common.to_load_protocol_from_file= + (SubGhzProtocolCommonLoadFromFile)subghz_protocol_gate_tx_to_load_protocol_from_file; + instance->common.to_load_protocol = + (SubGhzProtocolCommonLoadFromRAW)subghz_decoder_gate_tx_to_load_protocol; instance->common.get_upload_protocol = - (SubGhzProtocolEncoderCommonGetUpLoad)subghz_protocol_gate_tx_send_key; + (SubGhzProtocolCommonEncoderGetUpLoad)subghz_protocol_gate_tx_send_key; return instance; } @@ -29,7 +31,7 @@ void subghz_protocol_gate_tx_free(SubGhzProtocolGateTX* instance) { free(instance); } -bool subghz_protocol_gate_tx_send_key(SubGhzProtocolGateTX* instance, SubGhzProtocolEncoderCommon* encoder){ +bool subghz_protocol_gate_tx_send_key(SubGhzProtocolGateTX* instance, SubGhzProtocolCommonEncoder* encoder){ furi_assert(instance); furi_assert(encoder); size_t index = 0; @@ -133,9 +135,9 @@ void subghz_protocol_gate_tx_parse(SubGhzProtocolGateTX* instance, bool level, u void subghz_protocol_gate_tx_to_str(SubGhzProtocolGateTX* instance, string_t output) { subghz_protocol_gate_tx_check_remote_controller(instance); string_cat_printf(output, - "%s, %d Bit\r\n" - " KEY:%06lX\r\n" - " SN:%05lX BTN:%lX\r\n", + "%s %dbit\r\n" + "Key:%06lX\r\n" + "Sn:%05lX Btn:%lX\r\n", instance->common.name, instance->common.code_last_count_bit, (uint32_t)(instance->common.code_last_found & 0xFFFFFF), @@ -155,7 +157,7 @@ void subghz_protocol_gate_tx_to_save_str(SubGhzProtocolGateTX* instance, string_ (uint32_t)(instance->common.code_last_found & 0x00000000ffffffff)); } -bool subghz_protocol_gate_tx_to_load_protocol(FileWorker* file_worker, SubGhzProtocolGateTX* instance){ +bool subghz_protocol_gate_tx_to_load_protocol_from_file(FileWorker* file_worker, SubGhzProtocolGateTX* instance){ bool loaded = false; string_t temp_str; string_init(temp_str); @@ -192,3 +194,14 @@ bool subghz_protocol_gate_tx_to_load_protocol(FileWorker* file_worker, SubGhzPro return loaded; } + +void subghz_decoder_gate_tx_to_load_protocol( + SubGhzProtocolGateTX* instance, + void* context) { + furi_assert(context); + furi_assert(instance); + SubGhzProtocolCommonLoad* data = context; + instance->common.code_last_found = data->code_found; + instance->common.code_last_count_bit = data->code_count_bit; + subghz_protocol_gate_tx_check_remote_controller(instance); +} \ No newline at end of file diff --git a/lib/subghz/protocols/subghz_protocol_gate_tx.h b/lib/subghz/protocols/subghz_protocol_gate_tx.h index b5682d7d..b09bb077 100644 --- a/lib/subghz/protocols/subghz_protocol_gate_tx.h +++ b/lib/subghz/protocols/subghz_protocol_gate_tx.h @@ -19,10 +19,10 @@ void subghz_protocol_gate_tx_free(SubGhzProtocolGateTX* instance); /** Get upload protocol * * @param instance - SubGhzProtocolCame instance - * @param encoder - SubGhzProtocolEncoderCommon encoder + * @param encoder - SubGhzProtocolCommonEncoder encoder * @return bool */ -bool subghz_protocol_gate_tx_send_key(SubGhzProtocolGateTX* instance, SubGhzProtocolEncoderCommon* encoder); +bool subghz_protocol_gate_tx_send_key(SubGhzProtocolGateTX* instance, SubGhzProtocolCommonEncoder* encoder); /** Reset internal state * @param instance - SubGhzProtocolGateTX instance @@ -44,4 +44,5 @@ void subghz_protocol_gate_tx_parse(SubGhzProtocolGateTX* instance, bool level, u void subghz_protocol_gate_tx_to_str(SubGhzProtocolGateTX* instance, string_t output); void subghz_protocol_gate_tx_to_save_str(SubGhzProtocolGateTX* instance, string_t output); -bool subghz_protocol_gate_tx_to_load_protocol(FileWorker* file_worker, SubGhzProtocolGateTX* instance); +bool subghz_protocol_gate_tx_to_load_protocol_from_file(FileWorker* file_worker, SubGhzProtocolGateTX* instance); +void subghz_decoder_gate_tx_to_load_protocol(SubGhzProtocolGateTX* instance, void* context); diff --git a/lib/subghz/protocols/subghz_protocol_ido.c b/lib/subghz/protocols/subghz_protocol_ido.c index 95e571e3..a5d33f32 100644 --- a/lib/subghz/protocols/subghz_protocol_ido.c +++ b/lib/subghz/protocols/subghz_protocol_ido.c @@ -1,6 +1,5 @@ #include "subghz_protocol_ido.h" - struct SubGhzProtocolIDo { SubGhzProtocolCommon common; }; @@ -15,6 +14,8 @@ SubGhzProtocolIDo* subghz_protocol_ido_alloc(void) { instance->common.te_delta = 150; instance->common.type_protocol = TYPE_PROTOCOL_DYNAMIC; instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_protocol_ido_to_str; + instance->common.to_load_protocol = + (SubGhzProtocolCommonLoadFromRAW)subghz_decoder_ido_to_load_protocol; return instance; } @@ -30,7 +31,7 @@ void subghz_protocol_ido_free(SubGhzProtocolIDo* instance) { * @param bit - bit */ void subghz_protocol_ido_send_bit(SubGhzProtocolIDo* instance, uint8_t bit) { - if (bit) { + if(bit) { //send bit 1 SUBGHZ_TX_PIN_HIGH(); delay_us(instance->common.te_short); @@ -45,15 +46,19 @@ void subghz_protocol_ido_send_bit(SubGhzProtocolIDo* instance, uint8_t bit) { } } -void subghz_protocol_ido_send_key(SubGhzProtocolIDo* instance, uint64_t key, uint8_t bit,uint8_t repeat) { - while (repeat--) { +void subghz_protocol_ido_send_key( + SubGhzProtocolIDo* instance, + uint64_t key, + uint8_t bit, + uint8_t repeat) { + while(repeat--) { SUBGHZ_TX_PIN_HIGH(); //Send header delay_us(instance->common.te_short * 10); SUBGHZ_TX_PIN_LOW(); - delay_us(instance->common.te_short * 10); + delay_us(instance->common.te_short * 10); //Send key data - for (uint8_t i = bit; i > 0; i--) { + for(uint8_t i = bit; i > 0; i--) { subghz_protocol_ido_send_bit(instance, bit_read(key, i - 1)); } } @@ -68,7 +73,8 @@ void subghz_protocol_ido_reset(SubGhzProtocolIDo* instance) { * @param instance SubGhzProtocolIDo instance */ void subghz_protocol_ido_check_remote_controller(SubGhzProtocolIDo* instance) { - uint64_t code_found_reverse = subghz_protocol_common_reverse_key(instance->common.code_last_found, instance->common.code_last_count_bit); + uint64_t code_found_reverse = subghz_protocol_common_reverse_key( + instance->common.code_last_found, instance->common.code_last_count_bit); uint32_t code_fix = code_found_reverse & 0xFFFFFF; instance->common.serial = code_fix & 0xFFFFF; @@ -76,18 +82,18 @@ void subghz_protocol_ido_check_remote_controller(SubGhzProtocolIDo* instance) { } void subghz_protocol_ido_parse(SubGhzProtocolIDo* instance, bool level, uint32_t duration) { - switch (instance->common.parser_step) { + switch(instance->common.parser_step) { case 0: - if ((level) - && (DURATION_DIFF(duration,instance->common.te_short * 10)< instance->common.te_delta * 5)) { + if((level) && (DURATION_DIFF(duration, instance->common.te_short * 10) < + instance->common.te_delta * 5)) { instance->common.parser_step = 1; } else { instance->common.parser_step = 0; } break; case 1: - if ((!level) - && (DURATION_DIFF(duration,instance->common.te_short * 10)< instance->common.te_delta * 5)) { + if((!level) && (DURATION_DIFF(duration, instance->common.te_short * 10) < + instance->common.te_delta * 5)) { //Found Preambula instance->common.parser_step = 2; instance->common.code_found = 0; @@ -97,13 +103,16 @@ void subghz_protocol_ido_parse(SubGhzProtocolIDo* instance, bool level, uint32_t } break; case 2: - if (level) { - if (duration >= (instance->common.te_short * 5 + instance->common.te_delta)) { + if(level) { + if(duration >= (instance->common.te_short * 5 + instance->common.te_delta)) { instance->common.parser_step = 1; - if (instance->common.code_count_bit>= instance->common.code_min_count_bit_for_found) { + if(instance->common.code_count_bit >= + instance->common.code_min_count_bit_for_found) { instance->common.code_last_found = instance->common.code_found; instance->common.code_last_count_bit = instance->common.code_count_bit; - if (instance->common.callback) instance->common.callback((SubGhzProtocolCommon*)instance, instance->common.context); + if(instance->common.callback) + instance->common.callback( + (SubGhzProtocolCommon*)instance, instance->common.context); } instance->common.code_found = 0; instance->common.code_count_bit = 0; @@ -113,18 +122,22 @@ void subghz_protocol_ido_parse(SubGhzProtocolIDo* instance, bool level, uint32_t instance->common.parser_step = 3; } - }else{ + } else { instance->common.parser_step = 0; } break; case 3: - if(!level){ - if ((DURATION_DIFF(instance->common.te_last,instance->common.te_short)< instance->common.te_delta) - && (DURATION_DIFF(duration,instance->common.te_long)< instance->common.te_delta*3)) { + if(!level) { + if((DURATION_DIFF(instance->common.te_last, instance->common.te_short) < + instance->common.te_delta) && + (DURATION_DIFF(duration, instance->common.te_long) < + instance->common.te_delta * 3)) { subghz_protocol_common_add_bit(&instance->common, 0); instance->common.parser_step = 2; - } else if ((DURATION_DIFF(instance->common.te_last,instance->common.te_short )< instance->common.te_delta*3) - && (DURATION_DIFF(duration,instance->common.te_short)< instance->common.te_delta)) { + } else if( + (DURATION_DIFF(instance->common.te_last, instance->common.te_short) < + instance->common.te_delta * 3) && + (DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta)) { subghz_protocol_common_add_bit(&instance->common, 1); instance->common.parser_step = 2; } else { @@ -139,21 +152,35 @@ void subghz_protocol_ido_parse(SubGhzProtocolIDo* instance, bool level, uint32_t void subghz_protocol_ido_to_str(SubGhzProtocolIDo* instance, string_t output) { subghz_protocol_ido_check_remote_controller(instance); - uint64_t code_found_reverse = subghz_protocol_common_reverse_key(instance->common.code_last_found, instance->common.code_last_count_bit); + uint64_t code_found_reverse = subghz_protocol_common_reverse_key( + instance->common.code_last_found, instance->common.code_last_count_bit); uint32_t code_fix = code_found_reverse & 0xFFFFFF; - uint32_t code_hop = (code_found_reverse >>24) & 0xFFFFFF; + uint32_t code_hop = (code_found_reverse >> 24) & 0xFFFFFF; - string_cat_printf(output, - "%s, %d Bit\r\n" - " KEY:0x%lX%08lX\r\n" - " FIX:%06lX \r\n" - " HOP:%06lX \r\n" - " SN:%05lX BTN:%lX\r\n", - instance->common.name, - instance->common.code_last_count_bit, - (uint32_t)(instance->common.code_last_found >> 32), - (uint32_t)instance->common.code_last_found, - code_fix, code_hop, - instance->common.serial, - instance->common.btn); + string_cat_printf( + output, + "%s %dbit\r\n" + "Key:0x%lX%08lX\r\n" + "Fix:%06lX \r\n" + "Hop:%06lX \r\n" + "Sn:%05lX Btn:%lX\r\n", + instance->common.name, + instance->common.code_last_count_bit, + (uint32_t)(instance->common.code_last_found >> 32), + (uint32_t)instance->common.code_last_found, + code_fix, + code_hop, + instance->common.serial, + instance->common.btn); +} + +void subghz_decoder_ido_to_load_protocol( + SubGhzProtocolIDo* instance, + void* context) { + furi_assert(context); + furi_assert(instance); + SubGhzProtocolCommonLoad* data = context; + instance->common.code_last_found = data->code_found; + instance->common.code_last_count_bit = data->code_count_bit; + subghz_protocol_ido_check_remote_controller(instance); } \ No newline at end of file diff --git a/lib/subghz/protocols/subghz_protocol_ido.h b/lib/subghz/protocols/subghz_protocol_ido.h index 35d26967..df03ad0a 100644 --- a/lib/subghz/protocols/subghz_protocol_ido.h +++ b/lib/subghz/protocols/subghz_protocol_ido.h @@ -49,3 +49,4 @@ void subghz_protocol_ido_parse(SubGhzProtocolIDo* instance, bool level, uint32_t * @param output - output string */ void subghz_protocol_ido_to_str(SubGhzProtocolIDo* instance, string_t output); +void subghz_decoder_ido_to_load_protocol(SubGhzProtocolIDo* instance, void* context); diff --git a/lib/subghz/protocols/subghz_protocol_keeloq.c b/lib/subghz/protocols/subghz_protocol_keeloq.c index 6bbc9c80..eb4154fc 100644 --- a/lib/subghz/protocols/subghz_protocol_keeloq.c +++ b/lib/subghz/protocols/subghz_protocol_keeloq.c @@ -27,10 +27,12 @@ SubGhzProtocolKeeloq* subghz_protocol_keeloq_alloc(SubGhzKeystore* keystore) { instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_protocol_keeloq_to_str; instance->common.to_save_string = (SubGhzProtocolCommonGetStrSave)subghz_protocol_keeloq_to_save_str; + instance->common.to_load_protocol_from_file = + (SubGhzProtocolCommonLoadFromFile)subghz_protocol_keeloq_to_load_protocol_from_file; instance->common.to_load_protocol = - (SubGhzProtocolCommonLoad)subghz_protocol_keeloq_to_load_protocol; + (SubGhzProtocolCommonLoadFromRAW)subghz_decoder_keeloq_to_load_protocol; instance->common.get_upload_protocol = - (SubGhzProtocolEncoderCommonGetUpLoad)subghz_protocol_keeloq_send_key; + (SubGhzProtocolCommonEncoderGetUpLoad)subghz_protocol_keeloq_send_key; return instance; } @@ -165,7 +167,14 @@ void subghz_protocol_keeloq_check_remote_controller(SubGhzProtocolKeeloq* instan instance->common.serial = key_fix & 0x0FFFFFFF; instance->common.btn = key_fix >> 28; } -void subghz_protocol_keeloq_set_manufacture_name (void* context, const char* manufacture_name){ + +const char* subghz_protocol_keeloq_get_manufacture_name(void* context) { + SubGhzProtocolKeeloq* instance = context; + subghz_protocol_keeloq_check_remote_controller(instance); + return instance->manufacture_name; +} + +void subghz_protocol_keeloq_set_manufacture_name(void* context, const char* manufacture_name) { SubGhzProtocolKeeloq* instance = context; instance->manufacture_name = manufacture_name; } @@ -205,17 +214,20 @@ uint64_t subghz_protocol_keeloq_gen_key(void* context) { return subghz_protocol_common_reverse_key(yek, instance->common.code_last_count_bit); } -bool subghz_protocol_keeloq_send_key(SubGhzProtocolKeeloq* instance, SubGhzProtocolEncoderCommon* encoder){ +bool subghz_protocol_keeloq_send_key( + SubGhzProtocolKeeloq* instance, + SubGhzProtocolCommonEncoder* encoder) { furi_assert(instance); furi_assert(encoder); //gen new key instance->common.cnt++; instance->common.code_last_found = subghz_protocol_keeloq_gen_key(instance); - if(instance->common.callback)instance->common.callback((SubGhzProtocolCommon*)instance, instance->common.context); - + if(instance->common.callback) + instance->common.callback((SubGhzProtocolCommon*)instance, instance->common.context); + size_t index = 0; - encoder->size_upload =11*2+2+(instance->common.code_last_count_bit * 2) + 4; + encoder->size_upload = 11 * 2 + 2 + (instance->common.code_last_count_bit * 2) + 4; if(encoder->size_upload > SUBGHZ_ENCODER_UPLOAD_MAX_SIZE) return false; //Send header @@ -224,18 +236,23 @@ bool subghz_protocol_keeloq_send_key(SubGhzProtocolKeeloq* instance, SubGhzProto encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->common.te_short); } encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_short); - encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->common.te_short*10); + encoder->upload[index++] = + level_duration_make(false, (uint32_t)instance->common.te_short * 10); //Send key data - for (uint8_t i = instance->common.code_last_count_bit; i > 0; i--) { - if(bit_read(instance->common.code_last_found, i - 1)){ + for(uint8_t i = instance->common.code_last_count_bit; i > 0; i--) { + if(bit_read(instance->common.code_last_found, i - 1)) { //send bit 1 - encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_short); - encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->common.te_long); - }else{ + encoder->upload[index++] = + level_duration_make(true, (uint32_t)instance->common.te_short); + encoder->upload[index++] = + level_duration_make(false, (uint32_t)instance->common.te_long); + } else { //send bit 0 - encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_long); - encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->common.te_short); + encoder->upload[index++] = + level_duration_make(true, (uint32_t)instance->common.te_long); + encoder->upload[index++] = + level_duration_make(false, (uint32_t)instance->common.te_short); } } // +send 2 status bit @@ -247,7 +264,8 @@ bool subghz_protocol_keeloq_send_key(SubGhzProtocolKeeloq* instance, SubGhzProto // send end encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_short); - encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->common.te_short*40); + encoder->upload[index++] = + level_duration_make(false, (uint32_t)instance->common.te_short * 40); return true; } @@ -353,25 +371,27 @@ void subghz_protocol_keeloq_to_str(SubGhzProtocolKeeloq* instance, string_t outp uint32_t code_found_reverse_lo = code_found_reverse & 0x00000000ffffffff; string_cat_printf( output, - "%s, %d Bit\r\n" - "KEY:0x%lX%lX\r\n" - "FIX:%08lX MF:%s \r\n" - "HOP:%08lX \r\n" - "SN:%07lX CNT:%04X B:%02lX\r\n", + "%s %dbit\r\n" + "Key:0x%lX%lX\r\n" + "Fix:0x%08lX Cnt:%04X\r\n" + "Hop:0x%08lX Btn:%02lX\r\n" + "MF:%s\r\n" + "Sn:0x%07lX \r\n", instance->common.name, instance->common.code_last_count_bit, code_found_hi, code_found_lo, code_found_reverse_hi, - instance->manufacture_name, - code_found_reverse_lo, - instance->common.serial, instance->common.cnt, - instance->common.btn); + code_found_reverse_lo, + instance->common.btn, + instance->manufacture_name, + instance->common.serial + ); } void subghz_protocol_keeloq_to_save_str(SubGhzProtocolKeeloq* instance, string_t output) { - string_printf( + string_printf( output, "Protocol: %s\n" "Bit: %d\n" @@ -379,11 +399,10 @@ void subghz_protocol_keeloq_to_save_str(SubGhzProtocolKeeloq* instance, string_t instance->common.name, instance->common.code_last_count_bit, (uint32_t)(instance->common.code_last_found >> 32), - (uint32_t)(instance->common.code_last_found & 0xFFFFFFFF) - ); + (uint32_t)(instance->common.code_last_found & 0xFFFFFFFF)); } -bool subghz_protocol_keeloq_to_load_protocol( +bool subghz_protocol_keeloq_to_load_protocol_from_file( FileWorker* file_worker, SubGhzProtocolKeeloq* instance) { bool loaded = false; @@ -410,12 +429,12 @@ bool subghz_protocol_keeloq_to_load_protocol( // strlen("Key: ") = 5 string_right(temp_str, 5); - uint8_t buf_key[8]={0}; - if(!subghz_protocol_common_read_hex(temp_str, buf_key, 8)){ + uint8_t buf_key[8] = {0}; + if(!subghz_protocol_common_read_hex(temp_str, buf_key, 8)) { break; } - for(uint8_t i = 0; i < 8; i++){ + for(uint8_t i = 0; i < 8; i++) { instance->common.code_last_found = instance->common.code_last_found << 8 | buf_key[i]; } loaded = true; @@ -424,3 +443,14 @@ bool subghz_protocol_keeloq_to_load_protocol( return loaded; } + +void subghz_decoder_keeloq_to_load_protocol( + SubGhzProtocolKeeloq* instance, + void* context) { + furi_assert(context); + furi_assert(instance); + SubGhzProtocolCommonLoad* data = context; + instance->common.code_last_found = data->code_found; + instance->common.code_last_count_bit = data->code_count_bit; + subghz_protocol_keeloq_check_remote_controller(instance); +} \ No newline at end of file diff --git a/lib/subghz/protocols/subghz_protocol_keeloq.h b/lib/subghz/protocols/subghz_protocol_keeloq.h index cd591980..6680f52e 100644 --- a/lib/subghz/protocols/subghz_protocol_keeloq.h +++ b/lib/subghz/protocols/subghz_protocol_keeloq.h @@ -18,6 +18,8 @@ SubGhzProtocolKeeloq* subghz_protocol_keeloq_alloc(SubGhzKeystore* keystore); */ void subghz_protocol_keeloq_free(SubGhzProtocolKeeloq* instance); +const char* subghz_protocol_keeloq_get_manufacture_name(void* context); + /** Set manufacture name * * @param manufacture_name - manufacture name @@ -35,10 +37,10 @@ uint64_t subghz_protocol_keeloq_gen_key(void* context); /** Get upload protocol * * @param instance - SubGhzProtocolCame instance - * @param encoder - SubGhzProtocolEncoderCommon encoder + * @param encoder - SubGhzProtocolCommonEncoder encoder * @return bool */ -bool subghz_protocol_keeloq_send_key(SubGhzProtocolKeeloq* instance, SubGhzProtocolEncoderCommon* encoder); +bool subghz_protocol_keeloq_send_key(SubGhzProtocolKeeloq* instance, SubGhzProtocolCommonEncoder* encoder); /** Reset internal state * @param instance - SubGhzProtocolKeeloq instance @@ -60,4 +62,5 @@ void subghz_protocol_keeloq_parse(SubGhzProtocolKeeloq* instance, bool level, ui void subghz_protocol_keeloq_to_str(SubGhzProtocolKeeloq* instance, string_t output); void subghz_protocol_keeloq_to_save_str(SubGhzProtocolKeeloq* instance, string_t output); -bool subghz_protocol_keeloq_to_load_protocol(FileWorker* file_worker, SubGhzProtocolKeeloq* instance); +bool subghz_protocol_keeloq_to_load_protocol_from_file(FileWorker* file_worker, SubGhzProtocolKeeloq* instance); +void subghz_decoder_keeloq_to_load_protocol(SubGhzProtocolKeeloq* instance, void* context); diff --git a/lib/subghz/protocols/subghz_protocol_nero_sketch.c b/lib/subghz/protocols/subghz_protocol_nero_sketch.c index 4b20b4cb..4663bc05 100644 --- a/lib/subghz/protocols/subghz_protocol_nero_sketch.c +++ b/lib/subghz/protocols/subghz_protocol_nero_sketch.c @@ -17,10 +17,12 @@ SubGhzProtocolNeroSketch* subghz_protocol_nero_sketch_alloc(void) { instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_protocol_nero_sketch_to_str; instance->common.to_save_string = (SubGhzProtocolCommonGetStrSave)subghz_protocol_nero_sketch_to_save_str; - instance->common.to_load_protocol= - (SubGhzProtocolCommonLoad)subghz_protocol_nero_sketch_to_load_protocol; + instance->common.to_load_protocol_from_file= + (SubGhzProtocolCommonLoadFromFile)subghz_protocol_nero_sketch_to_load_protocol_from_file; + instance->common.to_load_protocol = + (SubGhzProtocolCommonLoadFromRAW)subghz_decoder_nero_sketch_to_load_protocol; instance->common.get_upload_protocol = - (SubGhzProtocolEncoderCommonGetUpLoad)subghz_protocol_nero_sketch_send_key; + (SubGhzProtocolCommonEncoderGetUpLoad)subghz_protocol_nero_sketch_send_key; return instance; } @@ -30,7 +32,7 @@ void subghz_protocol_nero_sketch_free(SubGhzProtocolNeroSketch* instance) { free(instance); } -bool subghz_protocol_nero_sketch_send_key(SubGhzProtocolNeroSketch* instance, SubGhzProtocolEncoderCommon* encoder){ +bool subghz_protocol_nero_sketch_send_key(SubGhzProtocolNeroSketch* instance, SubGhzProtocolCommonEncoder* encoder){ furi_assert(instance); furi_assert(encoder); size_t index = 0; @@ -184,9 +186,9 @@ void subghz_protocol_nero_sketch_to_str(SubGhzProtocolNeroSketch* instance, stri uint32_t code_found_reverse_lo = code_found_reverse&0x00000000ffffffff; string_cat_printf(output, - "%s, %d Bit\r\n" - " KEY:0x%lX%08lX\r\n" - " YEK:0x%lX%08lX\r\n", + "%s %dbit\r\n" + "Key:0x%lX%08lX\r\n" + "Yek:0x%lX%08lX\r\n", instance->common.name, instance->common.code_last_count_bit, code_found_hi, @@ -212,7 +214,7 @@ void subghz_protocol_nero_sketch_to_save_str(SubGhzProtocolNeroSketch* instance, ); } -bool subghz_protocol_nero_sketch_to_load_protocol(FileWorker* file_worker, SubGhzProtocolNeroSketch* instance){ +bool subghz_protocol_nero_sketch_to_load_protocol_from_file(FileWorker* file_worker, SubGhzProtocolNeroSketch* instance){ bool loaded = false; string_t temp_str; string_init(temp_str); @@ -249,3 +251,13 @@ bool subghz_protocol_nero_sketch_to_load_protocol(FileWorker* file_worker, SubGh return loaded; } + +void subghz_decoder_nero_sketch_to_load_protocol( + SubGhzProtocolNeroSketch* instance, + void* context) { + furi_assert(context); + furi_assert(instance); + SubGhzProtocolCommonLoad* data = context; + instance->common.code_last_found = data->code_found; + instance->common.code_last_count_bit = data->code_count_bit; +} \ No newline at end of file diff --git a/lib/subghz/protocols/subghz_protocol_nero_sketch.h b/lib/subghz/protocols/subghz_protocol_nero_sketch.h index 170895c4..82ef3d6e 100644 --- a/lib/subghz/protocols/subghz_protocol_nero_sketch.h +++ b/lib/subghz/protocols/subghz_protocol_nero_sketch.h @@ -19,10 +19,10 @@ void subghz_protocol_nero_sketch_free(SubGhzProtocolNeroSketch* instance); /** Get upload protocol * * @param instance - SubGhzProtocolCame instance - * @param encoder - SubGhzProtocolEncoderCommon encoder + * @param encoder - SubGhzProtocolCommonEncoder encoder * @return bool */ -bool subghz_protocol_nero_sketch_send_key(SubGhzProtocolNeroSketch* instance, SubGhzProtocolEncoderCommon* encoder); +bool subghz_protocol_nero_sketch_send_key(SubGhzProtocolNeroSketch* instance, SubGhzProtocolCommonEncoder* encoder); /** Reset internal state * @param instance - SubGhzProtocolNeroSketch instance @@ -50,4 +50,5 @@ void subghz_protocol_nero_sketch_parse(SubGhzProtocolNeroSketch* instance, bool void subghz_protocol_nero_sketch_to_str(SubGhzProtocolNeroSketch* instance, string_t output); void subghz_protocol_nero_sketch_to_save_str(SubGhzProtocolNeroSketch* instance, string_t output); -bool subghz_protocol_nero_sketch_to_load_protocol(FileWorker* file_worker, SubGhzProtocolNeroSketch* instance); +bool subghz_protocol_nero_sketch_to_load_protocol_from_file(FileWorker* file_worker, SubGhzProtocolNeroSketch* instance); +void subghz_decoder_nero_sketch_to_load_protocol(SubGhzProtocolNeroSketch* instance, void* context); \ No newline at end of file diff --git a/lib/subghz/protocols/subghz_protocol_nice_flo.c b/lib/subghz/protocols/subghz_protocol_nice_flo.c index b53160b8..af778543 100644 --- a/lib/subghz/protocols/subghz_protocol_nice_flo.c +++ b/lib/subghz/protocols/subghz_protocol_nice_flo.c @@ -22,10 +22,12 @@ SubGhzProtocolNiceFlo* subghz_protocol_nice_flo_alloc() { instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_protocol_nice_flo_to_str; instance->common.to_save_string = (SubGhzProtocolCommonGetStrSave)subghz_protocol_nice_flo_to_save_str; - instance->common.to_load_protocol= - (SubGhzProtocolCommonLoad)subghz_protocol_nice_flo_to_load_protocol; + instance->common.to_load_protocol_from_file= + (SubGhzProtocolCommonLoadFromFile)subghz_protocol_nice_flo_to_load_protocol_from_file; + instance->common.to_load_protocol = + (SubGhzProtocolCommonLoadFromRAW)subghz_decoder_nice_flo_to_load_protocol; instance->common.get_upload_protocol = - (SubGhzProtocolEncoderCommonGetUpLoad)subghz_protocol_nice_flo_send_key; + (SubGhzProtocolCommonEncoderGetUpLoad)subghz_protocol_nice_flo_send_key; return instance; } @@ -34,7 +36,7 @@ void subghz_protocol_nice_flo_free(SubGhzProtocolNiceFlo* instance) { free(instance); } -bool subghz_protocol_nice_flo_send_key(SubGhzProtocolNiceFlo* instance, SubGhzProtocolEncoderCommon* encoder){ +bool subghz_protocol_nice_flo_send_key(SubGhzProtocolNiceFlo* instance, SubGhzProtocolCommonEncoder* encoder){ furi_assert(instance); furi_assert(encoder); size_t index = 0; @@ -137,9 +139,9 @@ void subghz_protocol_nice_flo_to_str(SubGhzProtocolNiceFlo* instance, string_t o string_cat_printf( output, - "%s %d Bit\r\n" - " KEY:0x%08lX\r\n" - " YEK:0x%08lX\r\n", + "%s %dbit\r\n" + "Key:0x%08lX\r\n" + "Yek:0x%08lX\r\n", instance->common.name, instance->common.code_last_count_bit, code_found_lo, @@ -159,7 +161,7 @@ void subghz_protocol_nice_flo_to_save_str(SubGhzProtocolNiceFlo* instance, strin (uint32_t)(instance->common.code_last_found & 0x00000000ffffffff)); } -bool subghz_protocol_nice_flo_to_load_protocol(FileWorker* file_worker, SubGhzProtocolNiceFlo* instance){ +bool subghz_protocol_nice_flo_to_load_protocol_from_file(FileWorker* file_worker, SubGhzProtocolNiceFlo* instance){ bool loaded = false; string_t temp_str; string_init(temp_str); @@ -195,3 +197,15 @@ bool subghz_protocol_nice_flo_to_load_protocol(FileWorker* file_worker, SubGhzPr return loaded; } + +void subghz_decoder_nice_flo_to_load_protocol( + SubGhzProtocolNiceFlo* instance, + void* context) { + furi_assert(context); + furi_assert(instance); + SubGhzProtocolCommonLoad* data = context; + instance->common.code_last_found = data->code_found; + instance->common.code_last_count_bit = data->code_count_bit; + instance->common.serial = 0x0; + instance->common.btn = 0x0; +} \ No newline at end of file diff --git a/lib/subghz/protocols/subghz_protocol_nice_flo.h b/lib/subghz/protocols/subghz_protocol_nice_flo.h index fc80f02a..3f76fe89 100644 --- a/lib/subghz/protocols/subghz_protocol_nice_flo.h +++ b/lib/subghz/protocols/subghz_protocol_nice_flo.h @@ -19,10 +19,10 @@ void subghz_protocol_nice_flo_free(SubGhzProtocolNiceFlo* instance); /** Get upload protocol * * @param instance - SubGhzProtocolCame instance - * @param encoder - SubGhzProtocolEncoderCommon encoder + * @param encoder - SubGhzProtocolCommonEncoder encoder * @return bool */ -bool subghz_protocol_nice_flo_send_key(SubGhzProtocolNiceFlo* instance, SubGhzProtocolEncoderCommon* encoder); +bool subghz_protocol_nice_flo_send_key(SubGhzProtocolNiceFlo* instance, SubGhzProtocolCommonEncoder* encoder); /** Reset internal state * @param instance - SubGhzProtocolNiceFlo instance @@ -44,4 +44,5 @@ void subghz_protocol_nice_flo_parse(SubGhzProtocolNiceFlo* instance, bool level, void subghz_protocol_nice_flo_to_str(SubGhzProtocolNiceFlo* instance, string_t output); void subghz_protocol_nice_flo_to_save_str(SubGhzProtocolNiceFlo* instance, string_t output); -bool subghz_protocol_nice_flo_to_load_protocol(FileWorker* file_worker, SubGhzProtocolNiceFlo* instance); +bool subghz_protocol_nice_flo_to_load_protocol_from_file(FileWorker* file_worker, SubGhzProtocolNiceFlo* instance); +void subghz_decoder_nice_flo_to_load_protocol(SubGhzProtocolNiceFlo* instance, void* context); diff --git a/lib/subghz/protocols/subghz_protocol_nice_flor_s.c b/lib/subghz/protocols/subghz_protocol_nice_flor_s.c index ab6b83ea..84b81334 100644 --- a/lib/subghz/protocols/subghz_protocol_nice_flor_s.c +++ b/lib/subghz/protocols/subghz_protocol_nice_flor_s.c @@ -23,6 +23,8 @@ SubGhzProtocolNiceFlorS* subghz_protocol_nice_flor_s_alloc() { instance->common.te_delta = 300; instance->common.type_protocol = TYPE_PROTOCOL_DYNAMIC; instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_protocol_nice_flor_s_to_str; + instance->common.to_load_protocol = + (SubGhzProtocolCommonLoadFromRAW)subghz_decoder_nice_flor_s_to_load_protocol; return instance; } @@ -224,10 +226,10 @@ void subghz_protocol_nice_flor_s_to_str(SubGhzProtocolNiceFlorS* instance, strin string_cat_printf( output, - "%s, %d Bit\r\n" - " KEY:0x%lX%08lX\r\n" - " SN:%05lX\r\n" - " CNT:%04X BTN:%02lX\r\n", + "%s %dbit\r\n" + "Key:0x%lX%08lX\r\n" + "Sn:%05lX\r\n" + "Cnt:%04X Btn:%02lX\r\n", instance->common.name, instance->common.code_last_count_bit, code_found_hi, @@ -236,4 +238,15 @@ void subghz_protocol_nice_flor_s_to_str(SubGhzProtocolNiceFlorS* instance, strin instance->common.cnt, instance->common.btn ); +} + +void subghz_decoder_nice_flor_s_to_load_protocol( + SubGhzProtocolNiceFlorS* instance, + void* context) { + furi_assert(context); + furi_assert(instance); + SubGhzProtocolCommonLoad* data = context; + instance->common.code_last_found = data->code_found; + instance->common.code_last_count_bit = data->code_count_bit; + subghz_nice_flor_s_decoder_decrypt(instance); } \ No newline at end of file diff --git a/lib/subghz/protocols/subghz_protocol_nice_flor_s.h b/lib/subghz/protocols/subghz_protocol_nice_flor_s.h index 32ae54fa..6127f94f 100644 --- a/lib/subghz/protocols/subghz_protocol_nice_flor_s.h +++ b/lib/subghz/protocols/subghz_protocol_nice_flor_s.h @@ -50,3 +50,4 @@ void subghz_protocol_nice_flor_s_parse(SubGhzProtocolNiceFlorS* instance, bool l * @param output - output string */ void subghz_protocol_nice_flor_s_to_str(SubGhzProtocolNiceFlorS* instance, string_t output); +void subghz_decoder_nice_flor_s_to_load_protocol(SubGhzProtocolNiceFlorS* instance, void* context); \ No newline at end of file diff --git a/lib/subghz/protocols/subghz_protocol_princeton.c b/lib/subghz/protocols/subghz_protocol_princeton.c index c05f297b..fe51ca0f 100644 --- a/lib/subghz/protocols/subghz_protocol_princeton.c +++ b/lib/subghz/protocols/subghz_protocol_princeton.c @@ -16,7 +16,6 @@ struct SubGhzEncoderPrinceton { size_t front; }; - SubGhzEncoderPrinceton* subghz_encoder_princeton_alloc() { SubGhzEncoderPrinceton* instance = furi_alloc(sizeof(SubGhzEncoderPrinceton)); return instance; @@ -27,16 +26,15 @@ void subghz_encoder_princeton_free(SubGhzEncoderPrinceton* instance) { free(instance); } -void subghz_encoder_princeton_set_te(SubGhzEncoderPrinceton* instance, void* decoder){ - SubGhzDecoderPrinceton* pricenton = decoder; - if((pricenton->te) !=0){ +void subghz_encoder_princeton_set_te(SubGhzEncoderPrinceton* instance, void* decoder) { + SubGhzDecoderPrinceton* pricenton = decoder; + if((pricenton->te) != 0) { instance->te = pricenton->te; - }else{ + } else { instance->te = SUBGHZ_PT_SHORT; } } - void subghz_encoder_princeton_set(SubGhzEncoderPrinceton* instance, uint32_t key, size_t repeat) { furi_assert(instance); instance->te = SUBGHZ_PT_SHORT; @@ -93,11 +91,13 @@ SubGhzDecoderPrinceton* subghz_decoder_princeton_alloc(void) { instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_decoder_princeton_to_str; instance->common.to_save_string = (SubGhzProtocolCommonGetStrSave)subghz_decoder_princeton_to_save_str; - instance->common.to_load_protocol= - (SubGhzProtocolCommonLoad)subghz_decoder_princeton_to_load_protocol; + instance->common.to_load_protocol_from_file = + (SubGhzProtocolCommonLoadFromFile)subghz_decoder_princeton_to_load_protocol_from_file; + instance->common.to_load_protocol = + (SubGhzProtocolCommonLoadFromRAW)subghz_decoder_princeton_to_load_protocol; instance->common.get_upload_protocol = - (SubGhzProtocolEncoderCommonGetUpLoad)subghz_protocol_princeton_send_key; - + (SubGhzProtocolCommonEncoderGetUpLoad)subghz_protocol_princeton_send_key; + return instance; } @@ -106,30 +106,37 @@ void subghz_decoder_princeton_free(SubGhzDecoderPrinceton* instance) { free(instance); } -bool subghz_protocol_princeton_send_key(SubGhzDecoderPrinceton* instance, SubGhzProtocolEncoderCommon* encoder){ +uint16_t subghz_protocol_princeton_get_te(void* context) { + SubGhzDecoderPrinceton* instance = context; + return instance->te; +} + +bool subghz_protocol_princeton_send_key( + SubGhzDecoderPrinceton* instance, + SubGhzProtocolCommonEncoder* encoder) { furi_assert(instance); furi_assert(encoder); size_t index = 0; - encoder->size_upload =(instance->common.code_last_count_bit * 2) + 2; + encoder->size_upload = (instance->common.code_last_count_bit * 2) + 2; if(encoder->size_upload > SUBGHZ_ENCODER_UPLOAD_MAX_SIZE) return false; - + //Send key data - for (uint8_t i = instance->common.code_last_count_bit; i > 0; i--) { - if(bit_read(instance->common.code_last_found, i - 1)){ + for(uint8_t i = instance->common.code_last_count_bit; i > 0; i--) { + if(bit_read(instance->common.code_last_found, i - 1)) { //send bit 1 - encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->te*3); + encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->te * 3); encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->te); - }else{ + } else { //send bit 0 encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->te); - encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->te*3); + encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->te * 3); } } //Send Stop bit encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->te); //Send PT_GUARD - encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->te*30); + encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->te * 30); return true; } @@ -221,17 +228,18 @@ void subghz_decoder_princeton_to_str(SubGhzDecoderPrinceton* instance, string_t string_cat_printf( output, - "%s %d Bit te %dus\r\n" - " KEY:0x%08lX\r\n" - " YEK:0x%08lX\r\n" - " SN:0x%05lX BTN:%02X\r\n", + "%s %dbit\r\n" + "Key:0x%08lX\r\n" + "Yek:0x%08lX\r\n" + "Sn:0x%05lX BTN:%02X\r\n" + "Te:%dus\r\n", instance->common.name, instance->common.code_last_count_bit, - instance->te, code_found_lo, code_found_reverse_lo, instance->common.serial, - instance->common.btn); + instance->common.btn, + instance->te); } void subghz_decoder_princeton_to_save_str(SubGhzDecoderPrinceton* instance, string_t output) { @@ -247,7 +255,9 @@ void subghz_decoder_princeton_to_save_str(SubGhzDecoderPrinceton* instance, stri (uint32_t)(instance->common.code_last_found & 0x00000000ffffffff)); } -bool subghz_decoder_princeton_to_load_protocol(FileWorker* file_worker, SubGhzDecoderPrinceton* instance){ +bool subghz_decoder_princeton_to_load_protocol_from_file( + FileWorker* file_worker, + SubGhzDecoderPrinceton* instance) { bool loaded = false; string_t temp_str; string_init(temp_str); @@ -295,3 +305,16 @@ bool subghz_decoder_princeton_to_load_protocol(FileWorker* file_worker, SubGhzDe return loaded; } + +void subghz_decoder_princeton_to_load_protocol( + SubGhzDecoderPrinceton* instance, + void* context) { + furi_assert(context); + furi_assert(instance); + SubGhzProtocolCommonLoad* data = context; + instance->common.code_last_found = data->code_found; + instance->common.code_last_count_bit = data->code_count_bit; + instance->te = data->param1; + instance->common.serial = instance->common.code_last_found >> 4; + instance->common.btn = (uint8_t)instance->common.code_last_found & 0x00000F; +} diff --git a/lib/subghz/protocols/subghz_protocol_princeton.h b/lib/subghz/protocols/subghz_protocol_princeton.h index a414b6a2..463d9ada 100644 --- a/lib/subghz/protocols/subghz_protocol_princeton.h +++ b/lib/subghz/protocols/subghz_protocol_princeton.h @@ -20,7 +20,6 @@ SubGhzEncoderPrinceton* subghz_encoder_princeton_alloc(); */ void subghz_encoder_princeton_free(SubGhzEncoderPrinceton* instance); - /** Set new encoder params * @param instance - SubGhzEncoderPrinceton instance * @param key - 24bit key @@ -40,14 +39,10 @@ size_t subghz_encoder_princeton_get_repeat_left(SubGhzEncoderPrinceton* instance */ LevelDuration subghz_encoder_princeton_yield(void* context); - /** SubGhzDecoderPrinceton anonymous type */ typedef struct SubGhzDecoderPrinceton SubGhzDecoderPrinceton; - -void subghz_encoder_princeton_set_te( - SubGhzEncoderPrinceton* instance, - void* decoder); +void subghz_encoder_princeton_set_te(SubGhzEncoderPrinceton* instance, void* decoder); /** Allocate SubGhzDecoderPrinceton * @@ -61,13 +56,17 @@ SubGhzDecoderPrinceton* subghz_decoder_princeton_alloc(); */ void subghz_decoder_princeton_free(SubGhzDecoderPrinceton* instance); +uint16_t subghz_protocol_princeton_get_te(void* context); + /** Get upload protocol * * @param instance - SubGhzDecoderPrinceton instance - * @param encoder - SubGhzProtocolEncoderCommon encoder + * @param encoder - SubGhzProtocolCommonEncoder encoder * @return bool */ -bool subghz_protocol_princeton_send_key(SubGhzDecoderPrinceton* instance, SubGhzProtocolEncoderCommon* encoder); +bool subghz_protocol_princeton_send_key( + SubGhzDecoderPrinceton* instance, + SubGhzProtocolCommonEncoder* encoder); /** Reset internal state * @param instance - SubGhzDecoderPrinceton instance @@ -79,7 +78,10 @@ void subghz_decoder_princeton_reset(SubGhzDecoderPrinceton* instance); * @param instance - SubGhzDecoderPrinceton instance * @param data - LevelDuration level_duration */ -void subghz_decoder_princeton_parse(SubGhzDecoderPrinceton* instance, bool level, uint32_t duration); +void subghz_decoder_princeton_parse( + SubGhzDecoderPrinceton* instance, + bool level, + uint32_t duration); /** Outputting information from the parser * @@ -89,6 +91,10 @@ void subghz_decoder_princeton_parse(SubGhzDecoderPrinceton* instance, bool level void subghz_decoder_princeton_to_str(SubGhzDecoderPrinceton* instance, string_t output); void subghz_decoder_princeton_to_save_str(SubGhzDecoderPrinceton* instance, string_t output); -bool subghz_decoder_princeton_to_load_protocol(FileWorker* file_worker, SubGhzDecoderPrinceton* instance); - +bool subghz_decoder_princeton_to_load_protocol_from_file( + FileWorker* file_worker, + SubGhzDecoderPrinceton* instance); +void subghz_decoder_princeton_to_load_protocol( + SubGhzDecoderPrinceton* instance, + void* context) ; diff --git a/lib/subghz/protocols/subghz_protocol_star_line.c b/lib/subghz/protocols/subghz_protocol_star_line.c index 1890b5e6..384ec10c 100644 --- a/lib/subghz/protocols/subghz_protocol_star_line.c +++ b/lib/subghz/protocols/subghz_protocol_star_line.c @@ -27,6 +27,8 @@ SubGhzProtocolStarLine* subghz_protocol_star_line_alloc(SubGhzKeystore* keystore instance->common.te_delta = 120; instance->common.type_protocol = TYPE_PROTOCOL_DYNAMIC; instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_protocol_star_line_to_str; + instance->common.to_load_protocol = + (SubGhzProtocolCommonLoadFromRAW)subghz_decoder_star_line_to_load_protocol; return instance; } @@ -36,6 +38,12 @@ void subghz_protocol_star_line_free(SubGhzProtocolStarLine* instance) { free(instance); } +const char* subghz_protocol_star_line_get_manufacture_name (void* context){ + SubGhzProtocolStarLine* instance = context; + subghz_protocol_star_line_check_remote_controller(instance); + return instance->manufacture_name; +} + /** Send bit * * @param instance - SubGhzProtocolStarLine instance @@ -268,20 +276,32 @@ void subghz_protocol_star_line_to_str(SubGhzProtocolStarLine* instance, string_t uint32_t code_found_reverse_lo = code_found_reverse&0x00000000ffffffff; string_cat_printf( output, - "%s, %d Bit\r\n" - "KEY:0x%lX%lX\r\n" - "FIX:%08lX MF:%s \r\n" - "HOP:%08lX \r\n" - "SN:%06lX CNT:%04X B:%02lX\r\n", + "%s %dbit\r\n" + "Key:0x%lX%lX\r\n" + "Fix:0x%08lX Cnt:%04X\r\n" + "Hop:0x%08lX Btn:%02lX\r\n" + "MF:%s\r\n" + "Sn:0x%07lX \r\n", instance->common.name, instance->common.code_last_count_bit, code_found_hi, code_found_lo, code_found_reverse_hi, - instance->manufacture_name, + instance->common.cnt, code_found_reverse_lo, - instance->common.serial, - instance->common.cnt, - instance->common.btn + instance->common.btn, + instance->manufacture_name, + instance->common.serial ); } + +void subghz_decoder_star_line_to_load_protocol( + SubGhzProtocolStarLine* instance, + void* context) { + furi_assert(context); + furi_assert(instance); + SubGhzProtocolCommonLoad* data = context; + instance->common.code_last_found = data->code_found; + instance->common.code_last_count_bit = data->code_count_bit; + subghz_protocol_star_line_check_remote_controller(instance); +} \ No newline at end of file diff --git a/lib/subghz/protocols/subghz_protocol_star_line.h b/lib/subghz/protocols/subghz_protocol_star_line.h index e39cbbc6..840f0344 100644 --- a/lib/subghz/protocols/subghz_protocol_star_line.h +++ b/lib/subghz/protocols/subghz_protocol_star_line.h @@ -18,6 +18,8 @@ SubGhzProtocolStarLine* subghz_protocol_star_line_alloc(SubGhzKeystore* keystore */ void subghz_protocol_star_line_free(SubGhzProtocolStarLine* instance); +const char* subghz_protocol_star_line_get_manufacture_name(void* context); + /** Sends the key on the air * * @param instance - SubGhzProtocolStarLine instance @@ -51,3 +53,4 @@ void subghz_protocol_star_line_parse(SubGhzProtocolStarLine* instance, bool leve * @param output - output string */ void subghz_protocol_star_line_to_str(SubGhzProtocolStarLine* instance, string_t output); +void subghz_decoder_star_line_to_load_protocol(SubGhzProtocolStarLine* instance, void* context); diff --git a/lib/subghz/subghz_worker.c b/lib/subghz/subghz_worker.c index 8cab5e01..626ec77f 100644 --- a/lib/subghz/subghz_worker.c +++ b/lib/subghz/subghz_worker.c @@ -117,3 +117,8 @@ void subghz_worker_stop(SubGhzWorker* instance) { furi_thread_join(instance->thread); } + +bool subghz_worker_is_running(SubGhzWorker* instance) { + furi_assert(instance); + return instance->running; +} diff --git a/lib/subghz/subghz_worker.h b/lib/subghz/subghz_worker.h index 6ef10190..4516352a 100644 --- a/lib/subghz/subghz_worker.h +++ b/lib/subghz/subghz_worker.h @@ -54,3 +54,9 @@ void subghz_worker_start(SubGhzWorker* instance); * @param instance SubGhzWorker instance */ void subghz_worker_stop(SubGhzWorker* instance); + +/** Check if worker is running + * @param instance SubGhzWorker instance + * @return bool - true if running + */ +bool subghz_worker_is_running(SubGhzWorker* instance);