diff options
author | Skorpionm <85568270+Skorpionm@users.noreply.github.com> | 2021-08-16 22:56:23 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-08-16 22:56:23 +0300 |
commit | a024e470b7878c3ff6c129e3b6cf4eac609cb1bf (patch) | |
tree | 31d97ffd9ed07fc76abd113088666ae8144ebadc /applications/subghz | |
parent | a548525d757e1e06729ffbcb405c5e5fa0de914f (diff) |
SubGhz: read and save static remotes. Create new static and dynamic remotes. (#646)
* SubGhz: the functions of saving loading KeeLog have been modified, saving KeeLog is prohibited
* SubGhz: Fix displaying Nice FlorS in the Raed scene
* SubGhz: Fix displaying Faac SLH in the Raed scene
* SubGhz: Fix displaying iDo in the Raed scene
* SubGhz: Fix displaying Star Line in the Raed scene
* SubGhz: Fix displaying Nice Flo in the Raed scene, added save and load functions. (testing needed, no remote control)
* SubGhz: subghz_beginadded common encoder upload signal
* SubGhz: add Came encoder
* SubGhz: modified pricenton encoder, fix view transmitter hide the "Send" button if there is no encoder
* SubGhz: add nice flo encoder, need testing no remote control
* SubGhz: add gate_tx encoder
* SubGhz: add nero_sketch encoder
* SubGhz: add keelog encoder
* SubGhz: add long upload upload while the button is pressed while releasing the transfer is over, with a check for sticking (maximum 200 upload repetitions)
* SubGhz: fix max upload
* SubGhz: Fix structure subghz add encoder
* SubGhz: add generating and sending a dynamic keelog key, refactoring the code
* SubGhz: add notifications
* SubGhz: add creating a new remote control (Pricenton, Nice Flo 12bit, Nice Flo 24bit, CAME 12bit, CAME 24bit, Gate TX, DoorHan)
* SubGhz: Fix load file, fix scene start
* Subghz: Fix show key
* SubGhz: Fix subghz_cli
* SubGhz: Fix furi-hal-subghz
* Format sources
* SubGhz: standard notification scheme, fix broken assert in DMA.
* SubGhz: move level alignment logic to furi-hal-subghz, fix spelling, cleanup.
Co-authored-by: Aleksandr Kutuzov <alleteam@gmail.com>
Diffstat (limited to 'applications/subghz')
-rw-r--r-- | applications/subghz/scenes/subghz_scene_analyze.c | 6 | ||||
-rw-r--r-- | applications/subghz/scenes/subghz_scene_config.h | 1 | ||||
-rw-r--r-- | applications/subghz/scenes/subghz_scene_read.c | 9 | ||||
-rw-r--r-- | applications/subghz/scenes/subghz_scene_save_name.c | 48 | ||||
-rw-r--r-- | applications/subghz/scenes/subghz_scene_saved.c | 70 | ||||
-rw-r--r-- | applications/subghz/scenes/subghz_scene_set_type.c | 173 | ||||
-rw-r--r-- | applications/subghz/scenes/subghz_scene_start.c | 16 | ||||
-rw-r--r-- | applications/subghz/scenes/subghz_scene_transmitter.c | 45 | ||||
-rw-r--r-- | applications/subghz/subghz.c | 7 | ||||
-rw-r--r-- | applications/subghz/subghz_cli.c | 21 | ||||
-rw-r--r-- | applications/subghz/subghz_i.c | 153 | ||||
-rw-r--r-- | applications/subghz/subghz_i.h | 15 | ||||
-rw-r--r-- | applications/subghz/views/subghz_receiver.c | 7 | ||||
-rw-r--r-- | applications/subghz/views/subghz_static.c | 2 | ||||
-rw-r--r-- | applications/subghz/views/subghz_test_packet.c | 2 | ||||
-rw-r--r-- | applications/subghz/views/subghz_transmitter.c | 22 | ||||
-rw-r--r-- | applications/subghz/views/subghz_transmitter.h | 3 |
17 files changed, 433 insertions, 167 deletions
diff --git a/applications/subghz/scenes/subghz_scene_analyze.c b/applications/subghz/scenes/subghz_scene_analyze.c index e5985893..33a891f2 100644 --- a/applications/subghz/scenes/subghz_scene_analyze.c +++ b/applications/subghz/scenes/subghz_scene_analyze.c @@ -6,7 +6,11 @@ const void subghz_scene_analyze_on_enter(void* context) { } const bool subghz_scene_analyze_on_event(void* context, SceneManagerEvent event) { - // SubGhz* subghz = context; + SubGhz* subghz = context; + if(event.type == SceneManagerEventTypeTick) { + notification_message(subghz->notifications, &sequence_blink_blue_10); + return true; + } return false; } diff --git a/applications/subghz/scenes/subghz_scene_config.h b/applications/subghz/scenes/subghz_scene_config.h index aa2ddd6a..460001d2 100644 --- a/applications/subghz/scenes/subghz_scene_config.h +++ b/applications/subghz/scenes/subghz_scene_config.h @@ -10,3 +10,4 @@ ADD_SCENE(subghz, static, Static) ADD_SCENE(subghz, test, Test) ADD_SCENE(subghz, test_carrier, TestCarrier) ADD_SCENE(subghz, test_packet, TestPacket) +ADD_SCENE(subghz, set_type, SetType) diff --git a/applications/subghz/scenes/subghz_scene_read.c b/applications/subghz/scenes/subghz_scene_read.c index 02906ff8..7cab340d 100644 --- a/applications/subghz/scenes/subghz_scene_read.c +++ b/applications/subghz/scenes/subghz_scene_read.c @@ -25,6 +25,7 @@ const void subghz_scene_read_on_enter(void* context) { //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); @@ -36,9 +37,13 @@ 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, SubGhzViewReceiver); + 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; } @@ -46,7 +51,7 @@ const bool subghz_scene_read_on_event(void* context, SceneManagerEvent event) { const void subghz_scene_read_on_exit(void* context) { SubGhz* subghz = context; - //Stop CC1101 + // Stop CC1101 subghz_worker_stop(subghz->worker); furi_hal_subghz_stop_async_rx(); subghz_end(); diff --git a/applications/subghz/scenes/subghz_scene_save_name.c b/applications/subghz/scenes/subghz_scene_save_name.c index 329c6931..5a3452f8 100644 --- a/applications/subghz/scenes/subghz_scene_save_name.c +++ b/applications/subghz/scenes/subghz_scene_save_name.c @@ -4,52 +4,6 @@ #define SCENE_SAVE_NAME_CUSTOM_EVENT (0UL) -bool subghz_scene_save_data_to_file(void* context, const char* dev_name) { - SubGhz* subghz = context; - FileWorker* file_worker = file_worker_alloc(false); - string_t dev_file_name; - string_init(dev_file_name); - string_t temp_str; - string_init(temp_str); - bool saved = false; - - do { - // Create subghz folder directory if necessary - if(!file_worker_mkdir(file_worker, SUBGHZ_APP_FOLDER)) { - break; - } - // Create saved directory if necessary - if(!file_worker_mkdir(file_worker, SUBGHZ_APP_PATH_FOLDER)) { - break; - } - // First remove subghz device file if it was saved - string_printf( - dev_file_name, "%s/%s%s", SUBGHZ_APP_PATH_FOLDER, dev_name, SUBGHZ_APP_EXTENSION); - if(!file_worker_remove(file_worker, string_get_cstr(dev_file_name))) { - break; - } - // Open file - if(!file_worker_open( - file_worker, string_get_cstr(dev_file_name), FSAM_WRITE, FSOM_CREATE_ALWAYS)) { - break; - } - //Get string save - subghz->protocol_result->to_save_string(subghz->protocol_result, temp_str); - // Prepare and write data to file - if(!file_worker_write(file_worker, string_get_cstr(temp_str), string_size(temp_str))) { - break; - } - saved = true; - } while(0); - - string_clear(temp_str); - string_clear(dev_file_name); - file_worker_close(file_worker); - file_worker_free(file_worker); - - return saved; -} - void subghz_scene_save_name_text_input_callback(void* context) { SubGhz* subghz = context; view_dispatcher_send_custom_event(subghz->view_dispatcher, SCENE_SAVE_NAME_CUSTOM_EVENT); @@ -81,7 +35,7 @@ const bool subghz_scene_save_name_on_event(void* context, SceneManagerEvent even if(event.type == SceneManagerEventTypeCustom) { if(event.event == SCENE_SAVE_NAME_CUSTOM_EVENT) { - if(subghz_scene_save_data_to_file(subghz, subghz->text_store)) { + if(subghz_save_protocol_to_file(subghz, subghz->text_store)) { scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaveSuccess); return true; } else { diff --git a/applications/subghz/scenes/subghz_scene_saved.c b/applications/subghz/scenes/subghz_scene_saved.c index d1dd058a..09b7a4ac 100644 --- a/applications/subghz/scenes/subghz_scene_saved.c +++ b/applications/subghz/scenes/subghz_scene_saved.c @@ -1,77 +1,9 @@ #include "../subghz_i.h" -bool subghz_scene_saved_file_select(SubGhz* subghz) { - furi_assert(subghz); - - FileWorker* file_worker = file_worker_alloc(false); - string_t protocol_file_name; - string_init(protocol_file_name); - string_t temp_str; - string_init(temp_str); - - // Input events and views are managed by file_select - bool res = file_worker_file_select( - file_worker, - SUBGHZ_APP_PATH_FOLDER, - SUBGHZ_APP_EXTENSION, - subghz->text_store, - sizeof(subghz->text_store), - NULL); - - if(res) { - // Get key file path - string_printf( - protocol_file_name, - "%s/%s%s", - SUBGHZ_APP_PATH_FOLDER, - subghz->text_store, - SUBGHZ_APP_EXTENSION); - } else { - string_clear(temp_str); - string_clear(protocol_file_name); - - file_worker_close(file_worker); - file_worker_free(file_worker); - return res; - } - - do { - if(!file_worker_open( - file_worker, string_get_cstr(protocol_file_name), FSAM_READ, FSOM_OPEN_EXISTING)) { - break; - } - // Read and parse name protocol from 1st line - if(!file_worker_read_until(file_worker, temp_str, '\n')) { - break; - } - // strlen("Protocol: ") = 10 - string_right(temp_str, 10); - 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"); - break; - } - res = true; - } while(0); - - string_clear(temp_str); - string_clear(protocol_file_name); - - file_worker_close(file_worker); - file_worker_free(file_worker); - - return res; -} - const void subghz_scene_saved_on_enter(void* context) { SubGhz* subghz = context; - if(subghz_scene_saved_file_select(subghz)) { + if(subghz_saved_protocol_select(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 new file mode 100644 index 00000000..d3c36f54 --- /dev/null +++ b/applications/subghz/scenes/subghz_scene_set_type.c @@ -0,0 +1,173 @@ +#include "../subghz_i.h" +#include "../lib/subghz/protocols/subghz_protocol_keeloq.h" + +enum SubmenuIndex { + SubmenuIndexPricenton, + SubmenuIndexNiceFlo12bit, + SubmenuIndexNiceFlo24bit, + SubmenuIndexCAME12bit, + SubmenuIndexCAME24bit, + SubmenuIndexNeroSketch, + SubmenuIndexGateTX, + SubmenuIndexDoorHan, +}; + +bool subghz_scene_set_type_submenu_to_find_protocol(void* context, const char* protocol_name) { + SubGhz* subghz = context; + subghz->protocol_result = subghz_protocol_get_by_name(subghz->protocol, protocol_name); + if(subghz->protocol_result == NULL) { + //show error + return false; + } + return true; +} + +void subghz_scene_set_type_submenu_callback(void* context, uint32_t index) { + SubGhz* subghz = context; + view_dispatcher_send_custom_event(subghz->view_dispatcher, index); +} + +const void subghz_scene_set_type_on_enter(void* context) { + SubGhz* subghz = context; + + submenu_add_item( + subghz->submenu, + "Pricenton", + SubmenuIndexPricenton, + subghz_scene_set_type_submenu_callback, + subghz); + submenu_add_item( + subghz->submenu, + "Nice Flo 12bit", + SubmenuIndexNiceFlo12bit, + subghz_scene_set_type_submenu_callback, + subghz); + submenu_add_item( + subghz->submenu, + "Nice Flo 24bit", + SubmenuIndexNiceFlo24bit, + subghz_scene_set_type_submenu_callback, + subghz); + submenu_add_item( + subghz->submenu, + "CAME 12bit", + SubmenuIndexCAME12bit, + subghz_scene_set_type_submenu_callback, + subghz); + submenu_add_item( + subghz->submenu, + "CAME 24bit", + SubmenuIndexCAME24bit, + subghz_scene_set_type_submenu_callback, + subghz); + // submenu_add_item( + // subghz->submenu, "Nero Sketch", SubmenuIndexNeroSketch, subghz_scene_set_type_submenu_callback, subghz); + submenu_add_item( + subghz->submenu, + "Gate TX", + SubmenuIndexGateTX, + subghz_scene_set_type_submenu_callback, + subghz); + submenu_add_item( + subghz->submenu, + "DoorHan", + SubmenuIndexDoorHan, + subghz_scene_set_type_submenu_callback, + subghz); + + submenu_set_selected_item( + subghz->submenu, scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneSetType)); + + view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewMenu); +} + +const bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) { + SubGhz* subghz = context; + bool generated_protocol = false; + + if(event.type == SceneManagerEventTypeCustom) { + uint32_t key = subghz_random_serial(); + switch(event.event) { + case SubmenuIndexPricenton: + if(subghz_scene_set_type_submenu_to_find_protocol(subghz, "Princeton")) { + subghz->protocol_result->code_last_count_bit = 24; + key = (key & 0x00FFFFF0) | 0x4; //btn 0x1, 0x2, 0x4, 0x8 + subghz->protocol_result->code_last_found = key; + generated_protocol = true; + } + break; + case SubmenuIndexNiceFlo12bit: + if(subghz_scene_set_type_submenu_to_find_protocol(subghz, "Nice FLO")) { + subghz->protocol_result->code_last_count_bit = 12; + key = (key & 0x0000FFF0) | 0x1; //btn 0x1, 0x2, 0x4 + subghz->protocol_result->code_last_found = key; + generated_protocol = true; + } + break; + case SubmenuIndexNiceFlo24bit: + if(subghz_scene_set_type_submenu_to_find_protocol(subghz, "Nice FLO")) { + subghz->protocol_result->code_last_count_bit = 24; + key = (key & 0x00FFFFF0) | 0x4; //btn 0x1, 0x2, 0x4, 0x8 + subghz->protocol_result->code_last_found = key; + generated_protocol = true; + } + break; + case SubmenuIndexCAME12bit: + if(subghz_scene_set_type_submenu_to_find_protocol(subghz, "CAME")) { + subghz->protocol_result->code_last_count_bit = 12; + key = (key & 0x0000FFF0) | 0x1; //btn 0x1, 0x2, 0x4 + subghz->protocol_result->code_last_found = key; + generated_protocol = true; + } + break; + case SubmenuIndexCAME24bit: + if(subghz_scene_set_type_submenu_to_find_protocol(subghz, "CAME")) { + subghz->protocol_result->code_last_count_bit = 24; + key = (key & 0x00FFFFF0) | 0x4; //btn 0x1, 0x2, 0x4, 0x8 + subghz->protocol_result->code_last_found = key; + generated_protocol = true; + } + break; + // case SubmenuIndexNeroSketch: + // /* code */ + // break; + case SubmenuIndexGateTX: + if(subghz_scene_set_type_submenu_to_find_protocol(subghz, "GateTX")) { + subghz->protocol_result->code_last_count_bit = 24; + key = (key & 0x00F0FFFF) | 0xF << 16; //btn 0xF, 0xC, 0xA, 0x6 + subghz->protocol_result->code_last_found = subghz_protocol_common_reverse_key( + key, subghz->protocol_result->code_last_count_bit); + generated_protocol = true; + } + break; + case SubmenuIndexDoorHan: + if(subghz_scene_set_type_submenu_to_find_protocol(subghz, "KeeLoq")) { + subghz->protocol_result->code_last_count_bit = 64; + subghz->protocol_result->serial = key & 0x0FFFFFFF; + subghz->protocol_result->btn = 0x2; //btn 0x1, 0x2, 0x4, 0x8 + subghz->protocol_result->cnt = 0x0003; + subghz_protocol_keeloq_set_manufacture_name(subghz->protocol_result, "DoorHan"); + subghz->protocol_result->code_last_found = + subghz_protocol_keeloq_gen_key(subghz->protocol_result); + + generated_protocol = true; + } + break; + + default: + return false; + break; + } + if(generated_protocol) { + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaveName); + return true; + } + } + + return false; +} + +const void subghz_scene_set_type_on_exit(void* context) { + SubGhz* subghz = context; + submenu_clean(subghz->submenu); +} diff --git a/applications/subghz/scenes/subghz_scene_start.c b/applications/subghz/scenes/subghz_scene_start.c index 88b69962..d30536a5 100644 --- a/applications/subghz/scenes/subghz_scene_start.c +++ b/applications/subghz/scenes/subghz_scene_start.c @@ -6,6 +6,7 @@ enum SubmenuIndex { SubmenuIndexSaved, SubmenuIndexStatic, SubmenuIndexTest, + SubmenuIndexAddManualy, }; void subghz_scene_start_submenu_callback(void* context, uint32_t index) { @@ -15,7 +16,9 @@ void subghz_scene_start_submenu_callback(void* context, uint32_t index) { const void subghz_scene_start_on_enter(void* context) { SubGhz* subghz = context; - + if(subghz->state_notifications == NOTIFICATION_STARTING_STATE) { + subghz->state_notifications = NOTIFICATION_IDLE_STATE; + } submenu_add_item( subghz->submenu, "Analyze", @@ -27,6 +30,12 @@ const void subghz_scene_start_on_enter(void* context) { submenu_add_item( subghz->submenu, "Saved", SubmenuIndexSaved, subghz_scene_start_submenu_callback, subghz); submenu_add_item( + subghz->submenu, + "Add manually", + SubmenuIndexAddManualy, + subghz_scene_start_submenu_callback, + subghz); + submenu_add_item( subghz->submenu, "Static", SubmenuIndexStatic, subghz_scene_start_submenu_callback, subghz); submenu_add_item( subghz->submenu, "Test", SubmenuIndexTest, subghz_scene_start_submenu_callback, subghz); @@ -56,6 +65,11 @@ const bool subghz_scene_start_on_event(void* context, SceneManagerEvent event) { subghz->scene_manager, SubGhzSceneStart, SubmenuIndexSaved); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaved); return true; + } else if(event.event == SubmenuIndexAddManualy) { + scene_manager_set_scene_state( + subghz->scene_manager, SubGhzSceneStart, SubmenuIndexAddManualy); + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSetType); + return true; } else if(event.event == SubmenuIndexStatic) { scene_manager_set_scene_state( subghz->scene_manager, SubGhzSceneStart, SubmenuIndexStatic); diff --git a/applications/subghz/scenes/subghz_scene_transmitter.c b/applications/subghz/scenes/subghz_scene_transmitter.c index c2c9ce51..e28e6d88 100644 --- a/applications/subghz/scenes/subghz_scene_transmitter.c +++ b/applications/subghz/scenes/subghz_scene_transmitter.c @@ -1,28 +1,5 @@ #include "../subghz_i.h" #include "../views/subghz_transmitter.h" -#include "lib/subghz/protocols/subghz_protocol_princeton.h" - -void subghz_scene_transmitter_tx(void* context) { - SubGhz* subghz = context; - SubGhzEncoderPrinceton* encoder = subghz_encoder_princeton_alloc(); - - subghz_encoder_princeton_reset(encoder, subghz->protocol_result->code_last_found, 4); - subghz_encoder_princeton_set_te(encoder, subghz->protocol_result); - - subghz_begin(FuriHalSubGhzPresetOokAsync); - subghz_tx(433920000); - - furi_hal_subghz_start_async_tx(subghz_encoder_princeton_yield, encoder); - - while(!furi_hal_subghz_is_async_tx_complete()) { - osDelay(20); - } - - //Stop tx - furi_hal_subghz_stop_async_tx(); - subghz_end(); - subghz_encoder_princeton_free(encoder); -} void subghz_scene_transmitter_callback(SubghzTransmitterEvent event, void* context) { furi_assert(context); @@ -35,24 +12,36 @@ const void subghz_scene_transmitter_on_enter(void* context) { SubghzTransmitter* subghz_transmitter = subghz->subghz_transmitter; subghz_transmitter_set_callback(subghz_transmitter, subghz_scene_transmitter_callback, subghz); - subghz_transmitter_set_protocol(subghz_transmitter, subghz->protocol_result); + view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewTransmitter); + + subghz->state_notifications = NOTIFICATION_IDLE_STATE; } const bool subghz_scene_transmitter_on_event(void* context, SceneManagerEvent event) { SubGhz* subghz = context; if(event.type == SceneManagerEventTypeCustom) { - if(event.event == SubghzTransmitterEventSend) { - //scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaveName); - subghz_scene_transmitter_tx(subghz); + if(event.event == SubghzTransmitterEventSendStart) { + subghz->state_notifications = NOTIFICATION_TX_STATE; + subghz_transmitter_tx_start(subghz); + return true; + } else if(event.event == SubghzTransmitterEventSendStop) { + subghz->state_notifications = NOTIFICATION_IDLE_STATE; + subghz_transmitter_tx_stop(subghz); return true; } else if(event.event == SubghzTransmitterEventBack) { + subghz->state_notifications = NOTIFICATION_IDLE_STATE; scene_manager_search_and_switch_to_previous_scene( subghz->scene_manager, SubGhzSceneStart); return true; } + } else if(event.type == SceneManagerEventTypeTick) { + if(subghz->state_notifications == NOTIFICATION_TX_STATE) { + notification_message(subghz->notifications, &sequence_blink_red_10); + } + return true; } return false; } @@ -60,6 +49,6 @@ const bool subghz_scene_transmitter_on_event(void* context, SceneManagerEvent ev const void subghz_scene_transmitter_on_exit(void* context) { SubGhz* subghz = context; SubghzTransmitter* subghz_transmitter = subghz->subghz_transmitter; - subghz_transmitter_set_callback(subghz_transmitter, NULL, subghz); + subghz->state_notifications = NOTIFICATION_IDLE_STATE; } diff --git a/applications/subghz/subghz.c b/applications/subghz/subghz.c index bf45208b..acc054ab 100644 --- a/applications/subghz/subghz.c +++ b/applications/subghz/subghz.c @@ -62,6 +62,9 @@ SubGhz* subghz_alloc() { view_dispatcher_set_tick_event_callback( subghz->view_dispatcher, subghz_tick_event_callback, 100); + // Open Notification record + subghz->notifications = furi_record_open("notification"); + // SubMenu subghz->submenu = submenu_alloc(); view_dispatcher_add_view( @@ -196,6 +199,10 @@ void subghz_free(SubGhz* subghz) { subghz_protocol_free(subghz->protocol); subghz_worker_free(subghz->worker); + // Notifications + furi_record_close("notification"); + subghz->notifications = NULL; + // The rest free(subghz); } diff --git a/applications/subghz/subghz_cli.c b/applications/subghz/subghz_cli.c index 9681fdef..0e4eb7fe 100644 --- a/applications/subghz/subghz_cli.c +++ b/applications/subghz/subghz_cli.c @@ -4,6 +4,7 @@ #include <furi-hal.h> #include <stream_buffer.h> #include <lib/subghz/protocols/subghz_protocol.h> +#include <lib/subghz/protocols/subghz_protocol_common.h> #include <lib/subghz/protocols/subghz_protocol_princeton.h> #define SUBGHZ_FREQUENCY_RANGE_STR \ @@ -129,25 +130,29 @@ void subghz_cli_command_tx(Cli* cli, string_t args, void* context) { key, repeat); - SubGhzEncoderPrinceton* encoder = subghz_encoder_princeton_alloc(); - subghz_encoder_princeton_reset(encoder, key, repeat); + SubGhzDecoderPrinceton* protocol = subghz_decoder_princeton_alloc(); + protocol->common.code_last_found = key; + protocol->common.code_last_count_bit = 24; + SubGhzProtocolEncoderCommon* 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); frequency = furi_hal_subghz_set_frequency_and_path(frequency); + furi_hal_subghz_start_async_tx(subghz_protocol_encoder_common_yield, encoder); - furi_hal_subghz_start_async_tx(subghz_encoder_princeton_yield, encoder); - - while(!furi_hal_subghz_is_async_tx_complete()) { + while(!(furi_hal_subghz_is_async_tx_complete() || cli_cmd_interrupt_received(cli))) { printf("."); fflush(stdout); osDelay(333); } - furi_hal_subghz_stop_async_tx(); - furi_hal_subghz_sleep(); - subghz_encoder_princeton_free(encoder); + + subghz_decoder_princeton_free(protocol); + subghz_protocol_encoder_common_free(encoder); } typedef struct { diff --git a/applications/subghz/subghz_i.c b/applications/subghz/subghz_i.c index 359b2651..03ebbc26 100644 --- a/applications/subghz/subghz_i.c +++ b/applications/subghz/subghz_i.c @@ -7,6 +7,7 @@ #include <gui/elements.h> #include <notification/notification-messages.h> #include "file-worker.h" +#include "../notification/notification.h" void subghz_begin(FuriHalSubGhzPreset preset) { furi_hal_subghz_reset(); @@ -39,6 +40,34 @@ void subghz_end(void) { furi_hal_subghz_sleep(); } +void subghz_transmitter_tx_start(void* context) { + SubGhz* subghz = context; + subghz->encoder = subghz_protocol_encoder_common_alloc(); + subghz->encoder->repeat = 200; //max repeat with the button held down + //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); + //Start TX + furi_hal_subghz_start_async_tx(subghz_protocol_encoder_common_yield, subghz->encoder); + } + } +} + +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) { + subghz_save_protocol_to_file(subghz, subghz->text_store); + } + notification_message(subghz->notifications, &sequence_reset_red); +} + bool subghz_key_load(SubGhz* subghz, const char* file_path) { furi_assert(subghz); furi_assert(file_path); @@ -81,3 +110,127 @@ bool subghz_key_load(SubGhz* subghz, const char* file_path) { return loaded; } + +bool subghz_save_protocol_to_file(void* context, const char* dev_name) { + SubGhz* subghz = context; + FileWorker* file_worker = file_worker_alloc(false); + string_t dev_file_name; + string_init(dev_file_name); + string_t temp_str; + string_init(temp_str); + bool saved = false; + + do { + // Create subghz folder directory if necessary + if(!file_worker_mkdir(file_worker, SUBGHZ_APP_FOLDER)) { + break; + } + // Create saved directory if necessary + if(!file_worker_mkdir(file_worker, SUBGHZ_APP_PATH_FOLDER)) { + break; + } + // First remove subghz device file if it was saved + string_printf( + dev_file_name, "%s/%s%s", SUBGHZ_APP_PATH_FOLDER, dev_name, SUBGHZ_APP_EXTENSION); + if(!file_worker_remove(file_worker, string_get_cstr(dev_file_name))) { + break; + } + // Open file + if(!file_worker_open( + file_worker, string_get_cstr(dev_file_name), FSAM_WRITE, FSOM_CREATE_ALWAYS)) { + break; + } + //Get string save + subghz->protocol_result->to_save_string(subghz->protocol_result, temp_str); + // Prepare and write data to file + if(!file_worker_write(file_worker, string_get_cstr(temp_str), string_size(temp_str))) { + break; + } + saved = true; + } while(0); + + string_clear(temp_str); + string_clear(dev_file_name); + file_worker_close(file_worker); + file_worker_free(file_worker); + + return saved; +} + +bool subghz_saved_protocol_select(SubGhz* subghz) { + furi_assert(subghz); + + FileWorker* file_worker = file_worker_alloc(false); + string_t protocol_file_name; + string_init(protocol_file_name); + string_t temp_str; + string_init(temp_str); + + // Input events and views are managed by file_select + bool res = file_worker_file_select( + file_worker, + SUBGHZ_APP_PATH_FOLDER, + SUBGHZ_APP_EXTENSION, + subghz->text_store, + sizeof(subghz->text_store), + NULL); + + if(res) { + // Get key file path + string_printf( + protocol_file_name, + "%s/%s%s", + SUBGHZ_APP_PATH_FOLDER, + subghz->text_store, + SUBGHZ_APP_EXTENSION); + } else { + string_clear(temp_str); + string_clear(protocol_file_name); + + file_worker_close(file_worker); + file_worker_free(file_worker); + return res; + } + res = false; + do { + if(!file_worker_open( + file_worker, string_get_cstr(protocol_file_name), FSAM_READ, FSOM_OPEN_EXISTING)) { + break; + } + // Read and parse name protocol from 1st line + if(!file_worker_read_until(file_worker, temp_str, '\n')) { + break; + } + // strlen("Protocol: ") = 10 + string_right(temp_str, 10); + 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"); + break; + } + res = true; + } while(0); + + string_clear(temp_str); + string_clear(protocol_file_name); + + file_worker_close(file_worker); + file_worker_free(file_worker); + + return res; +} + +uint32_t subghz_random_serial(void) { + static bool rand_generator_inited = false; + + if(!rand_generator_inited) { + srand(DWT->CYCCNT); + rand_generator_inited = true; + } + return (uint32_t)rand(); +} diff --git a/applications/subghz/subghz_i.h b/applications/subghz/subghz_i.h index a7a86a8c..8149363d 100644 --- a/applications/subghz/subghz_i.h +++ b/applications/subghz/subghz_i.h @@ -13,6 +13,7 @@ #include <furi-hal.h> #include <gui/gui.h> #include <gui/scene_manager.h> +#include <notification/notification-messages.h> #include <gui/view_dispatcher.h> #include <gui/modules/submenu.h> #include <gui/modules/dialog_ex.h> @@ -27,16 +28,22 @@ #define SUBGHZ_TEXT_STORE_SIZE 128 +#define NOTIFICATION_STARTING_STATE 0u +#define NOTIFICATION_IDLE_STATE 1u +#define NOTIFICATION_TX_STATE 2u + extern const uint32_t subghz_frequencies[]; extern const uint32_t subghz_frequencies_count; extern const uint32_t subghz_frequencies_433_92; struct SubGhz { Gui* gui; + NotificationApp* notifications; SubGhzWorker* worker; SubGhzProtocol* protocol; SubGhzProtocolCommon* protocol_result; + SubGhzProtocolEncoderCommon* encoder; SceneManager* scene_manager; @@ -47,6 +54,7 @@ struct SubGhz { Popup* popup; TextInput* text_input; char text_store[SUBGHZ_TEXT_STORE_SIZE + 1]; + uint8_t state_notifications; SubghzAnalyze* subghz_analyze; SubghzReceiver* subghz_receiver; @@ -77,4 +85,9 @@ void subghz_rx(uint32_t frequency); void subghz_tx(uint32_t frequency); void subghz_idle(void); void subghz_end(void); -bool subghz_key_load(SubGhz* subghz, const char* file_path);
\ No newline at end of file +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); +uint32_t subghz_random_serial(void); diff --git a/applications/subghz/views/subghz_receiver.c b/applications/subghz/views/subghz_receiver.c index 11b030d1..a4d9aef7 100644 --- a/applications/subghz/views/subghz_receiver.c +++ b/applications/subghz/views/subghz_receiver.c @@ -47,7 +47,8 @@ void subghz_receiver_draw(Canvas* canvas, SubghzReceiverModel* model) { elements_multiline_text(canvas, 0, 10, string_get_cstr(model->text)); elements_button_left(canvas, "Back"); - if(model->protocol && model->protocol->to_save_string) { + if(model->protocol && model->protocol->to_save_string && + strcmp(model->protocol->name, "KeeLoq")) { elements_button_right(canvas, "Save"); } } @@ -61,7 +62,9 @@ bool subghz_receiver_input(InputEvent* event, void* context) { bool can_be_saved = false; with_view_model( subghz_receiver->view, (SubghzReceiverModel * model) { - can_be_saved = (model->protocol && model->protocol->to_save_string); + can_be_saved = + (model->protocol && model->protocol->to_save_string && + strcmp(model->protocol->name, "KeeLoq")); return false; }); diff --git a/applications/subghz/views/subghz_static.c b/applications/subghz/views/subghz_static.c index 52bf0ae6..d8937bf3 100644 --- a/applications/subghz/views/subghz_static.c +++ b/applications/subghz/views/subghz_static.c @@ -89,7 +89,7 @@ bool subghz_static_input(InputEvent* event, void* context) { NotificationApp* notification = furi_record_open("notification"); notification_message_block(notification, &sequence_set_red_255); - subghz_encoder_princeton_reset( + subghz_encoder_princeton_set( instance->encoder, subghz_static_keys[model->button], 20); furi_hal_subghz_start_async_tx( subghz_encoder_princeton_yield, instance->encoder); diff --git a/applications/subghz/views/subghz_test_packet.c b/applications/subghz/views/subghz_test_packet.c index 44841af2..a15cc33f 100644 --- a/applications/subghz/views/subghz_test_packet.c +++ b/applications/subghz/views/subghz_test_packet.c @@ -153,7 +153,7 @@ static bool subghz_test_packet_input(InputEvent* event, void* context) { if(model->status == SubghzTestPacketModelStatusRx) { furi_hal_subghz_start_async_rx(subghz_test_packet_rx_callback, instance); } else { - subghz_encoder_princeton_reset(instance->encoder, 0x00AABBCC, 1000); + subghz_encoder_princeton_set(instance->encoder, 0x00AABBCC, 1000); furi_hal_subghz_start_async_tx(subghz_encoder_princeton_yield, instance->encoder); } diff --git a/applications/subghz/views/subghz_transmitter.c b/applications/subghz/views/subghz_transmitter.c index 703d00d8..1ba76d97 100644 --- a/applications/subghz/views/subghz_transmitter.c +++ b/applications/subghz/views/subghz_transmitter.c @@ -48,19 +48,31 @@ void subghz_transmitter_draw(Canvas* canvas, SubghzTransmitterModel* model) { canvas_set_font(canvas, FontSecondary); elements_multiline_text(canvas, 0, 10, string_get_cstr(model->text)); - elements_button_center(canvas, "Send"); + if(model->protocol && model->protocol->get_upload_protocol) { + elements_button_center(canvas, "Send"); + } } bool subghz_transmitter_input(InputEvent* event, void* context) { furi_assert(context); SubghzTransmitter* subghz_transmitter = context; - - if(event->type != InputTypeShort) return false; + bool can_be_send = false; + with_view_model( + subghz_transmitter->view, (SubghzTransmitterModel * model) { + can_be_send = (model->protocol && model->protocol->get_upload_protocol); + string_clean(model->text); + model->protocol->to_string(model->protocol, model->text); + return true; + }); + //if(event->type != InputTypeShort) return false; if(event->key == InputKeyBack) { return false; - } else if(event->key == InputKeyOk) { - subghz_transmitter->callback(SubghzTransmitterEventSend, subghz_transmitter->context); + } else if(can_be_send && event->key == InputKeyOk && event->type == InputTypePress) { + subghz_transmitter->callback(SubghzTransmitterEventSendStart, subghz_transmitter->context); + return true; + } else if(can_be_send && event->key == InputKeyOk && event->type == InputTypeRelease) { + subghz_transmitter->callback(SubghzTransmitterEventSendStop, subghz_transmitter->context); return true; } diff --git a/applications/subghz/views/subghz_transmitter.h b/applications/subghz/views/subghz_transmitter.h index ffd27373..2c1f1b72 100644 --- a/applications/subghz/views/subghz_transmitter.h +++ b/applications/subghz/views/subghz_transmitter.h @@ -4,7 +4,8 @@ #include <lib/subghz/protocols/subghz_protocol_common.h> typedef enum { - SubghzTransmitterEventSend, + SubghzTransmitterEventSendStart, + SubghzTransmitterEventSendStop, SubghzTransmitterEventBack, } SubghzTransmitterEvent; |