Merge commit '97eaee54c8f12c0103487c7c5c8df6ba0b538e12' into mntm-dev

This commit is contained in:
WillyJL
2026-02-28 20:11:35 +01:00
68 changed files with 1118 additions and 388 deletions
+4
View File
@@ -13,6 +13,9 @@
- UL: Sommer last button code 0x6 support (mapped on arrow keys) (by @xMasterX)
- UL: V2 Phoenix (Phox) added 2 counter modes support (docs updated) (by @xMasterX)
- UL: Add 390MHz and 430.5MHz to default hopper list (6 elements like in OFW) (works well with Hopper RSSI level set for your enviroment) (by @xMasterX)
- UL: Add signals button editor and real remote simulation (full signal transmit with just one click) (by @Dmitry422)
- UL: KeeLoq add counter mode 7 (sends 7 signals increasing counter with 0x3333 steps) - may bypass counter on some receivers! (by @xMasterX)
- UL: JS: Add IR capabilities to the JS engine (by @LuisMayo)
- UL: Docs: Add [full list of supported SubGHz protocols](https://github.com/Next-Flip/Momentum-Firmware/blob/dev/documentation/SubGHzSupportedSystems.md) and their frequencies/modulations that can be used for reading remotes (by @xMasterX)
### Updated:
@@ -47,6 +50,7 @@
- UL: Various fixes and cleanup (by @xMasterX)
- UL: Nice Flor S remove extra uint64 variable (by @xMasterX)
- UL: Fix Alutech AT4N false positives (by @xMasterX)
- UL: Fix documentation link for HT12A protocol (by @carlogrisetti)
- NFC:
- Fix sending 32+ byte ISO 15693-3 commands (by @WillyJL)
- Fixes to `READ_MULTI` and `GET_BLOCK_SECURITY` commands in ISO 15693-3 emulation (#501 by @WillyJL & aaronjamt)
@@ -249,7 +249,6 @@ SubGhzTxRxStartTxState subghz_txrx_tx_start(SubGhzTxRx* instance, FlipperFormat*
SubGhzTxRxStartTxState ret = SubGhzTxRxStartTxStateErrorParserOthers;
FuriString* temp_str = furi_string_alloc();
uint32_t repeat = 200;
do {
if(!flipper_format_rewind(flipper_format)) {
FURI_LOG_E(TAG, "Rewind error");
@@ -259,10 +258,6 @@ SubGhzTxRxStartTxState subghz_txrx_tx_start(SubGhzTxRx* instance, FlipperFormat*
FURI_LOG_E(TAG, "Missing Protocol");
break;
}
if(!flipper_format_insert_or_update_uint32(flipper_format, "Repeat", &repeat, 1)) {
FURI_LOG_E(TAG, "Unable Repeat");
break;
}
ret = SubGhzTxRxStartTxStateOk;
SubGhzRadioPreset* preset = instance->preset;
@@ -2,6 +2,9 @@
#include <lib/subghz/blocks/custom_btn.h>
#include "applications/main/subghz/helpers/subghz_txrx_i.h"
#include <lib/subghz/blocks/generic.h>
#define TAG "SubGhzSceneReceiverInfo"
void subghz_scene_receiver_info_callback(GuiButtonType result, InputType type, void* context) {
@@ -147,25 +150,22 @@ bool subghz_scene_receiver_info_on_event(void* context, SceneManagerEvent event)
subghz_txrx_hopper_unpause(subghz->txrx);
subghz->state_notifications = SubGhzNotificationStateRx;
} else {
// key concept: we start endless TX until user release OK button, and after this we send last
// protocols repeats - this guarantee that one press OK will
// be guarantee send the required minimum protocol data packets
// for all of this we use subghz_block_generic_global.endless_tx in protocols _yield function.
subghz->state_notifications = SubGhzNotificationStateTx;
subghz_block_generic_global.endless_tx = true;
}
return true;
} else if(event.event == SubGhzCustomEventSceneReceiverInfoTxStop) {
//CC1101 Stop Tx -> Start RX
//CC1101 Stop Tx -> next tick event Start RX
// user release OK
// we switch off endless_tx - that mean protocols yield finish endless transmission,
// send upload "repeat=xx" times, and after will be stoped by the tick event down in this code
subghz->state_notifications = SubGhzNotificationStateIDLE;
subghz_block_generic_global.endless_tx = false;
widget_reset(subghz->widget);
subghz_scene_receiver_info_draw_widget(subghz);
subghz_txrx_stop(subghz->txrx);
if(!scene_manager_has_previous_scene(subghz->scene_manager, SubGhzSceneDecodeRAW)) {
subghz_txrx_rx_start(subghz->txrx);
subghz_txrx_hopper_unpause(subghz->txrx);
if(!subghz_history_full(subghz->history)) {
subghz->state_notifications = SubGhzNotificationStateRx;
}
}
return true;
} else if(event.event == SubGhzCustomEventSceneReceiverInfoSave) {
//CC1101 Stop RX -> Save
@@ -218,6 +218,25 @@ bool subghz_scene_receiver_info_on_event(void* context, SceneManagerEvent event)
notification_message(subghz->notifications, &sequence_blink_green_100);
subghz->state_notifications = SubGhzNotificationStateRx;
break;
case SubGhzNotificationStateIDLE:
// we wait until hardware TX finished and after stop TX and start RX, else just blink led
if(!subghz_devices_is_async_complete_tx(subghz->txrx->radio_device)) {
notification_message(subghz->notifications, &sequence_blink_magenta_10);
} else {
subghz_txrx_stop(subghz->txrx);
// update screen
widget_reset(subghz->widget);
subghz_scene_receiver_info_draw_widget(subghz);
if(!scene_manager_has_previous_scene(subghz->scene_manager, SubGhzSceneDecodeRAW)) {
subghz_txrx_rx_start(subghz->txrx);
subghz_txrx_hopper_unpause(subghz->txrx);
if(!subghz_history_full(subghz->history)) {
subghz->state_notifications = SubGhzNotificationStateRx;
}
}
}
break;
default:
break;
}
@@ -11,11 +11,18 @@
static uint32_t counter_mode = 0xff;
static uint32_t counter32 = 0x0;
static uint16_t counter16 = 0x0;
static uint8_t byte_count = 0;
static uint8_t* byte_ptr = NULL;
static uint8_t cnt_byte_count = 0;
static uint8_t* cnt_byte_ptr = NULL;
static FuriString* byte_input_text;
#define COUNTER_MODE_COUNT 7
static uint8_t button = 0x0;
static uint8_t btn_byte_count = 1;
static uint8_t* btn_byte_ptr = NULL;
static uint8_t submenu_called = 0;
#define COUNTER_MODE_COUNT 8
static const char* const counter_mode_text[COUNTER_MODE_COUNT] = {
"System",
"Mode 1",
@@ -24,6 +31,7 @@ static const char* const counter_mode_text[COUNTER_MODE_COUNT] = {
"Mode 4",
"Mode 5",
"Mode 6",
"Mode 7",
};
static const int32_t counter_mode_value[COUNTER_MODE_COUNT] = {
@@ -34,6 +42,7 @@ static const int32_t counter_mode_value[COUNTER_MODE_COUNT] = {
4,
5,
6,
7,
};
typedef struct {
@@ -46,7 +55,7 @@ static Protocols protocols[] = {
{"Nice FloR-S", 3},
{"CAME Atomo", 4},
{"Alutech AT-4N", 3},
{"KeeLoq", 7},
{"KeeLoq", 8},
{"Phoenix_V2", 3},
};
@@ -68,6 +77,7 @@ void subghz_scene_signal_settings_variable_item_list_enter_callback(void* contex
// when we click OK on "Edit counter" item
if(index == 1) {
submenu_called = 1;
furi_string_cat_printf(byte_input_text, "%i", subghz_block_generic_global.cnt_length_bit);
furi_string_cat_str(byte_input_text, "-bits counter in HEX");
@@ -80,8 +90,27 @@ void subghz_scene_signal_settings_variable_item_list_enter_callback(void* contex
subghz_scene_signal_settings_byte_input_callback,
NULL,
subghz,
byte_ptr,
byte_count);
cnt_byte_ptr,
cnt_byte_count);
view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdByteInput);
}
// when we click OK on "Edit button" item
if(index == 2) {
submenu_called = 2;
furi_string_cat_printf(byte_input_text, "%i", subghz_block_generic_global.btn_length_bit);
furi_string_cat_str(byte_input_text, "-bits button in HEX");
// Setup byte_input view
ByteInput* byte_input = subghz->byte_input;
byte_input_set_header_text(byte_input, furi_string_get_cstr(byte_input_text));
byte_input_set_result_callback(
byte_input,
subghz_scene_signal_settings_byte_input_callback,
NULL,
subghz,
btn_byte_ptr,
btn_byte_count);
view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdByteInput);
}
}
@@ -131,44 +160,9 @@ void subghz_scene_signal_settings_on_enter(void* context) {
flipper_format_free(fff_data_file);
furi_record_close(RECORD_STORAGE);
// ### Counter edit section ###
byte_input_text = furi_string_alloc_set_str("Enter ");
bool counter_not_available = true;
SubGhzProtocolDecoderBase* decoder = subghz_txrx_get_decoder(subghz->txrx);
// deserialaze and decode loaded sugbhz file and push data to subghz_block_generic_global variable
if(subghz_protocol_decoder_base_deserialize(decoder, subghz_txrx_get_fff_data(subghz->txrx)) ==
SubGhzProtocolStatusOk) {
subghz_protocol_decoder_base_get_string(decoder, tmp_text);
} else {
FURI_LOG_E(TAG, "Cant deserialize this subghz file");
}
if(!subghz_block_generic_global.cnt_is_available) {
counter_mode = 0xff;
FURI_LOG_D(TAG, "Counter mode and edit not available for this protocol");
} else {
counter_not_available = false;
// Check is there byte_count more than 2 hex bytes long or not
// To show hex value we must correct revert bytes for ByteInput view with __bswapХХ
if(subghz_block_generic_global.cnt_length_bit > 16) {
counter32 = subghz_block_generic_global.current_cnt;
furi_string_printf(tmp_text, "%lX", counter32);
counter32 = __bswap32(counter32);
byte_ptr = (uint8_t*)&counter32;
byte_count = 4;
} else {
counter16 = subghz_block_generic_global.current_cnt;
furi_string_printf(tmp_text, "%X", counter16);
counter16 = __bswap16(counter16);
byte_ptr = (uint8_t*)&counter16;
byte_count = 2;
}
}
furi_assert(byte_ptr);
furi_assert(byte_count > 0);
bool button_not_available = true;
//Create and Enable/Disable variable_item_list depending on current values
VariableItemList* variable_item_list = subghz->variable_item_list;
@@ -187,15 +181,72 @@ void subghz_scene_signal_settings_on_enter(void* context) {
subghz_scene_signal_settings_counter_mode_changed,
subghz);
value_index = value_index_int32(counter_mode, counter_mode_value, mode_count);
variable_item_set_current_value_index(item, value_index);
variable_item_set_current_value_text(item, counter_mode_text[value_index]);
variable_item_set_locked(item, (counter_mode == 0xff), "Not available\nfor this\nprotocol !");
//
SubGhzProtocolDecoderBase* decoder = subghz_txrx_get_decoder(subghz->txrx);
// deserialaze and decode loaded sugbhz file and push data to subghz_block_generic_global variable
if(subghz_protocol_decoder_base_deserialize(decoder, subghz_txrx_get_fff_data(subghz->txrx)) ==
SubGhzProtocolStatusOk) {
subghz_protocol_decoder_base_get_string(decoder, tmp_text);
} else {
FURI_LOG_E(TAG, "Cant deserialize this subghz file");
}
// ### Counter edit section ###
if(!subghz_block_generic_global.cnt_is_available) {
counter_mode = 0xff;
FURI_LOG_D(TAG, "Counter mode and edit not available for this protocol");
} else {
counter_not_available = false;
// Check is there byte_count more than 2 hex bytes long or not
// To show hex value we must correct revert bytes for ByteInput view with __bswapХХ
if(subghz_block_generic_global.cnt_length_bit > 16) {
counter32 = subghz_block_generic_global.current_cnt;
furi_string_printf(tmp_text, "%lX", counter32);
counter32 = __bswap32(counter32);
cnt_byte_ptr = (uint8_t*)&counter32;
cnt_byte_count = 4;
} else {
counter16 = subghz_block_generic_global.current_cnt;
furi_string_printf(tmp_text, "%X", counter16);
counter16 = __bswap16(counter16);
cnt_byte_ptr = (uint8_t*)&counter16;
cnt_byte_count = 2;
}
}
item = variable_item_list_add(variable_item_list, "Edit Counter", 1, NULL, subghz);
variable_item_set_current_value_index(item, 0);
variable_item_set_current_value_text(item, furi_string_get_cstr(tmp_text));
variable_item_set_locked(item, (counter_not_available), "Not available\nfor this\nprotocol !");
//
// ### Button edit section ###
if(!subghz_block_generic_global.btn_is_available) {
FURI_LOG_D(TAG, "Button edit not available for this protocol");
} else {
button_not_available = false;
button = subghz_block_generic_global.current_btn;
furi_string_printf(tmp_text, "%X", button);
btn_byte_ptr = (uint8_t*)&button;
}
item = variable_item_list_add(variable_item_list, "Edit Button", 1, NULL, subghz);
variable_item_set_current_value_index(item, 0);
variable_item_set_current_value_text(item, furi_string_get_cstr(tmp_text));
variable_item_set_locked(item, (button_not_available), "Not available\nfor this\nprotocol !");
//
furi_assert(cnt_byte_ptr);
furi_assert(cnt_byte_count > 0);
furi_assert(btn_byte_ptr);
furi_string_free(tmp_text);
@@ -207,21 +258,40 @@ bool subghz_scene_signal_settings_on_event(void* context, SceneManagerEvent even
if(event.type == SceneManagerEventTypeCustom) {
if(event.event == SubGhzCustomEventByteInputDone) {
switch(byte_count) {
switch(submenu_called) {
// edit counter
case 1:
switch(cnt_byte_count) {
case 2:
// set new cnt value and override_flag to global variable and call transmit to generate and save subghz signal
counter16 = __bswap16(counter16);
subghz_block_generic_global_counter_override_set(counter16);
subghz_tx_start(subghz, subghz_txrx_get_fff_data(subghz->txrx));
subghz_txrx_stop(subghz->txrx);
break;
case 4:
// the same for 32 bit Counter
counter32 = __bswap32(counter32);
subghz_block_generic_global_counter_override_set(counter32);
subghz_tx_start(subghz, subghz_txrx_get_fff_data(subghz->txrx));
subghz_txrx_stop(subghz->txrx);
break;
default:
break;
}
break;
// edit button
case 2:
// set new cnt value and override_flag to global variable and call transmit to generate and save subghz signal
counter16 = __bswap16(counter16);
subghz_block_generic_global_counter_override_set(counter16);
subghz_tx_start(subghz, subghz_txrx_get_fff_data(subghz->txrx));
subghz_txrx_stop(subghz->txrx);
break;
case 4:
// the same for 32 bit Counter
counter32 = __bswap32(counter32);
subghz_block_generic_global_counter_override_set(counter32);
subghz_block_generic_global_button_override_set(button);
// save counter mult to rewrite subghz singnal without changing counter
int32_t tmp_counter = furi_hal_subghz_get_rolling_counter_mult();
furi_hal_subghz_set_rolling_counter_mult(0);
subghz_tx_start(subghz, subghz_txrx_get_fff_data(subghz->txrx));
subghz_txrx_stop(subghz->txrx);
// restore counter mult
furi_hal_subghz_set_rolling_counter_mult(tmp_counter);
break;
default:
break;
}
@@ -5,6 +5,10 @@
#include <lib/subghz/blocks/custom_btn.h>
#include <lib/subghz/devices/devices.c>
#include "applications/main/subghz/helpers/subghz_txrx_i.h"
#include "lib/subghz/blocks/generic.h"
#define TAG "SubGhzSceneTransmitter"
void subghz_scene_transmitter_callback(SubGhzCustomEvent event, void* context) {
@@ -80,11 +84,16 @@ void subghz_scene_transmitter_on_enter(void* context) {
}
bool subghz_scene_transmitter_on_event(void* context, SceneManagerEvent event) {
// key concept: we start endless TX until user release OK button, and after this we send last
// protocols repeats - this guarantee that one press OK will
// be guarantee send the required minimum protocol data packets
// for all of this we use subghz_block_generic_global.endless_tx in protocols _yield function.
SubGhz* subghz = context;
if(event.type == SceneManagerEventTypeCustom) {
if(event.event == SubGhzCustomEventViewTransmitterSendStart) {
// user press OK - start endless TX
subghz->state_notifications = SubGhzNotificationStateIDLE;
subghz_block_generic_global.endless_tx = true;
if(subghz_tx_start(subghz, subghz_txrx_get_fff_data(subghz->txrx))) {
subghz->state_notifications = SubGhzNotificationStateTx;
subghz_scene_transmitter_update_data_show(subghz);
@@ -92,29 +101,12 @@ bool subghz_scene_transmitter_on_event(void* context, SceneManagerEvent event) {
}
return true;
} else if(event.event == SubGhzCustomEventViewTransmitterSendStop) {
subghz->state_notifications = SubGhzNotificationStateIDLE;
subghz_txrx_stop(subghz->txrx);
if(subghz_custom_btn_get() != SUBGHZ_CUSTOM_BTN_OK) {
subghz_custom_btn_set(SUBGHZ_CUSTOM_BTN_OK);
int32_t tmp_counter = furi_hal_subghz_get_rolling_counter_mult();
furi_hal_subghz_set_rolling_counter_mult(0);
// Calling restore!
subghz_tx_start(subghz, subghz_txrx_get_fff_data(subghz->txrx));
subghz_txrx_stop(subghz->txrx);
// Calling restore 2nd time special for FAAC SLH!
// TODO: Find better way to restore after custom button is used!!!
subghz_tx_start(subghz, subghz_txrx_get_fff_data(subghz->txrx));
subghz_txrx_stop(subghz->txrx);
furi_hal_subghz_set_rolling_counter_mult(tmp_counter);
}
if(subghz->fav_timeout) {
while(scene_manager_handle_back_event(subghz->scene_manager))
;
view_dispatcher_stop(subghz->view_dispatcher);
}
// user release OK
// we switch off endless_tx - that mean protocols yield finish endless transmission,
// send upload "repeat=xx" times, and after will be stoped by tick event down this code.
subghz_block_generic_global.endless_tx = false;
return true;
} else if(event.event == SubGhzCustomEventViewTransmitterBack) {
subghz->state_notifications = SubGhzNotificationStateIDLE;
scene_manager_search_and_switch_to_previous_scene(
subghz->scene_manager, SubGhzSceneStart);
return true;
@@ -124,7 +116,33 @@ bool subghz_scene_transmitter_on_event(void* context, SceneManagerEvent event) {
}
} else if(event.type == SceneManagerEventTypeTick) {
if(subghz->state_notifications == SubGhzNotificationStateTx) {
notification_message(subghz->notifications, &sequence_blink_magenta_10);
// if hardware TX still working at this time so we just blink led and return
if(!subghz_devices_is_async_complete_tx(subghz->txrx->radio_device)) {
notification_message(subghz->notifications, &sequence_blink_magenta_10);
return true;
// if hardware TX was stoped so we stop TX correctly
} else {
subghz->state_notifications = SubGhzNotificationStateIDLE;
subghz_txrx_stop(subghz->txrx);
if(subghz_custom_btn_get() != SUBGHZ_CUSTOM_BTN_OK) {
subghz_custom_btn_set(SUBGHZ_CUSTOM_BTN_OK);
int32_t tmp_counter = furi_hal_subghz_get_rolling_counter_mult();
furi_hal_subghz_set_rolling_counter_mult(0);
// Calling restore!
subghz_tx_start(subghz, subghz_txrx_get_fff_data(subghz->txrx));
subghz_txrx_stop(subghz->txrx);
// Calling restore 2nd time special for FAAC SLH!
// TODO: Find better way to restore after custom button is used!!!
subghz_tx_start(subghz, subghz_txrx_get_fff_data(subghz->txrx));
subghz_txrx_stop(subghz->txrx);
furi_hal_subghz_set_rolling_counter_mult(tmp_counter);
}
if(subghz->fav_timeout) {
while(scene_manager_handle_back_event(subghz->scene_manager))
;
view_dispatcher_stop(subghz->view_dispatcher);
}
}
}
return true;
}
@@ -253,6 +253,14 @@ App(
sources=["modules/js_subghz/*.c"],
)
App(
appid="js_infrared",
apptype=FlipperAppType.PLUGIN,
entry_point="js_infrared_ep",
requires=["js_app"],
sources=["modules/js_infrared/*.c"],
)
App(
appid="js_blebeacon",
apptype=FlipperAppType.PLUGIN,
@@ -0,0 +1,47 @@
checkSdkFeatures(["infrared-send"]);
let infrared = require("infrared");
print("Sending Samsung32 signal (lowers volume)...");
infrared.sendSignal("Samsung32", 0x00000007, 0x0000000b);
delay(1000);
print("Sending raw signal... (Fujitsu AC)");
infrared.sendRawSignal(
[
3298, 1571, 442, 368, 442, 367, 443, 1180, 442, 370, 440, 1181, 442, 368,
442, 367, 442, 368, 442, 1180, 443, 1180, 442, 368, 441, 367, 442, 369, 441,
1180, 442, 1180, 443, 368, 442, 369, 441, 368, 442, 368, 442, 368, 442, 368,
441, 368, 441, 368, 442, 368, 442, 368, 442, 367, 442, 368, 442, 366, 444,
1181, 442, 368, 441, 367, 442, 368, 442, 367, 442, 369, 441, 367, 443, 367,
442, 1180, 442, 368, 442, 368, 442, 368, 441, 368, 441, 1180, 442, 1180,
442, 1181, 442, 1181, 441, 1181, 442, 1181, 442, 1181, 442, 1181, 442, 369,
441, 368, 441, 1182, 442, 367, 443, 367, 443, 367, 442, 368, 442, 1181, 441,
369, 441, 369, 441, 369, 441, 1180, 442, 1181, 441, 369, 442, 368, 442, 367,
442, 368, 441, 1181, 441, 1183, 440, 368, 442, 368, 441, 369, 441, 1181,
442, 368, 442, 367, 443, 1181, 442, 368, 442, 369, 441, 368, 441, 369, 440,
368, 442, 367, 443, 367, 442, 367, 442, 367, 442, 368, 442, 369, 441, 369,
441, 368, 442, 369, 441, 368, 441, 367, 443, 368, 442, 367, 442, 369, 441,
369, 441, 368, 441, 367, 442, 367, 442, 368, 442, 368, 441, 368, 442, 368,
442, 368, 441, 367, 442, 367, 442, 368, 442, 368, 441, 368, 442, 369, 441,
368, 441, 367, 442, 368, 441, 368, 442, 368, 442, 368, 442, 368, 442, 367,
442, 1181, 442, 367, 442, 368, 441, 1181, 442, 1182, 441, 1181, 442, 1181,
442, 1181, 441, 368, 442, 368, 442, 369, 441,
],
true,
{ frequency: 38000, dutyCycle: 0.33 },
);
delay(1000);
print(
"Sending raw signal... (Fujitsu AC) with default frequency and duty cycle",
);
infrared.sendRawSignal([
3300, 1596, 416, 362, 448, 363, 446, 1177, 445, 363, 446, 1177, 445, 362, 448,
362, 448, 364, 446, 1178, 444, 1207, 415, 362, 448, 362, 448, 363, 447, 1177,
445, 1177, 446, 362, 448, 362, 447, 362, 447, 362, 448, 363, 447, 362, 447,
363, 447, 363, 447, 363, 446, 363, 446, 362, 447, 362, 447, 363, 446, 1177,
445, 363, 447, 364, 446, 362, 448, 363, 447, 363, 446, 362, 447, 362, 448,
1175, 447, 363, 447, 364, 446, 362, 448, 362, 448, 1176, 446, 362, 448, 362,
448, 363, 446, 362, 448, 362, 448, 363, 447, 1175, 446, 394, 415, 1176, 446,
1178, 444, 1174, 449, 1177, 445, 1180, 443, 1179, 443,
]);
print("Success");
+1
View File
@@ -277,6 +277,7 @@ static const char* extra_features[] = {
"blebeacon",
"i2c",
"spi",
"infrared-send",
"subghz",
"usbdisk",
"vgm",
@@ -0,0 +1,129 @@
#include "../../js_modules.h"
#include <infrared_worker.h>
#include <lib/infrared/signal/infrared_signal.h>
#include <lib/infrared/worker/infrared_transmit.h>
#define TAG "JsMath"
static void ret_bad_args(struct mjs* mjs, const char* error) {
mjs_prepend_errorf(mjs, MJS_BAD_ARGS_ERROR, "%s", error);
mjs_return(mjs, MJS_UNDEFINED);
}
void js_send_protocol_signal(struct mjs* mjs) {
size_t num_args = mjs_nargs(mjs);
if(num_args < 3 || num_args > 4) {
ret_bad_args(mjs, "Wrong argument count");
return;
}
if(!mjs_is_string(mjs_arg(mjs, 0)) || !mjs_is_number(mjs_arg(mjs, 1)) ||
!mjs_is_number(mjs_arg(mjs, 2)) || (num_args == 4 && !mjs_is_object(mjs_arg(mjs, 3)))) {
ret_bad_args(mjs, "Wrong argument type");
return;
}
bool repeat = false;
int times = 1;
if(num_args == 4) {
mjs_val_t options_obj = mjs_arg(mjs, 3);
mjs_val_t repeat_val = mjs_get(mjs, options_obj, "repeat", ~0);
if(mjs_is_boolean(repeat_val)) {
repeat = mjs_get_bool(mjs, repeat_val);
} else if(!mjs_is_undefined(repeat_val)) {
ret_bad_args(mjs, "Wrong 'repeat' option type");
return;
}
mjs_val_t times_val = mjs_get(mjs, options_obj, "times", ~0);
if(mjs_is_number(times_val)) {
times = mjs_get_int(mjs, times_val);
} else if(!mjs_is_undefined(times_val)) {
ret_bad_args(mjs, "Wrong 'times' option type");
return;
}
}
InfraredMessage message;
message.repeat = repeat;
mjs_val_t protocol_arg = mjs_arg(mjs, 0);
message.protocol = infrared_get_protocol_by_name(mjs_get_cstring(mjs, &protocol_arg));
message.address = mjs_get_int(mjs, mjs_arg(mjs, 1));
message.command = mjs_get_int(mjs, mjs_arg(mjs, 2));
infrared_send(&message, times);
}
void js_send_raw_signal(struct mjs* mjs) {
size_t num_args = mjs_nargs(mjs);
if(num_args < 1 || num_args > 3) {
ret_bad_args(mjs, "Wrong argument count");
return;
}
if(!mjs_is_array(mjs_arg(mjs, 0)) || (num_args > 1 && !mjs_is_boolean(mjs_arg(mjs, 1))) ||
(num_args > 2 && !mjs_is_object(mjs_arg(mjs, 2)))) {
ret_bad_args(mjs, "Wrong argument type");
return;
}
int array_length = mjs_array_length(mjs, mjs_arg(mjs, 0));
uint32_t timings[array_length];
for(int i = 0; i < array_length; i++) {
mjs_val_t elem = mjs_array_get(mjs, mjs_arg(mjs, 0), i);
if(!mjs_is_number(elem)) {
ret_bad_args(mjs, "Timings array must contain only numbers");
return;
}
timings[i] = mjs_get_int(mjs, elem);
}
bool start_from_mark = true;
if(num_args > 1) {
start_from_mark = mjs_get_bool(mjs, mjs_arg(mjs, 1));
}
if(num_args > 2) {
mjs_val_t options_obj = mjs_arg(mjs, 2);
mjs_val_t frequency_val = mjs_get(mjs, options_obj, "frequency", ~0);
if(!mjs_is_number(frequency_val)) {
ret_bad_args(mjs, "Wrong 'frequency' option type");
return;
}
mjs_val_t duty_val = mjs_get(mjs, options_obj, "dutyCycle", ~0);
if(!mjs_is_number(duty_val)) {
ret_bad_args(mjs, "Wrong 'dutyCycle' option type");
return;
}
uint32_t frequency = mjs_get_int(mjs, frequency_val);
float duty_cycle = mjs_get_double(mjs, duty_val);
infrared_send_raw_ext(timings, array_length, start_from_mark, frequency, duty_cycle);
} else {
infrared_send_raw(timings, array_length, start_from_mark);
}
return;
}
static void* js_infrared_create(struct mjs* mjs, mjs_val_t* object, JsModules* modules) {
UNUSED(modules);
mjs_val_t infrared_object = mjs_mk_object(mjs);
mjs_set(mjs, infrared_object, "sendSignal", ~0, MJS_MK_FN(js_send_protocol_signal));
mjs_set(mjs, infrared_object, "sendRawSignal", ~0, MJS_MK_FN(js_send_raw_signal));
*object = infrared_object;
return (void*)1;
}
static const JsModuleDescriptor js_infrared_desc = {
"infrared",
js_infrared_create,
NULL,
NULL,
};
static const FlipperAppPluginDescriptor plugin_descriptor = {
.appid = PLUGIN_APP_ID,
.ep_api_version = PLUGIN_API_VERSION,
.entry_point = &js_infrared_desc,
};
const FlipperAppPluginDescriptor* js_infrared_ep(void) {
return &plugin_descriptor;
}
@@ -0,0 +1,41 @@
/**
* Module for using Infrared blaster/receptor
* @version Available with JS feature `infrared-send`
* @module
*/
/**
* Sends an IR signal using a known protocol by Flipper Firmware
* @param address Note that the address expects a number. If you're reading from Flipper's IR files, the address is usually in little-endian hex format. Javascript numbers are defined as big endian by default.
* @param command Note that the command expects a number. If you're reading from Flipper's IR files, the command is usually in little-endian hex format. Javascript numbers are defined as big endian by default.
* @param options Repeat marks the signal as a repeat signal, times indicates how many times to send the signal
*/
export declare function sendSignal(
protocol:
| "NEC"
| "NECext"
| "NEC42"
| "NEC42ext"
| "Samsung32"
| "RC6"
| "RC5"
| "RC5X"
| "SIRC"
| "SIRC15"
| "SIRC20"
| "Kaseikyo"
| "RCA",
address: number,
command: number,
options?: { repeat?: boolean; times?: number },
): void;
/**
* Sends a signal from an unknown protocol
* @param startFromMark defaults to true
*/
export declare function sendRawSignal(
timings: number[],
startFromMark?: boolean,
advancedSettings?: { frequency: number; dutyCycle: number },
): void;
+6
View File
@@ -129,6 +129,12 @@ CounterMode: 1
**Mode 6:**
- Counter freeze - do not increment
**Mode 7:**
- Incremental mode: `+0x3333` 5 times to current counter and return original value back adding +1 - 2 times - 7 signals in pack total
- Might work with Doorhan, seen in some "universal remotes"
- One click of Send button on flipper may bypass receiver counter, wait for full transmission
---
### 5. V2 Phoenix (Phox)
+22 -1
View File
@@ -17,7 +17,7 @@ void subghz_block_generic_global_counter_override_set(uint32_t counter) {
bool subghz_block_generic_global_counter_override_get(uint32_t* counter) {
// if override flag was enabled then return succes TRUE and return overrided counter, else return success = FALSE
// we cut counter bit length to available protocol bits length by the logical AND function
// we cut counter bits length to available protocol bits length by the logical AND function
if(subghz_block_generic_global.cnt_need_override) {
*counter = subghz_block_generic_global.new_cnt &
((0xFFFFFFFF >> (32 - subghz_block_generic_global.cnt_length_bit)));
@@ -28,9 +28,30 @@ bool subghz_block_generic_global_counter_override_get(uint32_t* counter) {
}
}
void subghz_block_generic_global_button_override_set(uint8_t button) {
subghz_block_generic_global.new_btn = button; // set global variable
subghz_block_generic_global.btn_need_override = true; // set flag for protocols
}
bool subghz_block_generic_global_button_override_get(uint8_t* button) {
// if override flag was enabled then return succes TRUE and return overrided button, else return success = FALSE
// we cut button bits length to available protocol bits length by the logical AND function
if(subghz_block_generic_global.btn_need_override) {
*button = subghz_block_generic_global.new_btn &
((0xFF >> (8 - subghz_block_generic_global.btn_length_bit)));
subghz_block_generic_global.btn_need_override = false;
return true;
} else {
return false;
}
}
void subghz_block_generic_global_reset(void* p) {
UNUSED(p);
// dont reset endless_tx, its used in protocols yield function to undless TX
bool tmp = subghz_block_generic_global.endless_tx;
memset(&subghz_block_generic_global, 0, sizeof(subghz_block_generic_global));
subghz_block_generic_global.endless_tx = tmp;
}
void subghz_block_generic_get_preset_name(const char* preset_name, FuriString* preset_str) {
+26 -5
View File
@@ -30,28 +30,49 @@ struct SubGhzBlockGeneric {
typedef struct SubGhzBlockGenericGlobal SubGhzBlockGenericGlobal;
struct SubGhzBlockGenericGlobal {
uint32_t current_cnt; // global counter value;
uint32_t new_cnt; // global counter value;
uint32_t current_cnt; // current counter value;
uint32_t new_cnt; // new counter value;
bool cnt_need_override; // flag for protocols to override signals counter inside of protocols
uint8_t cnt_length_bit; // counter length in bytes (used in counter editor giu)
uint8_t cnt_length_bit; // counter length in bits (used in counter editor giu)
bool cnt_is_available; // is there counter available for protocol (used in counter editor giu)
uint8_t current_btn; // current button value;
uint8_t new_btn; // new button value;
bool btn_need_override; // flag for protocols to override button inside of protocols
uint8_t btn_length_bit; // button length in bits (used in counter editor giu)
bool btn_is_available; // is there button available for protocol (used in button editor giu)
bool endless_tx; // used for endless/breakless transmission in subghz protols yield function (when user hold OK button)
};
extern SubGhzBlockGenericGlobal subghz_block_generic_global; //global structure for subghz
/**
* Setup SubGhzBlockGenericGlobal.cnt and cnt_need_override flag to be used in protocols;
* Setup new_cnt and cnt_need_override flag to be used in protocols;
* @param counter new counter value;
*/
void subghz_block_generic_global_counter_override_set(uint32_t counter);
/**
* Return true if incomming variable was overrided by SubGhzBlockGenericGlobal.cnt
* Return true if incomming variable was overrided by new_cnt
* else return false and not change incomming variable
* @param counter pointer to counter variable that must be changed
*/
bool subghz_block_generic_global_counter_override_get(uint32_t* counter);
/**
* Setup new_btn and btn_need_override flag to be used in protocols;
* @param button new button value;
*/
void subghz_block_generic_global_button_override_set(uint8_t button);
/**
* Return true if incomming variable was overrided by new_btn
* else return false and not change incomming variable
* @param button pointer to counter variable that must be changed
*/
bool subghz_block_generic_global_button_override_get(uint8_t* button);
/**
* Reset subghz_block_generic global structure;
*/
+10 -2
View File
@@ -96,7 +96,7 @@ void* subghz_protocol_encoder_alutech_at_4n_alloc(SubGhzEnvironment* environment
instance->base.protocol = &subghz_protocol_alutech_at_4n;
instance->generic.protocol_name = instance->base.protocol->name;
instance->encoder.repeat = 10;
instance->encoder.repeat = 3;
instance->encoder.size_upload = 512;
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
instance->encoder.is_running = false;
@@ -134,7 +134,7 @@ LevelDuration subghz_protocol_encoder_alutech_at_4n_yield(void* context) {
LevelDuration ret = instance->encoder.upload[instance->encoder.front];
if(++instance->encoder.front == instance->encoder.size_upload) {
instance->encoder.repeat--;
if(!subghz_block_generic_global.endless_tx) instance->encoder.repeat--;
instance->encoder.front = 0;
}
@@ -402,6 +402,10 @@ static bool subghz_protocol_encoder_alutech_at_4n_get_upload(
btn = subghz_protocol_alutech_at_4n_get_btn_code();
// override button if we change it with signal settings button editor
if(subghz_block_generic_global_button_override_get(&btn))
FURI_LOG_D(TAG, "Button sucessfully changed to 0x%X", btn);
// Gen new key
if(!subghz_protocol_alutech_at_4n_gen_data(instance, btn)) {
return false;
@@ -897,6 +901,10 @@ void subghz_protocol_decoder_alutech_at_4n_get_string(void* context, FuriString*
subghz_block_generic_global.cnt_is_available = true;
subghz_block_generic_global.cnt_length_bit = 16;
subghz_block_generic_global.current_cnt = instance->generic.cnt;
subghz_block_generic_global.btn_is_available = true;
subghz_block_generic_global.current_btn = instance->generic.btn;
subghz_block_generic_global.btn_length_bit = 8;
//
furi_string_cat_printf(
+9 -2
View File
@@ -84,7 +84,7 @@ void* subghz_protocol_encoder_ansonic_alloc(SubGhzEnvironment* environment) {
instance->base.protocol = &subghz_protocol_ansonic;
instance->generic.protocol_name = instance->base.protocol->name;
instance->encoder.repeat = 10;
instance->encoder.repeat = 3;
instance->encoder.size_upload = 52;
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
instance->encoder.is_running = false;
@@ -182,7 +182,7 @@ LevelDuration subghz_protocol_encoder_ansonic_yield(void* context) {
LevelDuration ret = instance->encoder.upload[instance->encoder.front];
if(++instance->encoder.front == instance->encoder.size_upload) {
instance->encoder.repeat--;
if(!subghz_block_generic_global.endless_tx) instance->encoder.repeat--;
instance->encoder.front = 0;
}
@@ -325,6 +325,13 @@ void subghz_protocol_decoder_ansonic_get_string(void* context, FuriString* outpu
furi_assert(context);
SubGhzProtocolDecoderAnsonic* instance = context;
subghz_protocol_ansonic_check_remote_controller(&instance->generic);
// push protocol data to global variable
subghz_block_generic_global.btn_is_available = false;
subghz_block_generic_global.current_btn = instance->generic.btn;
subghz_block_generic_global.btn_length_bit = 2;
//
furi_string_cat_printf(
output,
"%s %dbit\r\n"
+11 -2
View File
@@ -258,7 +258,7 @@ void* subghz_protocol_encoder_beninca_arc_alloc(SubGhzEnvironment* environment)
instance->generic.protocol_name = instance->base.protocol->name;
instance->keystore = subghz_environment_get_keystore(environment);
instance->encoder.repeat = 10;
instance->encoder.repeat = 1;
instance->encoder.size_upload = 800;
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
instance->encoder.is_running = false;
@@ -352,6 +352,10 @@ static void subghz_protocol_beninca_arc_encoder_prepare_packets(
// Generate new key using custom or default button
instance->generic.btn = subghz_protocol_beninca_arc_get_btn_code();
// override button if we change it with signal settings button editor
if(subghz_block_generic_global_button_override_get(&instance->generic.btn))
FURI_LOG_D(TAG, "Button sucessfully changed to 0x%X", instance->generic.btn);
// Make 3 packets with different mini counter values - 2, 4, 6
for(uint8_t i = 0; i < 3; i++) {
subghz_protocol_beninca_arc_encrypt(
@@ -479,7 +483,7 @@ LevelDuration subghz_protocol_encoder_beninca_arc_yield(void* context) {
LevelDuration ret = instance->encoder.upload[instance->encoder.front];
if(++instance->encoder.front == instance->encoder.size_upload) {
instance->encoder.repeat--;
if(!subghz_block_generic_global.endless_tx) instance->encoder.repeat--;
instance->encoder.front = 0;
}
@@ -661,6 +665,11 @@ void subghz_protocol_decoder_beninca_arc_get_string(void* context, FuriString* o
subghz_block_generic_global.cnt_length_bit = 32;
subghz_block_generic_global.current_cnt = instance->generic.cnt;
subghz_block_generic_global.btn_is_available = true;
subghz_block_generic_global.current_btn = instance->generic.btn;
subghz_block_generic_global.btn_length_bit = 8;
//
furi_string_printf(
output,
"%s %db\r\n"
+2 -2
View File
@@ -93,7 +93,7 @@ void* subghz_protocol_encoder_bett_alloc(SubGhzEnvironment* environment) {
instance->base.protocol = &subghz_protocol_bett;
instance->generic.protocol_name = instance->base.protocol->name;
instance->encoder.repeat = 10;
instance->encoder.repeat = 3;
instance->encoder.size_upload = 52;
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
instance->encoder.is_running = false;
@@ -201,7 +201,7 @@ LevelDuration subghz_protocol_encoder_bett_yield(void* context) {
LevelDuration ret = instance->encoder.upload[instance->encoder.front];
if(++instance->encoder.front == instance->encoder.size_upload) {
instance->encoder.repeat--;
if(!subghz_block_generic_global.endless_tx) instance->encoder.repeat--;
instance->encoder.front = 0;
}
+2 -2
View File
@@ -144,7 +144,7 @@ void* subghz_protocol_encoder_bin_raw_alloc(SubGhzEnvironment* environment) {
instance->base.protocol = &subghz_protocol_bin_raw;
instance->generic.protocol_name = instance->base.protocol->name;
instance->encoder.repeat = 10;
instance->encoder.repeat = 3;
instance->encoder.size_upload = BIN_RAW_BUF_DATA_SIZE * 5;
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
instance->data = malloc(instance->encoder.size_upload * sizeof(uint8_t));
@@ -344,7 +344,7 @@ LevelDuration subghz_protocol_encoder_bin_raw_yield(void* context) {
LevelDuration ret = instance->encoder.upload[instance->encoder.front];
if(++instance->encoder.front == instance->encoder.size_upload) {
instance->encoder.repeat--;
if(!subghz_block_generic_global.endless_tx) instance->encoder.repeat--;
instance->encoder.front = 0;
}
+2 -2
View File
@@ -92,7 +92,7 @@ void* subghz_protocol_encoder_came_alloc(SubGhzEnvironment* environment) {
instance->base.protocol = &subghz_protocol_came;
instance->generic.protocol_name = instance->base.protocol->name;
instance->encoder.repeat = 10;
instance->encoder.repeat = 3;
instance->encoder.size_upload = 128;
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
instance->encoder.is_running = false;
@@ -213,7 +213,7 @@ LevelDuration subghz_protocol_encoder_came_yield(void* context) {
LevelDuration ret = instance->encoder.upload[instance->encoder.front];
if(++instance->encoder.front == instance->encoder.size_upload) {
instance->encoder.repeat--;
if(!subghz_block_generic_global.endless_tx) instance->encoder.repeat--;
instance->encoder.front = 0;
}
+11 -2
View File
@@ -91,7 +91,7 @@ void* subghz_protocol_encoder_came_atomo_alloc(SubGhzEnvironment* environment) {
instance->base.protocol = &subghz_protocol_came_atomo;
instance->generic.protocol_name = instance->base.protocol->name;
instance->encoder.repeat = 10;
instance->encoder.repeat = 1;
instance->encoder.size_upload = 900; //actual size 766+
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
instance->encoder.is_running = false;
@@ -253,6 +253,10 @@ static void subghz_protocol_encoder_came_atomo_get_upload(
btn = 0x6;
}
// override button if we change it with signal settings button editor
if(subghz_block_generic_global_button_override_get(&btn))
FURI_LOG_D(TAG, "Button sucessfully changed to 0x%X", btn);
//Send header
instance->encoder.upload[index++] =
level_duration_make(true, (uint32_t)subghz_protocol_came_atomo_const.te_long * 15);
@@ -432,7 +436,7 @@ LevelDuration subghz_protocol_encoder_came_atomo_yield(void* context) {
LevelDuration ret = instance->encoder.upload[instance->encoder.front];
if(++instance->encoder.front == instance->encoder.size_upload) {
instance->encoder.repeat--;
if(!subghz_block_generic_global.endless_tx) instance->encoder.repeat--;
instance->encoder.front = 0;
}
@@ -831,6 +835,11 @@ void subghz_protocol_decoder_came_atomo_get_string(void* context, FuriString* ou
subghz_block_generic_global.cnt_is_available = true;
subghz_block_generic_global.cnt_length_bit = 16;
subghz_block_generic_global.current_cnt = instance->generic.cnt;
subghz_block_generic_global.btn_is_available = true;
subghz_block_generic_global.current_btn = instance->generic.btn;
subghz_block_generic_global.btn_length_bit = 4;
//
furi_string_cat_printf(
+9 -3
View File
@@ -111,8 +111,8 @@ void* subghz_protocol_encoder_came_twee_alloc(SubGhzEnvironment* environment) {
instance->base.protocol = &subghz_protocol_came_twee;
instance->generic.protocol_name = instance->base.protocol->name;
instance->encoder.repeat = 10;
instance->encoder.size_upload = 1536; //max upload 92*14 = 1288 !!!!
instance->encoder.repeat = 3;
instance->encoder.size_upload = 1536; // 1308
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
instance->encoder.is_running = false;
return instance;
@@ -286,7 +286,7 @@ LevelDuration subghz_protocol_encoder_came_twee_yield(void* context) {
LevelDuration ret = instance->encoder.upload[instance->encoder.front];
if(++instance->encoder.front == instance->encoder.size_upload) {
instance->encoder.repeat--;
if(!subghz_block_generic_global.endless_tx) instance->encoder.repeat--;
instance->encoder.front = 0;
}
@@ -446,6 +446,12 @@ void subghz_protocol_decoder_came_twee_get_string(void* context, FuriString* out
uint32_t code_found_hi = instance->generic.data >> 32;
uint32_t code_found_lo = instance->generic.data & 0x00000000ffffffff;
// push protocol data to global variable
subghz_block_generic_global.btn_is_available = false;
subghz_block_generic_global.current_btn = instance->generic.btn;
subghz_block_generic_global.btn_length_bit = 4;
//
furi_string_cat_printf(
output,
"%s %db\r\n"
+2 -2
View File
@@ -107,7 +107,7 @@ void* subghz_protocol_encoder_chamb_code_alloc(SubGhzEnvironment* environment) {
instance->base.protocol = &subghz_protocol_chamb_code;
instance->generic.protocol_name = instance->base.protocol->name;
instance->encoder.repeat = 10;
instance->encoder.repeat = 3;
instance->encoder.size_upload = 24;
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
instance->encoder.is_running = false;
@@ -256,7 +256,7 @@ LevelDuration subghz_protocol_encoder_chamb_code_yield(void* context) {
LevelDuration ret = instance->encoder.upload[instance->encoder.front];
if(++instance->encoder.front == instance->encoder.size_upload) {
instance->encoder.repeat--;
if(!subghz_block_generic_global.endless_tx) instance->encoder.repeat--;
instance->encoder.front = 0;
}
+10 -3
View File
@@ -92,7 +92,7 @@ void* subghz_protocol_encoder_clemsa_alloc(SubGhzEnvironment* environment) {
instance->base.protocol = &subghz_protocol_clemsa;
instance->generic.protocol_name = instance->base.protocol->name;
instance->encoder.repeat = 10;
instance->encoder.repeat = 3;
instance->encoder.size_upload = 52;
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
instance->encoder.is_running = false;
@@ -201,7 +201,7 @@ LevelDuration subghz_protocol_encoder_clemsa_yield(void* context) {
LevelDuration ret = instance->encoder.upload[instance->encoder.front];
if(++instance->encoder.front == instance->encoder.size_upload) {
instance->encoder.repeat--;
if(!subghz_block_generic_global.endless_tx) instance->encoder.repeat--;
instance->encoder.front = 0;
}
@@ -340,10 +340,17 @@ void subghz_protocol_decoder_clemsa_get_string(void* context, FuriString* output
SubGhzProtocolDecoderClemsa* instance = context;
subghz_protocol_clemsa_check_remote_controller(&instance->generic);
//uint32_t data = (uint32_t)(instance->generic.data & 0xFFFFFF);
// push protocol data to global variable
subghz_block_generic_global.btn_is_available = false;
subghz_block_generic_global.current_btn = instance->generic.btn;
subghz_block_generic_global.btn_length_bit = 2;
//
furi_string_cat_printf(
output,
"%s %dbit\r\n"
"Key:%05lX Btn %X\r\n"
"Key:%05lX Btn:%X\r\n"
" +: " DIP_PATTERN "\r\n"
" o: " DIP_PATTERN "\r\n"
" -: " DIP_PATTERN "\r\n",
+2 -2
View File
@@ -134,7 +134,7 @@ void* subghz_protocol_encoder_dickert_mahs_alloc(SubGhzEnvironment* environment)
instance->base.protocol = &subghz_protocol_dickert_mahs;
instance->generic.protocol_name = instance->base.protocol->name;
instance->encoder.repeat = 10;
instance->encoder.repeat = 3;
instance->encoder.size_upload = 128;
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
instance->encoder.is_running = false;
@@ -239,7 +239,7 @@ LevelDuration subghz_protocol_encoder_dickert_mahs_yield(void* context) {
LevelDuration ret = instance->encoder.upload[instance->encoder.front];
if(++instance->encoder.front == instance->encoder.size_upload) {
instance->encoder.repeat--;
if(!subghz_block_generic_global.endless_tx) instance->encoder.repeat--;
instance->encoder.front = 0;
}
+9 -2
View File
@@ -84,7 +84,7 @@ void* subghz_protocol_encoder_doitrand_alloc(SubGhzEnvironment* environment) {
instance->base.protocol = &subghz_protocol_doitrand;
instance->generic.protocol_name = instance->base.protocol->name;
instance->encoder.repeat = 10;
instance->encoder.repeat = 3;
instance->encoder.size_upload = 128;
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
instance->encoder.is_running = false;
@@ -181,7 +181,7 @@ LevelDuration subghz_protocol_encoder_doitrand_yield(void* context) {
LevelDuration ret = instance->encoder.upload[instance->encoder.front];
if(++instance->encoder.front == instance->encoder.size_upload) {
instance->encoder.repeat--;
if(!subghz_block_generic_global.endless_tx) instance->encoder.repeat--;
instance->encoder.front = 0;
}
@@ -335,6 +335,13 @@ void subghz_protocol_decoder_doitrand_get_string(void* context, FuriString* outp
furi_assert(context);
SubGhzProtocolDecoderDoitrand* instance = context;
subghz_protocol_doitrand_check_remote_controller(&instance->generic);
// push protocol data to global variable
subghz_block_generic_global.btn_is_available = false;
subghz_block_generic_global.current_btn = instance->generic.btn;
subghz_block_generic_global.btn_length_bit = 2;
//
furi_string_cat_printf(
output,
"%s %dbit\r\n"
+10 -3
View File
@@ -79,7 +79,7 @@ void* subghz_protocol_encoder_dooya_alloc(SubGhzEnvironment* environment) {
instance->base.protocol = &subghz_protocol_dooya;
instance->generic.protocol_name = instance->base.protocol->name;
instance->encoder.repeat = 10;
instance->encoder.repeat = 3;
instance->encoder.size_upload = 128;
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
instance->encoder.is_running = false;
@@ -191,7 +191,7 @@ LevelDuration subghz_protocol_encoder_dooya_yield(void* context) {
LevelDuration ret = instance->encoder.upload[instance->encoder.front];
if(++instance->encoder.front == instance->encoder.size_upload) {
instance->encoder.repeat--;
if(!subghz_block_generic_global.endless_tx) instance->encoder.repeat--;
instance->encoder.front = 0;
}
@@ -420,16 +420,23 @@ void subghz_protocol_decoder_dooya_get_string(void* context, FuriString* output)
subghz_protocol_dooya_check_remote_controller(&instance->generic);
// push protocol data to global variable
subghz_block_generic_global.btn_is_available = false;
subghz_block_generic_global.current_btn = instance->generic.btn;
subghz_block_generic_global.btn_length_bit = 8;
//
furi_string_cat_printf(
output,
"%s %dbit\r\n"
"Key:0x%010llX\r\n"
"Sn:0x%08lX\r\n"
"Btn:%s\r\n",
"Btn:%X - %s\r\n",
instance->generic.protocol_name,
instance->generic.data_count_bit,
instance->generic.data,
instance->generic.serial,
instance->generic.btn,
subghz_protocol_dooya_get_name_button(instance->generic.btn));
if(instance->generic.cnt == DOYA_SINGLE_CHANNEL) {
furi_string_cat_printf(output, "Ch:Single\r\n");
+3 -3
View File
@@ -75,8 +75,8 @@ void* subghz_protocol_encoder_elplast_alloc(SubGhzEnvironment* environment) {
instance->base.protocol = &subghz_protocol_elplast;
instance->generic.protocol_name = instance->base.protocol->name;
instance->encoder.repeat = 10;
instance->encoder.size_upload = 256;
instance->encoder.repeat = 3;
instance->encoder.size_upload = 64;
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
instance->encoder.is_running = false;
return instance;
@@ -170,7 +170,7 @@ LevelDuration subghz_protocol_encoder_elplast_yield(void* context) {
LevelDuration ret = instance->encoder.upload[instance->encoder.front];
if(++instance->encoder.front == instance->encoder.size_upload) {
instance->encoder.repeat--;
if(!subghz_block_generic_global.endless_tx) instance->encoder.repeat--;
instance->encoder.front = 0;
}
+96 -80
View File
@@ -111,7 +111,7 @@ void* subghz_protocol_encoder_faac_slh_alloc(SubGhzEnvironment* environment) {
instance->generic.protocol_name = instance->base.protocol->name;
instance->keystore = subghz_environment_get_keystore(environment);
instance->encoder.repeat = 10;
instance->encoder.repeat = 3;
instance->encoder.size_upload = 256;
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
instance->encoder.is_running = false;
@@ -126,108 +126,115 @@ void subghz_protocol_encoder_faac_slh_free(void* context) {
}
static bool subghz_protocol_faac_slh_gen_data(SubGhzProtocolEncoderFaacSLH* instance) {
// TODO: Stupid bypass for custom button, remake later
if(subghz_custom_btn_get_original() == 0) {
subghz_custom_btn_set_original(0xF);
}
// override button if we change it with signal settings button editor
// else work as standart
if(subghz_block_generic_global_button_override_get(&instance->generic.btn)) {
FURI_LOG_D(TAG, "Button sucessfully changed to 0x%X", instance->generic.btn);
} else {
// TODO: Stupid bypass for custom button, remake later
if(subghz_custom_btn_get_original() == 0) {
subghz_custom_btn_set_original(0xF);
}
uint8_t custom_btn_id = subghz_custom_btn_get();
uint8_t custom_btn_id = subghz_custom_btn_get();
// If we are using UP button - generate programming mode key and send it, otherwise - send regular key if possible
if((custom_btn_id == SUBGHZ_CUSTOM_BTN_UP) &&
!(!allow_zero_seed && (instance->generic.seed == 0x0))) {
uint8_t data_tmp = 0;
uint8_t data_prg[8];
// If we are using UP button - generate programming mode key and send it, otherwise - send regular key if possible
if((custom_btn_id == SUBGHZ_CUSTOM_BTN_UP) &&
!(!allow_zero_seed && (instance->generic.seed == 0x0))) {
uint8_t data_tmp = 0;
uint8_t data_prg[8];
data_prg[0] = 0x00;
data_prg[0] = 0x00;
if(allow_zero_seed || (instance->generic.seed != 0x0)) {
// check OFEX mode
if(furi_hal_subghz_get_rolling_counter_mult() != -0x7FFFFFFF) {
// standart counter mode. PULL data from subghz_block_generic_global variables
if(!subghz_block_generic_global_counter_override_get(&instance->generic.cnt)) {
// if counter_override_get return FALSE then counter was not changed and we increase counter by standart mult value
if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) >
0xFFFFF) {
instance->generic.cnt = 0;
} else {
instance->generic.cnt += furi_hal_subghz_get_rolling_counter_mult();
}
}
} else {
// TODO: OFEX mode
instance->generic.cnt += 1;
}
if(temp_counter_backup != 0x0) {
if(allow_zero_seed || (instance->generic.seed != 0x0)) {
// check OFEX mode
if(furi_hal_subghz_get_rolling_counter_mult() != -0x7FFFFFFF) {
// standart counter mode. PULL data from subghz_block_generic_global variables
if(!subghz_block_generic_global_counter_override_get(&temp_counter_backup)) {
if(!subghz_block_generic_global_counter_override_get(&instance->generic.cnt)) {
// if counter_override_get return FALSE then counter was not changed and we increase counter by standart mult value
if((temp_counter_backup + furi_hal_subghz_get_rolling_counter_mult()) >
if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) >
0xFFFFF) {
temp_counter_backup = 0;
instance->generic.cnt = 0;
} else {
temp_counter_backup += furi_hal_subghz_get_rolling_counter_mult();
instance->generic.cnt += furi_hal_subghz_get_rolling_counter_mult();
}
}
} else {
// todo OFEX mode
temp_counter_backup += 1;
// TODO: OFEX mode
instance->generic.cnt += 1;
}
if(temp_counter_backup != 0x0) {
// check OFEX mode
if(furi_hal_subghz_get_rolling_counter_mult() != -0x7FFFFFFF) {
// standart counter mode. PULL data from subghz_block_generic_global variables
if(!subghz_block_generic_global_counter_override_get(
&temp_counter_backup)) {
// if counter_override_get return FALSE then counter was not changed and we increase counter by standart mult value
if((temp_counter_backup + furi_hal_subghz_get_rolling_counter_mult()) >
0xFFFFF) {
temp_counter_backup = 0;
} else {
temp_counter_backup += furi_hal_subghz_get_rolling_counter_mult();
}
}
} else {
// todo OFEX mode
temp_counter_backup += 1;
}
}
}
}
data_prg[1] = instance->generic.cnt & 0xFF;
data_prg[1] = instance->generic.cnt & 0xFF;
data_prg[2] = (uint8_t)(instance->generic.seed & 0xFF);
data_prg[3] = (uint8_t)(instance->generic.seed >> 8 & 0xFF);
data_prg[4] = (uint8_t)(instance->generic.seed >> 16 & 0xFF);
data_prg[5] = (uint8_t)(instance->generic.seed >> 24);
data_prg[2] = (uint8_t)(instance->generic.seed & 0xFF);
data_prg[3] = (uint8_t)(instance->generic.seed >> 8 & 0xFF);
data_prg[4] = (uint8_t)(instance->generic.seed >> 16 & 0xFF);
data_prg[5] = (uint8_t)(instance->generic.seed >> 24);
data_prg[2] ^= data_prg[1];
data_prg[3] ^= data_prg[1];
data_prg[4] ^= data_prg[1];
data_prg[5] ^= data_prg[1];
data_prg[2] ^= data_prg[1];
data_prg[3] ^= data_prg[1];
data_prg[4] ^= data_prg[1];
data_prg[5] ^= data_prg[1];
for(uint8_t i = data_prg[1] & 0x0F; i != 0; i--) {
data_tmp = data_prg[5];
for(uint8_t i = data_prg[1] & 0x0F; i != 0; i--) {
data_tmp = data_prg[5];
data_prg[5] = ((data_prg[5] << 1) & 0xFF) | (data_prg[4] & 0x80) >> 7;
data_prg[4] = ((data_prg[4] << 1) & 0xFF) | (data_prg[3] & 0x80) >> 7;
data_prg[3] = ((data_prg[3] << 1) & 0xFF) | (data_prg[2] & 0x80) >> 7;
data_prg[2] = ((data_prg[2] << 1) & 0xFF) | (data_tmp & 0x80) >> 7;
}
data_prg[6] = 0x0F;
data_prg[7] = 0x52;
data_prg[5] = ((data_prg[5] << 1) & 0xFF) | (data_prg[4] & 0x80) >> 7;
data_prg[4] = ((data_prg[4] << 1) & 0xFF) | (data_prg[3] & 0x80) >> 7;
data_prg[3] = ((data_prg[3] << 1) & 0xFF) | (data_prg[2] & 0x80) >> 7;
data_prg[2] = ((data_prg[2] << 1) & 0xFF) | (data_tmp & 0x80) >> 7;
}
data_prg[6] = 0x0F;
data_prg[7] = 0x52;
uint32_t enc_prg_1 = data_prg[7] << 24 | data_prg[6] << 16 | data_prg[5] << 8 |
data_prg[4];
uint32_t enc_prg_2 = data_prg[3] << 24 | data_prg[2] << 16 | data_prg[1] << 8 |
data_prg[0];
instance->generic.data = (uint64_t)enc_prg_1 << 32 | enc_prg_2;
//FURI_LOG_D(TAG, "New Prog Mode Key Generated: %016llX\r", instance->generic.data);
uint32_t enc_prg_1 = data_prg[7] << 24 | data_prg[6] << 16 | data_prg[5] << 8 |
data_prg[4];
uint32_t enc_prg_2 = data_prg[3] << 24 | data_prg[2] << 16 | data_prg[1] << 8 |
data_prg[0];
instance->generic.data = (uint64_t)enc_prg_1 << 32 | enc_prg_2;
//FURI_LOG_D(TAG, "New Prog Mode Key Generated: %016llX\r", instance->generic.data);
return true;
} else {
if(!allow_zero_seed && (instance->generic.seed == 0x0)) {
// Do not generate new data, send data from buffer
return true;
} else {
if(!allow_zero_seed && (instance->generic.seed == 0x0)) {
// Do not generate new data, send data from buffer
return true;
}
// If we are in prog mode and regular Send button is used - Do not generate new data, send data from buffer
if((faac_prog_mode == true) && (instance->generic.serial == 0x0) &&
(instance->generic.btn == 0x0) && (temp_fix_backup == 0x0)) {
return true;
}
}
// If we are in prog mode and regular Send button is used - Do not generate new data, send data from buffer
if((faac_prog_mode == true) && (instance->generic.serial == 0x0) &&
(instance->generic.btn == 0x0) && (temp_fix_backup == 0x0)) {
return true;
}
}
// Restore main remote data when we exit programming mode
if((instance->generic.serial == 0x0) && (instance->generic.btn == 0x0) &&
(temp_fix_backup != 0x0) && !faac_prog_mode) {
instance->generic.serial = temp_fix_backup >> 4;
instance->generic.btn = temp_fix_backup & 0xF;
if(temp_counter_backup != 0x0) {
instance->generic.cnt = temp_counter_backup;
// Restore main remote data when we exit programming mode
if((instance->generic.serial == 0x0) && (instance->generic.btn == 0x0) &&
(temp_fix_backup != 0x0) && !faac_prog_mode) {
instance->generic.serial = temp_fix_backup >> 4;
instance->generic.btn = temp_fix_backup & 0xF;
if(temp_counter_backup != 0x0) {
instance->generic.cnt = temp_counter_backup;
}
}
}
uint32_t fix = instance->generic.serial << 4 | instance->generic.btn;
@@ -443,7 +450,7 @@ LevelDuration subghz_protocol_encoder_faac_slh_yield(void* context) {
LevelDuration ret = instance->encoder.upload[instance->encoder.front];
if(++instance->encoder.front == instance->encoder.size_upload) {
instance->encoder.repeat--;
if(!subghz_block_generic_global.endless_tx) instance->encoder.repeat--;
instance->encoder.front = 0;
}
@@ -738,6 +745,11 @@ void subghz_protocol_decoder_faac_slh_get_string(void* context, FuriString* outp
instance->generic.seed,
(uint8_t)(instance->generic.cnt & 0xFF));
} else if((allow_zero_seed == false) && (instance->generic.seed == 0x0)) {
// push protocol data to global variable
subghz_block_generic_global.btn_is_available = true;
subghz_block_generic_global.current_btn = instance->generic.btn;
subghz_block_generic_global.btn_length_bit = 4;
//
furi_string_cat_printf(
output,
"%s %dbit\r\n"
@@ -758,6 +770,10 @@ void subghz_protocol_decoder_faac_slh_get_string(void* context, FuriString* outp
subghz_block_generic_global.cnt_is_available = true;
subghz_block_generic_global.cnt_length_bit = 20;
subghz_block_generic_global.current_cnt = instance->generic.cnt;
subghz_block_generic_global.btn_is_available = true;
subghz_block_generic_global.current_btn = instance->generic.btn;
subghz_block_generic_global.btn_length_bit = 4;
//
furi_string_cat_printf(
+2 -2
View File
@@ -77,7 +77,7 @@ void* subghz_protocol_encoder_feron_alloc(SubGhzEnvironment* environment) {
instance->base.protocol = &subghz_protocol_feron;
instance->generic.protocol_name = instance->base.protocol->name;
instance->encoder.repeat = 10;
instance->encoder.repeat = 3;
instance->encoder.size_upload = 256;
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
instance->encoder.is_running = false;
@@ -193,7 +193,7 @@ LevelDuration subghz_protocol_encoder_feron_yield(void* context) {
LevelDuration ret = instance->encoder.upload[instance->encoder.front];
if(++instance->encoder.front == instance->encoder.size_upload) {
instance->encoder.repeat--;
if(!subghz_block_generic_global.endless_tx) instance->encoder.repeat--;
instance->encoder.front = 0;
}
+12 -2
View File
@@ -79,7 +79,7 @@ void* subghz_protocol_encoder_gangqi_alloc(SubGhzEnvironment* environment) {
instance->base.protocol = &subghz_protocol_gangqi;
instance->generic.protocol_name = instance->base.protocol->name;
instance->encoder.repeat = 10;
instance->encoder.repeat = 3;
instance->encoder.size_upload = 1024;
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
instance->encoder.is_running = false;
@@ -172,6 +172,10 @@ static void subghz_protocol_encoder_gangqi_get_upload(SubGhzProtocolEncoderGangQ
// Generate new key using custom or default button
instance->generic.btn = subghz_protocol_gangqi_get_btn_code();
// override button if we change it with signal settings button editor
if(subghz_block_generic_global_button_override_get(&instance->generic.btn))
FURI_LOG_D(TAG, "Button sucessfully changed to 0x%X", instance->generic.btn);
uint16_t serial = (uint16_t)((instance->generic.data >> 18) & 0xFFFF);
uint8_t const_and_button = (uint8_t)(0xD0 | instance->generic.btn);
uint8_t serial_high = (uint8_t)(serial >> 8);
@@ -305,7 +309,7 @@ LevelDuration subghz_protocol_encoder_gangqi_yield(void* context) {
LevelDuration ret = instance->encoder.upload[instance->encoder.front];
if(++instance->encoder.front == instance->encoder.size_upload) {
instance->encoder.repeat--;
if(!subghz_block_generic_global.endless_tx) instance->encoder.repeat--;
instance->encoder.front = 0;
}
@@ -471,6 +475,12 @@ void subghz_protocol_decoder_gangqi_get_string(void* context, FuriString* output
uint8_t sum_type1 = (uint8_t)(0xC8 - serial_high - serial_low - const_and_button);
uint8_t sum_type2 = (uint8_t)(0x02 + serial_high + serial_low + const_and_button);
// push protocol data to global variable
subghz_block_generic_global.btn_is_available = true;
subghz_block_generic_global.current_btn = instance->generic.btn;
subghz_block_generic_global.btn_length_bit = 4;
//
furi_string_cat_printf(
output,
"%s %db\r\n"
+9 -2
View File
@@ -77,7 +77,7 @@ void* subghz_protocol_encoder_gate_tx_alloc(SubGhzEnvironment* environment) {
instance->base.protocol = &subghz_protocol_gate_tx;
instance->generic.protocol_name = instance->base.protocol->name;
instance->encoder.repeat = 10;
instance->encoder.repeat = 3;
instance->encoder.size_upload = 52; //max 24bit*2 + 2 (start, stop)
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
instance->encoder.is_running = false;
@@ -174,7 +174,7 @@ LevelDuration subghz_protocol_encoder_gate_tx_yield(void* context) {
LevelDuration ret = instance->encoder.upload[instance->encoder.front];
if(++instance->encoder.front == instance->encoder.size_upload) {
instance->encoder.repeat--;
if(!subghz_block_generic_global.endless_tx) instance->encoder.repeat--;
instance->encoder.front = 0;
}
@@ -313,6 +313,13 @@ void subghz_protocol_decoder_gate_tx_get_string(void* context, FuriString* outpu
furi_assert(context);
SubGhzProtocolDecoderGateTx* instance = context;
subghz_protocol_gate_tx_check_remote_controller(&instance->generic);
// push protocol data to global variable
subghz_block_generic_global.btn_is_available = false;
subghz_block_generic_global.current_btn = instance->generic.btn;
subghz_block_generic_global.btn_length_bit = 4;
//
furi_string_cat_printf(
output,
"%s %dbit\r\n"
+12 -3
View File
@@ -77,8 +77,8 @@ void* subghz_protocol_encoder_hay21_alloc(SubGhzEnvironment* environment) {
instance->base.protocol = &subghz_protocol_hay21;
instance->generic.protocol_name = instance->base.protocol->name;
instance->encoder.repeat = 10;
instance->encoder.size_upload = 256;
instance->encoder.repeat = 3;
instance->encoder.size_upload = 64;
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
instance->encoder.is_running = false;
return instance;
@@ -146,6 +146,10 @@ static void subghz_protocol_encoder_hay21_get_upload(SubGhzProtocolEncoderHay21*
// Generate new key using custom or default button
instance->generic.btn = subghz_protocol_hay21_get_btn_code();
// override button if we change it with signal settings button editor
if(subghz_block_generic_global_button_override_get(&instance->generic.btn))
FURI_LOG_D(TAG, "Button sucessfully changed to 0x%X", instance->generic.btn);
// Counter increment
// Check for OFEX (overflow experimental) mode
if(furi_hal_subghz_get_rolling_counter_mult() != -0x7FFFFFFF) {
@@ -311,7 +315,7 @@ LevelDuration subghz_protocol_encoder_hay21_yield(void* context) {
LevelDuration ret = instance->encoder.upload[instance->encoder.front];
if(++instance->encoder.front == instance->encoder.size_upload) {
instance->encoder.repeat--;
if(!subghz_block_generic_global.endless_tx) instance->encoder.repeat--;
instance->encoder.front = 0;
}
@@ -470,6 +474,11 @@ void subghz_protocol_decoder_hay21_get_string(void* context, FuriString* output)
subghz_block_generic_global.cnt_length_bit = 8;
subghz_block_generic_global.current_cnt = instance->generic.cnt;
subghz_block_generic_global.btn_is_available = true;
subghz_block_generic_global.current_btn = instance->generic.btn;
subghz_block_generic_global.btn_length_bit = 8;
//
furi_string_cat_printf(
output,
"%s - %dbit\r\n"
+13 -3
View File
@@ -79,8 +79,8 @@ void* subghz_protocol_encoder_hollarm_alloc(SubGhzEnvironment* environment) {
instance->base.protocol = &subghz_protocol_hollarm;
instance->generic.protocol_name = instance->base.protocol->name;
instance->encoder.repeat = 10;
instance->encoder.size_upload = 256;
instance->encoder.repeat = 3;
instance->encoder.size_upload = 128;
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
instance->encoder.is_running = false;
return instance;
@@ -171,6 +171,10 @@ static void subghz_protocol_encoder_hollarm_get_upload(SubGhzProtocolEncoderHoll
// Generate new key using custom or default button
instance->generic.btn = subghz_protocol_hollarm_get_btn_code();
// override button if we change it with signal settings button editor
if(subghz_block_generic_global_button_override_get(&instance->generic.btn))
FURI_LOG_D(TAG, "Button sucessfully changed to 0x%X", instance->generic.btn);
uint64_t new_key = (instance->generic.data >> 12) << 12 | (instance->generic.btn << 8);
uint8_t bytesum = ((new_key >> 32) & 0xFF) + ((new_key >> 24) & 0xFF) +
@@ -301,7 +305,7 @@ LevelDuration subghz_protocol_encoder_hollarm_yield(void* context) {
LevelDuration ret = instance->encoder.upload[instance->encoder.front];
if(++instance->encoder.front == instance->encoder.size_upload) {
instance->encoder.repeat--;
if(!subghz_block_generic_global.endless_tx) instance->encoder.repeat--;
instance->encoder.front = 0;
}
@@ -473,6 +477,12 @@ void subghz_protocol_decoder_hollarm_get_string(void* context, FuriString* outpu
((instance->generic.data >> 32) & 0xFF) + ((instance->generic.data >> 24) & 0xFF) +
((instance->generic.data >> 16) & 0xFF) + ((instance->generic.data >> 8) & 0xFF);
// push protocol data to global variable
subghz_block_generic_global.btn_is_available = true;
subghz_block_generic_global.current_btn = instance->generic.btn;
subghz_block_generic_global.btn_length_bit = 4;
//
furi_string_cat_printf(
output,
"%s %db\r\n"
+8 -2
View File
@@ -88,7 +88,7 @@ void* subghz_protocol_encoder_holtek_alloc(SubGhzEnvironment* environment) {
instance->base.protocol = &subghz_protocol_holtek;
instance->generic.protocol_name = instance->base.protocol->name;
instance->encoder.repeat = 10;
instance->encoder.repeat = 3;
instance->encoder.size_upload = 128;
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
instance->encoder.is_running = false;
@@ -187,7 +187,7 @@ LevelDuration subghz_protocol_encoder_holtek_yield(void* context) {
LevelDuration ret = instance->encoder.upload[instance->encoder.front];
if(++instance->encoder.front == instance->encoder.size_upload) {
instance->encoder.repeat--;
if(!subghz_block_generic_global.endless_tx) instance->encoder.repeat--;
instance->encoder.front = 0;
}
@@ -346,6 +346,12 @@ void subghz_protocol_decoder_holtek_get_string(void* context, FuriString* output
SubGhzProtocolDecoderHoltek* instance = context;
subghz_protocol_holtek_check_remote_controller(&instance->generic);
// push protocol data to global variable
subghz_block_generic_global.btn_is_available = false;
subghz_block_generic_global.current_btn = instance->generic.btn;
subghz_block_generic_global.btn_length_bit = 4;
//
furi_string_cat_printf(
output,
"%s %dbit\r\n"
+9 -3
View File
@@ -8,7 +8,7 @@
/*
* Help
* https://www.holtek.com/documents/10179/116711/HT12A_Ev130.pdf
* https://www.holtek.com/webapi/116711/HT12A_Ev130.pdf
*
*/
@@ -96,7 +96,7 @@ void* subghz_protocol_encoder_holtek_th12x_alloc(SubGhzEnvironment* environment)
instance->base.protocol = &subghz_protocol_holtek_th12x;
instance->generic.protocol_name = instance->base.protocol->name;
instance->encoder.repeat = 10;
instance->encoder.repeat = 3;
instance->encoder.size_upload = 128;
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
instance->encoder.is_running = false;
@@ -202,7 +202,7 @@ LevelDuration subghz_protocol_encoder_holtek_th12x_yield(void* context) {
LevelDuration ret = instance->encoder.upload[instance->encoder.front];
if(++instance->encoder.front == instance->encoder.size_upload) {
instance->encoder.repeat--;
if(!subghz_block_generic_global.endless_tx) instance->encoder.repeat--;
instance->encoder.front = 0;
}
@@ -391,6 +391,12 @@ void subghz_protocol_decoder_holtek_th12x_get_string(void* context, FuriString*
SubGhzProtocolDecoderHoltek_HT12X* instance = context;
subghz_protocol_holtek_th12x_check_remote_controller(&instance->generic);
// push protocol data to global variable
subghz_block_generic_global.btn_is_available = false;
subghz_block_generic_global.current_btn = instance->generic.btn;
subghz_block_generic_global.btn_length_bit = 4;
//
furi_string_cat_printf(
output,
"%s %db\r\n"
+1 -1
View File
@@ -246,7 +246,7 @@ LevelDuration subghz_protocol_encoder_honeywell_yield(void* context) {
}
LevelDuration ret = instance->encoder.upload[instance->encoder.front];
if(++instance->encoder.front == instance->encoder.size_upload) {
instance->encoder.repeat--;
if(!subghz_block_generic_global.endless_tx) instance->encoder.repeat--;
instance->encoder.front = 0;
}
return ret;
+2 -2
View File
@@ -92,7 +92,7 @@ void* subghz_protocol_encoder_honeywell_wdb_alloc(SubGhzEnvironment* environment
instance->base.protocol = &subghz_protocol_honeywell_wdb;
instance->generic.protocol_name = instance->base.protocol->name;
instance->encoder.repeat = 10;
instance->encoder.repeat = 3;
instance->encoder.size_upload = 128;
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
instance->encoder.is_running = false;
@@ -190,7 +190,7 @@ LevelDuration subghz_protocol_encoder_honeywell_wdb_yield(void* context) {
LevelDuration ret = instance->encoder.upload[instance->encoder.front];
if(++instance->encoder.front == instance->encoder.size_upload) {
instance->encoder.repeat--;
if(!subghz_block_generic_global.endless_tx) instance->encoder.repeat--;
instance->encoder.front = 0;
}
+10 -4
View File
@@ -82,8 +82,8 @@ void* subghz_protocol_encoder_hormann_alloc(SubGhzEnvironment* environment) {
instance->base.protocol = &subghz_protocol_hormann;
instance->generic.protocol_name = instance->base.protocol->name;
instance->encoder.repeat = 10;
instance->encoder.size_upload = 2048;
instance->encoder.repeat = 1;
instance->encoder.size_upload = 1850; // 1801
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
instance->encoder.is_running = false;
return instance;
@@ -112,7 +112,6 @@ static bool subghz_protocol_encoder_hormann_get_upload(SubGhzProtocolEncoderHorm
} else {
instance->encoder.size_upload = size_upload;
}
instance->encoder.repeat = 10; //original remote does 10 repeats
for(size_t repeat = 0; repeat < 20; repeat++) {
//Send start bit
@@ -139,6 +138,7 @@ static bool subghz_protocol_encoder_hormann_get_upload(SubGhzProtocolEncoderHorm
}
instance->encoder.upload[index++] =
level_duration_make(true, (uint32_t)subghz_protocol_hormann_const.te_short * 24);
return true;
}
@@ -187,7 +187,7 @@ LevelDuration subghz_protocol_encoder_hormann_yield(void* context) {
LevelDuration ret = instance->encoder.upload[instance->encoder.front];
if(++instance->encoder.front == instance->encoder.size_upload) {
instance->encoder.repeat--;
if(!subghz_block_generic_global.endless_tx) instance->encoder.repeat--;
instance->encoder.front = 0;
}
@@ -321,6 +321,12 @@ void subghz_protocol_decoder_hormann_get_string(void* context, FuriString* outpu
SubGhzProtocolDecoderHormann* instance = context;
subghz_protocol_hormann_check_remote_controller(&instance->generic);
// push protocol data to global variable
subghz_block_generic_global.btn_is_available = false;
subghz_block_generic_global.current_btn = instance->generic.btn;
subghz_block_generic_global.btn_length_bit = 4;
//
furi_string_cat_printf(
output,
"%s\r\n"
+6
View File
@@ -209,6 +209,12 @@ void subghz_protocol_decoder_ido_get_string(void* context, FuriString* output) {
uint32_t code_fix = code_found_reverse & 0xFFFFFF;
uint32_t code_hop = (code_found_reverse >> 24) & 0xFFFFFF;
// push protocol data to global variable
subghz_block_generic_global.btn_is_available = false;
subghz_block_generic_global.current_btn = instance->generic.btn;
subghz_block_generic_global.btn_length_bit = 4;
//
furi_string_cat_printf(
output,
"%s %dbit\r\n"
+12 -2
View File
@@ -88,7 +88,7 @@ void* subghz_protocol_encoder_intertechno_v3_alloc(SubGhzEnvironment* environmen
instance->base.protocol = &subghz_protocol_intertechno_v3;
instance->generic.protocol_name = instance->base.protocol->name;
instance->encoder.repeat = 10;
instance->encoder.repeat = 3;
instance->encoder.size_upload = 256;
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
instance->encoder.is_running = false;
@@ -209,7 +209,7 @@ LevelDuration subghz_protocol_encoder_intertechno_v3_yield(void* context) {
LevelDuration ret = instance->encoder.upload[instance->encoder.front];
if(++instance->encoder.front == instance->encoder.size_upload) {
instance->encoder.repeat--;
if(!subghz_block_generic_global.endless_tx) instance->encoder.repeat--;
instance->encoder.front = 0;
}
@@ -446,6 +446,10 @@ void subghz_protocol_decoder_intertechno_v3_get_string(void* context, FuriString
subghz_protocol_intertechno_v3_check_remote_controller(&instance->generic);
// push protocol data to global variable
subghz_block_generic_global.current_btn = instance->generic.btn;
//
furi_string_cat_printf(
output,
"%.11s %db\r\n"
@@ -461,12 +465,16 @@ void subghz_protocol_decoder_intertechno_v3_get_string(void* context, FuriString
if(instance->generic.cnt >> 5) {
furi_string_cat_printf(
output, "Ch: All Btn:%s\r\n", (instance->generic.btn ? "On" : "Off"));
subghz_block_generic_global.btn_is_available = false;
subghz_block_generic_global.btn_length_bit = 1;
} else {
furi_string_cat_printf(
output,
"Ch:" CH_PATTERN " Btn:%s\r\n",
CNT_TO_CH(instance->generic.cnt),
(instance->generic.btn ? "On" : "Off"));
subghz_block_generic_global.btn_is_available = false;
subghz_block_generic_global.btn_length_bit = 1;
}
} else if(instance->generic.data_count_bit == INTERTECHNO_V3_DIMMING_COUNT_BIT) {
furi_string_cat_printf(
@@ -474,5 +482,7 @@ void subghz_protocol_decoder_intertechno_v3_get_string(void* context, FuriString
"Ch:" CH_PATTERN " Dimm:%d%%\r\n",
CNT_TO_CH(instance->generic.cnt),
(int)(6.67f * (float)instance->generic.btn));
subghz_block_generic_global.btn_is_available = false;
subghz_block_generic_global.btn_length_bit = 4;
}
}
+11 -2
View File
@@ -102,7 +102,7 @@ void* subghz_protocol_encoder_jarolift_alloc(SubGhzEnvironment* environment) {
instance->generic.protocol_name = instance->base.protocol->name;
instance->keystore = subghz_environment_get_keystore(environment);
instance->encoder.repeat = 10;
instance->encoder.repeat = 3;
instance->encoder.size_upload = 256;
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
instance->encoder.is_running = false;
@@ -133,7 +133,7 @@ LevelDuration subghz_protocol_encoder_jarolift_yield(void* context) {
LevelDuration ret = instance->encoder.upload[instance->encoder.front];
if(++instance->encoder.front == instance->encoder.size_upload) {
instance->encoder.repeat--;
if(!subghz_block_generic_global.endless_tx) instance->encoder.repeat--;
instance->encoder.front = 0;
}
@@ -154,6 +154,10 @@ static bool
btn = subghz_protocol_jarolift_get_btn_code();
// override button if we change it with signal settings button editor
if(subghz_block_generic_global_button_override_get(&btn))
FURI_LOG_D(TAG, "Button sucessfully changed to 0x%X", btn);
// Check for OFEX (overflow experimental) mode
if(furi_hal_subghz_get_rolling_counter_mult() != -0x7FFFFFFF) {
// standart counter mode. PULL data from subghz_block_generic_global variables
@@ -762,6 +766,11 @@ void subghz_protocol_decoder_jarolift_get_string(void* context, FuriString* outp
subghz_block_generic_global.cnt_length_bit = 16;
subghz_block_generic_global.current_cnt = instance->generic.cnt;
subghz_block_generic_global.btn_is_available = true;
subghz_block_generic_global.current_btn = instance->generic.btn;
subghz_block_generic_global.btn_length_bit = 4;
//
furi_string_cat_printf(
output,
"%s %dbit\r\n"
+144 -88
View File
@@ -102,6 +102,14 @@ static uint32_t subghz_protocol_keeloq_check_remote_controller(
SubGhzKeystore* keystore,
const char** manufacture_name);
/**
* Defines the button value for the current btn_id
* Basic set | 0x1 | 0x2 | 0x4 | 0x8 | 0xA or Special Learning Code |
* @param last_btn_code Candidate for the last button
* @return Button code
*/
static uint8_t subghz_protocol_keeloq_get_btn_code(uint8_t last_btn_code);
void* subghz_protocol_encoder_keeloq_alloc(SubGhzEnvironment* environment) {
SubGhzProtocolEncoderKeeloq* instance = malloc(sizeof(SubGhzProtocolEncoderKeeloq));
@@ -109,8 +117,8 @@ void* subghz_protocol_encoder_keeloq_alloc(SubGhzEnvironment* environment) {
instance->generic.protocol_name = instance->base.protocol->name;
instance->keystore = subghz_environment_get_keystore(environment);
instance->encoder.repeat = 100;
instance->encoder.size_upload = 256;
instance->encoder.repeat = 3;
instance->encoder.size_upload = 1100;
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
instance->encoder.is_running = false;
@@ -136,19 +144,68 @@ void subghz_protocol_encoder_keeloq_free(void* context) {
static bool subghz_protocol_keeloq_gen_data(
SubGhzProtocolEncoderKeeloq* instance,
uint8_t btn,
bool counter_up) {
bool counter_up,
bool skip_btn_check) {
// No mf name set? -> set to ""
if(instance->manufacture_name == 0x0) {
instance->manufacture_name = "";
}
// add gendata part
ProgMode prog_mode = subghz_custom_btn_get_prog_mode();
if(!skip_btn_check && (keeloq_counter_mode != 7)) {
// Save original button
if(subghz_custom_btn_get_original() == 0) {
subghz_custom_btn_set_original(btn);
}
// Prog mode checks and extra fixage of MF Names
if(prog_mode == PROG_MODE_KEELOQ_BFT) {
instance->manufacture_name = "BFT";
} else if(prog_mode == PROG_MODE_KEELOQ_APRIMATIC) {
instance->manufacture_name = "Aprimatic";
} else if(prog_mode == PROG_MODE_KEELOQ_DEA_MIO) {
instance->manufacture_name = "Dea_Mio";
}
// Custom button (programming mode button) for BFT, Aprimatic, Dea_Mio
uint8_t klq_last_custom_btn = 0xA;
if((strcmp(instance->manufacture_name, "BFT") == 0) ||
(strcmp(instance->manufacture_name, "Aprimatic") == 0) ||
(strcmp(instance->manufacture_name, "Dea_Mio") == 0) ||
(strcmp(instance->manufacture_name, "NICE_MHOUSE") == 0)) {
klq_last_custom_btn = 0xF;
} else if(
(strcmp(instance->manufacture_name, "FAAC_RC,XT") == 0) ||
(strcmp(instance->manufacture_name, "Monarch") == 0) ||
(strcmp(instance->manufacture_name, "NICE_Smilo") == 0)) {
klq_last_custom_btn = 0xB;
} else if(
(strcmp(instance->manufacture_name, "Novoferm") == 0) ||
(strcmp(instance->manufacture_name, "Stilmatic") == 0)) {
klq_last_custom_btn = 0x9;
} else if(
(strcmp(instance->manufacture_name, "EcoStar") == 0) ||
(strcmp(instance->manufacture_name, "Sommer") == 0)) {
klq_last_custom_btn = 0x6;
} else if((strcmp(instance->manufacture_name, "AN-Motors") == 0)) {
klq_last_custom_btn = 0xC;
} else if((strcmp(instance->manufacture_name, "Cardin_S449") == 0)) {
klq_last_custom_btn = 0xD;
}
btn = subghz_protocol_keeloq_get_btn_code(klq_last_custom_btn);
}
// end gendata part
// override button if we change it with signal settings button editor
if(subghz_block_generic_global_button_override_get(&btn))
FURI_LOG_D(TAG, "Button sucessfully changed to 0x%X", btn);
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;
// No mf name set? -> set to ""
if(instance->manufacture_name == 0x0) {
instance->manufacture_name = "";
}
// programming mode on / off conditions
ProgMode prog_mode = subghz_custom_btn_get_prog_mode();
if(strcmp(instance->manufacture_name, "BFT") == 0) {
// BFT programming mode on / off conditions
if(btn == 0xF) {
@@ -257,8 +314,16 @@ static bool subghz_protocol_keeloq_gen_data(
} else {
instance->generic.cnt = 0xFFFF;
}
} else {
} else if(keeloq_counter_mode == 6) {
// Mode 6 - Freeze counter
} else {
// Mode 7 - Make 12 signals in row with mode 2
// + 0x3333 each time
if((instance->generic.cnt + 0x3333) > 0xFFFF) {
instance->generic.cnt = 0;
} else {
instance->generic.cnt += 0x3333;
}
}
}
if(prog_mode == PROG_MODE_OFF) {
@@ -435,7 +500,7 @@ bool subghz_protocol_keeloq_create_data(
instance->generic.cnt = cnt;
instance->manufacture_name = manufacture_name;
instance->generic.data_count_bit = 64;
if(subghz_protocol_keeloq_gen_data(instance, btn, false)) {
if(subghz_protocol_keeloq_gen_data(instance, btn, false, true)) {
return (
subghz_block_generic_serialize(&instance->generic, flipper_format, preset) ==
SubGhzProtocolStatusOk);
@@ -461,7 +526,7 @@ bool subghz_protocol_keeloq_bft_create_data(
instance->manufacture_name = manufacture_name;
instance->generic.data_count_bit = 64;
// hehehehe
if(subghz_protocol_keeloq_gen_data(instance, btn, false)) {
if(subghz_protocol_keeloq_gen_data(instance, btn, false, true)) {
return (
subghz_block_generic_serialize(&instance->generic, flipper_format, preset) ==
SubGhzProtocolStatusOk);
@@ -469,65 +534,15 @@ bool subghz_protocol_keeloq_bft_create_data(
return false;
}
/**
* Defines the button value for the current btn_id
* Basic set | 0x1 | 0x2 | 0x4 | 0x8 | 0xA or Special Learning Code |
* @param last_btn_code Candidate for the last button
* @return Button code
*/
static uint8_t subghz_protocol_keeloq_get_btn_code(uint8_t last_btn_code);
/**
* Generating an upload from data.
* @param instance Pointer to a SubGhzProtocolEncoderKeeloq instance
* @return true On success
*/
static bool
subghz_protocol_encoder_keeloq_get_upload(SubGhzProtocolEncoderKeeloq* instance, uint8_t btn) {
static size_t subghz_protocol_encoder_keeloq_encode_to_timings(
SubGhzProtocolEncoderKeeloq* instance,
uint8_t btn,
bool counter_up,
size_t index) {
furi_assert(instance);
// Save original button
if(subghz_custom_btn_get_original() == 0) {
subghz_custom_btn_set_original(btn);
}
// No mf name set? -> set to ""
if(instance->manufacture_name == 0x0) {
instance->manufacture_name = "";
}
// Prog mode checks and extra fixage of MF Names
ProgMode prog_mode = subghz_custom_btn_get_prog_mode();
if(prog_mode == PROG_MODE_KEELOQ_BFT) {
instance->manufacture_name = "BFT";
} else if(prog_mode == PROG_MODE_KEELOQ_APRIMATIC) {
instance->manufacture_name = "Aprimatic";
} else if(prog_mode == PROG_MODE_KEELOQ_DEA_MIO) {
instance->manufacture_name = "Dea_Mio";
}
// Custom button (programming mode button) for BFT, Aprimatic, Dea_Mio
uint8_t klq_last_custom_btn = 0xA;
if((strcmp(instance->manufacture_name, "BFT") == 0) ||
(strcmp(instance->manufacture_name, "Aprimatic") == 0) ||
(strcmp(instance->manufacture_name, "Dea_Mio") == 0) ||
(strcmp(instance->manufacture_name, "NICE_MHOUSE") == 0)) {
klq_last_custom_btn = 0xF;
} else if(
(strcmp(instance->manufacture_name, "FAAC_RC,XT") == 0) ||
(strcmp(instance->manufacture_name, "Monarch") == 0) ||
(strcmp(instance->manufacture_name, "NICE_Smilo") == 0)) {
klq_last_custom_btn = 0xB;
} else if(
(strcmp(instance->manufacture_name, "Novoferm") == 0) ||
(strcmp(instance->manufacture_name, "Stilmatic") == 0)) {
klq_last_custom_btn = 0x9;
} else if(
(strcmp(instance->manufacture_name, "EcoStar") == 0) ||
(strcmp(instance->manufacture_name, "Sommer") == 0)) {
klq_last_custom_btn = 0x6;
} else if((strcmp(instance->manufacture_name, "AN-Motors") == 0)) {
klq_last_custom_btn = 0xC;
} else if((strcmp(instance->manufacture_name, "Cardin_S449") == 0)) {
klq_last_custom_btn = 0xD;
// Generate new key
if(!subghz_protocol_keeloq_gen_data(instance, btn, counter_up, false)) {
return 0;
}
uint32_t gap_duration = subghz_protocol_keeloq_const.te_short * 40;
@@ -535,24 +550,6 @@ static bool
gap_duration = subghz_protocol_keeloq_const.te_short * 29;
}
btn = subghz_protocol_keeloq_get_btn_code(klq_last_custom_btn);
// Generate new key
if(subghz_protocol_keeloq_gen_data(instance, btn, true)) {
// OK
} else {
return false;
}
size_t index = 0;
size_t size_upload = 11 * 2 + 2 + (instance->generic.data_count_bit * 2) + 4;
if(size_upload > instance->encoder.size_upload) {
FURI_LOG_E(TAG, "Size upload exceeds allocated encoder buffer.");
return false;
} else {
instance->encoder.size_upload = size_upload;
}
//Send header
for(uint8_t i = 11; i > 0; i--) {
instance->encoder.upload[index++] =
@@ -591,6 +588,52 @@ static bool
level_duration_make(true, (uint32_t)subghz_protocol_keeloq_const.te_short);
instance->encoder.upload[index++] = level_duration_make(false, gap_duration);
return index;
}
/**
* Generating an upload from data.
* @param instance Pointer to a SubGhzProtocolEncoderKeeloq instance
* @return true On success
*/
static bool
subghz_protocol_encoder_keeloq_get_upload(SubGhzProtocolEncoderKeeloq* instance, uint8_t btn) {
furi_assert(instance);
instance->encoder.size_upload = 0;
size_t upindex = 0;
if(keeloq_counter_mode == 7) {
uint16_t temp_cnt = instance->generic.cnt;
instance->encoder.repeat = 1;
for(uint8_t i = 7; i > 0; i--) {
if(i == 3) {
instance->generic.cnt = 0x0000;
upindex = subghz_protocol_encoder_keeloq_encode_to_timings(
instance, (uint8_t)0x00, false, upindex);
continue;
} else if(i == 2) {
instance->generic.cnt = temp_cnt;
upindex = subghz_protocol_encoder_keeloq_encode_to_timings(
instance, btn, false, upindex);
continue;
} else if(i == 1) {
instance->generic.cnt = temp_cnt + 1;
upindex = subghz_protocol_encoder_keeloq_encode_to_timings(
instance, btn, false, upindex);
continue;
}
upindex = subghz_protocol_encoder_keeloq_encode_to_timings(
instance, (uint8_t)0x00, true, upindex);
}
instance->encoder.size_upload = upindex;
return true;
} else {
instance->encoder.repeat = 3;
instance->encoder.size_upload =
subghz_protocol_encoder_keeloq_encode_to_timings(instance, btn, true, upindex);
}
return true;
}
@@ -717,7 +760,7 @@ LevelDuration subghz_protocol_encoder_keeloq_yield(void* context) {
LevelDuration ret = instance->encoder.upload[instance->encoder.front];
if(++instance->encoder.front == instance->encoder.size_upload) {
instance->encoder.repeat--;
if(!subghz_block_generic_global.endless_tx) instance->encoder.repeat--;
instance->encoder.front = 0;
}
@@ -1514,9 +1557,16 @@ void subghz_protocol_decoder_keeloq_get_string(void* context, FuriString* output
uint32_t code_found_reverse_lo = code_found_reverse & 0x00000000ffffffff;
if(strcmp(instance->manufacture_name, "BFT") == 0) {
// push protocol data to global variable
subghz_block_generic_global.cnt_is_available = true;
subghz_block_generic_global.cnt_length_bit = 16;
subghz_block_generic_global.current_cnt = instance->generic.cnt;
subghz_block_generic_global.btn_is_available = true;
subghz_block_generic_global.current_btn = instance->generic.btn;
subghz_block_generic_global.btn_length_bit = 4;
//
ProgMode prog_mode = subghz_custom_btn_get_prog_mode();
if(prog_mode == PROG_MODE_KEELOQ_BFT) {
furi_string_cat_printf(
@@ -1556,6 +1606,9 @@ void subghz_protocol_decoder_keeloq_get_string(void* context, FuriString* output
instance->generic.seed);
}
} else if(strcmp(instance->manufacture_name, "Unknown") == 0) {
subghz_block_generic_global.btn_is_available = true;
subghz_block_generic_global.current_btn = instance->generic.btn;
subghz_block_generic_global.btn_length_bit = 4;
instance->generic.cnt = 0x0;
furi_string_cat_printf(
output,
@@ -1576,6 +1629,9 @@ void subghz_protocol_decoder_keeloq_get_string(void* context, FuriString* output
subghz_block_generic_global.cnt_is_available = true;
subghz_block_generic_global.cnt_length_bit = 16;
subghz_block_generic_global.current_cnt = instance->generic.cnt;
subghz_block_generic_global.btn_is_available = true;
subghz_block_generic_global.current_btn = instance->generic.btn;
subghz_block_generic_global.btn_length_bit = 4;
furi_string_cat_printf(
output,
"%s %dbit\r\n"
+11 -2
View File
@@ -103,7 +103,7 @@ void* subghz_protocol_encoder_kinggates_stylo_4k_alloc(SubGhzEnvironment* enviro
instance->generic.protocol_name = instance->base.protocol->name;
instance->keystore = subghz_environment_get_keystore(environment);
instance->encoder.repeat = 10;
instance->encoder.repeat = 3;
instance->encoder.size_upload = 512;
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
instance->encoder.is_running = false;
@@ -134,7 +134,7 @@ LevelDuration subghz_protocol_encoder_kinggates_stylo_4k_yield(void* context) {
LevelDuration ret = instance->encoder.upload[instance->encoder.front];
if(++instance->encoder.front == instance->encoder.size_upload) {
instance->encoder.repeat--;
if(!subghz_block_generic_global.endless_tx) instance->encoder.repeat--;
instance->encoder.front = 0;
}
@@ -156,6 +156,10 @@ static bool subghz_protocol_kinggates_stylo_4k_gen_data(
btn = subghz_protocol_kinggates_stylo_4k_get_btn_code();
// override button if we change it with signal settings button editor
if(subghz_block_generic_global_button_override_get(&btn))
FURI_LOG_D(TAG, "Button sucessfully changed to 0x%X", btn);
// Check for OFEX (overflow experimental) mode
if(furi_hal_subghz_get_rolling_counter_mult() != -0x7FFFFFFF) {
// standart counter mode. PULL data from subghz_block_generic_global variables
@@ -729,6 +733,11 @@ void subghz_protocol_decoder_kinggates_stylo_4k_get_string(void* context, FuriSt
subghz_block_generic_global.cnt_length_bit = 16;
subghz_block_generic_global.current_cnt = instance->generic.cnt;
subghz_block_generic_global.btn_is_available = true;
subghz_block_generic_global.current_btn = instance->generic.btn;
subghz_block_generic_global.btn_length_bit = 4;
//
furi_string_cat_printf(
output,
"%s\r\n"
+2 -2
View File
@@ -84,7 +84,7 @@ void* subghz_protocol_encoder_legrand_alloc(SubGhzEnvironment* environment) {
instance->base.protocol = &subghz_protocol_legrand;
instance->generic.protocol_name = instance->base.protocol->name;
instance->encoder.repeat = 10;
instance->encoder.repeat = 3;
instance->encoder.size_upload =
(subghz_protocol_legrand_const.min_count_bit_for_found * 6) * 2 + 2;
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
@@ -208,7 +208,7 @@ LevelDuration subghz_protocol_encoder_legrand_yield(void* context) {
LevelDuration ret = instance->encoder.upload[instance->encoder.front];
if(++instance->encoder.front == instance->encoder.size_upload) {
instance->encoder.repeat--;
if(!subghz_block_generic_global.endless_tx) instance->encoder.repeat--;
instance->encoder.front = 0;
}
+2 -2
View File
@@ -83,7 +83,7 @@ void* subghz_protocol_encoder_linear_alloc(SubGhzEnvironment* environment) {
instance->base.protocol = &subghz_protocol_linear;
instance->generic.protocol_name = instance->base.protocol->name;
instance->encoder.repeat = 10;
instance->encoder.repeat = 3;
instance->encoder.size_upload = 28; //max 10bit*2 + 2 (start, stop)
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
instance->encoder.is_running = false;
@@ -192,7 +192,7 @@ LevelDuration subghz_protocol_encoder_linear_yield(void* context) {
LevelDuration ret = instance->encoder.upload[instance->encoder.front];
if(++instance->encoder.front == instance->encoder.size_upload) {
instance->encoder.repeat--;
if(!subghz_block_generic_global.endless_tx) instance->encoder.repeat--;
instance->encoder.front = 0;
}
+2 -2
View File
@@ -85,7 +85,7 @@ void* subghz_protocol_encoder_linear_delta3_alloc(SubGhzEnvironment* environment
instance->base.protocol = &subghz_protocol_linear_delta3;
instance->generic.protocol_name = instance->base.protocol->name;
instance->encoder.repeat = 10;
instance->encoder.repeat = 3;
instance->encoder.size_upload = 16;
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
instance->encoder.is_running = false;
@@ -196,7 +196,7 @@ LevelDuration subghz_protocol_encoder_linear_delta3_yield(void* context) {
LevelDuration ret = instance->encoder.upload[instance->encoder.front];
if(++instance->encoder.front == instance->encoder.size_upload) {
instance->encoder.repeat--;
if(!subghz_block_generic_global.endless_tx) instance->encoder.repeat--;
instance->encoder.front = 0;
}
+9 -2
View File
@@ -81,7 +81,7 @@ void* subghz_protocol_encoder_magellan_alloc(SubGhzEnvironment* environment) {
instance->base.protocol = &subghz_protocol_magellan;
instance->generic.protocol_name = instance->base.protocol->name;
instance->encoder.repeat = 10;
instance->encoder.repeat = 3;
instance->encoder.size_upload = 256;
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
instance->encoder.is_running = false;
@@ -199,7 +199,7 @@ LevelDuration subghz_protocol_encoder_magellan_yield(void* context) {
LevelDuration ret = instance->encoder.upload[instance->encoder.front];
if(++instance->encoder.front == instance->encoder.size_upload) {
instance->encoder.repeat--;
if(!subghz_block_generic_global.endless_tx) instance->encoder.repeat--;
instance->encoder.front = 0;
}
@@ -502,6 +502,13 @@ void subghz_protocol_decoder_magellan_get_string(void* context, FuriString* outp
furi_assert(context);
SubGhzProtocolDecoderMagellan* instance = context;
subghz_protocol_magellan_check_remote_controller(&instance->generic);
// push protocol data to global variable
subghz_block_generic_global.btn_is_available = false;
subghz_block_generic_global.current_btn = instance->generic.btn;
subghz_block_generic_global.btn_length_bit = 8;
//
furi_string_cat_printf(
output,
"%s %dbit\r\n"
+8 -2
View File
@@ -79,7 +79,7 @@ void* subghz_protocol_encoder_marantec_alloc(SubGhzEnvironment* environment) {
instance->base.protocol = &subghz_protocol_marantec;
instance->generic.protocol_name = instance->base.protocol->name;
instance->encoder.repeat = 10;
instance->encoder.repeat = 3;
instance->encoder.size_upload = 256;
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
instance->encoder.is_running = false;
@@ -245,7 +245,7 @@ LevelDuration subghz_protocol_encoder_marantec_yield(void* context) {
LevelDuration ret = instance->encoder.upload[instance->encoder.front];
if(++instance->encoder.front == instance->encoder.size_upload) {
instance->encoder.repeat--;
if(!subghz_block_generic_global.endless_tx) instance->encoder.repeat--;
instance->encoder.front = 0;
}
@@ -395,6 +395,12 @@ void subghz_protocol_decoder_marantec_get_string(void* context, FuriString* outp
uint8_t crc = subghz_protocol_marantec_crc8(tdata, sizeof(tdata));
bool crc_ok = (crc == (instance->generic.data & 0xFF));
// push protocol data to global variable
subghz_block_generic_global.btn_is_available = false;
subghz_block_generic_global.current_btn = instance->generic.btn;
subghz_block_generic_global.btn_length_bit = 4;
//
furi_string_cat_printf(
output,
"%s %db\r\n"
+8 -2
View File
@@ -75,7 +75,7 @@ void* subghz_protocol_encoder_marantec24_alloc(SubGhzEnvironment* environment) {
instance->base.protocol = &subghz_protocol_marantec24;
instance->generic.protocol_name = instance->base.protocol->name;
instance->encoder.repeat = 10;
instance->encoder.repeat = 3;
instance->encoder.size_upload = 512;
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
instance->encoder.is_running = false;
@@ -191,7 +191,7 @@ LevelDuration subghz_protocol_encoder_marantec24_yield(void* context) {
LevelDuration ret = instance->encoder.upload[instance->encoder.front];
if(++instance->encoder.front == instance->encoder.size_upload) {
instance->encoder.repeat--;
if(!subghz_block_generic_global.endless_tx) instance->encoder.repeat--;
instance->encoder.front = 0;
}
@@ -340,6 +340,12 @@ void subghz_protocol_decoder_marantec24_get_string(void* context, FuriString* ou
subghz_protocol_marantec24_check_remote_controller(&instance->generic);
// push protocol data to global variable
subghz_block_generic_global.btn_is_available = false;
subghz_block_generic_global.current_btn = instance->generic.btn;
subghz_block_generic_global.btn_length_bit = 4;
//
furi_string_cat_printf(
output,
"%s %db\r\n"
+10 -3
View File
@@ -91,7 +91,7 @@ void* subghz_protocol_encoder_mastercode_alloc(SubGhzEnvironment* environment) {
instance->base.protocol = &subghz_protocol_mastercode;
instance->generic.protocol_name = instance->base.protocol->name;
instance->encoder.repeat = 10;
instance->encoder.repeat = 3;
instance->encoder.size_upload = 72;
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
instance->encoder.is_running = false;
@@ -201,7 +201,7 @@ LevelDuration subghz_protocol_encoder_mastercode_yield(void* context) {
LevelDuration ret = instance->encoder.upload[instance->encoder.front];
if(++instance->encoder.front == instance->encoder.size_upload) {
instance->encoder.repeat--;
if(!subghz_block_generic_global.endless_tx) instance->encoder.repeat--;
instance->encoder.front = 0;
}
@@ -345,10 +345,17 @@ void subghz_protocol_decoder_mastercode_get_string(void* context, FuriString* ou
furi_assert(context);
SubGhzProtocolDecoderMastercode* instance = context;
subghz_protocol_mastercode_check_remote_controller(&instance->generic);
// push protocol data to global variable
subghz_block_generic_global.btn_is_available = false;
subghz_block_generic_global.current_btn = instance->generic.btn;
subghz_block_generic_global.btn_length_bit = 2;
//
furi_string_cat_printf(
output,
"%s %dbit\r\n"
"Key:%llX Btn %X\r\n"
"Key:%llX Btn:%X\r\n"
" +: " DIP_PATTERN "\r\n"
" o: " DIP_PATTERN "\r\n"
" -: " DIP_PATTERN "\r\n",
+8 -2
View File
@@ -89,7 +89,7 @@ void* subghz_protocol_encoder_megacode_alloc(SubGhzEnvironment* environment) {
instance->base.protocol = &subghz_protocol_megacode;
instance->generic.protocol_name = instance->base.protocol->name;
instance->encoder.repeat = 10;
instance->encoder.repeat = 3;
instance->encoder.size_upload = 52;
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
instance->encoder.is_running = false;
@@ -220,7 +220,7 @@ LevelDuration subghz_protocol_encoder_megacode_yield(void* context) {
LevelDuration ret = instance->encoder.upload[instance->encoder.front];
if(++instance->encoder.front == instance->encoder.size_upload) {
instance->encoder.repeat--;
if(!subghz_block_generic_global.endless_tx) instance->encoder.repeat--;
instance->encoder.front = 0;
}
@@ -407,6 +407,12 @@ void subghz_protocol_decoder_megacode_get_string(void* context, FuriString* outp
SubGhzProtocolDecoderMegaCode* instance = context;
subghz_protocol_megacode_check_remote_controller(&instance->generic);
// push protocol data to global variable
subghz_block_generic_global.btn_is_available = false;
subghz_block_generic_global.current_btn = instance->generic.btn;
subghz_block_generic_global.btn_length_bit = 3;
//
furi_string_cat_printf(
output,
"%s %dbit\r\n"
+8 -2
View File
@@ -79,7 +79,7 @@ void* subghz_protocol_encoder_nero_radio_alloc(SubGhzEnvironment* environment) {
instance->base.protocol = &subghz_protocol_nero_radio;
instance->generic.protocol_name = instance->base.protocol->name;
instance->encoder.repeat = 10;
instance->encoder.repeat = 3;
instance->encoder.size_upload = 256;
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
instance->encoder.is_running = false;
@@ -212,7 +212,7 @@ LevelDuration subghz_protocol_encoder_nero_radio_yield(void* context) {
LevelDuration ret = instance->encoder.upload[instance->encoder.front];
if(++instance->encoder.front == instance->encoder.size_upload) {
instance->encoder.repeat--;
if(!subghz_block_generic_global.endless_tx) instance->encoder.repeat--;
instance->encoder.front = 0;
}
@@ -432,6 +432,12 @@ void subghz_protocol_decoder_nero_radio_get_string(void* context, FuriString* ou
subghz_protocol_nero_radio_parse_data(&instance->generic);
// push protocol data to global variable
subghz_block_generic_global.btn_is_available = false;
subghz_block_generic_global.current_btn = instance->generic.btn;
subghz_block_generic_global.btn_length_bit = 4;
//
furi_string_cat_printf(
output,
"%s %dbit\r\n"
+2 -2
View File
@@ -78,7 +78,7 @@ void* subghz_protocol_encoder_nero_sketch_alloc(SubGhzEnvironment* environment)
instance->base.protocol = &subghz_protocol_nero_sketch;
instance->generic.protocol_name = instance->base.protocol->name;
instance->encoder.repeat = 10;
instance->encoder.repeat = 3;
instance->encoder.size_upload = 256;
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
instance->encoder.is_running = false;
@@ -193,7 +193,7 @@ LevelDuration subghz_protocol_encoder_nero_sketch_yield(void* context) {
LevelDuration ret = instance->encoder.upload[instance->encoder.front];
if(++instance->encoder.front == instance->encoder.size_upload) {
instance->encoder.repeat--;
if(!subghz_block_generic_global.endless_tx) instance->encoder.repeat--;
instance->encoder.front = 0;
}
+2 -2
View File
@@ -77,7 +77,7 @@ void* subghz_protocol_encoder_nice_flo_alloc(SubGhzEnvironment* environment) {
instance->base.protocol = &subghz_protocol_nice_flo;
instance->generic.protocol_name = instance->base.protocol->name;
instance->encoder.repeat = 10;
instance->encoder.repeat = 3;
instance->encoder.size_upload = 52; //max 24bit*2 + 2 (start, stop)
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
instance->encoder.is_running = false;
@@ -179,7 +179,7 @@ LevelDuration subghz_protocol_encoder_nice_flo_yield(void* context) {
LevelDuration ret = instance->encoder.upload[instance->encoder.front];
if(++instance->encoder.front == instance->encoder.size_upload) {
instance->encoder.repeat--;
if(!subghz_block_generic_global.endless_tx) instance->encoder.repeat--;
instance->encoder.front = 0;
}
+12 -3
View File
@@ -108,8 +108,8 @@ void* subghz_protocol_encoder_nice_flor_s_alloc(SubGhzEnvironment* environment)
FURI_LOG_D(
TAG, "Loading rainbow table from %s", instance->nice_flor_s_rainbow_table_file_name);
}
instance->encoder.repeat = 10;
instance->encoder.size_upload = 2400; //wrong!! upload 186*16 = 2976 - actual size about 1728
instance->encoder.repeat = 1;
instance->encoder.size_upload = 2400; // 2368 for Nice ONE
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
instance->encoder.is_running = false;
return instance;
@@ -151,6 +151,10 @@ static void subghz_protocol_encoder_nice_flor_s_get_upload(
btn = subghz_protocol_nice_flor_s_get_btn_code();
// override button if we change it with signal settings button editor
if(subghz_block_generic_global_button_override_get(&btn))
FURI_LOG_D(TAG, "Button sucessfully changed to 0x%X", btn);
size_t size_upload = ((instance->generic.data_count_bit * 2) + ((37 + 2 + 2) * 2) * 16);
if(size_upload > instance->encoder.size_upload) {
FURI_LOG_E(TAG, "Size upload exceeds allocated encoder buffer.");
@@ -353,7 +357,7 @@ LevelDuration subghz_protocol_encoder_nice_flor_s_yield(void* context) {
LevelDuration ret = instance->encoder.upload[instance->encoder.front];
if(++instance->encoder.front == instance->encoder.size_upload) {
instance->encoder.repeat--;
if(!subghz_block_generic_global.endless_tx) instance->encoder.repeat--;
instance->encoder.front = 0;
}
@@ -941,6 +945,11 @@ void subghz_protocol_decoder_nice_flor_s_get_string(void* context, FuriString* o
subghz_block_generic_global.cnt_length_bit = 16;
subghz_block_generic_global.current_cnt = instance->generic.cnt;
subghz_block_generic_global.btn_is_available = true;
subghz_block_generic_global.current_btn = instance->generic.btn;
subghz_block_generic_global.btn_length_bit = 4;
//
if(instance->generic.data_count_bit == NICE_ONE_COUNT_BIT) {
furi_string_cat_printf(
output,
+16 -5
View File
@@ -79,7 +79,7 @@ void* subghz_protocol_encoder_phoenix_v2_alloc(SubGhzEnvironment* environment) {
instance->base.protocol = &subghz_protocol_phoenix_v2;
instance->generic.protocol_name = instance->base.protocol->name;
instance->encoder.repeat = 10;
instance->encoder.repeat = 3;
instance->encoder.size_upload = 128;
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
instance->encoder.is_running = false;
@@ -120,9 +120,11 @@ bool subghz_protocol_phoenix_v2_create_data(
local_data_rev, instance->generic.cnt);
instance->generic.data = subghz_protocol_blocks_reverse_key(
(uint64_t)(((uint64_t)encrypted_counter << 40) | ((uint64_t)instance->generic.btn << 32) |
(uint64_t)instance->generic.serial),
instance->generic.data_count_bit + 4);
(uint64_t)(((uint64_t)encrypted_counter << 40) |
((uint64_t)instance->generic.btn << 32) |
(uint64_t)instance->generic.serial),
instance->generic.data_count_bit + 4) &
0xFFFFFFFFFFFFF;
return SubGhzProtocolStatusOk ==
subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
@@ -255,6 +257,10 @@ static bool
// This will override the btn variable if a custom button is set
btn = subghz_protocol_phoenix_v2_get_btn_code();
// override button if we change it with signal settings button editor
if(subghz_block_generic_global_button_override_get(&btn))
FURI_LOG_D(TAG, "Button sucessfully changed to 0x%X", btn);
// Reconstruction of the data
if(v2_phoenix_counter_mode == 0) {
// Check for OFEX (overflow experimental) mode
@@ -405,7 +411,7 @@ LevelDuration subghz_protocol_encoder_phoenix_v2_yield(void* context) {
LevelDuration ret = instance->encoder.upload[instance->encoder.front];
if(++instance->encoder.front == instance->encoder.size_upload) {
instance->encoder.repeat--;
if(!subghz_block_generic_global.endless_tx) instance->encoder.repeat--;
instance->encoder.front = 0;
}
@@ -654,6 +660,11 @@ void subghz_protocol_decoder_phoenix_v2_get_string(void* context, FuriString* ou
subghz_block_generic_global.cnt_length_bit = 16;
subghz_block_generic_global.current_cnt = instance->generic.cnt;
subghz_block_generic_global.btn_is_available = true;
subghz_block_generic_global.current_btn = instance->generic.btn;
subghz_block_generic_global.btn_length_bit = 4;
//
furi_string_cat_printf(
output,
"V2 Phoenix %dbit\r\n"
+8 -2
View File
@@ -87,7 +87,7 @@ void* subghz_protocol_encoder_power_smart_alloc(SubGhzEnvironment* environment)
instance->base.protocol = &subghz_protocol_power_smart;
instance->generic.protocol_name = instance->base.protocol->name;
instance->encoder.repeat = 10;
instance->encoder.repeat = 3;
instance->encoder.size_upload = 1024;
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
instance->encoder.is_running = false;
@@ -238,7 +238,7 @@ LevelDuration subghz_protocol_encoder_power_smart_yield(void* context) {
LevelDuration ret = instance->encoder.upload[instance->encoder.front];
if(++instance->encoder.front == instance->encoder.size_upload) {
instance->encoder.repeat--;
if(!subghz_block_generic_global.endless_tx) instance->encoder.repeat--;
instance->encoder.front = 0;
}
@@ -371,6 +371,12 @@ void subghz_protocol_decoder_power_smart_get_string(void* context, FuriString* o
SubGhzProtocolDecoderPowerSmart* instance = context;
subghz_protocol_power_smart_remote_controller(&instance->generic);
// push protocol data to global variable
subghz_block_generic_global.btn_is_available = false;
subghz_block_generic_global.current_btn = instance->generic.btn;
subghz_block_generic_global.btn_length_bit = 2;
//
furi_string_cat_printf(
output,
"%s %db\r\n"
+13 -2
View File
@@ -97,7 +97,7 @@ void* subghz_protocol_encoder_princeton_alloc(SubGhzEnvironment* environment) {
instance->base.protocol = &subghz_protocol_princeton;
instance->generic.protocol_name = instance->base.protocol->name;
instance->encoder.repeat = 10;
instance->encoder.repeat = 3;
instance->encoder.size_upload = 52; //max 24bit*2 + 2 (start, stop)
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
instance->encoder.is_running = false;
@@ -261,6 +261,10 @@ static bool
// Generate new key using custom or default button
instance->generic.btn = subghz_protocol_princeton_get_btn_code();
// override button if we change it with signal settings button editor
if(subghz_block_generic_global_button_override_get(&instance->generic.btn))
FURI_LOG_D(TAG, "Button sucessfully changed to 0x%X", instance->generic.btn);
// Reconstruction of the data
// If we have 8bit button code move serial to left by 8 bits (and 4 if 4 bits)
if(instance->generic.btn == 0x30 || instance->generic.btn == 0xC0) {
@@ -414,7 +418,7 @@ LevelDuration subghz_protocol_encoder_princeton_yield(void* context) {
LevelDuration ret = instance->encoder.upload[instance->encoder.front];
if(++instance->encoder.front == instance->encoder.size_upload) {
instance->encoder.repeat--;
if(!subghz_block_generic_global.endless_tx) instance->encoder.repeat--;
instance->encoder.front = 0;
}
@@ -594,8 +598,14 @@ void subghz_protocol_decoder_princeton_get_string(void* context, FuriString* out
uint32_t data_rev = subghz_protocol_blocks_reverse_key(
instance->generic.data, instance->generic.data_count_bit);
// push protocol data to global variable
subghz_block_generic_global.btn_is_available = true;
subghz_block_generic_global.current_btn = instance->generic.btn;
//
if(instance->generic.btn == 0x30 || instance->generic.btn == 0xC0 ||
instance->generic.btn == 0xF3 || instance->generic.btn == 0xFC) {
subghz_block_generic_global.btn_length_bit = 8;
furi_string_cat_printf(
output,
"%s %dbit\r\n"
@@ -614,6 +624,7 @@ void subghz_protocol_decoder_princeton_get_string(void* context, FuriString* out
instance->te,
instance->guard_time);
} else {
subghz_block_generic_global.btn_length_bit = 4;
furi_string_cat_printf(
output,
"%s %dbit\r\n"
+2 -2
View File
@@ -79,7 +79,7 @@ void* subghz_protocol_encoder_revers_rb2_alloc(SubGhzEnvironment* environment) {
instance->base.protocol = &subghz_protocol_revers_rb2;
instance->generic.protocol_name = instance->base.protocol->name;
instance->encoder.repeat = 10;
instance->encoder.repeat = 3;
instance->encoder.size_upload = 1768;
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
instance->encoder.is_running = false;
@@ -210,7 +210,7 @@ LevelDuration subghz_protocol_encoder_revers_rb2_yield(void* context) {
LevelDuration ret = instance->encoder.upload[instance->encoder.front];
if(++instance->encoder.front == instance->encoder.size_upload) {
instance->encoder.repeat--;
if(!subghz_block_generic_global.endless_tx) instance->encoder.repeat--;
instance->encoder.front = 0;
}
+13 -3
View File
@@ -76,8 +76,8 @@ void* subghz_protocol_encoder_roger_alloc(SubGhzEnvironment* environment) {
instance->base.protocol = &subghz_protocol_roger;
instance->generic.protocol_name = instance->base.protocol->name;
instance->encoder.repeat = 10;
instance->encoder.size_upload = 256;
instance->encoder.repeat = 3;
instance->encoder.size_upload = 128;
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
instance->encoder.is_running = false;
return instance;
@@ -178,6 +178,10 @@ static void subghz_protocol_encoder_roger_get_upload(SubGhzProtocolEncoderRoger*
// This will override the btn variable if a custom button is set
btn = subghz_protocol_roger_get_btn_code();
// override button if we change it with signal settings button editor
if(subghz_block_generic_global_button_override_get(&btn))
FURI_LOG_D(TAG, "Button sucessfully changed to 0x%X", btn);
// If End is not == button - transmit as is, no custom button allowed
// For "End" values 23 and 20 - transmit correct ending used for their buttons
if((instance->generic.data & 0xFF) == instance->generic.btn) {
@@ -305,7 +309,7 @@ LevelDuration subghz_protocol_encoder_roger_yield(void* context) {
LevelDuration ret = instance->encoder.upload[instance->encoder.front];
if(++instance->encoder.front == instance->encoder.size_upload) {
instance->encoder.repeat--;
if(!subghz_block_generic_global.endless_tx) instance->encoder.repeat--;
instance->encoder.front = 0;
}
@@ -435,6 +439,12 @@ void subghz_protocol_decoder_roger_get_string(void* context, FuriString* output)
subghz_protocol_roger_check_remote_controller(&instance->generic);
// push protocol data to global variable
subghz_block_generic_global.btn_is_available = true;
subghz_block_generic_global.current_btn = instance->generic.btn;
subghz_block_generic_global.btn_length_bit = 4;
//
furi_string_cat_printf(
output,
"%s %db\r\n"
+7 -2
View File
@@ -100,7 +100,7 @@ void* subghz_protocol_encoder_secplus_v1_alloc(SubGhzEnvironment* environment) {
instance->base.protocol = &subghz_protocol_secplus_v1;
instance->generic.protocol_name = instance->base.protocol->name;
instance->encoder.repeat = 10;
instance->encoder.repeat = 3;
instance->encoder.size_upload = 128;
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
instance->encoder.is_running = false;
@@ -346,7 +346,7 @@ LevelDuration subghz_protocol_encoder_secplus_v1_yield(void* context) {
LevelDuration ret = instance->encoder.upload[instance->encoder.front];
if(++instance->encoder.front == instance->encoder.size_upload) {
instance->encoder.repeat--;
if(!subghz_block_generic_global.endless_tx) instance->encoder.repeat--;
instance->encoder.front = 0;
}
@@ -588,6 +588,11 @@ void subghz_protocol_decoder_secplus_v1_get_string(void* context, FuriString* ou
subghz_block_generic_global.cnt_length_bit = 32;
subghz_block_generic_global.current_cnt = instance->generic.cnt;
subghz_block_generic_global.btn_is_available = false;
subghz_block_generic_global.current_btn = instance->generic.btn;
subghz_block_generic_global.btn_length_bit = 2;
//
furi_string_cat_printf(
output,
"%s %db\r\n"
+11 -2
View File
@@ -94,7 +94,7 @@ void* subghz_protocol_encoder_secplus_v2_alloc(SubGhzEnvironment* environment) {
instance->base.protocol = &subghz_protocol_secplus_v2;
instance->generic.protocol_name = instance->base.protocol->name;
instance->encoder.repeat = 10;
instance->encoder.repeat = 3;
instance->encoder.size_upload = 256;
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
instance->encoder.is_running = false;
@@ -397,6 +397,10 @@ static void subghz_protocol_secplus_v2_encode(SubGhzProtocolEncoderSecPlus_v2* i
instance->generic.btn = subghz_protocol_secplus_v2_get_btn_code();
// override button if we change it with signal settings button editor
if(subghz_block_generic_global_button_override_get(&instance->generic.btn))
FURI_LOG_D(TAG, "Button sucessfully changed to 0x%X", instance->generic.btn);
uint32_t fixed_1[1] = {instance->generic.btn << 12 | instance->generic.serial >> 20};
uint32_t fixed_2[1] = {instance->generic.serial & 0xFFFFF};
uint8_t rolling_digits[18] = {0};
@@ -625,7 +629,7 @@ LevelDuration subghz_protocol_encoder_secplus_v2_yield(void* context) {
LevelDuration ret = instance->encoder.upload[instance->encoder.front];
if(++instance->encoder.front == instance->encoder.size_upload) {
instance->encoder.repeat--;
if(!subghz_block_generic_global.endless_tx) instance->encoder.repeat--;
instance->encoder.front = 0;
}
@@ -968,6 +972,11 @@ void subghz_protocol_decoder_secplus_v2_get_string(void* context, FuriString* ou
subghz_block_generic_global.cnt_length_bit = 28;
subghz_block_generic_global.current_cnt = instance->generic.cnt;
subghz_block_generic_global.btn_is_available = true;
subghz_block_generic_global.current_btn = instance->generic.btn;
subghz_block_generic_global.btn_length_bit = 8;
//
furi_string_cat_printf(
output,
"%s %db\r\n"
+2 -2
View File
@@ -103,7 +103,7 @@ void* subghz_protocol_encoder_smc5326_alloc(SubGhzEnvironment* environment) {
instance->base.protocol = &subghz_protocol_smc5326;
instance->generic.protocol_name = instance->base.protocol->name;
instance->encoder.repeat = 10;
instance->encoder.repeat = 3;
instance->encoder.size_upload = 128;
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
instance->encoder.is_running = false;
@@ -210,7 +210,7 @@ LevelDuration subghz_protocol_encoder_smc5326_yield(void* context) {
LevelDuration ret = instance->encoder.upload[instance->encoder.front];
if(++instance->encoder.front == instance->encoder.size_upload) {
instance->encoder.repeat--;
if(!subghz_block_generic_global.endless_tx) instance->encoder.repeat--;
instance->encoder.front = 0;
}
+13 -3
View File
@@ -83,7 +83,7 @@ void* subghz_protocol_encoder_somfy_keytis_alloc(SubGhzEnvironment* environment)
instance->base.protocol = &subghz_protocol_somfy_keytis;
instance->generic.protocol_name = instance->base.protocol->name;
instance->encoder.repeat = 10;
instance->encoder.repeat = 3;
instance->encoder.size_upload = 512;
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
instance->encoder.is_running = false;
@@ -132,6 +132,10 @@ static bool
instance->generic.cnt = (data >> 24) & 0xFFFF;
instance->generic.serial = data & 0xFFFFFF;
// override button if we change it with signal settings button editor
if(subghz_block_generic_global_button_override_get(&instance->generic.btn))
FURI_LOG_D(TAG, "Button sucessfully changed to 0x%X", instance->generic.btn);
// Check for OFEX (overflow experimental) mode
if(furi_hal_subghz_get_rolling_counter_mult() != -0x7FFFFFFF) {
// standart counter mode. PULL data from subghz_block_generic_global variables
@@ -457,7 +461,7 @@ LevelDuration subghz_protocol_encoder_somfy_keytis_yield(void* context) {
LevelDuration ret = instance->encoder.upload[instance->encoder.front];
if(++instance->encoder.front == instance->encoder.size_upload) {
instance->encoder.repeat--;
if(!subghz_block_generic_global.endless_tx) instance->encoder.repeat--;
instance->encoder.front = 0;
}
@@ -803,13 +807,18 @@ void subghz_protocol_decoder_somfy_keytis_get_string(void* context, FuriString*
subghz_block_generic_global.cnt_length_bit = 16;
subghz_block_generic_global.current_cnt = instance->generic.cnt;
subghz_block_generic_global.btn_is_available = true;
subghz_block_generic_global.current_btn = instance->generic.btn;
subghz_block_generic_global.btn_length_bit = 4;
//
furi_string_cat_printf(
output,
"%s %db\r\n"
"%lX%08lX%06lX\r\n"
"Sn:0x%06lX \r\n"
"Cnt:%04lX\r\n"
"Btn:%s\r\n",
"Btn:%X - %s\r\n",
instance->generic.protocol_name,
instance->generic.data_count_bit,
@@ -818,5 +827,6 @@ void subghz_protocol_decoder_somfy_keytis_get_string(void* context, FuriString*
instance->press_duration_counter,
instance->generic.serial,
instance->generic.cnt,
instance->generic.btn,
subghz_protocol_somfy_keytis_get_name_button(instance->generic.btn));
}
+13 -3
View File
@@ -84,7 +84,7 @@ void* subghz_protocol_encoder_somfy_telis_alloc(SubGhzEnvironment* environment)
instance->base.protocol = &subghz_protocol_somfy_telis;
instance->generic.protocol_name = instance->base.protocol->name;
instance->encoder.repeat = 10;
instance->encoder.repeat = 3;
instance->encoder.size_upload = 512;
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
instance->encoder.is_running = false;
@@ -126,6 +126,10 @@ static bool subghz_protocol_somfy_telis_gen_data(
btn = subghz_protocol_somfy_telis_get_btn_code();
// override button if we change it with signal settings button editor
if(subghz_block_generic_global_button_override_get(&btn))
FURI_LOG_D(TAG, "Button sucessfully changed to 0x%X", btn);
// Check for OFEX (overflow experimental) mode
if(furi_hal_subghz_get_rolling_counter_mult() != -0x7FFFFFFF) {
// standart counter mode. PULL data from subghz_block_generic_global variables
@@ -386,7 +390,7 @@ LevelDuration subghz_protocol_encoder_somfy_telis_yield(void* context) {
LevelDuration ret = instance->encoder.upload[instance->encoder.front];
if(++instance->encoder.front == instance->encoder.size_upload) {
instance->encoder.repeat--;
if(!subghz_block_generic_global.endless_tx) instance->encoder.repeat--;
instance->encoder.front = 0;
}
@@ -760,13 +764,18 @@ void subghz_protocol_decoder_somfy_telis_get_string(void* context, FuriString* o
subghz_block_generic_global.cnt_length_bit = 16;
subghz_block_generic_global.current_cnt = instance->generic.cnt;
subghz_block_generic_global.btn_is_available = true;
subghz_block_generic_global.current_btn = instance->generic.btn;
subghz_block_generic_global.btn_length_bit = 4;
//
furi_string_cat_printf(
output,
"%s %db\r\n"
"Key:0x%lX%08lX\r\n"
"Sn:0x%06lX \r\n"
"Cnt:%04lX\r\n"
"Btn:%s\r\n",
"Btn:%X - %s\r\n",
instance->generic.protocol_name,
instance->generic.data_count_bit,
@@ -774,5 +783,6 @@ void subghz_protocol_decoder_somfy_telis_get_string(void* context, FuriString* o
(uint32_t)instance->generic.data,
instance->generic.serial,
instance->generic.cnt,
instance->generic.btn,
subghz_protocol_somfy_telis_get_name_button(instance->generic.btn));
}
+10 -3
View File
@@ -75,8 +75,8 @@ void* subghz_protocol_encoder_treadmill37_alloc(SubGhzEnvironment* environment)
instance->base.protocol = &subghz_protocol_treadmill37;
instance->generic.protocol_name = instance->base.protocol->name;
instance->encoder.repeat = 10;
instance->encoder.size_upload = 256;
instance->encoder.repeat = 3;
instance->encoder.size_upload = 128;
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
instance->encoder.is_running = false;
return instance;
@@ -181,7 +181,7 @@ LevelDuration subghz_protocol_encoder_treadmill37_yield(void* context) {
LevelDuration ret = instance->encoder.upload[instance->encoder.front];
if(++instance->encoder.front == instance->encoder.size_upload) {
instance->encoder.repeat--;
if(!subghz_block_generic_global.endless_tx) instance->encoder.repeat--;
instance->encoder.front = 0;
}
@@ -335,6 +335,13 @@ void subghz_protocol_decoder_treadmill37_get_string(void* context, FuriString* o
uint64_t code_found_reverse = subghz_protocol_blocks_reverse_key(
instance->generic.data, instance->generic.data_count_bit);
// for future use
// // push protocol data to global variable
// subghz_block_generic_global.btn_is_available = false;
// subghz_block_generic_global.current_btn = instance->generic.btn;
// subghz_block_generic_global.btn_length_bit = 4;
// //
furi_string_cat_printf(
output,
"%s %db\r\n"
+2
View File
@@ -3618,6 +3618,8 @@ Function,+,subghz_app,int32_t,char*
Function,+,subghz_block_generic_deserialize,SubGhzProtocolStatus,"SubGhzBlockGeneric*, FlipperFormat*"
Function,+,subghz_block_generic_deserialize_check_count_bit,SubGhzProtocolStatus,"SubGhzBlockGeneric*, FlipperFormat*, uint16_t"
Function,+,subghz_block_generic_get_preset_name,void,"const char*, FuriString*"
Function,+,subghz_block_generic_global_button_override_get,_Bool,uint8_t*
Function,+,subghz_block_generic_global_button_override_set,void,uint8_t
Function,+,subghz_block_generic_global_counter_override_get,_Bool,uint32_t*
Function,+,subghz_block_generic_global_counter_override_set,void,uint32_t
Function,+,subghz_block_generic_global_reset,void,void*
1 entry status name type params
3618 Function + subghz_block_generic_deserialize SubGhzProtocolStatus SubGhzBlockGeneric*, FlipperFormat*
3619 Function + subghz_block_generic_deserialize_check_count_bit SubGhzProtocolStatus SubGhzBlockGeneric*, FlipperFormat*, uint16_t
3620 Function + subghz_block_generic_get_preset_name void const char*, FuriString*
3621 Function + subghz_block_generic_global_button_override_get _Bool uint8_t*
3622 Function + subghz_block_generic_global_button_override_set void uint8_t
3623 Function + subghz_block_generic_global_counter_override_get _Bool uint32_t*
3624 Function + subghz_block_generic_global_counter_override_set void uint32_t
3625 Function + subghz_block_generic_global_reset void void*
+4 -2
View File
@@ -699,10 +699,12 @@ static inline uint32_t furi_hal_subghz_async_tx_middleware_get_duration(
}
}
}
// here we fill DMA buffer by signal durations until we recieve duration=0 (that mean protocol give as full data = signal_size*repeats)
// or until we reach the end of required samples count
static void furi_hal_subghz_async_tx_refill(uint32_t* buffer, size_t samples) {
furi_check(furi_hal_subghz.state == SubGhzStateAsyncTx);
// furi_hal_subghz_async_tx.callback - linked to protocols "_yield" function
// and return one current LevelDuration from protocol upload buffer.
while(samples > 0) {
volatile uint32_t duration = furi_hal_subghz_async_tx_middleware_get_duration(
&furi_hal_subghz_async_tx.middleware, furi_hal_subghz_async_tx.callback);