This commit is contained in:
Willy-JL
2023-02-28 21:01:06 +00:00
parent fa8ed7f6e4
commit 2d9c6d5bb9
26 changed files with 479 additions and 140 deletions

View File

@@ -8,11 +8,14 @@ typedef enum {
//SubmenuIndex //SubmenuIndex
SubmenuIndexFaacSLH_433, SubmenuIndexFaacSLH_433,
SubmenuIndexFaacSLH_868, SubmenuIndexFaacSLH_868,
SubmenuIndexBFT, SubmenuIndexBFTClone,
SubmenuIndexBFTMitto,
SubmenuIndexSomfyTelis,
SubmenuIndexPricenton, SubmenuIndexPricenton,
SubmenuIndexNiceFlo12bit, SubmenuIndexNiceFlo12bit,
SubmenuIndexNiceFlo24bit, SubmenuIndexNiceFlo24bit,
SubmenuIndexNiceFlorS_433_92, SubmenuIndexNiceFlorS_433_92,
SubmenuIndexNiceOne_433_92,
SubmenuIndexNiceSmilo_433_92, SubmenuIndexNiceSmilo_433_92,
SubmenuIndexCAME12bit, SubmenuIndexCAME12bit,
SubmenuIndexCAME24bit, SubmenuIndexCAME24bit,

View File

@@ -17,9 +17,12 @@ const char* const debug_pin_text[DEBUG_P_COUNT] = {
"17(1W)", "17(1W)",
}; };
#define DEBUG_COUNTER_COUNT 3 #define DEBUG_COUNTER_COUNT 6
const char* const debug_counter_text[DEBUG_COUNTER_COUNT] = { const char* const debug_counter_text[DEBUG_COUNTER_COUNT] = {
"+1", "+1",
"+2",
"+3",
"+4",
"+5", "+5",
"+10", "+10",
}; };
@@ -55,9 +58,18 @@ static void subghz_scene_receiver_config_set_debug_counter(VariableItem* item) {
furi_hal_subghz_set_rolling_counter_mult(1); furi_hal_subghz_set_rolling_counter_mult(1);
break; break;
case 1: case 1:
furi_hal_subghz_set_rolling_counter_mult(5); furi_hal_subghz_set_rolling_counter_mult(2);
break; break;
case 2: 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); furi_hal_subghz_set_rolling_counter_mult(10);
break; break;
default: default:
@@ -101,12 +113,21 @@ void subghz_scene_ext_module_settings_on_enter(void* context) {
case 1: case 1:
value_index_cnt = 0; value_index_cnt = 0;
break; break;
case 5: case 2:
value_index_cnt = 1; value_index_cnt = 1;
break; break;
case 10: case 3:
value_index_cnt = 2; value_index_cnt = 2;
break; break;
case 4:
value_index_cnt = 3;
break;
case 5:
value_index_cnt = 4;
break;
case 10:
value_index_cnt = 5;
break;
default: default:
break; break;
} }

View File

@@ -4,6 +4,7 @@
#include <lib/subghz/protocols/star_line.h> #include <lib/subghz/protocols/star_line.h>
#include <lib/subghz/protocols/alutech_at_4n.h> #include <lib/subghz/protocols/alutech_at_4n.h>
#include <lib/subghz/protocols/nice_flor_s.h> #include <lib/subghz/protocols/nice_flor_s.h>
#include <lib/subghz/protocols/somfy_telis.h>
void subghz_scene_receiver_info_callback(GuiButtonType result, InputType type, void* context) { void subghz_scene_receiver_info_callback(GuiButtonType result, InputType type, void* context) {
furi_assert(context); furi_assert(context);
@@ -238,6 +239,7 @@ void subghz_scene_receiver_info_on_exit(void* context) {
keeloq_reset_original_btn(); keeloq_reset_original_btn();
alutech_reset_original_btn(); alutech_reset_original_btn();
nice_flors_reset_original_btn(); nice_flors_reset_original_btn();
somfy_telis_reset_original_btn();
star_line_reset_mfname(); star_line_reset_mfname();
star_line_reset_kl_type(); star_line_reset_kl_type();
} }

View File

@@ -3,6 +3,8 @@
#include <lib/subghz/protocols/star_line.h> #include <lib/subghz/protocols/star_line.h>
#include <lib/subghz/protocols/alutech_at_4n.h> #include <lib/subghz/protocols/alutech_at_4n.h>
#include <lib/subghz/protocols/nice_flor_s.h> #include <lib/subghz/protocols/nice_flor_s.h>
#include <lib/subghz/protocols/somfy_telis.h>
#include "xtreme/assets.h" #include "xtreme/assets.h"
typedef enum { typedef enum {
@@ -115,6 +117,7 @@ void subghz_scene_rpc_on_exit(void* context) {
keeloq_reset_original_btn(); keeloq_reset_original_btn();
alutech_reset_original_btn(); alutech_reset_original_btn();
nice_flors_reset_original_btn(); nice_flors_reset_original_btn();
somfy_telis_reset_original_btn();
star_line_reset_mfname(); star_line_reset_mfname();
star_line_reset_kl_type(); star_line_reset_kl_type();
} }

View File

@@ -79,10 +79,22 @@ void subghz_scene_set_type_on_enter(void* context) {
SubmenuIndexFaacSLH_433, SubmenuIndexFaacSLH_433,
subghz_scene_set_type_submenu_callback, subghz_scene_set_type_submenu_callback,
subghz); subghz);
submenu_add_item(
subghz->submenu,
"BFT [Manual] 433MHz",
SubmenuIndexBFTClone,
subghz_scene_set_type_submenu_callback,
subghz);
submenu_add_item( submenu_add_item(
subghz->submenu, subghz->submenu,
"BFT Mitto 433MHz", "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_scene_set_type_submenu_callback,
subghz); subghz);
submenu_add_item( submenu_add_item(
@@ -115,6 +127,12 @@ void subghz_scene_set_type_on_enter(void* context) {
SubmenuIndexNiceFlorS_433_92, SubmenuIndexNiceFlorS_433_92,
subghz_scene_set_type_submenu_callback, subghz_scene_set_type_submenu_callback,
subghz); subghz);
submenu_add_item(
subghz->submenu,
"Nice One 433MHz",
SubmenuIndexNiceOne_433_92,
subghz_scene_set_type_submenu_callback,
subghz);
submenu_add_item( submenu_add_item(
subghz->submenu, subghz->submenu,
"CAME 12bit 433MHz", "CAME 12bit 433MHz",
@@ -230,7 +248,7 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) {
case SubmenuIndexFaacSLH_433: case SubmenuIndexFaacSLH_433:
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSetFixFaac); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSetFixFaac);
break; break;
case SubmenuIndexBFT: case SubmenuIndexBFTClone:
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSetFixBft); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSetFixBft);
break; break;
case SubmenuIndexPricenton: case SubmenuIndexPricenton:
@@ -306,6 +324,66 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) {
generated_protocol = true; generated_protocol = true;
} }
break; 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: case SubmenuIndexDoorHan_433_92:
subghz->txrx->transmitter = subghz_transmitter_alloc_init( subghz->txrx->transmitter = subghz_transmitter_alloc_init(
subghz->txrx->environment, SUBGHZ_PROTOCOL_KEELOQ_NAME); subghz->txrx->environment, SUBGHZ_PROTOCOL_KEELOQ_NAME);
@@ -367,7 +445,33 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) {
key & 0x0FFFFFFF, key & 0x0FFFFFFF,
0x1, 0x1,
0x0003, 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; generated_protocol = true;
} else { } else {
generated_protocol = false; generated_protocol = false;

View File

@@ -5,6 +5,7 @@
#include <lib/subghz/protocols/alutech_at_4n.h> #include <lib/subghz/protocols/alutech_at_4n.h>
#include <lib/subghz/protocols/star_line.h> #include <lib/subghz/protocols/star_line.h>
#include <lib/subghz/protocols/nice_flor_s.h> #include <lib/subghz/protocols/nice_flor_s.h>
#include <lib/subghz/protocols/somfy_telis.h>
void subghz_scene_transmitter_callback(SubGhzCustomEvent event, void* context) { void subghz_scene_transmitter_callback(SubGhzCustomEvent event, void* context) {
furi_assert(context); furi_assert(context);
@@ -95,6 +96,7 @@ bool subghz_scene_transmitter_on_event(void* context, SceneManagerEvent event) {
keeloq_set_btn(0); keeloq_set_btn(0);
alutech_set_btn(0); alutech_set_btn(0);
nice_flors_set_btn(0); nice_flors_set_btn(0);
somfy_telis_set_btn(0);
uint8_t tmp_counter = furi_hal_subghz_get_rolling_counter_mult(); uint8_t tmp_counter = furi_hal_subghz_get_rolling_counter_mult();
furi_hal_subghz_set_rolling_counter_mult(0); furi_hal_subghz_set_rolling_counter_mult(0);
// Calling restore! // Calling restore!
@@ -138,6 +140,7 @@ void subghz_scene_transmitter_on_exit(void* context) {
keeloq_reset_original_btn(); keeloq_reset_original_btn();
alutech_reset_original_btn(); alutech_reset_original_btn();
nice_flors_reset_original_btn(); nice_flors_reset_original_btn();
somfy_telis_reset_original_btn();
star_line_reset_mfname(); star_line_reset_mfname();
star_line_reset_kl_type(); star_line_reset_kl_type();
} }

View File

@@ -7,6 +7,7 @@
#include <lib/subghz/protocols/keeloq.h> #include <lib/subghz/protocols/keeloq.h>
#include <lib/subghz/protocols/alutech_at_4n.h> #include <lib/subghz/protocols/alutech_at_4n.h>
#include <lib/subghz/protocols/nice_flor_s.h> #include <lib/subghz/protocols/nice_flor_s.h>
#include <lib/subghz/protocols/somfy_telis.h>
struct SubGhzViewTransmitter { struct SubGhzViewTransmitter {
View* view; View* view;
@@ -161,6 +162,7 @@ bool subghz_view_transmitter_input(InputEvent* event, void* context) {
keeloq_set_btn(1); keeloq_set_btn(1);
alutech_set_btn(1); alutech_set_btn(1);
nice_flors_set_btn(1); nice_flors_set_btn(1);
somfy_telis_set_btn(1);
with_view_model( with_view_model(
subghz_transmitter->view, subghz_transmitter->view,
SubGhzViewTransmitterModel * model, SubGhzViewTransmitterModel * model,
@@ -176,6 +178,10 @@ bool subghz_view_transmitter_input(InputEvent* event, void* context) {
furi_string_printf( furi_string_printf(
model->temp_button_id, "%01X", nice_flors_get_original_btn()); model->temp_button_id, "%01X", nice_flors_get_original_btn());
model->draw_temp_button = true; 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); true);
@@ -192,6 +198,7 @@ bool subghz_view_transmitter_input(InputEvent* event, void* context) {
keeloq_set_btn(2); keeloq_set_btn(2);
alutech_set_btn(2); alutech_set_btn(2);
nice_flors_set_btn(2); nice_flors_set_btn(2);
somfy_telis_set_btn(2);
with_view_model( with_view_model(
subghz_transmitter->view, subghz_transmitter->view,
SubGhzViewTransmitterModel * model, SubGhzViewTransmitterModel * model,
@@ -207,6 +214,10 @@ bool subghz_view_transmitter_input(InputEvent* event, void* context) {
furi_string_printf( furi_string_printf(
model->temp_button_id, "%01X", nice_flors_get_original_btn()); model->temp_button_id, "%01X", nice_flors_get_original_btn());
model->draw_temp_button = true; 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); true);
@@ -223,6 +234,7 @@ bool subghz_view_transmitter_input(InputEvent* event, void* context) {
keeloq_set_btn(3); keeloq_set_btn(3);
alutech_set_btn(3); alutech_set_btn(3);
nice_flors_set_btn(3); nice_flors_set_btn(3);
somfy_telis_set_btn(3);
with_view_model( with_view_model(
subghz_transmitter->view, subghz_transmitter->view,
SubGhzViewTransmitterModel * model, SubGhzViewTransmitterModel * model,
@@ -238,6 +250,10 @@ bool subghz_view_transmitter_input(InputEvent* event, void* context) {
furi_string_printf( furi_string_printf(
model->temp_button_id, "%01X", nice_flors_get_original_btn()); model->temp_button_id, "%01X", nice_flors_get_original_btn());
model->draw_temp_button = true; 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); true);

View File

@@ -21,6 +21,7 @@
#include <lib/subghz/protocols/star_line.h> #include <lib/subghz/protocols/star_line.h>
#include <lib/subghz/protocols/alutech_at_4n.h> #include <lib/subghz/protocols/alutech_at_4n.h>
#include <lib/subghz/protocols/nice_flor_s.h> #include <lib/subghz/protocols/nice_flor_s.h>
#include <lib/subghz/protocols/somfy_telis.h>
#define UNIRFMAP_FOLDER "/ext/subghz/unirf" #define UNIRFMAP_FOLDER "/ext/subghz/unirf"
#define UNIRFMAP_EXTENSION ".txt" #define UNIRFMAP_EXTENSION ".txt"
@@ -486,6 +487,7 @@ void unirfremix_tx_stop(UniRFRemix* app) {
keeloq_reset_original_btn(); keeloq_reset_original_btn();
alutech_reset_original_btn(); alutech_reset_original_btn();
nice_flors_reset_original_btn(); nice_flors_reset_original_btn();
somfy_telis_reset_original_btn();
star_line_reset_mfname(); star_line_reset_mfname();
star_line_reset_kl_type(); star_line_reset_kl_type();
} }

View File

@@ -1 +0,0 @@
## (5V -> VCC) / (GND -> GND) / (13|TX -> Trig) / (14|RX -> Echo)

View File

@@ -3,6 +3,7 @@
// Ported and modified by @xMasterX // Ported and modified by @xMasterX
#include <furi.h> #include <furi.h>
#include <furi_hal.h>
#include <furi_hal_power.h> #include <furi_hal_power.h>
#include <furi_hal_console.h> #include <furi_hal_console.h>
#include <gui/gui.h> #include <gui/gui.h>
@@ -26,7 +27,7 @@ typedef struct {
NotificationApp* notification; NotificationApp* notification;
bool have_5v; bool have_5v;
bool measurement_made; bool measurement_made;
uint32_t echo; // ms uint32_t echo; // us
float distance; // meters float distance; // meters
} PluginState; } PluginState;
@@ -72,7 +73,7 @@ static void render_callback(Canvas* const canvas, void* ctx) {
FuriString* str_buf; FuriString* str_buf;
str_buf = furi_string_alloc(); 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_draw_str_aligned(
canvas, 8, 38, AlignLeft, AlignTop, furi_string_get_cstr(str_buf)); 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) { float hc_sr04_us_to_m(uint32_t us) {
const float speed_sound_m_per_s = 343.0f; //speed of sound for 20°C, 50% relative humidity
const float time_s = ms / 1e3f; //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; const float total_dist = time_s * speed_sound_m_per_s;
return total_dist / 2.0f; return total_dist / 2.0f;
} }
@@ -147,10 +150,6 @@ static void hc_sr04_measure(PluginState* const plugin_state) {
furi_delay_ms(10); furi_delay_ms(10);
furi_hal_gpio_write(&gpio_usart_tx, false); 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(); const uint32_t start = furi_get_tick();
while(furi_get_tick() - start < timeout_ms && furi_hal_gpio_read(&gpio_usart_rx)) 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)) 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)) 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(); //FURI_CRITICAL_EXIT();
plugin_state->echo = pulse_end - pulse_start; plugin_state->echo =
plugin_state->distance = hc_sr04_ms_to_m(pulse_end - pulse_start); (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; plugin_state->measurement_made = true;
//furi_hal_light_set(LightRed, 0x00); //furi_hal_light_set(LightRed, 0x00);

View File

@@ -1,5 +1,7 @@
# Metronome # 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). 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) ![screenshot](img/screenshot.png)
@@ -17,5 +19,5 @@ A metronome for the [Flipper Zero](https://flipperzero.one/) device. Goes along
## Compiling ## Compiling
``` ```
./fbt fap_metronome ./fbt firmware_metronome
``` ```

View File

@@ -8,8 +8,8 @@ App(
"gui", "gui",
], ],
fap_icon="metronome_icon.png", fap_icon="metronome_icon.png",
fap_icon_assets="icons",
fap_category="Music", fap_category="Music",
fap_icon_assets="images",
stack_size=2 * 1024, stack_size=2 * 1024,
order=20, order=20,
) )

View File

@@ -1,6 +1,6 @@
#include <gui/canvas.h> #include <gui/canvas.h>
#include <gui/icon_i.h> #include <gui/icon_i.h>
#include "Metronome_icons.h" #include <Metronome_icons.h>
//lib can only do bottom left/right //lib can only do bottom left/right
void elements_button_top_left(Canvas* canvas, const char* str) { void elements_button_top_left(Canvas* canvas, const char* str) {

View File

Before

Width:  |  Height:  |  Size: 102 B

After

Width:  |  Height:  |  Size: 102 B

View File

@@ -287,7 +287,6 @@ int32_t metronome_app() {
metronome_state->timer = furi_timer_alloc(timer_callback, FuriTimerTypePeriodic, &state_mutex); metronome_state->timer = furi_timer_alloc(timer_callback, FuriTimerTypePeriodic, &state_mutex);
// Open GUI and register view_port // Open GUI and register view_port
//
Gui* gui = furi_record_open("gui"); Gui* gui = furi_record_open("gui");
gui_add_view_port(gui, view_port, GuiLayerFullscreen); gui_add_view_port(gui, view_port, GuiLayerFullscreen);
@@ -326,7 +325,7 @@ int32_t metronome_app() {
case InputKeyBack: case InputKeyBack:
processing = false; processing = false;
break; break;
case InputKeyMAX: default:
break; break;
} }
} else if(event.input.type == InputTypeLong) { } else if(event.input.type == InputTypeLong) {
@@ -348,7 +347,7 @@ int32_t metronome_app() {
case InputKeyBack: case InputKeyBack:
processing = false; processing = false;
break; break;
case InputKeyMAX: default:
break; break;
} }
} else if(event.input.type == InputTypeRepeat) { } else if(event.input.type == InputTypeRepeat) {
@@ -369,7 +368,7 @@ int32_t metronome_app() {
case InputKeyBack: case InputKeyBack:
processing = false; processing = false;
break; break;
case InputKeyMAX: default:
break; break;
} }
} }

View File

@@ -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) { 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); //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++) { 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)); memcpy(dk, &mj_ducky_keys[i], sizeof(MJDuckyKey));
return true; return true;
} }
@@ -165,26 +166,23 @@ static void release_key(
uint8_t* addr, uint8_t* addr,
uint8_t addr_size, uint8_t addr_size,
uint8_t rate, uint8_t rate,
PluginState* plugin_state PluginState* plugin_state) {
) {
// This function release keys currently pressed, but keep pressing special keys // This function release keys currently pressed, but keep pressing special keys
// if holding mod keys variable are set to true // if holding mod keys variable are set to true
uint8_t hid_payload[LOGITECH_HID_TEMPLATE_SIZE] = {0}; uint8_t hid_payload[LOGITECH_HID_TEMPLATE_SIZE] = {0};
build_hid_packet( build_hid_packet(
0 | holding_ctrl 0 | holding_ctrl | holding_shift << 1 | holding_alt << 2 | holding_gui << 3,
| holding_shift << 1 0,
| holding_alt << 2 hid_payload);
| holding_gui << 3,
0, hid_payload);
inject_packet( inject_packet(
handle, handle,
addr, addr,
addr_size, addr_size,
rate, rate,
hid_payload, hid_payload,
LOGITECH_HID_TEMPLATE_SIZE, LOGITECH_HID_TEMPLATE_SIZE,
plugin_state); // empty hid packet plugin_state); // empty hid packet
} }
static void send_hid_packet( static void send_hid_packet(
@@ -196,15 +194,13 @@ static void send_hid_packet(
uint8_t hid, uint8_t hid,
PluginState* plugin_state) { PluginState* plugin_state) {
uint8_t hid_payload[LOGITECH_HID_TEMPLATE_SIZE] = {0}; uint8_t hid_payload[LOGITECH_HID_TEMPLATE_SIZE] = {0};
if(hid == prev_hid ) if(hid == prev_hid) release_key(handle, addr, addr_size, rate, plugin_state);
release_key(handle, addr, addr_size, rate, plugin_state);
prev_hid = hid; prev_hid = hid;
build_hid_packet(mod build_hid_packet(
| holding_ctrl mod | holding_ctrl | holding_shift << 1 | holding_alt << 2 | holding_gui << 3,
| holding_shift << 1 hid,
| holding_alt << 2 hid_payload);
| holding_gui << 3, hid, hid_payload);
inject_packet( inject_packet(
handle, addr, addr_size, rate, hid_payload, LOGITECH_HID_TEMPLATE_SIZE, plugin_state); handle, addr, addr_size, rate, hid_payload, LOGITECH_HID_TEMPLATE_SIZE, plugin_state);
furi_delay_ms(12); furi_delay_ms(12);

View File

@@ -2543,6 +2543,10 @@ Function,-,siprintf,int,"char*, const char*, ..."
Function,-,siscanf,int,"const char*, const char*, ..." Function,-,siscanf,int,"const char*, const char*, ..."
Function,-,sniprintf,int,"char*, size_t, const char*, ..." Function,-,sniprintf,int,"char*, size_t, const char*, ..."
Function,+,snprintf,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,-,sprintf,int,"char*, const char*, ..."
Function,-,sqrt,double,double Function,-,sqrt,double,double
Function,-,sqrtf,float,float 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_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_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_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_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_file_encoder_worker_set_callback_end,void,"SubGhzProtocolEncoderRAW*, SubGhzProtocolEncoderRAWCallbackEnd, void*"
Function,+,subghz_protocol_raw_gen_fff_data,void,"FlipperFormat*, const char*" Function,+,subghz_protocol_raw_gen_fff_data,void,"FlipperFormat*, const char*"
1 entry status name type params
2543 Function - siscanf int const char*, const char*, ...
2544 Function - sniprintf int char*, size_t, const char*, ...
2545 Function + snprintf int char*, size_t, const char*, ...
2546 Function - somfy_telis_get_custom_btn uint8_t
2547 Function - somfy_telis_get_original_btn uint8_t
2548 Function - somfy_telis_reset_original_btn void
2549 Function - somfy_telis_set_btn void uint8_t
2550 Function - sprintf int char*, const char*, ...
2551 Function - sqrt double double
2552 Function - sqrtf float float
3277 Function - subghz_protocol_faac_slh_create_data _Bool void*, FlipperFormat*, uint32_t, uint8_t, uint32_t, uint32_t, const char*, SubGhzRadioPreset*
3278 Function - subghz_protocol_keeloq_bft_create_data _Bool void*, FlipperFormat*, uint32_t, uint8_t, uint16_t, uint32_t, const char*, SubGhzRadioPreset*
3279 Function - subghz_protocol_keeloq_create_data _Bool void*, FlipperFormat*, uint32_t, uint8_t, uint16_t, const char*, SubGhzRadioPreset*
3280 Function - subghz_protocol_nice_flor_s_create_data _Bool void*, FlipperFormat*, uint32_t, uint8_t, uint16_t, SubGhzRadioPreset* void*, FlipperFormat*, uint32_t, uint8_t, uint16_t, SubGhzRadioPreset*, _Bool
3281 Function - subghz_protocol_nice_flor_s_encrypt uint64_t uint64_t, const char*
3282 Function + subghz_protocol_raw_file_encoder_worker_set_callback_end void SubGhzProtocolEncoderRAW*, SubGhzProtocolEncoderRAWCallbackEnd, void*
3283 Function + subghz_protocol_raw_gen_fff_data void FlipperFormat*, const char*

View File

@@ -78,6 +78,16 @@ bool subghz_block_generic_serialize(
FURI_LOG_E(TAG, "Unable to add Key"); FURI_LOG_E(TAG, "Unable to add Key");
break; 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; res = true;
} while(false); } while(false);
furi_string_free(temp_str); furi_string_free(temp_str);

View File

@@ -110,11 +110,7 @@ void subghz_protocol_encoder_faac_slh_free(void* context) {
} }
static bool subghz_protocol_faac_slh_gen_data(SubGhzProtocolEncoderFaacSLH* instance) { 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 += furi_hal_subghz_get_rolling_counter_mult();
instance->generic.cnt = 0;
} else {
instance->generic.cnt += furi_hal_subghz_get_rolling_counter_mult();
}
uint32_t fix = instance->generic.serial << 4 | instance->generic.btn; uint32_t fix = instance->generic.serial << 4 | instance->generic.btn;
uint32_t hop = 0; uint32_t hop = 0;
uint32_t decrypt = 0; uint32_t decrypt = 0;

View File

@@ -88,6 +88,8 @@ static const char* mfname;
static uint8_t kl_type; static uint8_t kl_type;
static uint8_t btn_temp_id; static uint8_t btn_temp_id;
static uint8_t btn_temp_id_original; static uint8_t btn_temp_id_original;
static bool bft_prog_mode;
static uint16_t temp_counter;
void keeloq_set_btn(uint8_t b) { void keeloq_set_btn(uint8_t b) {
btn_temp_id = b; btn_temp_id = b;
@@ -103,6 +105,8 @@ uint8_t keeloq_get_custom_btn() {
void keeloq_reset_original_btn() { void keeloq_reset_original_btn() {
btn_temp_id_original = 0; btn_temp_id_original = 0;
temp_counter = 0;
bft_prog_mode = false;
} }
void keeloq_reset_mfname() { void keeloq_reset_mfname() {
@@ -158,7 +162,27 @@ static bool subghz_protocol_keeloq_gen_data(
SubGhzProtocolEncoderKeeloq* instance, SubGhzProtocolEncoderKeeloq* instance,
uint8_t btn, uint8_t btn,
bool counter_up) { 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 < 0xFFFF) {
if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) >= 0xFFFF) { if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) >= 0xFFFF) {
instance->generic.cnt = 0; instance->generic.cnt = 0;
@@ -169,49 +193,41 @@ static bool subghz_protocol_keeloq_gen_data(
instance->generic.cnt = 0; instance->generic.cnt = 0;
} }
} }
uint32_t fix = (uint32_t)btn << 28 | instance->generic.serial; if(!bft_prog_mode) {
uint32_t decrypt = (uint32_t)btn << 28 | uint32_t decrypt = (uint32_t)btn << 28 |
(instance->generic.serial & 0x3FF) (instance->generic.serial & 0x3FF)
<< 16 | //ToDo in some protocols the discriminator is 0 << 16 | //ToDo in some protocols the discriminator is 0
instance->generic.cnt; instance->generic.cnt;
uint32_t hop = 0; // DTM Neo uses 12bit -> simple learning -- FAAC_RC,XT , Mutanco_Mutancode -> 12bit normal learning
uint64_t man = 0; if((strcmp(instance->manufacture_name, "DTM_Neo") == 0) ||
uint64_t code_found_reverse; (strcmp(instance->manufacture_name, "FAAC_RC,XT") == 0) ||
int res = 0; (strcmp(instance->manufacture_name, "Mutanco_Mutancode") == 0)) {
if(instance->manufacture_name == 0x0) { decrypt = btn << 28 | (instance->generic.serial & 0xFFF) << 16 | instance->generic.cnt;
instance->manufacture_name = ""; }
}
// DTM Neo uses 12bit -> simple learning -- FAAC_RC,XT , Mutanco_Mutancode -> 12bit normal learning // Nice Smilo, MHouse, JCM, Normstahl -> 8bit serial - simple learning
if((strcmp(instance->manufacture_name, "DTM_Neo") == 0) || if((strcmp(instance->manufacture_name, "NICE_Smilo") == 0) ||
(strcmp(instance->manufacture_name, "FAAC_RC,XT") == 0) || (strcmp(instance->manufacture_name, "NICE_MHOUSE") == 0) ||
(strcmp(instance->manufacture_name, "Mutanco_Mutancode") == 0)) { (strcmp(instance->manufacture_name, "JCM_Tech") == 0) ||
decrypt = btn << 28 | (instance->generic.serial & 0xFFF) << 16 | instance->generic.cnt; (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 // Beninca -> 4bit serial - simple XOR
if((strcmp(instance->manufacture_name, "NICE_Smilo") == 0) || if(strcmp(instance->manufacture_name, "Beninca") == 0) {
(strcmp(instance->manufacture_name, "NICE_MHOUSE") == 0) || decrypt = btn << 28 | (instance->generic.serial & 0xF) << 16 | instance->generic.cnt;
(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, "Unknown") == 0) {
if(strcmp(instance->manufacture_name, "Beninca") == 0) { code_found_reverse = subghz_protocol_blocks_reverse_key(
decrypt = btn << 28 | (instance->generic.serial & 0xF) << 16 | instance->generic.cnt; instance->generic.data, instance->generic.data_count_bit);
} hop = code_found_reverse & 0x00000000ffffffff;
} else if(strcmp(instance->manufacture_name, "AN-Motors") == 0) {
if(strcmp(instance->manufacture_name, "Unknown") == 0) { hop = (instance->generic.cnt & 0xFF) << 24 | (instance->generic.cnt & 0xFF) << 16 |
code_found_reverse = subghz_protocol_blocks_reverse_key( (btn & 0xF) << 12 | 0x404;
instance->generic.data, instance->generic.data_count_bit); } else if(strcmp(instance->manufacture_name, "HCS101") == 0) {
hop = code_found_reverse & 0x00000000ffffffff; hop = instance->generic.cnt << 16 | (btn & 0xF) << 12 | 0x000;
} else if(strcmp(instance->manufacture_name, "AN-Motors") == 0) { } else {
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 for
M_EACH(manufacture_code, *subghz_keystore_get_data(instance->keystore), SubGhzKeyArray_t) { M_EACH(manufacture_code, *subghz_keystore_get_data(instance->keystore), SubGhzKeyArray_t) {
res = strcmp(furi_string_get_cstr(manufacture_code->name), instance->manufacture_name); res = strcmp(furi_string_get_cstr(manufacture_code->name), instance->manufacture_name);
@@ -270,6 +286,7 @@ static bool subghz_protocol_keeloq_gen_data(
break; break;
} }
} }
}
} }
if(hop) { if(hop) {
uint64_t yek = (uint64_t)fix << 32 | hop; uint64_t yek = (uint64_t)fix << 32 | hop;
@@ -339,6 +356,17 @@ static bool
btn_temp_id_original = btn; 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 // Set custom button
if(btn_temp_id == 1) { if(btn_temp_id == 1) {
switch(btn_temp_id_original) { switch(btn_temp_id_original) {
@@ -357,6 +385,9 @@ static bool
case 0x8: case 0x8:
btn = 0x1; btn = 0x1;
break; break;
case 0xF:
btn = 0x1;
break;
default: default:
break; break;
@@ -374,11 +405,14 @@ static bool
btn = 0x4; btn = 0x4;
break; break;
case 0x4: case 0x4:
btn = 0xA; btn = klq_last_custom_btn;
break; break;
case 0x8: case 0x8:
btn = 0x4; btn = 0x4;
break; break;
case 0xF:
btn = 0x4;
break;
default: default:
break; break;
@@ -401,6 +435,9 @@ static bool
case 0x8: case 0x8:
btn = 0x2; btn = 0x2;
break; break;
case 0xF:
btn = 0x8;
break;
default: default:
break; break;
@@ -409,10 +446,10 @@ static bool
if(btn_temp_id == 4) { if(btn_temp_id == 4) {
switch(btn_temp_id_original) { switch(btn_temp_id_original) {
case 0x1: case 0x1:
btn = 0xA; btn = klq_last_custom_btn;
break; break;
case 0x2: case 0x2:
btn = 0xA; btn = klq_last_custom_btn;
break; break;
case 0xA: case 0xA:
btn = 0x2; btn = 0x2;
@@ -421,7 +458,10 @@ static bool
btn = 0x2; btn = 0x2;
break; break;
case 0x8: case 0x8:
btn = 0xA; btn = klq_last_custom_btn;
break;
case 0xF:
btn = 0x2;
break; break;
default: default:
@@ -433,9 +473,10 @@ static bool
btn = btn_temp_id_original; btn = btn_temp_id_original;
} }
//gen new key // Generate new key
if(subghz_protocol_keeloq_gen_data(instance, btn, true)) { 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 { } else {
return false; return false;
} }
@@ -590,6 +631,8 @@ void* subghz_protocol_decoder_keeloq_alloc(SubGhzEnvironment* environment) {
instance->keystore = subghz_environment_get_keystore(environment); instance->keystore = subghz_environment_get_keystore(environment);
instance->manufacture_from_file = furi_string_alloc(); instance->manufacture_from_file = furi_string_alloc();
bft_prog_mode = false;
return instance; return instance;
} }
@@ -706,7 +749,7 @@ void subghz_protocol_decoder_keeloq_feed(void* context, bool level, uint32_t dur
/** /**
* Validation of decrypt data. * Validation of decrypt data.
* @param instance Pointer to a SubGhzBlockGeneric instance * @param instance Pointer to a SubGhzBlockGeneric instance
* @param decrypt Decrypd data * @param decrypt Decrypted data
* @param btn Button number, 4 bit * @param btn Button number, 4 bit
* @param end_serial decrement the last 10 bits of the serial number * @param end_serial decrement the last 10 bits of the serial number
* @return true On success * @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); uint64_t key = subghz_protocol_blocks_reverse_key(instance->data, instance->data_count_bit);
uint32_t key_fix = key >> 32; uint32_t key_fix = key >> 32;
uint32_t key_hop = key & 0x00000000ffffffff; uint32_t key_hop = key & 0x00000000ffffffff;
// Check key AN-Motors
if((key_hop >> 24) == ((key_hop >> 16) & 0x00ff) && // If we are in BFT programming mode we will set previous remembered counter and skip mf keys check
(key_fix >> 28) == ((key_hop >> 12) & 0x0f) && (key_hop & 0xFFF) == 0x404) { if(!bft_prog_mode) {
*manufacture_name = "AN-Motors"; // Check key AN-Motors
mfname = *manufacture_name; if((key_hop >> 24) == ((key_hop >> 16) & 0x00ff) &&
instance->cnt = key_hop >> 16; (key_fix >> 28) == ((key_hop >> 12) & 0x0f) && (key_hop & 0xFFF) == 0x404) {
} else if((key_hop & 0xFFF) == (0x000) && (key_fix >> 28) == ((key_hop >> 12) & 0x0f)) { *manufacture_name = "AN-Motors";
*manufacture_name = "HCS101"; mfname = *manufacture_name;
mfname = *manufacture_name; instance->cnt = key_hop >> 16;
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 { } else {
subghz_protocol_keeloq_check_remote_controller_selector( *manufacture_name = "BFT";
instance, key_fix, key_hop, keystore, manufacture_name); mfname = *manufacture_name;
instance->cnt = temp_counter;
} }
instance->serial = key_fix & 0x0FFFFFFF; instance->serial = key_fix & 0x0FFFFFFF;

View File

@@ -543,18 +543,36 @@ bool subghz_protocol_nice_flor_s_create_data(
uint32_t serial, uint32_t serial,
uint8_t btn, uint8_t btn,
uint16_t cnt, uint16_t cnt,
SubGhzRadioPreset* preset) { SubGhzRadioPreset* preset,
bool nice_one) {
furi_assert(context); furi_assert(context);
SubGhzProtocolEncoderNiceFlorS* instance = context; SubGhzProtocolEncoderNiceFlorS* instance = context;
instance->generic.serial = serial; instance->generic.serial = serial;
instance->generic.cnt = cnt; 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 decrypt = ((uint64_t)instance->generic.serial << 16) | instance->generic.cnt;
uint64_t enc_part = subghz_protocol_nice_flor_s_encrypt( uint64_t enc_part = subghz_protocol_nice_flor_s_encrypt(
decrypt, instance->nice_flor_s_rainbow_table_file_name); decrypt, instance->nice_flor_s_rainbow_table_file_name);
uint8_t byte = btn << 4 | (0xF ^ btn ^ 0x3); uint8_t byte = btn << 4 | (0xF ^ btn ^ 0x3);
instance->generic.data = (uint64_t)byte << 44 | enc_part; 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); bool res = subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
return res; return res;

View File

@@ -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 btn Button number, 4 bit
* @param cnt Counter value, 16 bit * @param cnt Counter value, 16 bit
* @param preset Modulation, SubGhzRadioPreset * @param preset Modulation, SubGhzRadioPreset
* @param nice_one Nice One if true, Nice Flor S if false
* @return true On success * @return true On success
*/ */
bool subghz_protocol_nice_flor_s_create_data( bool subghz_protocol_nice_flor_s_create_data(
@@ -71,7 +72,8 @@ bool subghz_protocol_nice_flor_s_create_data(
uint32_t serial, uint32_t serial,
uint8_t btn, uint8_t btn,
uint16_t cnt, uint16_t cnt,
SubGhzRadioPreset* preset); SubGhzRadioPreset* preset,
bool nice_one);
/** /**
* Allocate SubGhzProtocolDecoderNiceFlorS. * Allocate SubGhzProtocolDecoderNiceFlorS.

View File

@@ -379,11 +379,8 @@ static void subghz_protocol_secplus_v2_encode(SubGhzProtocolEncoderSecPlus_v2* i
uint8_t roll_1[9] = {0}; uint8_t roll_1[9] = {0};
uint8_t roll_2[9] = {0}; uint8_t roll_2[9] = {0};
if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) >= 0xFFFF) { instance->generic.cnt += furi_hal_subghz_get_rolling_counter_mult();
instance->generic.cnt = 0;
} else {
instance->generic.cnt += furi_hal_subghz_get_rolling_counter_mult();
}
//ToDo it is not known what value the counter starts //ToDo it is not known what value the counter starts
if(instance->generic.cnt > 0xFFFFFFF) instance->generic.cnt = 0xE500000; if(instance->generic.cnt > 0xFFFFFFF) instance->generic.cnt = 0xE500000;
uint32_t rolling = subghz_protocol_blocks_reverse_key(instance->generic.cnt, 28); uint32_t rolling = subghz_protocol_blocks_reverse_key(instance->generic.cnt, 28);

View File

@@ -73,6 +73,25 @@ const SubGhzProtocol subghz_protocol_somfy_telis = {
.encoder = &subghz_protocol_somfy_telis_encoder, .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) { void* subghz_protocol_encoder_somfy_telis_alloc(SubGhzEnvironment* environment) {
UNUSED(environment); UNUSED(environment);
SubGhzProtocolEncoderSomfyTelis* instance = malloc(sizeof(SubGhzProtocolEncoderSomfyTelis)); SubGhzProtocolEncoderSomfyTelis* instance = malloc(sizeof(SubGhzProtocolEncoderSomfyTelis));
@@ -95,13 +114,86 @@ void subghz_protocol_encoder_somfy_telis_free(void* context) {
free(instance); free(instance);
} }
static bool static bool subghz_protocol_somfy_telis_gen_data(
subghz_protocol_somfy_telis_gen_data(SubGhzProtocolEncoderSomfyTelis* instance, uint8_t btn) { SubGhzProtocolEncoderSomfyTelis* instance,
UNUSED(btn); 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); uint64_t data = instance->generic.data ^ (instance->generic.data >> 8);
instance->generic.btn = (data >> 44) & 0xF; // ctrl if(!new_remote) {
instance->generic.cnt = (data >> 24) & 0xFFFF; // rolling code instance->generic.btn = (data >> 44) & 0xF; // ctrl
instance->generic.serial = data & 0xFFFFFF; // address 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 < 0xFFFF) {
if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) >= 0xFFFF) { if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) >= 0xFFFF) {
@@ -114,8 +206,12 @@ static bool
} }
uint8_t frame[7]; uint8_t frame[7];
frame[0] = data >> 48; if(!new_remote) {
frame[1] = instance->generic.btn << 4; frame[0] = data >> 48;
} else {
frame[0] = 0xA7;
}
frame[1] = btn << 4;
frame[2] = instance->generic.cnt >> 8; frame[2] = instance->generic.cnt >> 8;
frame[3] = instance->generic.cnt; frame[3] = instance->generic.cnt;
frame[4] = instance->generic.serial >> 16; frame[4] = instance->generic.serial >> 16;
@@ -154,7 +250,7 @@ bool subghz_protocol_somfy_telis_create_data(
instance->generic.serial = serial; instance->generic.serial = serial;
instance->generic.cnt = cnt; instance->generic.cnt = cnt;
instance->generic.data_count_bit = 56; 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) { if(res) {
res = subghz_block_generic_serialize(&instance->generic, flipper_format, preset); 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); furi_assert(instance);
//gen new key //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 //ToDo if you need to add a callback to automatically update the data on the display
} else { } else {
return false; return false;
@@ -583,6 +679,11 @@ static void subghz_protocol_somfy_telis_check_remote_controller(SubGhzBlockGener
instance->btn = (data >> 44) & 0xF; // ctrl instance->btn = (data >> 44) & 0xF; // ctrl
instance->cnt = (data >> 24) & 0xFFFF; // rolling code instance->cnt = (data >> 24) & 0xFFFF; // rolling code
instance->serial = data & 0xFFFFFF; // address 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;
}
} }
/** /**

View File

@@ -11,6 +11,14 @@ extern const SubGhzProtocolDecoder subghz_protocol_somfy_telis_decoder;
extern const SubGhzProtocolEncoder subghz_protocol_somfy_telis_encoder; extern const SubGhzProtocolEncoder subghz_protocol_somfy_telis_encoder;
extern const SubGhzProtocol subghz_protocol_somfy_telis; 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. * Allocate SubGhzProtocolEncoderSomfyTelis.
* @param environment Pointer to a SubGhzEnvironment instance * @param environment Pointer to a SubGhzEnvironment instance