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", @@ -26,6 +29,12 @@ const void subghz_scene_start_on_enter(void* context) { subghz->submenu, "Read", SubmenuIndexRead, subghz_scene_start_submenu_callback, subghz); 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( @@ -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 #include #include +#include #include #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 #include #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 #include #include +#include #include #include #include @@ -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 typedef enum { - SubghzTransmitterEventSend, + SubghzTransmitterEventSendStart, + SubghzTransmitterEventSendStop, SubghzTransmitterEventBack, } SubghzTransmitterEvent; diff --git a/firmware/targets/f6/furi-hal/furi-hal-subghz.c b/firmware/targets/f6/furi-hal/furi-hal-subghz.c index 62cd2668..0b1b7b01 100644 --- a/firmware/targets/f6/furi-hal/furi-hal-subghz.c +++ b/firmware/targets/f6/furi-hal/furi-hal-subghz.c @@ -404,6 +404,7 @@ void furi_hal_subghz_stop_async_rx() { #define API_HAL_SUBGHZ_ASYNC_TX_BUFFER_FULL (256) #define API_HAL_SUBGHZ_ASYNC_TX_BUFFER_HALF (API_HAL_SUBGHZ_ASYNC_TX_BUFFER_FULL/2) +#define API_HAL_SUBGHZ_ASYNC_TX_GUARD_TIME 333 typedef struct { uint32_t* buffer; @@ -416,16 +417,30 @@ static FuriHalSubGhzAsyncTx furi_hal_subghz_async_tx = {0}; static void furi_hal_subghz_async_tx_refill(uint32_t* buffer, size_t samples) { while (samples > 0) { + bool is_odd = samples % 2; LevelDuration ld = furi_hal_subghz_async_tx.callback(furi_hal_subghz_async_tx.callback_context); if (level_duration_is_reset(ld)) { + // One more even sample required to end at low level + if (is_odd) { + *buffer = API_HAL_SUBGHZ_ASYNC_TX_GUARD_TIME; + buffer++; + samples--; + } break; - } else { + } else { + // Inject guard time if level is incorrect + if (is_odd == level_duration_get_level(ld)) { + *buffer = API_HAL_SUBGHZ_ASYNC_TX_GUARD_TIME; + buffer++; + samples--; + } + uint32_t duration = level_duration_get_duration(ld); assert(duration > 0); *buffer = duration; + buffer++; + samples--; } - buffer++; - samples--; } memset(buffer, 0, samples * sizeof(uint32_t)); @@ -452,7 +467,6 @@ static void furi_hal_subghz_async_tx_timer_isr() { } else { furi_hal_subghz_state = SubGhzStateAsyncTxEnd; LL_TIM_DisableCounter(TIM2); - hal_gpio_init(&gpio_cc1101_g0, GpioModeOutputPushPull, GpioPullDown, GpioSpeedLow); } } } diff --git a/lib/subghz/protocols/subghz_protocol.h b/lib/subghz/protocols/subghz_protocol.h index 3c33b814..f4a86c0b 100644 --- a/lib/subghz/protocols/subghz_protocol.h +++ b/lib/subghz/protocols/subghz_protocol.h @@ -41,7 +41,7 @@ void subghz_protocol_enable_dump_text(SubGhzProtocol* instance, SubGhzProtocolTe * @param callback - SubGhzProtocolTextCallback callback * @param context */ -void subghz_protocol_enable_dump( SubGhzProtocol* instance, SubGhzProtocolCommonCallbackDump callback, void* context); +void subghz_protocol_enable_dump(SubGhzProtocol* instance, SubGhzProtocolCommonCallbackDump callback, void* context); /** File name rainbow table Nice Flor-S * diff --git a/lib/subghz/protocols/subghz_protocol_came.c b/lib/subghz/protocols/subghz_protocol_came.c index 7af2f6dc..330a1509 100644 --- a/lib/subghz/protocols/subghz_protocol_came.c +++ b/lib/subghz/protocols/subghz_protocol_came.c @@ -14,16 +14,19 @@ struct SubGhzProtocolCame { SubGhzProtocolCame* subghz_protocol_came_alloc() { SubGhzProtocolCame* instance = furi_alloc(sizeof(SubGhzProtocolCame)); - instance->common.name = "Came"; + instance->common.name = "CAME"; instance->common.code_min_count_bit_for_found = 12; - instance->common.te_shot = 320; + instance->common.te_short = 320; instance->common.te_long = 640; instance->common.te_delta = 150; - instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_protocol_came_to_str; + instance->common.type_protocol = TYPE_PROTOCOL_STATIC; + 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.get_upload_protocol = + (SubGhzProtocolEncoderCommonGetUpLoad)subghz_protocol_came_send_key; return instance; } @@ -33,39 +36,29 @@ void subghz_protocol_came_free(SubGhzProtocolCame* instance) { free(instance); } -/** Send bit - * - * @param instance - SubGhzProtocolCame instance - * @param bit - bit - */ -void subghz_protocol_came_send_bit(SubGhzProtocolCame* instance, uint8_t bit) { - if (bit) { - //send bit 1 - SUBGHZ_TX_PIN_LOW(); - delay_us(instance->common.te_long); - SUBGHZ_TX_PIN_HIGTH(); - delay_us(instance->common.te_shot); - } else { - //send bit 0 - SUBGHZ_TX_PIN_LOW(); - delay_us(instance->common.te_shot); - SUBGHZ_TX_PIN_HIGTH(); - delay_us(instance->common.te_long); - } -} - -void subghz_protocol_came_send_key(SubGhzProtocolCame* instance, uint64_t key, uint8_t bit, uint8_t repeat) { - while (repeat--) { - //Send header - SUBGHZ_TX_PIN_LOW(); - delay_us(instance->common.te_shot * 34); //+2 interval v bit 1 - //Send start bit - subghz_protocol_came_send_bit(instance, 1); - //Send key data - for (uint8_t i = bit; i > 0; i--) { - subghz_protocol_came_send_bit(instance, bit_read(key, i - 1)); +bool subghz_protocol_came_send_key(SubGhzProtocolCame* instance, SubGhzProtocolEncoderCommon* encoder){ + furi_assert(instance); + furi_assert(encoder); + size_t index = 0; + encoder->size_upload =(instance->common.code_last_count_bit * 2) + 2; + if(encoder->size_upload > SUBGHZ_ENCODER_UPLOAD_MAX_SIZE) return false; + //Send header + encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->common.te_short * 36); + //Send start bit + encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_short); + //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)){ + //send bit 1 + encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->common.te_long); + encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_short); + }else{ + //send bit 0 + 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); } } + return true; } void subghz_protocol_came_reset(SubGhzProtocolCame* instance) { @@ -76,7 +69,7 @@ void subghz_protocol_came_parse(SubGhzProtocolCame* instance, bool level, uint32 switch (instance->common.parser_step) { case 0: if ((!level) - && (DURATION_DIFF(duration, instance->common.te_shot * 51)< instance->common.te_delta * 51)) { //Need protocol 36 te_shot + && (DURATION_DIFF(duration, instance->common.te_short * 51)< instance->common.te_delta * 51)) { //Need protocol 36 te_short //Found header CAME instance->common.parser_step = 1; } else { @@ -86,7 +79,7 @@ void subghz_protocol_came_parse(SubGhzProtocolCame* instance, bool level, uint32 case 1: if (!level) { break; - } else if (DURATION_DIFF(duration, instance->common.te_shot)< instance->common.te_delta) { + } else if (DURATION_DIFF(duration, instance->common.te_short)< instance->common.te_delta) { //Found start bit CAME instance->common.parser_step = 2; instance->common.code_found = 0; @@ -97,7 +90,7 @@ void subghz_protocol_came_parse(SubGhzProtocolCame* instance, bool level, uint32 break; case 2: if (!level) { //save interval - if (duration >= (instance->common.te_shot * 4)) { + if (duration >= (instance->common.te_short * 4)) { instance->common.parser_step = 1; if (instance->common.code_count_bit>= instance->common.code_min_count_bit_for_found) { @@ -122,12 +115,12 @@ void subghz_protocol_came_parse(SubGhzProtocolCame* instance, bool level, uint32 break; case 3: if (level) { - if ((DURATION_DIFF(instance->common.te_last,instance->common.te_shot) < instance->common.te_delta) + 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)) { subghz_protocol_common_add_bit(&instance->common, 0); instance->common.parser_step = 2; } else if ((DURATION_DIFF(instance->common.te_last,instance->common.te_long)< instance->common.te_delta) - && (DURATION_DIFF(duration, instance->common.te_shot)< instance->common.te_delta)) { + && (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 @@ -140,25 +133,21 @@ void subghz_protocol_came_parse(SubGhzProtocolCame* instance, bool level, uint32 } void subghz_protocol_came_to_str(SubGhzProtocolCame* instance, string_t output) { - uint32_t code_found_hi = instance->common.code_last_found >> 32; uint32_t code_found_lo = instance->common.code_last_found & 0x00000000ffffffff; uint64_t code_found_reverse = subghz_protocol_common_reverse_key( instance->common.code_last_found, instance->common.code_last_count_bit); - uint32_t code_found_reverse_hi = code_found_reverse >> 32; 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", + " KEY:0x%08lX\r\n" + " YEK:0x%08lX\r\n", instance->common.name, instance->common.code_last_count_bit, - code_found_hi, code_found_lo, - code_found_reverse_hi, code_found_reverse_lo ); } diff --git a/lib/subghz/protocols/subghz_protocol_came.h b/lib/subghz/protocols/subghz_protocol_came.h index 42c1b9a3..24810da4 100644 --- a/lib/subghz/protocols/subghz_protocol_came.h +++ b/lib/subghz/protocols/subghz_protocol_came.h @@ -16,14 +16,13 @@ SubGhzProtocolCame* subghz_protocol_came_alloc(); */ void subghz_protocol_came_free(SubGhzProtocolCame* instance); -/** Sends the key on the air +/** Get upload protocol * * @param instance - SubGhzProtocolCame instance - * @param key - key send - * @param bit - count bit key - * @param repeat - repeat send key + * @param encoder - SubGhzProtocolEncoderCommon encoder + * @return bool */ -void subghz_protocol_came_send_key(SubGhzProtocolCame* instance, uint64_t key, uint8_t bit, uint8_t repeat); +bool subghz_protocol_came_send_key(SubGhzProtocolCame* instance, SubGhzProtocolEncoderCommon* encoder); /** Reset internal state * @param instance - SubGhzProtocolCame instance diff --git a/lib/subghz/protocols/subghz_protocol_common.c b/lib/subghz/protocols/subghz_protocol_common.c index 97ded06e..2c5f4f2e 100644 --- a/lib/subghz/protocols/subghz_protocol_common.c +++ b/lib/subghz/protocols/subghz_protocol_common.c @@ -1,12 +1,50 @@ #include "subghz_protocol_common.h" #include +#include + + +SubGhzProtocolEncoderCommon* subghz_protocol_encoder_common_alloc() { + SubGhzProtocolEncoderCommon* instance = furi_alloc(sizeof(SubGhzProtocolEncoderCommon)); + 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) { + furi_assert(instance); + free(instance->upload); + free(instance); +} + +size_t subghz_encoder_common_get_repeat_left(SubGhzProtocolEncoderCommon* instance) { + furi_assert(instance); + return instance->repeat; +} + +LevelDuration subghz_protocol_encoder_common_yield(void* context) { + SubGhzProtocolEncoderCommon* instance = context; + + if(instance->repeat == 0){ + return level_duration_reset(); + } + + LevelDuration ret = instance->upload[instance->front]; + + if(++instance->front == instance->size_upload) { + instance->repeat--; + instance->front = 0; + } + + return ret; +} void subghz_protocol_common_add_bit(SubGhzProtocolCommon *common, uint8_t bit){ - common->code_found = common->code_found <<1 | bit; + common->code_found = common->code_found << 1 | bit; common->code_count_bit++; } -bool subghz_protocol_common_check_interval (SubGhzProtocolCommon *common, uint32_t duration, uint16_t duration_check) { +bool subghz_protocol_common_check_interval(SubGhzProtocolCommon *common, uint32_t duration, uint16_t duration_check) { if ((duration_check >= (duration - common->te_delta))&&(duration_check <= (duration + common->te_delta))){ return true; } else { @@ -75,3 +113,27 @@ void subghz_protocol_common_to_str(SubGhzProtocolCommon* instance, string_t outp } } } + +bool subghz_protocol_common_read_hex(string_t str, uint8_t* buff, uint16_t len) { + string_strim(str); + uint8_t nibble_high = 0; + uint8_t nibble_low = 0; + bool parsed = true; + + for(uint16_t i = 0; i < len; i++) { + if(hex_char_to_hex_nibble(string_get_char(str, 0), &nibble_high) && + hex_char_to_hex_nibble(string_get_char(str, 1), &nibble_low)) { + buff[i] = (nibble_high << 4) | nibble_low; + if(string_size(str)>2){ + string_right(str, 2); + }else if(icommon.name = "Faac SLH"; instance->common.code_min_count_bit_for_found = 64; - instance->common.te_shot = 255; + instance->common.te_short = 255; instance->common.te_long = 595; instance->common.te_delta = 100; + instance->common.type_protocol = TYPE_PROTOCOL_DYNAMIC; instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_protocol_faac_slh_to_str; return instance; @@ -31,14 +32,14 @@ void subghz_protocol_faac_slh_free(SubGhzProtocolFaacSLH* instance) { void subghz_protocol_faac_slh_send_bit(SubGhzProtocolFaacSLH* instance, uint8_t bit) { if (bit) { //send bit 1 - SUBGHZ_TX_PIN_HIGTH(); + SUBGHZ_TX_PIN_HIGH(); delay_us(instance->common.te_long); SUBGHZ_TX_PIN_LOW(); - delay_us(instance->common.te_shot); + delay_us(instance->common.te_short); } else { //send bit 0 - SUBGHZ_TX_PIN_HIGTH(); - delay_us(instance->common.te_shot); + SUBGHZ_TX_PIN_HIGH(); + delay_us(instance->common.te_short); SUBGHZ_TX_PIN_LOW(); delay_us(instance->common.te_long); } @@ -46,7 +47,7 @@ void subghz_protocol_faac_slh_send_bit(SubGhzProtocolFaacSLH* instance, uint8_t void subghz_protocol_faac_slh_send_key(SubGhzProtocolFaacSLH* instance, uint64_t key, uint8_t bit,uint8_t repeat) { while (repeat--) { - SUBGHZ_TX_PIN_HIGTH(); + SUBGHZ_TX_PIN_HIGH(); //Send header delay_us(instance->common.te_long * 2); SUBGHZ_TX_PIN_LOW(); @@ -67,15 +68,12 @@ void subghz_protocol_faac_slh_reset(SubGhzProtocolFaacSLH* instance) { * @param instance SubGhzProtocolFaacSLH instance */ void subghz_protocol_faac_slh_check_remote_controller(SubGhzProtocolFaacSLH* instance) { - uint64_t code_found_reverse = subghz_protocol_common_reverse_key(instance->common.code_found, instance->common.code_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 & 0xFFFFFFFF; //uint32_t code_hop = (code_found_reverse >> 24) & 0xFFFFF; instance->common.serial = code_fix & 0xFFFFFFF; instance->common.btn = (code_fix >> 28) & 0x0F; - - if (instance->common.callback) instance->common.callback((SubGhzProtocolCommon*)instance, instance->common.context); - } void subghz_protocol_faac_slh_parse(SubGhzProtocolFaacSLH* instance, bool level, uint32_t duration) { @@ -101,10 +99,12 @@ void subghz_protocol_faac_slh_parse(SubGhzProtocolFaacSLH* instance, bool level, break; case 2: if (level) { - if (duration >= (instance->common.te_shot * 3 + instance->common.te_delta)) { + if (duration >= (instance->common.te_short * 3 + instance->common.te_delta)) { instance->common.parser_step = 1; if (instance->common.code_count_bit>= instance->common.code_min_count_bit_for_found) { - subghz_protocol_faac_slh_check_remote_controller(instance); + 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); } instance->common.code_found = 0; instance->common.code_count_bit = 0; @@ -120,12 +120,12 @@ void subghz_protocol_faac_slh_parse(SubGhzProtocolFaacSLH* instance, bool level, break; case 3: if(!level){ - if ((DURATION_DIFF(instance->common.te_last,instance->common.te_shot)< instance->common.te_delta) + 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)) { subghz_protocol_common_add_bit(&instance->common, 0); instance->common.parser_step = 2; } else if ((DURATION_DIFF(instance->common.te_last,instance->common.te_long )< instance->common.te_delta) - && (DURATION_DIFF(duration,instance->common.te_shot)< instance->common.te_delta)) { + && (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,23 +139,21 @@ void subghz_protocol_faac_slh_parse(SubGhzProtocolFaacSLH* instance, bool level, } void subghz_protocol_faac_slh_to_str(SubGhzProtocolFaacSLH* instance, string_t output) { - - uint64_t code_found_reverse = subghz_protocol_common_reverse_key(instance->common.code_found, instance->common.code_count_bit); + subghz_protocol_faac_slh_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); uint32_t code_fix = code_found_reverse & 0xFFFFFFFF; uint32_t code_hop = (code_found_reverse >>32) & 0xFFFFFFFF; - //uint32_t rev_hi = - string_cat_printf(output, - "Protocol %s, %d Bit\r\n" + "%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", instance->common.name, - instance->common.code_count_bit, - (uint32_t)(instance->common.code_found >> 32), - (uint32_t)instance->common.code_found, + 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); diff --git a/lib/subghz/protocols/subghz_protocol_gate_tx.c b/lib/subghz/protocols/subghz_protocol_gate_tx.c index cfd01db0..d850d741 100644 --- a/lib/subghz/protocols/subghz_protocol_gate_tx.c +++ b/lib/subghz/protocols/subghz_protocol_gate_tx.c @@ -10,15 +10,17 @@ SubGhzProtocolGateTX* subghz_protocol_gate_tx_alloc(void) { instance->common.name = "GateTX"; instance->common.code_min_count_bit_for_found = 24; - instance->common.te_shot = 350; + instance->common.te_short = 350; instance->common.te_long = 700; instance->common.te_delta = 100; + instance->common.type_protocol = TYPE_PROTOCOL_STATIC; 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.get_upload_protocol = + (SubGhzProtocolEncoderCommonGetUpLoad)subghz_protocol_gate_tx_send_key; return instance; } @@ -27,40 +29,29 @@ void subghz_protocol_gate_tx_free(SubGhzProtocolGateTX* instance) { free(instance); } -/** Send bit - * - * @param instance - SubGhzProtocolGateTX instance - * @param bit - bit - */ -void subghz_protocol_gate_tx_send_bit(SubGhzProtocolGateTX* instance, uint8_t bit) { - if (bit) { - //send bit 1 - SUBGHZ_TX_PIN_LOW(); - delay_us(instance->common.te_long); - SUBGHZ_TX_PIN_HIGTH(); - delay_us(instance->common.te_shot); - } else { - //send bit 0 - SUBGHZ_TX_PIN_LOW(); - delay_us(instance->common.te_shot); - SUBGHZ_TX_PIN_HIGTH(); - delay_us(instance->common.te_long); - } -} - -void subghz_protocol_gate_tx_send_key(SubGhzProtocolGateTX* instance, uint64_t key, uint8_t bit,uint8_t repeat) { - while (repeat--) { - //Send header - SUBGHZ_TX_PIN_LOW(); - delay_us(instance->common.te_shot * 47); //+2 interval v bit 1 - //Send start bit - SUBGHZ_TX_PIN_HIGTH(); - delay_us(instance->common.te_long); - //Send key data - for (uint8_t i = bit; i > 0; i--) { - subghz_protocol_gate_tx_send_bit(instance, bit_read(key, i - 1)); +bool subghz_protocol_gate_tx_send_key(SubGhzProtocolGateTX* instance, SubGhzProtocolEncoderCommon* encoder){ + furi_assert(instance); + furi_assert(encoder); + size_t index = 0; + encoder->size_upload =(instance->common.code_last_count_bit * 2) + 2; + if(encoder->size_upload > SUBGHZ_ENCODER_UPLOAD_MAX_SIZE) return false; + //Send header + encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->common.te_short * 49); + //Send start bit + encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_long); + //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)){ + //send bit 1 + encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->common.te_long); + encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_short); + }else{ + //send bit 0 + 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); } } + return true; } void subghz_protocol_gate_tx_reset(SubGhzProtocolGateTX* instance) { @@ -82,7 +73,7 @@ void subghz_protocol_gate_tx_parse(SubGhzProtocolGateTX* instance, bool level, u switch (instance->common.parser_step) { case 0: if ((!level) - && (DURATION_DIFF(duration,instance->common.te_shot * 47)< instance->common.te_delta * 47)) { + && (DURATION_DIFF(duration,instance->common.te_short * 47)< instance->common.te_delta * 47)) { //Found Preambula instance->common.parser_step = 1; } else { @@ -101,7 +92,7 @@ void subghz_protocol_gate_tx_parse(SubGhzProtocolGateTX* instance, bool level, u break; case 2: if (!level) { - if (duration >= (instance->common.te_shot * 10 + instance->common.te_delta)) { + if (duration >= (instance->common.te_short * 10 + instance->common.te_delta)) { instance->common.parser_step = 1; if (instance->common.code_count_bit>= instance->common.code_min_count_bit_for_found) { @@ -121,12 +112,12 @@ void subghz_protocol_gate_tx_parse(SubGhzProtocolGateTX* instance, bool level, u break; case 3: if(level){ - if ((DURATION_DIFF(instance->common.te_last,instance->common.te_shot)< instance->common.te_delta) + 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_long)< instance->common.te_delta*3) - && (DURATION_DIFF(duration,instance->common.te_shot)< instance->common.te_delta)) { + && (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 { diff --git a/lib/subghz/protocols/subghz_protocol_gate_tx.h b/lib/subghz/protocols/subghz_protocol_gate_tx.h index c02a8c45..b5682d7d 100644 --- a/lib/subghz/protocols/subghz_protocol_gate_tx.h +++ b/lib/subghz/protocols/subghz_protocol_gate_tx.h @@ -16,14 +16,13 @@ SubGhzProtocolGateTX* subghz_protocol_gate_tx_alloc(); */ void subghz_protocol_gate_tx_free(SubGhzProtocolGateTX* instance); -/** Sends the key on the air +/** Get upload protocol * - * @param instance - SubGhzProtocolGateTX instance - * @param key - key send - * @param bit - count bit key - * @param repeat - repeat send key + * @param instance - SubGhzProtocolCame instance + * @param encoder - SubGhzProtocolEncoderCommon encoder + * @return bool */ -void subghz_protocol_gate_tx_send_key(SubGhzProtocolGateTX* instance, uint64_t key, uint8_t bit, uint8_t repeat); +bool subghz_protocol_gate_tx_send_key(SubGhzProtocolGateTX* instance, SubGhzProtocolEncoderCommon* encoder); /** Reset internal state * @param instance - SubGhzProtocolGateTX instance diff --git a/lib/subghz/protocols/subghz_protocol_ido.c b/lib/subghz/protocols/subghz_protocol_ido.c index 7b95061a..95e571e3 100644 --- a/lib/subghz/protocols/subghz_protocol_ido.c +++ b/lib/subghz/protocols/subghz_protocol_ido.c @@ -10,9 +10,10 @@ SubGhzProtocolIDo* subghz_protocol_ido_alloc(void) { instance->common.name = "iDo 117/111"; // PT4301-X"; instance->common.code_min_count_bit_for_found = 48; - instance->common.te_shot = 450; + instance->common.te_short = 450; instance->common.te_long = 1450; instance->common.te_delta = 150; + instance->common.type_protocol = TYPE_PROTOCOL_DYNAMIC; instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_protocol_ido_to_str; return instance; @@ -31,14 +32,14 @@ void subghz_protocol_ido_free(SubGhzProtocolIDo* instance) { void subghz_protocol_ido_send_bit(SubGhzProtocolIDo* instance, uint8_t bit) { if (bit) { //send bit 1 - SUBGHZ_TX_PIN_HIGTH(); - delay_us(instance->common.te_shot); + SUBGHZ_TX_PIN_HIGH(); + delay_us(instance->common.te_short); SUBGHZ_TX_PIN_LOW(); - delay_us(instance->common.te_shot); + delay_us(instance->common.te_short); } else { //send bit 0 - SUBGHZ_TX_PIN_HIGTH(); - delay_us(instance->common.te_shot); + SUBGHZ_TX_PIN_HIGH(); + delay_us(instance->common.te_short); SUBGHZ_TX_PIN_LOW(); delay_us(instance->common.te_long); } @@ -46,11 +47,11 @@ 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--) { - SUBGHZ_TX_PIN_HIGTH(); + SUBGHZ_TX_PIN_HIGH(); //Send header - delay_us(instance->common.te_shot * 10); + delay_us(instance->common.te_short * 10); SUBGHZ_TX_PIN_LOW(); - delay_us(instance->common.te_shot * 10); + delay_us(instance->common.te_short * 10); //Send key data for (uint8_t i = bit; i > 0; i--) { subghz_protocol_ido_send_bit(instance, bit_read(key, i - 1)); @@ -67,22 +68,18 @@ 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_found, instance->common.code_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) & 0xFFFFF; instance->common.serial = code_fix & 0xFFFFF; instance->common.btn = (code_fix >> 20) & 0x0F; - - if (instance->common.callback) instance->common.callback((SubGhzProtocolCommon*)instance, instance->common.context); - } void subghz_protocol_ido_parse(SubGhzProtocolIDo* instance, bool level, uint32_t duration) { switch (instance->common.parser_step) { case 0: if ((level) - && (DURATION_DIFF(duration,instance->common.te_shot * 10)< instance->common.te_delta * 5)) { + && (DURATION_DIFF(duration,instance->common.te_short * 10)< instance->common.te_delta * 5)) { instance->common.parser_step = 1; } else { instance->common.parser_step = 0; @@ -90,7 +87,7 @@ void subghz_protocol_ido_parse(SubGhzProtocolIDo* instance, bool level, uint32_t break; case 1: if ((!level) - && (DURATION_DIFF(duration,instance->common.te_shot * 10)< instance->common.te_delta * 5)) { + && (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; @@ -101,10 +98,12 @@ void subghz_protocol_ido_parse(SubGhzProtocolIDo* instance, bool level, uint32_t break; case 2: if (level) { - if (duration >= (instance->common.te_shot * 5 + instance->common.te_delta)) { + 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) { - subghz_protocol_ido_check_remote_controller(instance); + 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); } instance->common.code_found = 0; instance->common.code_count_bit = 0; @@ -120,12 +119,12 @@ void subghz_protocol_ido_parse(SubGhzProtocolIDo* instance, bool level, uint32_t break; case 3: if(!level){ - if ((DURATION_DIFF(instance->common.te_last,instance->common.te_shot)< instance->common.te_delta) + 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_shot )< instance->common.te_delta*3) - && (DURATION_DIFF(duration,instance->common.te_shot)< 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 +138,21 @@ void subghz_protocol_ido_parse(SubGhzProtocolIDo* instance, bool level, uint32_t } void subghz_protocol_ido_to_str(SubGhzProtocolIDo* instance, string_t output) { - - uint64_t code_found_reverse = subghz_protocol_common_reverse_key(instance->common.code_found, instance->common.code_count_bit); + 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); uint32_t code_fix = code_found_reverse & 0xFFFFFF; uint32_t code_hop = (code_found_reverse >>24) & 0xFFFFFF; string_cat_printf(output, - "Protocol %s, %d Bit\r\n" + "%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_count_bit, - (uint32_t)(instance->common.code_found >> 32), - (uint32_t)instance->common.code_found, + 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); diff --git a/lib/subghz/protocols/subghz_protocol_keeloq.c b/lib/subghz/protocols/subghz_protocol_keeloq.c index 878e17bc..6bbc9c80 100644 --- a/lib/subghz/protocols/subghz_protocol_keeloq.c +++ b/lib/subghz/protocols/subghz_protocol_keeloq.c @@ -20,14 +20,17 @@ SubGhzProtocolKeeloq* subghz_protocol_keeloq_alloc(SubGhzKeystore* keystore) { instance->common.name = "KeeLoq"; instance->common.code_min_count_bit_for_found = 64; - instance->common.te_shot = 400; + instance->common.te_short = 400; instance->common.te_long = 800; instance->common.te_delta = 140; + instance->common.type_protocol = TYPE_PROTOCOL_DYNAMIC; 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 = (SubGhzProtocolCommonLoad)subghz_protocol_keeloq_to_load_protocol; + instance->common.get_upload_protocol = + (SubGhzProtocolEncoderCommonGetUpLoad)subghz_protocol_keeloq_send_key; return instance; } @@ -162,53 +165,91 @@ void subghz_protocol_keeloq_check_remote_controller(SubGhzProtocolKeeloq* instan instance->common.serial = key_fix & 0x0FFFFFFF; instance->common.btn = key_fix >> 28; } - -/** Send bit - * - * @param instance - SubGhzProtocolKeeloq instance - * @param bit - bit - */ -void subghz_protocol_keeloq_send_bit(SubGhzProtocolKeeloq* instance, uint8_t bit) { - if(bit) { - // send bit 1 - SUBGHZ_TX_PIN_HIGTH(); - delay_us(instance->common.te_shot); - SUBGHZ_TX_PIN_LOW(); - delay_us(instance->common.te_long); - } else { - // send bit 0 - SUBGHZ_TX_PIN_HIGTH(); - delay_us(instance->common.te_long); - SUBGHZ_TX_PIN_LOW(); - delay_us(instance->common.te_shot); - } +void subghz_protocol_keeloq_set_manufacture_name (void* context, const char* manufacture_name){ + SubGhzProtocolKeeloq* instance = context; + instance->manufacture_name = manufacture_name; } -void subghz_protocol_keeloq_send_key( - SubGhzProtocolKeeloq* instance, - uint64_t key, - uint8_t bit, - uint8_t repeat) { - while(repeat--) { - // Send header - for(uint8_t i = 11; i > 0; i--) { - SUBGHZ_TX_PIN_HIGTH(); - delay_us(instance->common.te_shot); - SUBGHZ_TX_PIN_LOW(); - delay_us(instance->common.te_shot); - } - delay_us(instance->common.te_shot * 9); //+1 up Send header +uint64_t subghz_protocol_keeloq_gen_key(void* context) { + SubGhzProtocolKeeloq* instance = context; + uint32_t fix = instance->common.btn << 28 | instance->common.serial; + uint32_t decrypt = instance->common.btn << 28 | (instance->common.serial & 0x3FF) << 16 | + instance->common.cnt; + uint32_t hop = 0; + uint64_t man_normal_learning = 0; + int res = 0; - for(uint8_t i = bit; i > 0; i--) { - subghz_protocol_keeloq_send_bit(instance, bit_read(key, i - 1)); + for + M_EACH(manufacture_code, *subghz_keystore_get_data(instance->keystore), SubGhzKeyArray_t) { + res = strcmp(string_get_cstr(manufacture_code->name), instance->manufacture_name); + if(res == 0) { + switch(manufacture_code->type) { + case KEELOQ_LEARNING_SIMPLE: + //Simple Learning + hop = subghz_protocol_keeloq_common_encrypt(decrypt, manufacture_code->key); + break; + case KEELOQ_LEARNING_NORMAL: + //Simple Learning + man_normal_learning = + subghz_protocol_keeloq_common_normal_learning(fix, manufacture_code->key); + hop = subghz_protocol_keeloq_common_encrypt(decrypt, man_normal_learning); + break; + case KEELOQ_LEARNING_UNKNOWN: + hop = 0; //todo + break; + } + break; + } } - // +send 2 status bit - subghz_protocol_keeloq_send_bit(instance, 0); - subghz_protocol_keeloq_send_bit(instance, 0); - // send end - subghz_protocol_keeloq_send_bit(instance, 0); - delay_us(instance->common.te_shot * 2); //+2 interval END SEND + uint64_t yek = (uint64_t)fix << 32 | hop; + return subghz_protocol_common_reverse_key(yek, instance->common.code_last_count_bit); +} + +bool subghz_protocol_keeloq_send_key(SubGhzProtocolKeeloq* instance, SubGhzProtocolEncoderCommon* 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); + + size_t index = 0; + 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 + for(uint8_t i = 11; i > 0; i--) { + 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); } + 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); + + //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)){ + //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{ + //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); + } + } + // +send 2 status bit + 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); + + //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 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); + + return true; } void subghz_protocol_keeloq_reset(SubGhzProtocolKeeloq* instance) { @@ -219,7 +260,7 @@ void subghz_protocol_keeloq_parse(SubGhzProtocolKeeloq* instance, bool level, ui switch(instance->common.parser_step) { case 0: if((level) && - DURATION_DIFF(duration, instance->common.te_shot) < instance->common.te_delta) { + DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta) { instance->common.parser_step = 1; instance->common.header_count++; } else { @@ -229,12 +270,12 @@ void subghz_protocol_keeloq_parse(SubGhzProtocolKeeloq* instance, bool level, ui break; case 1: if((!level) && - (DURATION_DIFF(duration, instance->common.te_shot) < instance->common.te_delta)) { + (DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta)) { instance->common.parser_step = 0; break; } if((instance->common.header_count > 2) && - (DURATION_DIFF(duration, instance->common.te_shot * 10) < + (DURATION_DIFF(duration, instance->common.te_short * 10) < instance->common.te_delta * 10)) { // Found header instance->common.parser_step = 2; @@ -253,7 +294,7 @@ void subghz_protocol_keeloq_parse(SubGhzProtocolKeeloq* instance, bool level, ui break; case 3: if(!level) { - if(duration >= (instance->common.te_shot * 2 + instance->common.te_delta)) { + if(duration >= (instance->common.te_short * 2 + instance->common.te_delta)) { // Found end TX instance->common.parser_step = 0; if(instance->common.code_count_bit >= @@ -271,7 +312,7 @@ void subghz_protocol_keeloq_parse(SubGhzProtocolKeeloq* instance, bool level, ui } break; } else if( - (DURATION_DIFF(instance->common.te_last, instance->common.te_shot) < + (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)) { if(instance->common.code_count_bit < @@ -282,7 +323,7 @@ void subghz_protocol_keeloq_parse(SubGhzProtocolKeeloq* instance, bool level, ui } else if( (DURATION_DIFF(instance->common.te_last, instance->common.te_long) < instance->common.te_delta) && - (DURATION_DIFF(duration, instance->common.te_shot) < instance->common.te_delta)) { + (DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta)) { if(instance->common.code_count_bit < instance->common.code_min_count_bit_for_found) { subghz_protocol_common_add_bit(&instance->common, 0); @@ -329,55 +370,17 @@ void subghz_protocol_keeloq_to_str(SubGhzProtocolKeeloq* instance, string_t outp instance->common.btn); } -uint64_t subghz_protocol_keeloq_gen_key(SubGhzProtocolKeeloq* instance) { - uint32_t fix = instance->common.btn << 28 | instance->common.serial; - uint32_t decrypt = instance->common.btn << 28 | (instance->common.serial & 0x3FF) << 16 | - instance->common.cnt; - uint32_t hop = 0; - uint64_t man_normal_learning = 0; - int res = 0; - - for - M_EACH(manufacture_code, *subghz_keystore_get_data(instance->keystore), SubGhzKeyArray_t) { - res = strcmp(string_get_cstr(manufacture_code->name), instance->manufacture_name); - if(res == 0) { - switch(manufacture_code->type) { - case KEELOQ_LEARNING_SIMPLE: - //Simple Learning - hop = subghz_protocol_keeloq_common_encrypt(decrypt, manufacture_code->key); - break; - case KEELOQ_LEARNING_NORMAL: - //Simple Learning - man_normal_learning = - subghz_protocol_keeloq_common_normal_learning(fix, manufacture_code->key); - hop = subghz_protocol_keeloq_common_encrypt(decrypt, man_normal_learning); - break; - case KEELOQ_LEARNING_UNKNOWN: - hop = 0; //todo - break; - } - break; - } - } - uint64_t yek = (uint64_t)fix << 32 | hop; - return subghz_protocol_common_reverse_key(yek, instance->common.code_last_count_bit); -} - void subghz_protocol_keeloq_to_save_str(SubGhzProtocolKeeloq* instance, string_t output) { - string_printf( + string_printf( output, "Protocol: %s\n" "Bit: %d\n" - "Manufacture_name: %s\n" - "Serial: %08lX\n" - "Cnt: %04lX\n" - "Btn: %01lX\n", + "Key: %08lX%08lX\n", instance->common.name, instance->common.code_last_count_bit, - instance->manufacture_name, - instance->common.serial, - instance->common.cnt, - instance->common.btn); + (uint32_t)(instance->common.code_last_found >> 32), + (uint32_t)(instance->common.code_last_found & 0xFFFFFFFF) + ); } bool subghz_protocol_keeloq_to_load_protocol( @@ -386,8 +389,6 @@ bool subghz_protocol_keeloq_to_load_protocol( bool loaded = false; string_t temp_str; string_init(temp_str); - string_t temp_name_man; - string_init(temp_name_man); int res = 0; int data = 0; @@ -402,50 +403,23 @@ bool subghz_protocol_keeloq_to_load_protocol( } instance->common.code_last_count_bit = (uint8_t)data; - // Read and parse name protocol from 3st line - if(!file_worker_read_until(file_worker, temp_name_man, '\n')) { - break; - } - // strlen("Manufacture_name: ") = 18 - string_right(temp_name_man, 18); - instance->manufacture_name = string_get_cstr(temp_name_man); - - // Read and parse key data from 4nd line + // Read and parse key data from 3nd line if(!file_worker_read_until(file_worker, temp_str, '\n')) { break; } - uint32_t temp_param = 0; - res = sscanf(string_get_cstr(temp_str), "Serial: %08lX\n", &temp_param); - if(res != 1) { - break; - } - instance->common.serial = temp_param; + // strlen("Key: ") = 5 + string_right(temp_str, 5); - // Read and parse key data from 5nd line - if(!file_worker_read_until(file_worker, temp_str, '\n')) { + uint8_t buf_key[8]={0}; + if(!subghz_protocol_common_read_hex(temp_str, buf_key, 8)){ break; } - res = sscanf(string_get_cstr(temp_str), "Cnt: %04lX\n", &temp_param); - if(res != 1) { - break; - } - instance->common.cnt = (uint16_t)temp_param; - // Read and parse key data from 5nd line - if(!file_worker_read_until(file_worker, temp_str, '\n')) { - break; + for(uint8_t i = 0; i < 8; i++){ + instance->common.code_last_found = instance->common.code_last_found << 8 | buf_key[i]; } - res = sscanf(string_get_cstr(temp_str), "Btn: %01lX\n", &temp_param); - if(res != 1) { - break; - } - instance->common.btn = (uint8_t)temp_param; - - instance->common.code_last_found = subghz_protocol_keeloq_gen_key(instance); - loaded = true; } while(0); - string_clear(temp_name_man); string_clear(temp_str); return loaded; diff --git a/lib/subghz/protocols/subghz_protocol_keeloq.h b/lib/subghz/protocols/subghz_protocol_keeloq.h index 4560c725..cd591980 100644 --- a/lib/subghz/protocols/subghz_protocol_keeloq.h +++ b/lib/subghz/protocols/subghz_protocol_keeloq.h @@ -18,14 +18,27 @@ SubGhzProtocolKeeloq* subghz_protocol_keeloq_alloc(SubGhzKeystore* keystore); */ void subghz_protocol_keeloq_free(SubGhzProtocolKeeloq* instance); -/** Sends the key on the air +/** Set manufacture name * - * @param instance - SubGhzProtocolKeeloq instance - * @param key - key send - * @param bit - count bit key - * @param repeat - repeat send key + * @param manufacture_name - manufacture name + * @param context - SubGhzProtocolKeeloq context */ -void subghz_protocol_keeloq_send_key(SubGhzProtocolKeeloq* instance, uint64_t key, uint8_t bit, uint8_t repeat); +void subghz_protocol_keeloq_set_manufacture_name(void* context, const char* manufacture_name); + +/** Get key keeloq + * + * @param context - SubGhzProtocolKeeloq context + * @return key + */ +uint64_t subghz_protocol_keeloq_gen_key(void* context); + +/** Get upload protocol + * + * @param instance - SubGhzProtocolCame instance + * @param encoder - SubGhzProtocolEncoderCommon encoder + * @return bool + */ +bool subghz_protocol_keeloq_send_key(SubGhzProtocolKeeloq* instance, SubGhzProtocolEncoderCommon* encoder); /** Reset internal state * @param instance - SubGhzProtocolKeeloq instance diff --git a/lib/subghz/protocols/subghz_protocol_nero_sketch.c b/lib/subghz/protocols/subghz_protocol_nero_sketch.c index 8e22b0f3..4b20b4cb 100644 --- a/lib/subghz/protocols/subghz_protocol_nero_sketch.c +++ b/lib/subghz/protocols/subghz_protocol_nero_sketch.c @@ -10,14 +10,17 @@ SubGhzProtocolNeroSketch* subghz_protocol_nero_sketch_alloc(void) { instance->common.name = "Nero Sketch"; instance->common.code_min_count_bit_for_found = 40; - instance->common.te_shot = 330; + instance->common.te_short = 330; instance->common.te_long = 660; instance->common.te_delta = 150; + instance->common.type_protocol = TYPE_PROTOCOL_STATIC; 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.get_upload_protocol = + (SubGhzProtocolEncoderCommonGetUpLoad)subghz_protocol_nero_sketch_send_key; return instance; } @@ -27,53 +30,41 @@ void subghz_protocol_nero_sketch_free(SubGhzProtocolNeroSketch* instance) { free(instance); } -/** Send bit - * - * @param instance - SubGhzProtocolNeroSketch instance - * @param bit - bit - */ -void subghz_protocol_nero_sketch_send_bit(SubGhzProtocolNeroSketch* instance, uint8_t bit) { - if (bit) { - //send bit 1 - SUBGHZ_TX_PIN_HIGTH(); - delay_us(instance->common.te_long); - SUBGHZ_TX_PIN_LOW(); - delay_us(instance->common.te_shot); - } else { - //send bit 0 - SUBGHZ_TX_PIN_HIGTH(); - delay_us(instance->common.te_shot); - SUBGHZ_TX_PIN_LOW(); - delay_us(instance->common.te_long); +bool subghz_protocol_nero_sketch_send_key(SubGhzProtocolNeroSketch* instance, SubGhzProtocolEncoderCommon* encoder){ + furi_assert(instance); + furi_assert(encoder); + size_t index = 0; + encoder->size_upload = 47*2+2+(instance->common.code_last_count_bit * 2) + 2; + if(encoder->size_upload > SUBGHZ_ENCODER_UPLOAD_MAX_SIZE) return false; + + //Send header + for(uint8_t i = 0; i < 47; i++){ + 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); } -} + + //Send start bit + encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_short*4); + encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->common.te_short); -void subghz_protocol_nero_sketch_send_key(SubGhzProtocolNeroSketch* instance, uint64_t key, uint8_t bit,uint8_t repeat) { - while (repeat--) { - //Send header - for(uint8_t i = 0; i < 47; i++){ - SUBGHZ_TX_PIN_HIGTH(); - delay_us(instance->common.te_shot); - SUBGHZ_TX_PIN_LOW(); - delay_us(instance->common.te_shot); + //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)){ + //send bit 1 + 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); + }else{ + //send bit 0 + 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); } - - //Send start bit - SUBGHZ_TX_PIN_HIGTH(); - delay_us(instance->common.te_shot*4); - SUBGHZ_TX_PIN_LOW(); - delay_us(instance->common.te_shot); - - //Send key data - for (uint8_t i = bit; i > 0; i--) { - subghz_protocol_nero_sketch_send_bit(instance, bit_read(key, i - 1)); - } - //Send stop bit - SUBGHZ_TX_PIN_HIGTH(); - delay_us(instance->common.te_shot*3); - SUBGHZ_TX_PIN_LOW(); - delay_us(instance->common.te_shot); } + + //Send stop bit + encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_short*3); + encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->common.te_short); + + return true; } void subghz_protocol_nero_sketch_reset(SubGhzProtocolNeroSketch* instance) { @@ -101,7 +92,7 @@ void subghz_protocol_nero_sketch_parse(SubGhzProtocolNeroSketch* instance, bool switch (instance->common.parser_step) { case 0: if ((level) - && (DURATION_DIFF(duration,instance->common.te_shot)< instance->common.te_delta)) { + && (DURATION_DIFF(duration,instance->common.te_short)< instance->common.te_delta)) { instance->common.parser_step = 1; instance->common.te_last = duration; instance->common.header_count = 0; @@ -111,18 +102,18 @@ void subghz_protocol_nero_sketch_parse(SubGhzProtocolNeroSketch* instance, bool break; case 1: if (level){ - if((DURATION_DIFF(duration,instance->common.te_shot)< instance->common.te_delta ) - || (DURATION_DIFF(duration,instance->common.te_shot*4)< instance->common.te_delta)) { + if((DURATION_DIFF(duration,instance->common.te_short)< instance->common.te_delta ) + || (DURATION_DIFF(duration,instance->common.te_short*4)< instance->common.te_delta)) { instance->common.te_last = duration; } else { instance->common.parser_step = 0; } - } else if(DURATION_DIFF(duration,instance->common.te_shot)< instance->common.te_delta){ - if(DURATION_DIFF(instance->common.te_last,instance->common.te_shot)< instance->common.te_delta){ + } else if(DURATION_DIFF(duration,instance->common.te_short)< instance->common.te_delta){ + if(DURATION_DIFF(instance->common.te_last,instance->common.te_short)< instance->common.te_delta){ // Found header instance->common.header_count++; break; - }else if(DURATION_DIFF(instance->common.te_last,instance->common.te_shot*4)< instance->common.te_delta){ + }else if(DURATION_DIFF(instance->common.te_last,instance->common.te_short*4)< instance->common.te_delta){ // Found start bit if(instance->common.header_count>40) { instance->common.parser_step = 2; @@ -140,7 +131,7 @@ void subghz_protocol_nero_sketch_parse(SubGhzProtocolNeroSketch* instance, bool break; case 2: if (level) { - if (duration >= (instance->common.te_shot * 2 + instance->common.te_delta*2)) { + if (duration >= (instance->common.te_short * 2 + instance->common.te_delta*2)) { //Found stop bit instance->common.parser_step = 0; if (instance->common.code_count_bit>= instance->common.code_min_count_bit_for_found) { @@ -164,12 +155,12 @@ void subghz_protocol_nero_sketch_parse(SubGhzProtocolNeroSketch* instance, bool break; case 3: if(!level){ - if ((DURATION_DIFF(instance->common.te_last,instance->common.te_shot)< instance->common.te_delta) + 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)) { subghz_protocol_common_add_bit(&instance->common, 0); instance->common.parser_step = 2; } else if ((DURATION_DIFF(instance->common.te_last,instance->common.te_long )< instance->common.te_delta) - && (DURATION_DIFF(duration,instance->common.te_shot)< instance->common.te_delta)) { + && (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 { diff --git a/lib/subghz/protocols/subghz_protocol_nero_sketch.h b/lib/subghz/protocols/subghz_protocol_nero_sketch.h index 4fcce1c2..170895c4 100644 --- a/lib/subghz/protocols/subghz_protocol_nero_sketch.h +++ b/lib/subghz/protocols/subghz_protocol_nero_sketch.h @@ -16,14 +16,13 @@ SubGhzProtocolNeroSketch* subghz_protocol_nero_sketch_alloc(); */ void subghz_protocol_nero_sketch_free(SubGhzProtocolNeroSketch* instance); -/** Sends the key on the air +/** Get upload protocol * - * @param instance - SubGhzProtocolNeroSketch instance - * @param key - key send - * @param bit - count bit key - * @param repeat - repeat send key + * @param instance - SubGhzProtocolCame instance + * @param encoder - SubGhzProtocolEncoderCommon encoder + * @return bool */ -void subghz_protocol_faac_nero_sketch_key(SubGhzProtocolNeroSketch* instance, uint64_t key, uint8_t bit, uint8_t repeat); +bool subghz_protocol_nero_sketch_send_key(SubGhzProtocolNeroSketch* instance, SubGhzProtocolEncoderCommon* encoder); /** Reset internal state * @param instance - SubGhzProtocolNeroSketch instance diff --git a/lib/subghz/protocols/subghz_protocol_nice_flo.c b/lib/subghz/protocols/subghz_protocol_nice_flo.c index 0c0cb207..b53160b8 100644 --- a/lib/subghz/protocols/subghz_protocol_nice_flo.c +++ b/lib/subghz/protocols/subghz_protocol_nice_flo.c @@ -15,10 +15,17 @@ SubGhzProtocolNiceFlo* subghz_protocol_nice_flo_alloc() { instance->common.name = "Nice FLO"; instance->common.code_min_count_bit_for_found = 12; - instance->common.te_shot = 700; + instance->common.te_short = 700; instance->common.te_long = 1400; instance->common.te_delta = 200; - + instance->common.type_protocol = TYPE_PROTOCOL_STATIC; + 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.get_upload_protocol = + (SubGhzProtocolEncoderCommonGetUpLoad)subghz_protocol_nice_flo_send_key; return instance; } @@ -27,39 +34,29 @@ void subghz_protocol_nice_flo_free(SubGhzProtocolNiceFlo* instance) { free(instance); } -/** Send bit - * - * @param instance - SubGhzProtocolNiceFlo instance - * @param bit - bit - */ -void subghz_protocol_nice_flo_send_bit(SubGhzProtocolNiceFlo* instance, uint8_t bit) { - if (bit) { - //send bit 1 - SUBGHZ_TX_PIN_LOW(); - delay_us(instance->common.te_long); - SUBGHZ_TX_PIN_HIGTH(); - delay_us(instance->common.te_shot); - } else { - //send bit 0 - SUBGHZ_TX_PIN_LOW(); - delay_us(instance->common.te_shot); - SUBGHZ_TX_PIN_HIGTH(); - delay_us(instance->common.te_long); - } -} - -void subghz_protocol_nice_flo_send_key(SubGhzProtocolNiceFlo* instance, uint64_t key, uint8_t bit, uint8_t repeat) { - while (repeat--) { - //Send header - SUBGHZ_TX_PIN_LOW(); - delay_us(instance->common.te_shot * 34); //+2 interval v bit 1 - //Send start bit - subghz_protocol_nice_flo_send_bit(instance, 1); - //Send key data - for (uint8_t i = bit; i > 0; i--) { - subghz_protocol_nice_flo_send_bit(instance, bit_read(key, i - 1)); +bool subghz_protocol_nice_flo_send_key(SubGhzProtocolNiceFlo* instance, SubGhzProtocolEncoderCommon* encoder){ + furi_assert(instance); + furi_assert(encoder); + size_t index = 0; + encoder->size_upload =(instance->common.code_last_count_bit * 2) + 2; + if(encoder->size_upload > SUBGHZ_ENCODER_UPLOAD_MAX_SIZE) return false; + //Send header + encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->common.te_short * 36); + //Send start bit + encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_short); + //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)){ + //send bit 1 + encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->common.te_long); + encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_short); + }else{ + //send bit 0 + 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); } } + return true; } void subghz_protocol_nice_flo_reset(SubGhzProtocolNiceFlo* instance) { @@ -70,7 +67,7 @@ void subghz_protocol_nice_flo_parse(SubGhzProtocolNiceFlo* instance, bool level, switch (instance->common.parser_step) { case 0: if ((!level) - && (DURATION_DIFF(duration, instance->common.te_shot * 36)< instance->common.te_delta * 36)) { + && (DURATION_DIFF(duration, instance->common.te_short * 36)< instance->common.te_delta * 36)) { //Found header Nice Flo instance->common.parser_step = 1; } else { @@ -80,7 +77,7 @@ void subghz_protocol_nice_flo_parse(SubGhzProtocolNiceFlo* instance, bool level, case 1: if (!level) { break; - } else if (DURATION_DIFF(duration, instance->common.te_shot)< instance->common.te_delta) { + } else if (DURATION_DIFF(duration, instance->common.te_short)< instance->common.te_delta) { //Found start bit Nice Flo instance->common.parser_step = 2; instance->common.code_found = 0; @@ -91,10 +88,15 @@ void subghz_protocol_nice_flo_parse(SubGhzProtocolNiceFlo* instance, bool level, break; case 2: if (!level) { //save interval - if (duration >= (instance->common.te_shot * 4)) { + if (duration >= (instance->common.te_short * 4)) { instance->common.parser_step = 1; if (instance->common.code_count_bit>= instance->common.code_min_count_bit_for_found) { + + instance->common.serial = 0x0; + instance->common.btn = 0x0; + 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); } @@ -108,12 +110,12 @@ void subghz_protocol_nice_flo_parse(SubGhzProtocolNiceFlo* instance, bool level, break; case 3: if (level) { - if ((DURATION_DIFF(instance->common.te_last,instance->common.te_shot) < instance->common.te_delta) + 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)) { subghz_protocol_common_add_bit(&instance->common, 0); instance->common.parser_step = 2; } else if ((DURATION_DIFF(instance->common.te_last,instance->common.te_long)< instance->common.te_delta) - && (DURATION_DIFF(duration, instance->common.te_shot)< instance->common.te_delta)) { + && (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 @@ -124,3 +126,72 @@ void subghz_protocol_nice_flo_parse(SubGhzProtocolNiceFlo* instance, bool level, break; } } + +void subghz_protocol_nice_flo_to_str(SubGhzProtocolNiceFlo* instance, string_t output) { + uint32_t code_found_lo = instance->common.code_last_found & 0x00000000ffffffff; + + uint64_t code_found_reverse = subghz_protocol_common_reverse_key( + instance->common.code_last_found, instance->common.code_last_count_bit); + + uint32_t code_found_reverse_lo = code_found_reverse & 0x00000000ffffffff; + + string_cat_printf( + output, + "%s %d Bit\r\n" + " KEY:0x%08lX\r\n" + " YEK:0x%08lX\r\n", + instance->common.name, + instance->common.code_last_count_bit, + code_found_lo, + code_found_reverse_lo + ); +} + + +void subghz_protocol_nice_flo_to_save_str(SubGhzProtocolNiceFlo* instance, string_t output) { + string_printf( + output, + "Protocol: %s\n" + "Bit: %d\n" + "Key: %08lX\n", + instance->common.name, + instance->common.code_last_count_bit, + (uint32_t)(instance->common.code_last_found & 0x00000000ffffffff)); +} + +bool subghz_protocol_nice_flo_to_load_protocol(FileWorker* file_worker, SubGhzProtocolNiceFlo* instance){ + bool loaded = false; + string_t temp_str; + string_init(temp_str); + int res = 0; + int data = 0; + + do { + // Read and parse bit data from 2nd line + if(!file_worker_read_until(file_worker, temp_str, '\n')) { + break; + } + res = sscanf(string_get_cstr(temp_str), "Bit: %d\n", &data); + if(res != 1) { + break; + } + instance->common.code_last_count_bit = (uint8_t)data; + + // Read and parse key data from 3nd line + if(!file_worker_read_until(file_worker, temp_str, '\n')) { + break; + } + uint32_t temp_key = 0; + res = sscanf(string_get_cstr(temp_str), "Key: %08lX\n", &temp_key); + if(res != 1) { + break; + } + instance->common.code_last_found = (uint64_t)temp_key; + + loaded = true; + } while(0); + + string_clear(temp_str); + + return loaded; +} diff --git a/lib/subghz/protocols/subghz_protocol_nice_flo.h b/lib/subghz/protocols/subghz_protocol_nice_flo.h index 80075bb2..fc80f02a 100644 --- a/lib/subghz/protocols/subghz_protocol_nice_flo.h +++ b/lib/subghz/protocols/subghz_protocol_nice_flo.h @@ -16,14 +16,13 @@ SubGhzProtocolNiceFlo* subghz_protocol_nice_flo_alloc(); */ void subghz_protocol_nice_flo_free(SubGhzProtocolNiceFlo* instance); -/** Sends the key on the air +/** Get upload protocol * - * @param instance - SubGhzProtocolNiceFlo instance - * @param key - key send - * @param bit - count bit key - * @param repeat - repeat send key + * @param instance - SubGhzProtocolCame instance + * @param encoder - SubGhzProtocolEncoderCommon encoder + * @return bool */ -void subghz_protocol_nice_flo_send_key(SubGhzProtocolNiceFlo* instance, uint64_t key, uint8_t bit, uint8_t repeat); +bool subghz_protocol_nice_flo_send_key(SubGhzProtocolNiceFlo* instance, SubGhzProtocolEncoderCommon* encoder); /** Reset internal state * @param instance - SubGhzProtocolNiceFlo instance @@ -36,3 +35,13 @@ void subghz_protocol_nice_flo_reset(SubGhzProtocolNiceFlo* instance); * @param data - LevelDuration level_duration */ void subghz_protocol_nice_flo_parse(SubGhzProtocolNiceFlo* instance, bool level, uint32_t duration); + +/** Outputting information from the parser + * + * @param instance - SubGhzProtocolNiceFlo* instance + * @param output - output string + */ +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); diff --git a/lib/subghz/protocols/subghz_protocol_nice_flor_s.c b/lib/subghz/protocols/subghz_protocol_nice_flor_s.c index f774e6d8..ab6b83ea 100644 --- a/lib/subghz/protocols/subghz_protocol_nice_flor_s.c +++ b/lib/subghz/protocols/subghz_protocol_nice_flor_s.c @@ -18,9 +18,10 @@ SubGhzProtocolNiceFlorS* subghz_protocol_nice_flor_s_alloc() { instance->common.name = "Nice FloR-S"; instance->common.code_min_count_bit_for_found = 52; - instance->common.te_shot = 500; + instance->common.te_short = 500; instance->common.te_long = 1000; instance->common.te_delta = 300; + instance->common.type_protocol = TYPE_PROTOCOL_DYNAMIC; instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_protocol_nice_flor_s_to_str; return instance; @@ -44,14 +45,14 @@ void subghz_protocol_nice_flor_s_name_file(SubGhzProtocolNiceFlorS* instance, co void subghz_protocol_nice_flor_s_send_bit(SubGhzProtocolNiceFlorS* instance, uint8_t bit) { if(bit) { //send bit 1 - SUBGHZ_TX_PIN_HIGTH(); + SUBGHZ_TX_PIN_HIGH(); delay_us(instance->common.te_long); SUBGHZ_TX_PIN_LOW(); - delay_us(instance->common.te_shot); + delay_us(instance->common.te_short); } else { //send bit 0 - SUBGHZ_TX_PIN_HIGTH(); - delay_us(instance->common.te_shot); + SUBGHZ_TX_PIN_HIGH(); + delay_us(instance->common.te_short); SUBGHZ_TX_PIN_LOW(); delay_us(instance->common.te_long); } @@ -65,21 +66,21 @@ void subghz_protocol_nice_flor_s_send_key( while(repeat--) { //Send header SUBGHZ_TX_PIN_LOW(); - delay_us(instance->common.te_shot * 34); + delay_us(instance->common.te_short * 34); //Send Start Bit - SUBGHZ_TX_PIN_HIGTH(); - delay_us(instance->common.te_shot * 3); + SUBGHZ_TX_PIN_HIGH(); + delay_us(instance->common.te_short * 3); SUBGHZ_TX_PIN_LOW(); - delay_us(instance->common.te_shot * 3); + delay_us(instance->common.te_short * 3); //Send key data for(uint8_t i = bit; i > 0; i--) { subghz_protocol_nice_flor_s_send_bit(instance, bit_read(key, i - 1)); } //Send Stop Bit - SUBGHZ_TX_PIN_HIGTH(); - delay_us(instance->common.te_shot * 3); + SUBGHZ_TX_PIN_HIGH(); + delay_us(instance->common.te_short * 3); SUBGHZ_TX_PIN_LOW(); - delay_us(instance->common.te_shot * 3); + delay_us(instance->common.te_short * 3); } } @@ -130,18 +131,17 @@ void subghz_nice_flor_s_decoder_decrypt(SubGhzProtocolNiceFlorS* instance) { * S3,S2,S1,S0 - serial number of the console 28 bit. */ - uint16_t p3p4 = (uint16_t)(instance->common.code_found >> 24); - instance->common.cnt = subghz_nice_flor_s_get_byte_in_file(instance,p3p4*2) << 8 | subghz_nice_flor_s_get_byte_in_file(instance,p3p4*2+1); //nice_flor_srainbow_table_for_search[p3p4]; тут надо считать поле с файла причем адрес надо у множить на 2 - uint8_t k =(uint8_t)(p3p4 & 0x00FF) ^subghz_nice_flor_s_get_byte_in_file(instance,(0x20000 |(instance->common.cnt &0x00ff))); //nice_flor_srainbow_table_for_search[0x10000|subghz_protocol_nice_flor_s.cnt & 0x00ff]; + uint16_t p3p4 = (uint16_t)(instance->common.code_last_found >> 24); + instance->common.cnt = subghz_nice_flor_s_get_byte_in_file(instance,p3p4*2) << 8 | subghz_nice_flor_s_get_byte_in_file(instance,p3p4*2+1); + uint8_t k =(uint8_t)(p3p4 & 0x00FF) ^subghz_nice_flor_s_get_byte_in_file(instance,(0x20000 |(instance->common.cnt &0x00ff))); - uint8_t s3 = ((uint8_t)(instance->common.code_found >> 40) ^ k) & 0x0f; - uint8_t s2 = ((uint8_t)(instance->common.code_found >> 16) ^ k); - uint8_t s1 = ((uint8_t)(instance->common.code_found >> 8) ^ k); - uint8_t s0 = ((uint8_t)(instance->common.code_found) ^ k); + uint8_t s3 = ((uint8_t)(instance->common.code_last_found >> 40) ^ k) & 0x0f; + uint8_t s2 = ((uint8_t)(instance->common.code_last_found >> 16) ^ k); + uint8_t s1 = ((uint8_t)(instance->common.code_last_found >> 8) ^ k); + uint8_t s0 = ((uint8_t)(instance->common.code_last_found) ^ k); instance->common.serial = s3 << 24 | s2 << 16 | s1 << 8 | s0; - instance->common.btn = (instance->common.code_found >> 48) & 0x0f; - if(instance->common.callback) instance->common.callback((SubGhzProtocolCommon*)instance, instance->common.context); + instance->common.btn = (instance->common.code_last_found >> 48) & 0x0f; } void subghz_protocol_nice_flor_s_reset(SubGhzProtocolNiceFlorS* instance) { @@ -152,7 +152,7 @@ void subghz_protocol_nice_flor_s_parse(SubGhzProtocolNiceFlorS* instance, bool l switch(instance->common.parser_step) { case 0: if((!level) - && (DURATION_DIFF(duration, instance->common.te_shot * 38) < instance->common.te_delta * 38)) { + && (DURATION_DIFF(duration, instance->common.te_short * 38) < instance->common.te_delta * 38)) { //Found start header Nice Flor-S instance->common.parser_step = 1; } else { @@ -161,7 +161,7 @@ void subghz_protocol_nice_flor_s_parse(SubGhzProtocolNiceFlorS* instance, bool l break; case 1: if((level) - && (DURATION_DIFF(duration, instance->common.te_shot * 3) < instance->common.te_delta * 3)) { + && (DURATION_DIFF(duration, instance->common.te_short * 3) < instance->common.te_delta * 3)) { //Found next header Nice Flor-S instance->common.parser_step = 2; } else { @@ -170,7 +170,7 @@ void subghz_protocol_nice_flor_s_parse(SubGhzProtocolNiceFlorS* instance, bool l break; case 2: if((!level) - && (DURATION_DIFF(duration, instance->common.te_shot * 3) < instance->common.te_delta * 3)) { + && (DURATION_DIFF(duration, instance->common.te_short * 3) < instance->common.te_delta * 3)) { //Found header Nice Flor-S instance->common.parser_step = 3; instance->common.code_found = 0; @@ -181,13 +181,13 @@ void subghz_protocol_nice_flor_s_parse(SubGhzProtocolNiceFlorS* instance, bool l break; case 3: if(level) { - if(DURATION_DIFF(duration, instance->common.te_shot * 3) < instance->common.te_delta) { + if(DURATION_DIFF(duration, instance->common.te_short * 3) < instance->common.te_delta) { //Found STOP bit instance->common.parser_step = 0; if(instance->common.code_count_bit >=instance->common.code_min_count_bit_for_found) { - - subghz_nice_flor_s_decoder_decrypt(instance); - + 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); } break; } else { @@ -199,13 +199,13 @@ void subghz_protocol_nice_flor_s_parse(SubGhzProtocolNiceFlorS* instance, bool l break; case 4: if(!level) { - if((DURATION_DIFF(instance->common.te_last, instance->common.te_shot) < instance->common.te_delta) + 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)) { subghz_protocol_common_add_bit(&instance->common, 0); instance->common.parser_step = 3; } else if( (DURATION_DIFF(instance->common.te_last, instance->common.te_long) < instance->common.te_delta) - &&(DURATION_DIFF(duration, instance->common.te_shot) < instance->common.te_delta)) { + &&(DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta)) { subghz_protocol_common_add_bit(&instance->common, 1); instance->common.parser_step = 3; } else @@ -218,17 +218,18 @@ void subghz_protocol_nice_flor_s_parse(SubGhzProtocolNiceFlorS* instance, bool l } void subghz_protocol_nice_flor_s_to_str(SubGhzProtocolNiceFlorS* instance, string_t output) { - uint32_t code_found_hi = instance->common.code_found >> 32; - uint32_t code_found_lo = instance->common.code_found & 0x00000000ffffffff; + subghz_nice_flor_s_decoder_decrypt(instance); + uint32_t code_found_hi = instance->common.code_last_found >> 32; + uint32_t code_found_lo = instance->common.code_last_found & 0x00000000ffffffff; string_cat_printf( output, - "Protocol %s, %d Bit\r\n" + "%s, %d Bit\r\n" " KEY:0x%lX%08lX\r\n" " SN:%05lX\r\n" " CNT:%04X BTN:%02lX\r\n", instance->common.name, - instance->common.code_count_bit, + instance->common.code_last_count_bit, code_found_hi, code_found_lo, instance->common.serial, diff --git a/lib/subghz/protocols/subghz_protocol_princeton.c b/lib/subghz/protocols/subghz_protocol_princeton.c index 210f0db0..c05f297b 100644 --- a/lib/subghz/protocols/subghz_protocol_princeton.c +++ b/lib/subghz/protocols/subghz_protocol_princeton.c @@ -16,15 +16,9 @@ struct SubGhzEncoderPrinceton { size_t front; }; -struct SubGhzDecoderPrinceton { - SubGhzProtocolCommon common; - uint16_t te; -}; SubGhzEncoderPrinceton* subghz_encoder_princeton_alloc() { SubGhzEncoderPrinceton* instance = furi_alloc(sizeof(SubGhzEncoderPrinceton)); - - return instance; } @@ -32,6 +26,7 @@ void subghz_encoder_princeton_free(SubGhzEncoderPrinceton* instance) { furi_assert(instance); free(instance); } + void subghz_encoder_princeton_set_te(SubGhzEncoderPrinceton* instance, void* decoder){ SubGhzDecoderPrinceton* pricenton = decoder; if((pricenton->te) !=0){ @@ -42,7 +37,7 @@ void subghz_encoder_princeton_set_te(SubGhzEncoderPrinceton* instance, void* dec } -void subghz_encoder_princeton_reset(SubGhzEncoderPrinceton* instance, uint32_t key, size_t repeat) { +void subghz_encoder_princeton_set(SubGhzEncoderPrinceton* instance, uint32_t key, size_t repeat) { furi_assert(instance); instance->te = SUBGHZ_PT_SHORT; instance->key = key; @@ -85,21 +80,24 @@ LevelDuration subghz_encoder_princeton_yield(void* context) { return ret; } - SubGhzDecoderPrinceton* subghz_decoder_princeton_alloc(void) { SubGhzDecoderPrinceton* instance = furi_alloc(sizeof(SubGhzDecoderPrinceton)); + instance->te = SUBGHZ_PT_SHORT; instance->common.name = "Princeton"; instance->common.code_min_count_bit_for_found = 24; - instance->common.te_shot = 450; //150; - instance->common.te_long = 1350; //450; + instance->common.te_short = SUBGHZ_PT_SHORT; //150; + instance->common.te_long = SUBGHZ_PT_LONG; //450; instance->common.te_delta = 200; //50; + instance->common.type_protocol = TYPE_PROTOCOL_STATIC; 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.get_upload_protocol = + (SubGhzProtocolEncoderCommonGetUpLoad)subghz_protocol_princeton_send_key; + return instance; } @@ -108,43 +106,32 @@ void subghz_decoder_princeton_free(SubGhzDecoderPrinceton* instance) { free(instance); } -/** Send bit - * - * @param instance - SubGhzDecoderPrinceton instance - * @param bit - bit - */ -void subghz_decoder_princeton_send_bit(SubGhzDecoderPrinceton* instance, uint8_t bit) { - if(bit) { - //send bit 1 - SUBGHZ_TX_PIN_LOW(); - delay_us(instance->common.te_long); - SUBGHZ_TX_PIN_HIGTH(); - delay_us(instance->common.te_shot); - } else { - //send bit 0 - SUBGHZ_TX_PIN_LOW(); - delay_us(instance->common.te_shot); - SUBGHZ_TX_PIN_HIGTH(); - delay_us(instance->common.te_long); - } -} - -void subghz_decoder_princeton_send_key( - SubGhzDecoderPrinceton* instance, - uint64_t key, - uint8_t bit, - uint8_t repeat) { - while(repeat--) { - SUBGHZ_TX_PIN_LOW(); - //Send start bit - subghz_decoder_princeton_send_bit(instance, 1); - //Send header - delay_us(instance->common.te_shot * 33); //+2 interval v bit 1 - //Send key data - for(uint8_t i = bit; i > 0; i--) { - subghz_decoder_princeton_send_bit(instance, bit_read(key, i - 1)); +bool subghz_protocol_princeton_send_key(SubGhzDecoderPrinceton* instance, SubGhzProtocolEncoderCommon* encoder){ + furi_assert(instance); + furi_assert(encoder); + size_t index = 0; + 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)){ + //send bit 1 + encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->te*3); + encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->te); + }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); } } + + //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); + + return true; } void subghz_decoder_princeton_reset(SubGhzDecoderPrinceton* instance) { @@ -157,7 +144,7 @@ void subghz_decoder_princeton_parse( uint32_t duration) { switch(instance->common.parser_step) { case 0: - if((!level) && (DURATION_DIFF(duration, instance->common.te_shot * 36) < + if((!level) && (DURATION_DIFF(duration, instance->common.te_short * 36) < instance->common.te_delta * 36)) { //Found Preambula instance->common.parser_step = 1; @@ -176,7 +163,7 @@ void subghz_decoder_princeton_parse( break; case 2: if(!level) { - if(duration >= (instance->common.te_shot * 10 + instance->common.te_delta)) { + if(duration >= (instance->common.te_short * 10 + instance->common.te_delta)) { instance->common.parser_step = 1; if(instance->common.code_count_bit >= instance->common.code_min_count_bit_for_found) { @@ -202,7 +189,7 @@ void subghz_decoder_princeton_parse( break; } - if((DURATION_DIFF(instance->common.te_last, instance->common.te_shot) < + 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)) { @@ -211,7 +198,7 @@ void subghz_decoder_princeton_parse( } else if( (DURATION_DIFF(instance->common.te_last, instance->common.te_long) < instance->common.te_delta * 3) && - (DURATION_DIFF(duration, instance->common.te_shot) < instance->common.te_delta)) { + (DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta)) { subghz_protocol_common_add_bit(&instance->common, 1); instance->common.parser_step = 1; } else { @@ -225,27 +212,23 @@ void subghz_decoder_princeton_parse( } void subghz_decoder_princeton_to_str(SubGhzDecoderPrinceton* instance, string_t output) { - uint32_t code_found_hi = instance->common.code_last_found >> 32; uint32_t code_found_lo = instance->common.code_last_found & 0x00000000ffffffff; uint64_t code_found_reverse = subghz_protocol_common_reverse_key( instance->common.code_last_found, instance->common.code_last_count_bit); - uint32_t code_found_reverse_hi = code_found_reverse >> 32; uint32_t code_found_reverse_lo = code_found_reverse & 0x00000000ffffffff; string_cat_printf( output, "%s %d Bit te %dus\r\n" - " KEY:0x%lX%08lX\r\n" - " YEK:0x%lX%08lX\r\n" + " KEY:0x%08lX\r\n" + " YEK:0x%08lX\r\n" " SN:0x%05lX BTN:%02X\r\n", instance->common.name, instance->common.code_last_count_bit, instance->te, - code_found_hi, code_found_lo, - code_found_reverse_hi, code_found_reverse_lo, instance->common.serial, instance->common.btn); diff --git a/lib/subghz/protocols/subghz_protocol_princeton.h b/lib/subghz/protocols/subghz_protocol_princeton.h index 7feeb978..a414b6a2 100644 --- a/lib/subghz/protocols/subghz_protocol_princeton.h +++ b/lib/subghz/protocols/subghz_protocol_princeton.h @@ -2,6 +2,10 @@ #include "subghz_protocol_common.h" +struct SubGhzDecoderPrinceton { + SubGhzProtocolCommon common; + uint16_t te; +}; /** SubGhzEncoderPrinceton anonymous type */ typedef struct SubGhzEncoderPrinceton SubGhzEncoderPrinceton; @@ -17,12 +21,12 @@ SubGhzEncoderPrinceton* subghz_encoder_princeton_alloc(); void subghz_encoder_princeton_free(SubGhzEncoderPrinceton* instance); -/** Reset encoder with new params +/** Set new encoder params * @param instance - SubGhzEncoderPrinceton instance * @param key - 24bit key * @param repeat - how many times to repeat */ -void subghz_encoder_princeton_reset(SubGhzEncoderPrinceton* instance, uint32_t key, size_t repeat); +void subghz_encoder_princeton_set(SubGhzEncoderPrinceton* instance, uint32_t key, size_t repeat); /** Get repeat count left * @param instance - SubGhzEncoderPrinceton instance @@ -57,14 +61,13 @@ SubGhzDecoderPrinceton* subghz_decoder_princeton_alloc(); */ void subghz_decoder_princeton_free(SubGhzDecoderPrinceton* instance); -/** Sends the key on the air +/** Get upload protocol * * @param instance - SubGhzDecoderPrinceton instance - * @param key - key send - * @param bit - count bit key - * @param repeat - repeat send key + * @param encoder - SubGhzProtocolEncoderCommon encoder + * @return bool */ -void subghz_decoder_princeton_send_key(SubGhzDecoderPrinceton* instance, uint64_t key, uint8_t bit, uint8_t repeat); +bool subghz_protocol_princeton_send_key(SubGhzDecoderPrinceton* instance, SubGhzProtocolEncoderCommon* encoder); /** Reset internal state * @param instance - SubGhzDecoderPrinceton instance diff --git a/lib/subghz/protocols/subghz_protocol_star_line.c b/lib/subghz/protocols/subghz_protocol_star_line.c index b676f2e9..1890b5e6 100644 --- a/lib/subghz/protocols/subghz_protocol_star_line.c +++ b/lib/subghz/protocols/subghz_protocol_star_line.c @@ -22,9 +22,10 @@ SubGhzProtocolStarLine* subghz_protocol_star_line_alloc(SubGhzKeystore* keystore instance->common.name = "Star Line"; instance->common.code_min_count_bit_for_found = 64; - instance->common.te_shot = 250; + instance->common.te_short = 250; instance->common.te_long = 500; instance->common.te_delta = 120; + instance->common.type_protocol = TYPE_PROTOCOL_DYNAMIC; instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_protocol_star_line_to_str; return instance; @@ -43,16 +44,16 @@ void subghz_protocol_star_line_free(SubGhzProtocolStarLine* instance) { void subghz_protocol_star_line_send_bit(SubGhzProtocolStarLine* instance, uint8_t bit) { if (bit) { //send bit 1 - SUBGHZ_TX_PIN_HIGTH(); + SUBGHZ_TX_PIN_HIGH(); delay_us(instance->common.te_long); SUBGHZ_TX_PIN_LOW(); delay_us(instance->common.te_long); } else { //send bit 0 - SUBGHZ_TX_PIN_HIGTH(); - delay_us(instance->common.te_shot); + SUBGHZ_TX_PIN_HIGH(); + delay_us(instance->common.te_short); SUBGHZ_TX_PIN_LOW(); - delay_us(instance->common.te_shot); + delay_us(instance->common.te_short); } } @@ -60,7 +61,7 @@ void subghz_protocol_star_line_send_key(SubGhzProtocolStarLine* instance, uint64 while (repeat--) { //Send header for(uint8_t i = 0; i < 6; i++){ - SUBGHZ_TX_PIN_HIGTH(); + SUBGHZ_TX_PIN_HIGH(); delay_us(instance->common.te_long * 2); SUBGHZ_TX_PIN_LOW(); delay_us(instance->common.te_long * 2); @@ -174,7 +175,7 @@ uint8_t subghz_protocol_star_line_check_remote_controller_selector(SubGhzProtoco * @param instance SubGhzProtocolStarLine instance */ void subghz_protocol_star_line_check_remote_controller(SubGhzProtocolStarLine* instance) { - uint64_t key = subghz_protocol_common_reverse_key(instance->common.code_found, instance->common.code_count_bit); + uint64_t key = subghz_protocol_common_reverse_key(instance->common.code_last_found, instance->common.code_last_count_bit); uint32_t key_fix = key >> 32; uint32_t key_hop = key & 0x00000000ffffffff; @@ -182,10 +183,6 @@ void subghz_protocol_star_line_check_remote_controller(SubGhzProtocolStarLine* i instance ->common.serial= key_fix&0x00FFFFFF; instance->common.btn = key_fix >> 24; - - - if (instance->common.callback) instance->common.callback((SubGhzProtocolCommon*)instance, instance->common.context); - } void subghz_protocol_star_line_parse(SubGhzProtocolStarLine* instance, bool level, uint32_t duration) { @@ -222,7 +219,9 @@ void subghz_protocol_star_line_parse(SubGhzProtocolStarLine* instance, bool leve instance->common.parser_step = 0; if (instance->common.code_count_bit>= instance->common.code_min_count_bit_for_found) { if(instance->common.code_last_found != instance->common.code_found){ - subghz_protocol_star_line_check_remote_controller(instance); + 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); } } instance->common.code_found = 0; @@ -240,8 +239,8 @@ void subghz_protocol_star_line_parse(SubGhzProtocolStarLine* instance, bool leve break; case 3: if(!level){ - if ((DURATION_DIFF(instance->common.te_last,instance->common.te_shot)< instance->common.te_delta) - && (DURATION_DIFF(duration,instance->common.te_shot)< instance->common.te_delta)) { + if ((DURATION_DIFF(instance->common.te_last,instance->common.te_short)< instance->common.te_delta) + && (DURATION_DIFF(duration,instance->common.te_short)< instance->common.te_delta)) { subghz_protocol_common_add_bit(&instance->common, 0); instance->common.parser_step = 2; } else if ((DURATION_DIFF(instance->common.te_last,instance->common.te_long )< instance->common.te_delta) @@ -259,22 +258,23 @@ void subghz_protocol_star_line_parse(SubGhzProtocolStarLine* instance, bool leve } void subghz_protocol_star_line_to_str(SubGhzProtocolStarLine* instance, string_t output) { - uint32_t code_found_hi = instance->common.code_found >> 32; - uint32_t code_found_lo = instance->common.code_found & 0x00000000ffffffff; + subghz_protocol_star_line_check_remote_controller(instance); + uint32_t code_found_hi = instance->common.code_last_found >> 32; + uint32_t code_found_lo = instance->common.code_last_found & 0x00000000ffffffff; - uint64_t code_found_reverse = subghz_protocol_common_reverse_key(instance->common.code_found, instance->common.code_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_found_reverse_hi = code_found_reverse>>32; uint32_t code_found_reverse_lo = code_found_reverse&0x00000000ffffffff; string_cat_printf( output, - "Protocol %s, %d Bit\r\n" + "%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", instance->common.name, - instance->common.code_count_bit, + instance->common.code_last_count_bit, code_found_hi, code_found_lo, code_found_reverse_hi,