diff --git a/applications/main/subghz/helpers/subghz_custom_event.h b/applications/main/subghz/helpers/subghz_custom_event.h index 9ac4552f5..4475045ee 100644 --- a/applications/main/subghz/helpers/subghz_custom_event.h +++ b/applications/main/subghz/helpers/subghz_custom_event.h @@ -8,11 +8,14 @@ typedef enum { //SubmenuIndex SubmenuIndexFaacSLH_433, SubmenuIndexFaacSLH_868, - SubmenuIndexBFT, + SubmenuIndexBFTClone, + SubmenuIndexBFTMitto, + SubmenuIndexSomfyTelis, SubmenuIndexPricenton, SubmenuIndexNiceFlo12bit, SubmenuIndexNiceFlo24bit, SubmenuIndexNiceFlorS_433_92, + SubmenuIndexNiceOne_433_92, SubmenuIndexNiceSmilo_433_92, SubmenuIndexCAME12bit, SubmenuIndexCAME24bit, diff --git a/applications/main/subghz/scenes/subghz_scene_ext_module_settings.c b/applications/main/subghz/scenes/subghz_scene_ext_module_settings.c index 8d1154a13..df81eae29 100644 --- a/applications/main/subghz/scenes/subghz_scene_ext_module_settings.c +++ b/applications/main/subghz/scenes/subghz_scene_ext_module_settings.c @@ -17,9 +17,12 @@ const char* const debug_pin_text[DEBUG_P_COUNT] = { "17(1W)", }; -#define DEBUG_COUNTER_COUNT 3 +#define DEBUG_COUNTER_COUNT 6 const char* const debug_counter_text[DEBUG_COUNTER_COUNT] = { "+1", + "+2", + "+3", + "+4", "+5", "+10", }; @@ -55,9 +58,18 @@ static void subghz_scene_receiver_config_set_debug_counter(VariableItem* item) { furi_hal_subghz_set_rolling_counter_mult(1); break; case 1: - furi_hal_subghz_set_rolling_counter_mult(5); + furi_hal_subghz_set_rolling_counter_mult(2); break; case 2: + furi_hal_subghz_set_rolling_counter_mult(3); + break; + case 3: + furi_hal_subghz_set_rolling_counter_mult(4); + break; + case 4: + furi_hal_subghz_set_rolling_counter_mult(5); + break; + case 5: furi_hal_subghz_set_rolling_counter_mult(10); break; default: @@ -101,12 +113,21 @@ void subghz_scene_ext_module_settings_on_enter(void* context) { case 1: value_index_cnt = 0; break; - case 5: + case 2: value_index_cnt = 1; break; - case 10: + case 3: value_index_cnt = 2; break; + case 4: + value_index_cnt = 3; + break; + case 5: + value_index_cnt = 4; + break; + case 10: + value_index_cnt = 5; + break; default: break; } diff --git a/applications/main/subghz/scenes/subghz_scene_receiver_info.c b/applications/main/subghz/scenes/subghz_scene_receiver_info.c index c654ad0c5..fd28421a8 100644 --- a/applications/main/subghz/scenes/subghz_scene_receiver_info.c +++ b/applications/main/subghz/scenes/subghz_scene_receiver_info.c @@ -4,6 +4,7 @@ #include #include #include +#include void subghz_scene_receiver_info_callback(GuiButtonType result, InputType type, void* context) { furi_assert(context); @@ -238,6 +239,7 @@ void subghz_scene_receiver_info_on_exit(void* context) { keeloq_reset_original_btn(); alutech_reset_original_btn(); nice_flors_reset_original_btn(); + somfy_telis_reset_original_btn(); star_line_reset_mfname(); star_line_reset_kl_type(); } diff --git a/applications/main/subghz/scenes/subghz_scene_rpc.c b/applications/main/subghz/scenes/subghz_scene_rpc.c index a57a556dc..b9585ec36 100644 --- a/applications/main/subghz/scenes/subghz_scene_rpc.c +++ b/applications/main/subghz/scenes/subghz_scene_rpc.c @@ -3,6 +3,8 @@ #include #include #include +#include + #include "xtreme/assets.h" typedef enum { @@ -115,6 +117,7 @@ void subghz_scene_rpc_on_exit(void* context) { keeloq_reset_original_btn(); alutech_reset_original_btn(); nice_flors_reset_original_btn(); + somfy_telis_reset_original_btn(); star_line_reset_mfname(); star_line_reset_kl_type(); } diff --git a/applications/main/subghz/scenes/subghz_scene_set_type.c b/applications/main/subghz/scenes/subghz_scene_set_type.c index 95cb1ec03..5c5d5db3b 100644 --- a/applications/main/subghz/scenes/subghz_scene_set_type.c +++ b/applications/main/subghz/scenes/subghz_scene_set_type.c @@ -79,10 +79,22 @@ void subghz_scene_set_type_on_enter(void* context) { SubmenuIndexFaacSLH_433, subghz_scene_set_type_submenu_callback, subghz); + submenu_add_item( + subghz->submenu, + "BFT [Manual] 433MHz", + SubmenuIndexBFTClone, + subghz_scene_set_type_submenu_callback, + subghz); submenu_add_item( subghz->submenu, "BFT Mitto 433MHz", - SubmenuIndexBFT, + SubmenuIndexBFTMitto, + subghz_scene_set_type_submenu_callback, + subghz); + submenu_add_item( + subghz->submenu, + "Somfy Telis 433MHz", + SubmenuIndexSomfyTelis, subghz_scene_set_type_submenu_callback, subghz); submenu_add_item( @@ -115,6 +127,12 @@ void subghz_scene_set_type_on_enter(void* context) { SubmenuIndexNiceFlorS_433_92, subghz_scene_set_type_submenu_callback, subghz); + submenu_add_item( + subghz->submenu, + "Nice One 433MHz", + SubmenuIndexNiceOne_433_92, + subghz_scene_set_type_submenu_callback, + subghz); submenu_add_item( subghz->submenu, "CAME 12bit 433MHz", @@ -230,7 +248,7 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) { case SubmenuIndexFaacSLH_433: scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSetFixFaac); break; - case SubmenuIndexBFT: + case SubmenuIndexBFTClone: scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSetFixBft); break; case SubmenuIndexPricenton: @@ -306,6 +324,66 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) { generated_protocol = true; } break; + case SubmenuIndexBFTMitto: + subghz->txrx->transmitter = subghz_transmitter_alloc_init( + subghz->txrx->environment, SUBGHZ_PROTOCOL_KEELOQ_NAME); + subghz_preset_init(subghz, "AM650", 433920000, NULL, 0); + if(subghz->txrx->transmitter) { + subghz_protocol_keeloq_bft_create_data( + subghz_transmitter_get_protocol_instance(subghz->txrx->transmitter), + subghz->txrx->fff_data, + key & 0x000FFFFF, + 0x2, + 0x0002, + key & 0x000FFFFF, + "BFT", + subghz->txrx->preset); + + uint8_t seed_data[sizeof(uint32_t)] = {0}; + for(size_t i = 0; i < sizeof(uint32_t); i++) { + seed_data[sizeof(uint32_t) - i - 1] = ((key & 0x000FFFFF) >> i * 8) & 0xFF; + } + + flipper_format_write_hex( + subghz->txrx->fff_data, "Seed", seed_data, sizeof(uint32_t)); + + flipper_format_write_string_cstr(subghz->txrx->fff_data, "Manufacture", "BFT"); + + generated_protocol = true; + } else { + generated_protocol = false; + } + subghz_transmitter_free(subghz->txrx->transmitter); + if(!generated_protocol) { + furi_string_set( + subghz->error_str, "Function requires\nan SD card with\nfresh databases."); + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); + } + break; + case SubmenuIndexSomfyTelis: + subghz->txrx->transmitter = subghz_transmitter_alloc_init( + subghz->txrx->environment, SUBGHZ_PROTOCOL_SOMFY_TELIS_NAME); + subghz_preset_init( + subghz, "AM650", subghz_setting_get_default_frequency(subghz->setting), NULL, 0); + if(subghz->txrx->transmitter) { + subghz_protocol_somfy_telis_create_data( + subghz_transmitter_get_protocol_instance(subghz->txrx->transmitter), + subghz->txrx->fff_data, + key & 0x00FFFFFF, + 0x2, + 0x0003, + subghz->txrx->preset); + generated_protocol = true; + } else { + generated_protocol = false; + } + subghz_transmitter_free(subghz->txrx->transmitter); + if(!generated_protocol) { + furi_string_set( + subghz->error_str, "Function requires\nan SD card with\nfresh databases."); + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); + } + break; case SubmenuIndexDoorHan_433_92: subghz->txrx->transmitter = subghz_transmitter_alloc_init( subghz->txrx->environment, SUBGHZ_PROTOCOL_KEELOQ_NAME); @@ -367,7 +445,33 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) { key & 0x0FFFFFFF, 0x1, 0x0003, - subghz->txrx->preset); + subghz->txrx->preset, + false); + generated_protocol = true; + } else { + generated_protocol = false; + } + subghz_transmitter_free(subghz->txrx->transmitter); + if(!generated_protocol) { + furi_string_set( + subghz->error_str, "Function requires\nan SD card with\nfresh databases."); + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); + } + break; + case SubmenuIndexNiceOne_433_92: + subghz->txrx->transmitter = subghz_transmitter_alloc_init( + subghz->txrx->environment, SUBGHZ_PROTOCOL_NICE_FLOR_S_NAME); + subghz_preset_init( + subghz, "AM650", subghz_setting_get_default_frequency(subghz->setting), NULL, 0); + if(subghz->txrx->transmitter) { + subghz_protocol_nice_flor_s_create_data( + subghz_transmitter_get_protocol_instance(subghz->txrx->transmitter), + subghz->txrx->fff_data, + key & 0x0FFFFFFF, + 0x1, + 0x0003, + subghz->txrx->preset, + true); generated_protocol = true; } else { generated_protocol = false; diff --git a/applications/main/subghz/scenes/subghz_scene_transmitter.c b/applications/main/subghz/scenes/subghz_scene_transmitter.c index a10e10a37..00839170c 100644 --- a/applications/main/subghz/scenes/subghz_scene_transmitter.c +++ b/applications/main/subghz/scenes/subghz_scene_transmitter.c @@ -5,6 +5,7 @@ #include #include #include +#include void subghz_scene_transmitter_callback(SubGhzCustomEvent event, void* context) { furi_assert(context); @@ -95,6 +96,7 @@ bool subghz_scene_transmitter_on_event(void* context, SceneManagerEvent event) { keeloq_set_btn(0); alutech_set_btn(0); nice_flors_set_btn(0); + somfy_telis_set_btn(0); uint8_t tmp_counter = furi_hal_subghz_get_rolling_counter_mult(); furi_hal_subghz_set_rolling_counter_mult(0); // Calling restore! @@ -138,6 +140,7 @@ void subghz_scene_transmitter_on_exit(void* context) { keeloq_reset_original_btn(); alutech_reset_original_btn(); nice_flors_reset_original_btn(); + somfy_telis_reset_original_btn(); star_line_reset_mfname(); star_line_reset_kl_type(); } diff --git a/applications/main/subghz/views/transmitter.c b/applications/main/subghz/views/transmitter.c index 5a64f27e2..e6ed16d81 100644 --- a/applications/main/subghz/views/transmitter.c +++ b/applications/main/subghz/views/transmitter.c @@ -7,6 +7,7 @@ #include #include #include +#include struct SubGhzViewTransmitter { View* view; @@ -161,6 +162,7 @@ bool subghz_view_transmitter_input(InputEvent* event, void* context) { keeloq_set_btn(1); alutech_set_btn(1); nice_flors_set_btn(1); + somfy_telis_set_btn(1); with_view_model( subghz_transmitter->view, SubGhzViewTransmitterModel * model, @@ -176,6 +178,10 @@ bool subghz_view_transmitter_input(InputEvent* event, void* context) { furi_string_printf( model->temp_button_id, "%01X", nice_flors_get_original_btn()); model->draw_temp_button = true; + } else if(somfy_telis_get_original_btn() != 0) { + furi_string_printf( + model->temp_button_id, "%01X", somfy_telis_get_original_btn()); + model->draw_temp_button = true; } }, true); @@ -192,6 +198,7 @@ bool subghz_view_transmitter_input(InputEvent* event, void* context) { keeloq_set_btn(2); alutech_set_btn(2); nice_flors_set_btn(2); + somfy_telis_set_btn(2); with_view_model( subghz_transmitter->view, SubGhzViewTransmitterModel * model, @@ -207,6 +214,10 @@ bool subghz_view_transmitter_input(InputEvent* event, void* context) { furi_string_printf( model->temp_button_id, "%01X", nice_flors_get_original_btn()); model->draw_temp_button = true; + } else if(somfy_telis_get_original_btn() != 0) { + furi_string_printf( + model->temp_button_id, "%01X", somfy_telis_get_original_btn()); + model->draw_temp_button = true; } }, true); @@ -223,6 +234,7 @@ bool subghz_view_transmitter_input(InputEvent* event, void* context) { keeloq_set_btn(3); alutech_set_btn(3); nice_flors_set_btn(3); + somfy_telis_set_btn(3); with_view_model( subghz_transmitter->view, SubGhzViewTransmitterModel * model, @@ -238,6 +250,10 @@ bool subghz_view_transmitter_input(InputEvent* event, void* context) { furi_string_printf( model->temp_button_id, "%01X", nice_flors_get_original_btn()); model->draw_temp_button = true; + } else if(somfy_telis_get_original_btn() != 0) { + furi_string_printf( + model->temp_button_id, "%01X", somfy_telis_get_original_btn()); + model->draw_temp_button = true; } }, true); diff --git a/applications/main/unirfremix/unirfremix_app.c b/applications/main/unirfremix/unirfremix_app.c index 762428956..7cf1c2a00 100644 --- a/applications/main/unirfremix/unirfremix_app.c +++ b/applications/main/unirfremix/unirfremix_app.c @@ -21,6 +21,7 @@ #include #include #include +#include #define UNIRFMAP_FOLDER "/ext/subghz/unirf" #define UNIRFMAP_EXTENSION ".txt" @@ -486,6 +487,7 @@ void unirfremix_tx_stop(UniRFRemix* app) { keeloq_reset_original_btn(); alutech_reset_original_btn(); nice_flors_reset_original_btn(); + somfy_telis_reset_original_btn(); star_line_reset_mfname(); star_line_reset_kl_type(); } diff --git a/applications/plugins/hc_sr04/README.md b/applications/plugins/hc_sr04/README.md deleted file mode 100644 index 2fb3b8ce4..000000000 --- a/applications/plugins/hc_sr04/README.md +++ /dev/null @@ -1 +0,0 @@ -## (5V -> VCC) / (GND -> GND) / (13|TX -> Trig) / (14|RX -> Echo) \ No newline at end of file diff --git a/applications/plugins/hc_sr04/hc_sr04.c b/applications/plugins/hc_sr04/hc_sr04.c index dbbf4f3ec..db075247a 100644 --- a/applications/plugins/hc_sr04/hc_sr04.c +++ b/applications/plugins/hc_sr04/hc_sr04.c @@ -3,6 +3,7 @@ // Ported and modified by @xMasterX #include +#include #include #include #include @@ -26,7 +27,7 @@ typedef struct { NotificationApp* notification; bool have_5v; bool measurement_made; - uint32_t echo; // ms + uint32_t echo; // us float distance; // meters } PluginState; @@ -72,7 +73,7 @@ static void render_callback(Canvas* const canvas, void* ctx) { FuriString* str_buf; str_buf = furi_string_alloc(); - furi_string_printf(str_buf, "Echo: %ld ms", plugin_state->echo); + furi_string_printf(str_buf, "Echo: %ld us", plugin_state->echo); canvas_draw_str_aligned( canvas, 8, 38, AlignLeft, AlignTop, furi_string_get_cstr(str_buf)); @@ -110,9 +111,11 @@ static void hc_sr04_state_init(PluginState* const plugin_state) { } } -float hc_sr04_ms_to_m(uint32_t ms) { - const float speed_sound_m_per_s = 343.0f; - const float time_s = ms / 1e3f; +float hc_sr04_us_to_m(uint32_t us) { + //speed of sound for 20°C, 50% relative humidity + //331.3 + 20 * 0.606 + 50 * 0.0124 = 0.034404 + const float speed_sound_m_per_s = 344.04f; + const float time_s = us / 1e6f; const float total_dist = time_s * speed_sound_m_per_s; return total_dist / 2.0f; } @@ -147,10 +150,6 @@ static void hc_sr04_measure(PluginState* const plugin_state) { furi_delay_ms(10); furi_hal_gpio_write(&gpio_usart_tx, false); - // TODO change from furi_get_tick(), which returns ms, - // to DWT->CYCCNT, which is a more precise counter with - // us precision (see furi_hal_cortex_delay_us) - const uint32_t start = furi_get_tick(); while(furi_get_tick() - start < timeout_ms && furi_hal_gpio_read(&gpio_usart_rx)) @@ -158,16 +157,17 @@ static void hc_sr04_measure(PluginState* const plugin_state) { while(furi_get_tick() - start < timeout_ms && !furi_hal_gpio_read(&gpio_usart_rx)) ; - const uint32_t pulse_start = furi_get_tick(); + const uint32_t pulse_start = DWT->CYCCNT; while(furi_get_tick() - start < timeout_ms && furi_hal_gpio_read(&gpio_usart_rx)) ; + const uint32_t pulse_end = DWT->CYCCNT; - const uint32_t pulse_end = furi_get_tick(); //FURI_CRITICAL_EXIT(); - plugin_state->echo = pulse_end - pulse_start; - plugin_state->distance = hc_sr04_ms_to_m(pulse_end - pulse_start); + plugin_state->echo = + (pulse_end - pulse_start) / furi_hal_cortex_instructions_per_microsecond(); + plugin_state->distance = hc_sr04_us_to_m(plugin_state->echo); plugin_state->measurement_made = true; //furi_hal_light_set(LightRed, 0x00); @@ -270,4 +270,4 @@ int32_t hc_sr04_app() { delete_mutex(&state_mutex); return 0; -} \ No newline at end of file +} diff --git a/applications/plugins/metronome/README.md b/applications/plugins/metronome/README.md index 79134c350..4b6cd3122 100644 --- a/applications/plugins/metronome/README.md +++ b/applications/plugins/metronome/README.md @@ -1,5 +1,7 @@ # Metronome +[Original link](https://github.com/panki27/Metronome) + A metronome for the [Flipper Zero](https://flipperzero.one/) device. Goes along perfectly with my [BPM tapper](https://github.com/panki27/bpm-tapper). ![screenshot](img/screenshot.png) @@ -17,5 +19,5 @@ A metronome for the [Flipper Zero](https://flipperzero.one/) device. Goes along ## Compiling ``` -./fbt fap_metronome +./fbt firmware_metronome ``` diff --git a/applications/plugins/metronome/application.fam b/applications/plugins/metronome/application.fam index b40809638..32588d06e 100644 --- a/applications/plugins/metronome/application.fam +++ b/applications/plugins/metronome/application.fam @@ -8,8 +8,8 @@ App( "gui", ], fap_icon="metronome_icon.png", - fap_icon_assets="icons", fap_category="Music", + fap_icon_assets="images", stack_size=2 * 1024, order=20, ) diff --git a/applications/plugins/metronome/gui_extensions.c b/applications/plugins/metronome/gui_extensions.c index a7661ec28..458eb137b 100644 --- a/applications/plugins/metronome/gui_extensions.c +++ b/applications/plugins/metronome/gui_extensions.c @@ -1,6 +1,6 @@ #include #include -#include "Metronome_icons.h" +#include //lib can only do bottom left/right void elements_button_top_left(Canvas* canvas, const char* str) { diff --git a/applications/plugins/metronome/icons/ButtonUp_7x4.png b/applications/plugins/metronome/images/ButtonUp_7x4.png similarity index 100% rename from applications/plugins/metronome/icons/ButtonUp_7x4.png rename to applications/plugins/metronome/images/ButtonUp_7x4.png diff --git a/applications/plugins/metronome/metronome.c b/applications/plugins/metronome/metronome.c index 4c374aa75..06bce1bff 100644 --- a/applications/plugins/metronome/metronome.c +++ b/applications/plugins/metronome/metronome.c @@ -287,7 +287,6 @@ int32_t metronome_app() { metronome_state->timer = furi_timer_alloc(timer_callback, FuriTimerTypePeriodic, &state_mutex); // Open GUI and register view_port - // Gui* gui = furi_record_open("gui"); gui_add_view_port(gui, view_port, GuiLayerFullscreen); @@ -326,7 +325,7 @@ int32_t metronome_app() { case InputKeyBack: processing = false; break; - case InputKeyMAX: + default: break; } } else if(event.input.type == InputTypeLong) { @@ -348,7 +347,7 @@ int32_t metronome_app() { case InputKeyBack: processing = false; break; - case InputKeyMAX: + default: break; } } else if(event.input.type == InputTypeRepeat) { @@ -369,7 +368,7 @@ int32_t metronome_app() { case InputKeyBack: processing = false; break; - case InputKeyMAX: + default: break; } } diff --git a/applications/plugins/mousejacker/mousejacker_ducky.c b/applications/plugins/mousejacker/mousejacker_ducky.c index f9ded2d03..04b0bfaca 100644 --- a/applications/plugins/mousejacker/mousejacker_ducky.c +++ b/applications/plugins/mousejacker/mousejacker_ducky.c @@ -97,7 +97,8 @@ static uint32_t mj_ducky_get_command_len(const char* line) { static bool mj_get_ducky_key(char* key, size_t keylen, MJDuckyKey* dk) { //FURI_LOG_D(TAG, "looking up key %s with length %d", key, keylen); for(uint i = 0; i < sizeof(mj_ducky_keys) / sizeof(MJDuckyKey); i++) { - if(strlen(mj_ducky_keys[i].name) == keylen && !strncmp(mj_ducky_keys[i].name, key, keylen)) { + if(strlen(mj_ducky_keys[i].name) == keylen && + !strncmp(mj_ducky_keys[i].name, key, keylen)) { memcpy(dk, &mj_ducky_keys[i], sizeof(MJDuckyKey)); return true; } @@ -165,26 +166,23 @@ static void release_key( uint8_t* addr, uint8_t addr_size, uint8_t rate, - PluginState* plugin_state -) { + PluginState* plugin_state) { // This function release keys currently pressed, but keep pressing special keys // if holding mod keys variable are set to true uint8_t hid_payload[LOGITECH_HID_TEMPLATE_SIZE] = {0}; build_hid_packet( - 0 | holding_ctrl - | holding_shift << 1 - | holding_alt << 2 - | holding_gui << 3, - 0, hid_payload); + 0 | holding_ctrl | holding_shift << 1 | holding_alt << 2 | holding_gui << 3, + 0, + hid_payload); inject_packet( - handle, - addr, - addr_size, - rate, - hid_payload, - LOGITECH_HID_TEMPLATE_SIZE, - plugin_state); // empty hid packet + handle, + addr, + addr_size, + rate, + hid_payload, + LOGITECH_HID_TEMPLATE_SIZE, + plugin_state); // empty hid packet } static void send_hid_packet( @@ -196,15 +194,13 @@ static void send_hid_packet( uint8_t hid, PluginState* plugin_state) { uint8_t hid_payload[LOGITECH_HID_TEMPLATE_SIZE] = {0}; - if(hid == prev_hid ) - release_key(handle, addr, addr_size, rate, plugin_state); + if(hid == prev_hid) release_key(handle, addr, addr_size, rate, plugin_state); prev_hid = hid; - build_hid_packet(mod - | holding_ctrl - | holding_shift << 1 - | holding_alt << 2 - | holding_gui << 3, hid, hid_payload); + build_hid_packet( + mod | holding_ctrl | holding_shift << 1 | holding_alt << 2 | holding_gui << 3, + hid, + hid_payload); inject_packet( handle, addr, addr_size, rate, hid_payload, LOGITECH_HID_TEMPLATE_SIZE, plugin_state); furi_delay_ms(12); @@ -288,7 +284,7 @@ static bool mj_process_ducky_line( return true; } else if(strncmp(line_tmp, ducky_cmd_altstring, strlen(ducky_cmd_altstring)) == 0) { - // ALTSTRING + // ALTSTRING line_tmp = &line_tmp[mj_ducky_get_command_len(line_tmp) + 1]; for(size_t i = 0; i < strlen(line_tmp); i++) { if((line_tmp[i] < ' ') || (line_tmp[i] > '~')) { @@ -298,7 +294,7 @@ static bool mj_process_ducky_line( char alt_code[4]; // Getting altcode of the char snprintf(alt_code, 4, "%u", line_tmp[i]); - + uint8_t j = 0; while(!ducky_end_line(alt_code[j])) { char pad_num[5] = {'N', 'U', 'M', ' ', alt_code[j]}; @@ -425,7 +421,7 @@ static bool mj_process_ducky_line( if(!mj_get_ducky_key("TAB", 3, &dk)) return false; send_hid_packet(handle, addr, addr_size, rate, dk.mod, dk.hid, plugin_state); return true; - } + } return false; } diff --git a/applications/plugins/subbrute b/applications/plugins/subbrute index 819b53293..7cdb9e138 160000 --- a/applications/plugins/subbrute +++ b/applications/plugins/subbrute @@ -1 +1 @@ -Subproject commit 819b532937b8920504cd54385e25389c199285f9 +Subproject commit 7cdb9e1386778ad7351f7e3b3389980afaeafea3 diff --git a/firmware/targets/f7/api_symbols.csv b/firmware/targets/f7/api_symbols.csv index a7fa2adc4..9dc8c0fcd 100644 --- a/firmware/targets/f7/api_symbols.csv +++ b/firmware/targets/f7/api_symbols.csv @@ -2543,6 +2543,10 @@ Function,-,siprintf,int,"char*, const char*, ..." Function,-,siscanf,int,"const char*, const char*, ..." Function,-,sniprintf,int,"char*, size_t, const char*, ..." Function,+,snprintf,int,"char*, size_t, const char*, ..." +Function,-,somfy_telis_get_custom_btn,uint8_t, +Function,-,somfy_telis_get_original_btn,uint8_t, +Function,-,somfy_telis_reset_original_btn,void, +Function,-,somfy_telis_set_btn,void,uint8_t Function,-,sprintf,int,"char*, const char*, ..." Function,-,sqrt,double,double Function,-,sqrtf,float,float @@ -3273,7 +3277,7 @@ Function,-,subghz_protocol_encoder_star_line_yield,LevelDuration,void* Function,-,subghz_protocol_faac_slh_create_data,_Bool,"void*, FlipperFormat*, uint32_t, uint8_t, uint32_t, uint32_t, const char*, SubGhzRadioPreset*" Function,-,subghz_protocol_keeloq_bft_create_data,_Bool,"void*, FlipperFormat*, uint32_t, uint8_t, uint16_t, uint32_t, const char*, SubGhzRadioPreset*" Function,-,subghz_protocol_keeloq_create_data,_Bool,"void*, FlipperFormat*, uint32_t, uint8_t, uint16_t, const char*, SubGhzRadioPreset*" -Function,-,subghz_protocol_nice_flor_s_create_data,_Bool,"void*, FlipperFormat*, uint32_t, uint8_t, uint16_t, SubGhzRadioPreset*" +Function,-,subghz_protocol_nice_flor_s_create_data,_Bool,"void*, FlipperFormat*, uint32_t, uint8_t, uint16_t, SubGhzRadioPreset*, _Bool" Function,-,subghz_protocol_nice_flor_s_encrypt,uint64_t,"uint64_t, const char*" Function,+,subghz_protocol_raw_file_encoder_worker_set_callback_end,void,"SubGhzProtocolEncoderRAW*, SubGhzProtocolEncoderRAWCallbackEnd, void*" Function,+,subghz_protocol_raw_gen_fff_data,void,"FlipperFormat*, const char*" diff --git a/lib/subghz/blocks/generic.c b/lib/subghz/blocks/generic.c index 3d59adc82..54a401e05 100644 --- a/lib/subghz/blocks/generic.c +++ b/lib/subghz/blocks/generic.c @@ -78,6 +78,16 @@ bool subghz_block_generic_serialize( FURI_LOG_E(TAG, "Unable to add Key"); break; } + + // Nice One - Manual adding support + if(instance->data_count_bit == 72 && + (strcmp(instance->protocol_name, "Nice FloR-S") == 0)) { + uint32_t temp = (instance->data_2 >> 4) & 0xFFFFF; + if(!flipper_format_write_uint32(flipper_format, "Data", &temp, 1)) { + FURI_LOG_E(TAG, "Unable to add Data"); + break; + } + } res = true; } while(false); furi_string_free(temp_str); diff --git a/lib/subghz/protocols/faac_slh.c b/lib/subghz/protocols/faac_slh.c index 6918101a9..4b69ae73d 100644 --- a/lib/subghz/protocols/faac_slh.c +++ b/lib/subghz/protocols/faac_slh.c @@ -110,11 +110,7 @@ void subghz_protocol_encoder_faac_slh_free(void* context) { } static bool subghz_protocol_faac_slh_gen_data(SubGhzProtocolEncoderFaacSLH* instance) { - if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) >= 0xFFFF) { - instance->generic.cnt = 0; - } else { - instance->generic.cnt += furi_hal_subghz_get_rolling_counter_mult(); - } + instance->generic.cnt += furi_hal_subghz_get_rolling_counter_mult(); uint32_t fix = instance->generic.serial << 4 | instance->generic.btn; uint32_t hop = 0; uint32_t decrypt = 0; diff --git a/lib/subghz/protocols/keeloq.c b/lib/subghz/protocols/keeloq.c index efab023bc..a58a95ed6 100644 --- a/lib/subghz/protocols/keeloq.c +++ b/lib/subghz/protocols/keeloq.c @@ -88,6 +88,8 @@ static const char* mfname; static uint8_t kl_type; static uint8_t btn_temp_id; static uint8_t btn_temp_id_original; +static bool bft_prog_mode; +static uint16_t temp_counter; void keeloq_set_btn(uint8_t b) { btn_temp_id = b; @@ -103,6 +105,8 @@ uint8_t keeloq_get_custom_btn() { void keeloq_reset_original_btn() { btn_temp_id_original = 0; + temp_counter = 0; + bft_prog_mode = false; } void keeloq_reset_mfname() { @@ -158,7 +162,27 @@ static bool subghz_protocol_keeloq_gen_data( SubGhzProtocolEncoderKeeloq* instance, uint8_t btn, bool counter_up) { - if(counter_up) { + uint32_t fix = (uint32_t)btn << 28 | instance->generic.serial; + uint32_t hop = 0; + uint64_t man = 0; + uint64_t code_found_reverse; + int res = 0; + if(instance->manufacture_name == 0x0) { + instance->manufacture_name = ""; + } + + // BFT programming mode on / off conditions + if((strcmp(instance->manufacture_name, "BFT") == 0) && (btn == 0xF)) { + bft_prog_mode = true; + } + if((strcmp(instance->manufacture_name, "BFT") == 0) && (btn != 0xF) && bft_prog_mode) { + bft_prog_mode = false; + } + // If we using BFT programming mode we will trasmit its seed in hop part like original remote + if(bft_prog_mode) { + hop = instance->generic.seed; + } + if(counter_up && !bft_prog_mode) { if(instance->generic.cnt < 0xFFFF) { if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) >= 0xFFFF) { instance->generic.cnt = 0; @@ -169,49 +193,41 @@ static bool subghz_protocol_keeloq_gen_data( instance->generic.cnt = 0; } } - uint32_t fix = (uint32_t)btn << 28 | instance->generic.serial; - uint32_t decrypt = (uint32_t)btn << 28 | - (instance->generic.serial & 0x3FF) - << 16 | //ToDo in some protocols the discriminator is 0 - instance->generic.cnt; - uint32_t hop = 0; - uint64_t man = 0; - uint64_t code_found_reverse; - int res = 0; - if(instance->manufacture_name == 0x0) { - instance->manufacture_name = ""; - } + if(!bft_prog_mode) { + uint32_t decrypt = (uint32_t)btn << 28 | + (instance->generic.serial & 0x3FF) + << 16 | //ToDo in some protocols the discriminator is 0 + instance->generic.cnt; + // DTM Neo uses 12bit -> simple learning -- FAAC_RC,XT , Mutanco_Mutancode -> 12bit normal learning + if((strcmp(instance->manufacture_name, "DTM_Neo") == 0) || + (strcmp(instance->manufacture_name, "FAAC_RC,XT") == 0) || + (strcmp(instance->manufacture_name, "Mutanco_Mutancode") == 0)) { + decrypt = btn << 28 | (instance->generic.serial & 0xFFF) << 16 | instance->generic.cnt; + } - // DTM Neo uses 12bit -> simple learning -- FAAC_RC,XT , Mutanco_Mutancode -> 12bit normal learning - if((strcmp(instance->manufacture_name, "DTM_Neo") == 0) || - (strcmp(instance->manufacture_name, "FAAC_RC,XT") == 0) || - (strcmp(instance->manufacture_name, "Mutanco_Mutancode") == 0)) { - decrypt = btn << 28 | (instance->generic.serial & 0xFFF) << 16 | instance->generic.cnt; - } + // Nice Smilo, MHouse, JCM, Normstahl -> 8bit serial - simple learning + if((strcmp(instance->manufacture_name, "NICE_Smilo") == 0) || + (strcmp(instance->manufacture_name, "NICE_MHOUSE") == 0) || + (strcmp(instance->manufacture_name, "JCM_Tech") == 0) || + (strcmp(instance->manufacture_name, "Normstahl") == 0)) { + decrypt = btn << 28 | (instance->generic.serial & 0xFF) << 16 | instance->generic.cnt; + } - // Nice Smilo, MHouse, JCM, Normstahl -> 8bit serial - simple learning - if((strcmp(instance->manufacture_name, "NICE_Smilo") == 0) || - (strcmp(instance->manufacture_name, "NICE_MHOUSE") == 0) || - (strcmp(instance->manufacture_name, "JCM_Tech") == 0) || - (strcmp(instance->manufacture_name, "Normstahl") == 0)) { - decrypt = btn << 28 | (instance->generic.serial & 0xFF) << 16 | instance->generic.cnt; - } + // Beninca -> 4bit serial - simple XOR + if(strcmp(instance->manufacture_name, "Beninca") == 0) { + decrypt = btn << 28 | (instance->generic.serial & 0xF) << 16 | instance->generic.cnt; + } - // Beninca -> 4bit serial - simple XOR - if(strcmp(instance->manufacture_name, "Beninca") == 0) { - decrypt = btn << 28 | (instance->generic.serial & 0xF) << 16 | instance->generic.cnt; - } - - if(strcmp(instance->manufacture_name, "Unknown") == 0) { - code_found_reverse = subghz_protocol_blocks_reverse_key( - instance->generic.data, instance->generic.data_count_bit); - hop = code_found_reverse & 0x00000000ffffffff; - } else if(strcmp(instance->manufacture_name, "AN-Motors") == 0) { - hop = (instance->generic.cnt & 0xFF) << 24 | (instance->generic.cnt & 0xFF) << 16 | - (btn & 0xF) << 12 | 0x404; - } else if(strcmp(instance->manufacture_name, "HCS101") == 0) { - hop = instance->generic.cnt << 16 | (btn & 0xF) << 12 | 0x000; - } else { + if(strcmp(instance->manufacture_name, "Unknown") == 0) { + code_found_reverse = subghz_protocol_blocks_reverse_key( + instance->generic.data, instance->generic.data_count_bit); + hop = code_found_reverse & 0x00000000ffffffff; + } else if(strcmp(instance->manufacture_name, "AN-Motors") == 0) { + hop = (instance->generic.cnt & 0xFF) << 24 | (instance->generic.cnt & 0xFF) << 16 | + (btn & 0xF) << 12 | 0x404; + } else if(strcmp(instance->manufacture_name, "HCS101") == 0) { + hop = instance->generic.cnt << 16 | (btn & 0xF) << 12 | 0x000; + } else { for M_EACH(manufacture_code, *subghz_keystore_get_data(instance->keystore), SubGhzKeyArray_t) { res = strcmp(furi_string_get_cstr(manufacture_code->name), instance->manufacture_name); @@ -270,6 +286,7 @@ static bool subghz_protocol_keeloq_gen_data( break; } } + } } if(hop) { uint64_t yek = (uint64_t)fix << 32 | hop; @@ -339,6 +356,17 @@ static bool btn_temp_id_original = btn; } + if(instance->manufacture_name == 0x0) { + instance->manufacture_name = ""; + } + if(bft_prog_mode) { + instance->manufacture_name = "BFT"; + } + uint8_t klq_last_custom_btn = 0xA; + if(strcmp(instance->manufacture_name, "BFT") == 0) { + klq_last_custom_btn = 0xF; + } + // Set custom button if(btn_temp_id == 1) { switch(btn_temp_id_original) { @@ -357,6 +385,9 @@ static bool case 0x8: btn = 0x1; break; + case 0xF: + btn = 0x1; + break; default: break; @@ -374,11 +405,14 @@ static bool btn = 0x4; break; case 0x4: - btn = 0xA; + btn = klq_last_custom_btn; break; case 0x8: btn = 0x4; break; + case 0xF: + btn = 0x4; + break; default: break; @@ -401,6 +435,9 @@ static bool case 0x8: btn = 0x2; break; + case 0xF: + btn = 0x8; + break; default: break; @@ -409,10 +446,10 @@ static bool if(btn_temp_id == 4) { switch(btn_temp_id_original) { case 0x1: - btn = 0xA; + btn = klq_last_custom_btn; break; case 0x2: - btn = 0xA; + btn = klq_last_custom_btn; break; case 0xA: btn = 0x2; @@ -421,7 +458,10 @@ static bool btn = 0x2; break; case 0x8: - btn = 0xA; + btn = klq_last_custom_btn; + break; + case 0xF: + btn = 0x2; break; default: @@ -433,9 +473,10 @@ static bool btn = btn_temp_id_original; } - //gen new key + // Generate new key + if(subghz_protocol_keeloq_gen_data(instance, btn, true)) { - //ToDo if you need to add a callback to automatically update the data on the display + // OK } else { return false; } @@ -590,6 +631,8 @@ void* subghz_protocol_decoder_keeloq_alloc(SubGhzEnvironment* environment) { instance->keystore = subghz_environment_get_keystore(environment); instance->manufacture_from_file = furi_string_alloc(); + bft_prog_mode = false; + return instance; } @@ -706,7 +749,7 @@ void subghz_protocol_decoder_keeloq_feed(void* context, bool level, uint32_t dur /** * Validation of decrypt data. * @param instance Pointer to a SubGhzBlockGeneric instance - * @param decrypt Decrypd data + * @param decrypt Decrypted data * @param btn Button number, 4 bit * @param end_serial decrement the last 10 bits of the serial number * @return true On success @@ -1088,19 +1131,29 @@ static void subghz_protocol_keeloq_check_remote_controller( uint64_t key = subghz_protocol_blocks_reverse_key(instance->data, instance->data_count_bit); uint32_t key_fix = key >> 32; uint32_t key_hop = key & 0x00000000ffffffff; - // Check key AN-Motors - if((key_hop >> 24) == ((key_hop >> 16) & 0x00ff) && - (key_fix >> 28) == ((key_hop >> 12) & 0x0f) && (key_hop & 0xFFF) == 0x404) { - *manufacture_name = "AN-Motors"; - mfname = *manufacture_name; - instance->cnt = key_hop >> 16; - } else if((key_hop & 0xFFF) == (0x000) && (key_fix >> 28) == ((key_hop >> 12) & 0x0f)) { - *manufacture_name = "HCS101"; - mfname = *manufacture_name; - instance->cnt = key_hop >> 16; + + // If we are in BFT programming mode we will set previous remembered counter and skip mf keys check + if(!bft_prog_mode) { + // Check key AN-Motors + if((key_hop >> 24) == ((key_hop >> 16) & 0x00ff) && + (key_fix >> 28) == ((key_hop >> 12) & 0x0f) && (key_hop & 0xFFF) == 0x404) { + *manufacture_name = "AN-Motors"; + mfname = *manufacture_name; + instance->cnt = key_hop >> 16; + } else if((key_hop & 0xFFF) == (0x000) && (key_fix >> 28) == ((key_hop >> 12) & 0x0f)) { + *manufacture_name = "HCS101"; + mfname = *manufacture_name; + instance->cnt = key_hop >> 16; + } else { + subghz_protocol_keeloq_check_remote_controller_selector( + instance, key_fix, key_hop, keystore, manufacture_name); + } + temp_counter = instance->cnt; + } else { - subghz_protocol_keeloq_check_remote_controller_selector( - instance, key_fix, key_hop, keystore, manufacture_name); + *manufacture_name = "BFT"; + mfname = *manufacture_name; + instance->cnt = temp_counter; } instance->serial = key_fix & 0x0FFFFFFF; diff --git a/lib/subghz/protocols/nice_flor_s.c b/lib/subghz/protocols/nice_flor_s.c index f58c6084f..135bd4972 100644 --- a/lib/subghz/protocols/nice_flor_s.c +++ b/lib/subghz/protocols/nice_flor_s.c @@ -543,18 +543,36 @@ bool subghz_protocol_nice_flor_s_create_data( uint32_t serial, uint8_t btn, uint16_t cnt, - SubGhzRadioPreset* preset) { + SubGhzRadioPreset* preset, + bool nice_one) { furi_assert(context); SubGhzProtocolEncoderNiceFlorS* instance = context; instance->generic.serial = serial; instance->generic.cnt = cnt; - instance->generic.data_count_bit = 52; + if(nice_one) { + instance->generic.data_count_bit = NICE_ONE_COUNT_BIT; + } else { + instance->generic.data_count_bit = 52; + } uint64_t decrypt = ((uint64_t)instance->generic.serial << 16) | instance->generic.cnt; uint64_t enc_part = subghz_protocol_nice_flor_s_encrypt( decrypt, instance->nice_flor_s_rainbow_table_file_name); uint8_t byte = btn << 4 | (0xF ^ btn ^ 0x3); instance->generic.data = (uint64_t)byte << 44 | enc_part; + if(instance->generic.data_count_bit == NICE_ONE_COUNT_BIT) { + uint8_t add_data[10] = {0}; + for(size_t i = 0; i < 7; i++) { + add_data[i] = (instance->generic.data >> (48 - i * 8)) & 0xFF; + } + subghz_protocol_nice_one_get_data(add_data, 0, 0); + instance->generic.data_2 = 0; + for(size_t j = 7; j < 10; j++) { + instance->generic.data_2 <<= 8; + instance->generic.data_2 += add_data[j]; + } + } + bool res = subghz_block_generic_serialize(&instance->generic, flipper_format, preset); return res; diff --git a/lib/subghz/protocols/nice_flor_s.h b/lib/subghz/protocols/nice_flor_s.h index 52f0ca745..3b22db304 100644 --- a/lib/subghz/protocols/nice_flor_s.h +++ b/lib/subghz/protocols/nice_flor_s.h @@ -63,6 +63,7 @@ uint64_t subghz_protocol_nice_flor_s_encrypt(uint64_t data, const char* file_nam * @param btn Button number, 4 bit * @param cnt Counter value, 16 bit * @param preset Modulation, SubGhzRadioPreset + * @param nice_one Nice One if true, Nice Flor S if false * @return true On success */ bool subghz_protocol_nice_flor_s_create_data( @@ -71,7 +72,8 @@ bool subghz_protocol_nice_flor_s_create_data( uint32_t serial, uint8_t btn, uint16_t cnt, - SubGhzRadioPreset* preset); + SubGhzRadioPreset* preset, + bool nice_one); /** * Allocate SubGhzProtocolDecoderNiceFlorS. diff --git a/lib/subghz/protocols/secplus_v2.c b/lib/subghz/protocols/secplus_v2.c index 593be0494..9f8c31654 100644 --- a/lib/subghz/protocols/secplus_v2.c +++ b/lib/subghz/protocols/secplus_v2.c @@ -379,11 +379,8 @@ static void subghz_protocol_secplus_v2_encode(SubGhzProtocolEncoderSecPlus_v2* i uint8_t roll_1[9] = {0}; uint8_t roll_2[9] = {0}; - if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) >= 0xFFFF) { - instance->generic.cnt = 0; - } else { - instance->generic.cnt += furi_hal_subghz_get_rolling_counter_mult(); - } + instance->generic.cnt += furi_hal_subghz_get_rolling_counter_mult(); + //ToDo it is not known what value the counter starts if(instance->generic.cnt > 0xFFFFFFF) instance->generic.cnt = 0xE500000; uint32_t rolling = subghz_protocol_blocks_reverse_key(instance->generic.cnt, 28); diff --git a/lib/subghz/protocols/somfy_telis.c b/lib/subghz/protocols/somfy_telis.c index 143171a05..5d6b1c6f3 100644 --- a/lib/subghz/protocols/somfy_telis.c +++ b/lib/subghz/protocols/somfy_telis.c @@ -73,6 +73,25 @@ const SubGhzProtocol subghz_protocol_somfy_telis = { .encoder = &subghz_protocol_somfy_telis_encoder, }; +static uint8_t st_btn_temp_id; +static uint8_t st_btn_temp_id_original; + +void somfy_telis_set_btn(uint8_t b) { + st_btn_temp_id = b; +} + +uint8_t somfy_telis_get_original_btn() { + return st_btn_temp_id_original; +} + +uint8_t somfy_telis_get_custom_btn() { + return st_btn_temp_id; +} + +void somfy_telis_reset_original_btn() { + st_btn_temp_id_original = 0; +} + void* subghz_protocol_encoder_somfy_telis_alloc(SubGhzEnvironment* environment) { UNUSED(environment); SubGhzProtocolEncoderSomfyTelis* instance = malloc(sizeof(SubGhzProtocolEncoderSomfyTelis)); @@ -95,13 +114,86 @@ void subghz_protocol_encoder_somfy_telis_free(void* context) { free(instance); } -static bool - subghz_protocol_somfy_telis_gen_data(SubGhzProtocolEncoderSomfyTelis* instance, uint8_t btn) { - UNUSED(btn); +static bool subghz_protocol_somfy_telis_gen_data( + SubGhzProtocolEncoderSomfyTelis* instance, + uint8_t btn, + bool new_remote) { + // If we doing a clone we will use its data uint64_t data = instance->generic.data ^ (instance->generic.data >> 8); - instance->generic.btn = (data >> 44) & 0xF; // ctrl - instance->generic.cnt = (data >> 24) & 0xFFFF; // rolling code - instance->generic.serial = data & 0xFFFFFF; // address + if(!new_remote) { + instance->generic.btn = (data >> 44) & 0xF; // ctrl + btn = instance->generic.btn; + instance->generic.cnt = (data >> 24) & 0xFFFF; // rolling code + instance->generic.serial = data & 0xFFFFFF; // address + } + + // Save original button for later use + if(st_btn_temp_id_original == 0) { + st_btn_temp_id_original = btn; + } + + // Set custom button + if(st_btn_temp_id == 1) { + switch(st_btn_temp_id_original) { + case 0x1: + btn = 0x2; + break; + case 0x2: + btn = 0x1; + break; + case 0x4: + btn = 0x1; + break; + case 0x8: + btn = 0x1; + break; + + default: + break; + } + } + if(st_btn_temp_id == 2) { + switch(st_btn_temp_id_original) { + case 0x1: + btn = 0x4; + break; + case 0x2: + btn = 0x4; + break; + case 0x4: + btn = 0x2; + break; + case 0x8: + btn = 0x4; + break; + + default: + break; + } + } + if(st_btn_temp_id == 3) { + switch(st_btn_temp_id_original) { + case 0x1: + btn = 0x8; + break; + case 0x2: + btn = 0x8; + break; + case 0x4: + btn = 0x8; + break; + case 0x8: + btn = 0x2; + break; + + default: + break; + } + } + + if((st_btn_temp_id == 0) && (st_btn_temp_id_original != 0)) { + btn = st_btn_temp_id_original; + } if(instance->generic.cnt < 0xFFFF) { if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) >= 0xFFFF) { @@ -114,8 +206,12 @@ static bool } uint8_t frame[7]; - frame[0] = data >> 48; - frame[1] = instance->generic.btn << 4; + if(!new_remote) { + frame[0] = data >> 48; + } else { + frame[0] = 0xA7; + } + frame[1] = btn << 4; frame[2] = instance->generic.cnt >> 8; frame[3] = instance->generic.cnt; frame[4] = instance->generic.serial >> 16; @@ -154,7 +250,7 @@ bool subghz_protocol_somfy_telis_create_data( instance->generic.serial = serial; instance->generic.cnt = cnt; instance->generic.data_count_bit = 56; - bool res = subghz_protocol_somfy_telis_gen_data(instance, btn); + bool res = subghz_protocol_somfy_telis_gen_data(instance, btn, true); if(res) { res = subghz_block_generic_serialize(&instance->generic, flipper_format, preset); } @@ -172,7 +268,7 @@ static bool subghz_protocol_encoder_somfy_telis_get_upload( furi_assert(instance); //gen new key - if(subghz_protocol_somfy_telis_gen_data(instance, btn)) { + if(subghz_protocol_somfy_telis_gen_data(instance, btn, false)) { //ToDo if you need to add a callback to automatically update the data on the display } else { return false; @@ -583,6 +679,11 @@ static void subghz_protocol_somfy_telis_check_remote_controller(SubGhzBlockGener instance->btn = (data >> 44) & 0xF; // ctrl instance->cnt = (data >> 24) & 0xFFFF; // rolling code instance->serial = data & 0xFFFFFF; // address + + // Save original button for later use + if(st_btn_temp_id_original == 0) { + st_btn_temp_id_original = instance->btn; + } } /** diff --git a/lib/subghz/protocols/somfy_telis.h b/lib/subghz/protocols/somfy_telis.h index b5e989866..bca58b64b 100644 --- a/lib/subghz/protocols/somfy_telis.h +++ b/lib/subghz/protocols/somfy_telis.h @@ -11,6 +11,14 @@ extern const SubGhzProtocolDecoder subghz_protocol_somfy_telis_decoder; extern const SubGhzProtocolEncoder subghz_protocol_somfy_telis_encoder; extern const SubGhzProtocol subghz_protocol_somfy_telis; +// Custom buttons +void somfy_telis_set_btn(uint8_t b); + +uint8_t somfy_telis_get_original_btn(); +uint8_t somfy_telis_get_custom_btn(); + +void somfy_telis_reset_original_btn(); + /** * Allocate SubGhzProtocolEncoderSomfyTelis. * @param environment Pointer to a SubGhzEnvironment instance