mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-04-24 03:29:57 -07:00
Merge remote-tracking branch 'ul/dev' into mntm-dev --nobuild
This commit is contained in:
@@ -17,6 +17,7 @@ typedef enum {
|
|||||||
SubGhzCustomEventSceneReceiverInfoSave,
|
SubGhzCustomEventSceneReceiverInfoSave,
|
||||||
SubGhzCustomEventSceneReceiverInfoSats,
|
SubGhzCustomEventSceneReceiverInfoSats,
|
||||||
SubGhzCustomEventSceneSaveName,
|
SubGhzCustomEventSceneSaveName,
|
||||||
|
SubGhzCustomEventSceneSignalSettings,
|
||||||
SubGhzCustomEventSceneSaveSuccess,
|
SubGhzCustomEventSceneSaveSuccess,
|
||||||
SubGhzCustomEventSceneShowErrorBack,
|
SubGhzCustomEventSceneShowErrorBack,
|
||||||
SubGhzCustomEventSceneShowErrorOk,
|
SubGhzCustomEventSceneShowErrorOk,
|
||||||
|
|||||||
@@ -26,3 +26,4 @@ ADD_SCENE(subghz, delete_raw, DeleteRAW)
|
|||||||
ADD_SCENE(subghz, need_saving, NeedSaving)
|
ADD_SCENE(subghz, need_saving, NeedSaving)
|
||||||
ADD_SCENE(subghz, rpc, Rpc)
|
ADD_SCENE(subghz, rpc, Rpc)
|
||||||
ADD_SCENE(subghz, show_gps, ShowGps)
|
ADD_SCENE(subghz, show_gps, ShowGps)
|
||||||
|
ADD_SCENE(subghz, signal_settings, SignalSettings)
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ enum SubmenuIndex {
|
|||||||
SubmenuIndexEdit,
|
SubmenuIndexEdit,
|
||||||
SubmenuIndexDelete,
|
SubmenuIndexDelete,
|
||||||
SubmenuIndexGeo,
|
SubmenuIndexGeo,
|
||||||
|
SubmenuIndexSignalSettings,
|
||||||
};
|
};
|
||||||
|
|
||||||
void subghz_scene_saved_menu_submenu_callback(void* context, uint32_t index) {
|
void subghz_scene_saved_menu_submenu_callback(void* context, uint32_t index) {
|
||||||
@@ -45,6 +46,18 @@ void subghz_scene_saved_menu_on_enter(void* context) {
|
|||||||
subghz);
|
subghz);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
submenu_add_lockable_item(
|
||||||
|
subghz->submenu,
|
||||||
|
"Signal Settings",
|
||||||
|
SubmenuIndexSignalSettings,
|
||||||
|
subghz_scene_saved_menu_submenu_callback,
|
||||||
|
subghz,
|
||||||
|
!furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug),
|
||||||
|
"Enable\n"
|
||||||
|
"Settings >\n"
|
||||||
|
"System >\n"
|
||||||
|
"Debug");
|
||||||
|
|
||||||
submenu_set_selected_item(
|
submenu_set_selected_item(
|
||||||
subghz->submenu,
|
subghz->submenu,
|
||||||
scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneSavedMenu));
|
scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneSavedMenu));
|
||||||
@@ -77,6 +90,11 @@ bool subghz_scene_saved_menu_on_event(void* context, SceneManagerEvent event) {
|
|||||||
scene_manager_set_scene_state(subghz->scene_manager, SubGhzSceneShowGps, true);
|
scene_manager_set_scene_state(subghz->scene_manager, SubGhzSceneShowGps, true);
|
||||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowGps);
|
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowGps);
|
||||||
return true;
|
return true;
|
||||||
|
} else if(event.event == SubmenuIndexSignalSettings) {
|
||||||
|
scene_manager_set_scene_state(
|
||||||
|
subghz->scene_manager, SubGhzSceneSavedMenu, SubmenuIndexSignalSettings);
|
||||||
|
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSignalSettings);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
157
applications/main/subghz/scenes/subghz_scene_signal_settings.c
Normal file
157
applications/main/subghz/scenes/subghz_scene_signal_settings.c
Normal file
@@ -0,0 +1,157 @@
|
|||||||
|
#include "../subghz_i.h"
|
||||||
|
#include "subghz/types.h"
|
||||||
|
#include "../helpers/subghz_custom_event.h"
|
||||||
|
#include <lib/toolbox/value_index.h>
|
||||||
|
|
||||||
|
#define TAG "SubGhzSceneSignalSettings"
|
||||||
|
|
||||||
|
static uint32_t counter_mode = 0xff;
|
||||||
|
|
||||||
|
#define COUNTER_MODE_COUNT 7
|
||||||
|
static const char* const counter_mode_text[COUNTER_MODE_COUNT] = {
|
||||||
|
"System",
|
||||||
|
"Mode 1",
|
||||||
|
"Mode 2",
|
||||||
|
"Mode 3",
|
||||||
|
"Mode 4",
|
||||||
|
"Mode 5",
|
||||||
|
"Mode 6",
|
||||||
|
};
|
||||||
|
|
||||||
|
static const int32_t counter_mode_value[COUNTER_MODE_COUNT] = {
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3,
|
||||||
|
4,
|
||||||
|
5,
|
||||||
|
6,
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char* name;
|
||||||
|
uint8_t mode_count;
|
||||||
|
} Protocols;
|
||||||
|
|
||||||
|
// List of protocols names and appropriate CounterMode counts
|
||||||
|
static Protocols protocols[] = {
|
||||||
|
{"Nice FloR-S", 3},
|
||||||
|
{"CAME Atomo", 4},
|
||||||
|
{"Alutech AT-4N", 3},
|
||||||
|
{"KeeLoq", 7},
|
||||||
|
};
|
||||||
|
|
||||||
|
#define PROTOCOLS_COUNT (sizeof(protocols) / sizeof(Protocols));
|
||||||
|
|
||||||
|
void subghz_scene_signal_settings_counter_mode_changed(VariableItem* item) {
|
||||||
|
uint8_t index = variable_item_get_current_value_index(item);
|
||||||
|
variable_item_set_current_value_text(item, counter_mode_text[index]);
|
||||||
|
counter_mode = counter_mode_value[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
void subghz_scene_signal_settings_on_enter(void* context) {
|
||||||
|
// When we open saved file we do some check and fill up subghz->file_path.
|
||||||
|
// So now we use it to check is there CounterMode in file or not
|
||||||
|
SubGhz* subghz = context;
|
||||||
|
|
||||||
|
const char* file_path = furi_string_get_cstr(subghz->file_path);
|
||||||
|
|
||||||
|
furi_assert(subghz);
|
||||||
|
furi_assert(file_path);
|
||||||
|
|
||||||
|
Storage* storage = furi_record_open(RECORD_STORAGE);
|
||||||
|
FlipperFormat* fff_data_file = flipper_format_file_alloc(storage);
|
||||||
|
FuriString* tmp_string = furi_string_alloc();
|
||||||
|
|
||||||
|
uint32_t tmp_counter_mode = 0;
|
||||||
|
counter_mode = 0xff;
|
||||||
|
uint8_t mode_count = 1;
|
||||||
|
|
||||||
|
// Open file and check is it contains allowed protocols and CounterMode variable - if not then CcounterMode will stay 0xff
|
||||||
|
// if file contain allowed protocol but not contain CounterMode value then setup default CounterMode value = 0 and available CounterMode count for this protocol
|
||||||
|
// if file contain CounterMode value then load it
|
||||||
|
if(!flipper_format_file_open_existing(fff_data_file, file_path)) {
|
||||||
|
FURI_LOG_E(TAG, "Error open file %s", file_path);
|
||||||
|
} else {
|
||||||
|
flipper_format_read_string(fff_data_file, "Protocol", tmp_string);
|
||||||
|
// compare available protocols names, load CounterMode value from file and setup variable_item_list values_count
|
||||||
|
for(uint8_t i = 0; i < PROTOCOLS_COUNT i++) {
|
||||||
|
if(!strcmp(furi_string_get_cstr(tmp_string), protocols[i].name)) {
|
||||||
|
mode_count = protocols[i].mode_count;
|
||||||
|
if(flipper_format_read_uint32(fff_data_file, "CounterMode", &tmp_counter_mode, 1)) {
|
||||||
|
counter_mode = (uint8_t)tmp_counter_mode;
|
||||||
|
} else {
|
||||||
|
counter_mode = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FURI_LOG_D(TAG, "Current CounterMode value %li", counter_mode);
|
||||||
|
|
||||||
|
furi_string_free(tmp_string);
|
||||||
|
flipper_format_file_close(fff_data_file);
|
||||||
|
flipper_format_free(fff_data_file);
|
||||||
|
furi_record_close(RECORD_STORAGE);
|
||||||
|
|
||||||
|
//Create and Enable/Disable variable_item_list depent from current CounterMode value
|
||||||
|
VariableItemList* variable_item_list = subghz->variable_item_list;
|
||||||
|
int32_t value_index;
|
||||||
|
VariableItem* item;
|
||||||
|
|
||||||
|
item = variable_item_list_add(
|
||||||
|
variable_item_list,
|
||||||
|
"Counter Mode",
|
||||||
|
mode_count,
|
||||||
|
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 !");
|
||||||
|
|
||||||
|
view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdVariableItemList);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool subghz_scene_signal_settings_on_event(void* context, SceneManagerEvent event) {
|
||||||
|
SubGhz* subghz = context;
|
||||||
|
if(event.type == SceneManagerEventTypeBack) {
|
||||||
|
scene_manager_previous_scene(subghz->scene_manager);
|
||||||
|
return true;
|
||||||
|
} else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void subghz_scene_signal_settings_on_exit(void* context) {
|
||||||
|
SubGhz* subghz = context;
|
||||||
|
const char* file_path = furi_string_get_cstr(subghz->file_path);
|
||||||
|
|
||||||
|
furi_assert(subghz);
|
||||||
|
furi_assert(file_path);
|
||||||
|
|
||||||
|
// if ConterMode was changed from 0xff then we must update or write new value to file
|
||||||
|
if(counter_mode != 0xff) {
|
||||||
|
Storage* storage = furi_record_open(RECORD_STORAGE);
|
||||||
|
FlipperFormat* fff_data_file = flipper_format_file_alloc(storage);
|
||||||
|
|
||||||
|
// check is the file available for update/insert CounterMode value
|
||||||
|
if(flipper_format_file_open_existing(fff_data_file, file_path)) {
|
||||||
|
if(flipper_format_insert_or_update_uint32(
|
||||||
|
fff_data_file, "CounterMode", &counter_mode, 1)) {
|
||||||
|
FURI_LOG_D(
|
||||||
|
TAG, "Successfully updated/inserted CounterMode value %li", counter_mode);
|
||||||
|
} else {
|
||||||
|
FURI_LOG_E(TAG, "Error update/insert CounterMode value");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
FURI_LOG_E(TAG, "Error open file %s for writing", file_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
flipper_format_file_close(fff_data_file);
|
||||||
|
flipper_format_free(fff_data_file);
|
||||||
|
furi_record_close(RECORD_STORAGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
variable_item_list_set_selected_item(subghz->variable_item_list, 0);
|
||||||
|
variable_item_list_reset(subghz->variable_item_list);
|
||||||
|
}
|
||||||
201
documentation/SubGHzCounterMode.md
Normal file
201
documentation/SubGHzCounterMode.md
Normal file
@@ -0,0 +1,201 @@
|
|||||||
|
# SubGHz Counter Experimental Mode
|
||||||
|
|
||||||
|
Credit to [Unleashed Firmware](https://github.com/DarkFlippers/unleashed-firmware) team for documentation and the feature itself
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
Experimental Counter Mode is an advanced feature that allows you to customize how rolling codes increment when transmitting SubGHz signals. Different protocols support different counter modes, which can be useful for specific cases, main purpose is to make clone of the original remote that will not conflict with original remote, so both Flipper and original remote can be used at same time in rolling code systems without desync or other issues.
|
||||||
|
|
||||||
|
**Be aware, do not experiment with equipment you don't have access to, if you are not sure what mode works for you and can't reprogram your original remote to the receiver - do not use these modes!!!**
|
||||||
|
|
||||||
|
In case you have access to the receiver and can do some tests, try some of these modes on your system and let us know how it works for you, in github issues or our communities, thanks!
|
||||||
|
|
||||||
|
## How to Use Experimental Counter Mode
|
||||||
|
|
||||||
|
To enable a specific counter mode, you need to manually edit your `.sub` file and add a `CounterMode` line.
|
||||||
|
|
||||||
|
### Steps:
|
||||||
|
|
||||||
|
1. Locate your `.sub` file (in `/ext/subghz/` on your Flipper Zero SD card)
|
||||||
|
2. Open the file in a text editor
|
||||||
|
3. Add the following line at the end of the file:
|
||||||
|
```
|
||||||
|
CounterMode: X
|
||||||
|
```
|
||||||
|
Where `X` is the mode number (0, 1, 2, etc.)
|
||||||
|
|
||||||
|
### Example .sub File:
|
||||||
|
|
||||||
|
```
|
||||||
|
Filetype: Flipper SubGhz Key File
|
||||||
|
Version: 1
|
||||||
|
Frequency: 433920000
|
||||||
|
Preset: FuriHalSubGhzPresetOok650Async
|
||||||
|
Protocol: Nice FloR-S
|
||||||
|
Bit: 52
|
||||||
|
Key: AA AA AA AA AA AA AA
|
||||||
|
CounterMode: 1
|
||||||
|
```
|
||||||
|
|
||||||
|
## Supported Protocols and Counter Modes
|
||||||
|
|
||||||
|
### 1. Nice Flor S
|
||||||
|
|
||||||
|
**Mode 0 (Default):**
|
||||||
|
- Standard - acts like regular remote
|
||||||
|
- Uses rolling counter multiplier from global settings (default +1)
|
||||||
|
- Counter increments based on the multiplier value (default +1)
|
||||||
|
- Resets to 0 when overflow occurs (> 0xFFFF)
|
||||||
|
|
||||||
|
**Mode 1 (floxi2r):**
|
||||||
|
- Counter sequence: `0x0001 / 0xFFFE`
|
||||||
|
- For receiver model floxi2r
|
||||||
|
|
||||||
|
**Mode 2 (ox2):**
|
||||||
|
- Counter sequence: `0x0000 / 0x0001`
|
||||||
|
- For receiver model ox2
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 2. Came Atomo
|
||||||
|
|
||||||
|
**Mode 0 (Default):**
|
||||||
|
- Standard - acts like regular remote
|
||||||
|
- Uses rolling counter multiplier from global settings (default +1)
|
||||||
|
- Counter increments based on the multiplier value (default +1)
|
||||||
|
- Resets to 0 when overflow occurs (> 0xFFFF)
|
||||||
|
|
||||||
|
**Mode 1:**
|
||||||
|
- Counter sequence: `0x0000 / 0x0001 / 0xFFFE / 0xFFFF`
|
||||||
|
- Works with external CAME RE432 receiver, may work with other type of receivers
|
||||||
|
|
||||||
|
**Mode 2:**
|
||||||
|
- Counter sequence: `0x807B / 0x807C / 0x007B / 0x007C`
|
||||||
|
- Works with external CAME RE432 receiver, may work with other type of receivers
|
||||||
|
|
||||||
|
**Mode 3:**
|
||||||
|
- Counter freeze - do not increment
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 3. Alutech AT-4N
|
||||||
|
|
||||||
|
**Mode 0 (Default):**
|
||||||
|
- Standard - acts like regular remote
|
||||||
|
- Uses rolling counter multiplier from global settings (default +1)
|
||||||
|
- Counter increments based on the multiplier value (default +1)
|
||||||
|
- Resets to 0 when overflow occurs (> 0xFFFF)
|
||||||
|
|
||||||
|
**Mode 1:**
|
||||||
|
- Counter sequence: `0x0000 / 0x0001 / 0xFFFE / 0xFFFF`
|
||||||
|
- For receiver model MCSW-3.3M
|
||||||
|
|
||||||
|
**Mode 2:**
|
||||||
|
- Counter sequence: `0x0000 / 0x0001 / 0x0002 / 0x0003 / 0x0004 / 0x0005`
|
||||||
|
- For other receiver boards
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 4. KeeLoq
|
||||||
|
|
||||||
|
**Mode 0 (Default):**
|
||||||
|
- Standard - acts like regular remote
|
||||||
|
- Uses rolling counter multiplier from global settings (default +1)
|
||||||
|
- Counter increments based on the multiplier value (default +1)
|
||||||
|
- Resets to 0 when overflow occurs (> 0xFFFF)
|
||||||
|
|
||||||
|
**Mode 1:**
|
||||||
|
- Counter sequence: `0x0000 / 0x0001 / 0xFFFE / 0xFFFF`
|
||||||
|
- Might work with some systems (let us know!)
|
||||||
|
|
||||||
|
**Mode 2:**
|
||||||
|
- Incremental mode: `+0x3333` each transmission
|
||||||
|
- Adds 0x3333 (13107 in decimal) to counter each time
|
||||||
|
- Might work with Doorhan, seen in some "universal remotes"
|
||||||
|
|
||||||
|
**Mode 3:**
|
||||||
|
- Counter sequence: `0x8006 / 0x8007 / 0x0006 / 0x0007`
|
||||||
|
- Might work with some systems like Hormann EcoStar
|
||||||
|
|
||||||
|
**Mode 4:**
|
||||||
|
- Counter sequence: `0x807B / 0x807C / 0x007B / 0x007C`
|
||||||
|
- Might work with some systems like Nice Smilo
|
||||||
|
|
||||||
|
**Mode 5:**
|
||||||
|
- Counter sequence: `0x0000 / 0xFFFF`
|
||||||
|
- Alternates between 0 and maximum value (65535)
|
||||||
|
- Might work with some systems (let us know!)
|
||||||
|
|
||||||
|
**Mode 6:**
|
||||||
|
- Counter freeze - do not increment
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Notes and Warnings
|
||||||
|
|
||||||
|
### Important Considerations:
|
||||||
|
|
||||||
|
1. **Default Behavior:**
|
||||||
|
- If you don't specify a `CounterMode`, Regular remote simulation (cnt +1) is used by default
|
||||||
|
- Regular remote simulation is the standard mode and works with most cases
|
||||||
|
|
||||||
|
2. **Protocol Compatibility:**
|
||||||
|
- Not all protocols support all counter modes
|
||||||
|
- Using an unsupported mode number may result in unexpected behavior
|
||||||
|
- Always test your configuration before relying on it
|
||||||
|
|
||||||
|
### Troubleshooting:
|
||||||
|
|
||||||
|
- If your file doesn't work after adding `CounterMode`:
|
||||||
|
1. Double-check the syntax: `CounterMode: X` (with space after colon)
|
||||||
|
2. Verify the mode number is valid for your protocol
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Example Configurations
|
||||||
|
|
||||||
|
### Example 1: Nice Flor S with Mode 1
|
||||||
|
```
|
||||||
|
Filetype: Flipper SubGhz Key File
|
||||||
|
Version: 1
|
||||||
|
Frequency: 433920000
|
||||||
|
Preset: FuriHalSubGhzPresetOok650Async
|
||||||
|
Protocol: Nice FloR-S
|
||||||
|
Bit: 52
|
||||||
|
Key: 01 23 45 67 89 AB CD
|
||||||
|
CounterMode: 1
|
||||||
|
```
|
||||||
|
|
||||||
|
### Example 2: KeeLoq with Mode 2 (+0x3333 (Doorhan))
|
||||||
|
```
|
||||||
|
Filetype: Flipper SubGhz Key File
|
||||||
|
Version: 1
|
||||||
|
Frequency: 433920000
|
||||||
|
Preset: FuriHalSubGhzPresetOok650Async
|
||||||
|
Protocol: KeeLoq
|
||||||
|
Bit: 64
|
||||||
|
Key: DE AD BE EF CA FE BA BE
|
||||||
|
Manufacture: Doorhan
|
||||||
|
CounterMode: 2
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## FAQ
|
||||||
|
|
||||||
|
**Q: Will this damage my remote or receiver?**
|
||||||
|
A: Yes it may do that - depending on the receiver, it may desync your remote, be aware and don't experiment with equipment you don't have access to
|
||||||
|
|
||||||
|
**Q: Which mode should I use?**
|
||||||
|
A: Do not use those mods if you are not sure
|
||||||
|
|
||||||
|
**Q: What happens if I use an invalid mode number?**
|
||||||
|
A: Last mode from the list will be used
|
||||||
|
|
||||||
|
**Q: Do I need to add CounterMode to every .sub file?**
|
||||||
|
A: No, only add it if you need non-default behavior. Mode 0 is automatic if not specified.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*Made for Unleashed FW, please mention source when copying*
|
||||||
@@ -47,6 +47,8 @@ typedef enum {
|
|||||||
Alutech_at_4nDecoderStepCheckDuration,
|
Alutech_at_4nDecoderStepCheckDuration,
|
||||||
} Alutech_at_4nDecoderStep;
|
} Alutech_at_4nDecoderStep;
|
||||||
|
|
||||||
|
static uint8_t alutech_at4n_counter_mode = 0;
|
||||||
|
|
||||||
const SubGhzProtocolDecoder subghz_protocol_alutech_at_4n_decoder = {
|
const SubGhzProtocolDecoder subghz_protocol_alutech_at_4n_decoder = {
|
||||||
.alloc = subghz_protocol_decoder_alutech_at_4n_alloc,
|
.alloc = subghz_protocol_decoder_alutech_at_4n_alloc,
|
||||||
.free = subghz_protocol_decoder_alutech_at_4n_free,
|
.free = subghz_protocol_decoder_alutech_at_4n_free,
|
||||||
@@ -275,24 +277,44 @@ static bool subghz_protocol_alutech_at_4n_gen_data(
|
|||||||
instance->generic.serial = (uint32_t)(data >> 24) & 0xFFFFFFFF;
|
instance->generic.serial = (uint32_t)(data >> 24) & 0xFFFFFFFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for OFEX (overflow experimental) mode
|
if(alutech_at4n_counter_mode == 0) {
|
||||||
if(furi_hal_subghz_get_rolling_counter_mult() != 0xFFFE) {
|
// Check for OFEX (overflow experimental) mode
|
||||||
if(instance->generic.cnt < 0xFFFF) {
|
if(furi_hal_subghz_get_rolling_counter_mult() != 0xFFFE) {
|
||||||
if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) > 0xFFFF) {
|
if(instance->generic.cnt < 0xFFFF) {
|
||||||
|
if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) > 0xFFFF) {
|
||||||
|
instance->generic.cnt = 0;
|
||||||
|
} else {
|
||||||
|
instance->generic.cnt += furi_hal_subghz_get_rolling_counter_mult();
|
||||||
|
}
|
||||||
|
} else if(
|
||||||
|
(instance->generic.cnt >= 0xFFFF) &&
|
||||||
|
(furi_hal_subghz_get_rolling_counter_mult() != 0)) {
|
||||||
instance->generic.cnt = 0;
|
instance->generic.cnt = 0;
|
||||||
} else {
|
|
||||||
instance->generic.cnt += furi_hal_subghz_get_rolling_counter_mult();
|
|
||||||
}
|
}
|
||||||
} else if(
|
} else {
|
||||||
(instance->generic.cnt >= 0xFFFF) &&
|
if((instance->generic.cnt + 0x1) > 0xFFFF) {
|
||||||
(furi_hal_subghz_get_rolling_counter_mult() != 0)) {
|
instance->generic.cnt = 0;
|
||||||
instance->generic.cnt = 0;
|
} else if(instance->generic.cnt >= 0x1 && instance->generic.cnt != 0xFFFE) {
|
||||||
|
instance->generic.cnt = furi_hal_subghz_get_rolling_counter_mult();
|
||||||
|
} else {
|
||||||
|
instance->generic.cnt++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else if(alutech_at4n_counter_mode == 1) {
|
||||||
|
// Mode 1
|
||||||
|
// 0000 / 0001 / FFFE / FFFF
|
||||||
if((instance->generic.cnt + 0x1) > 0xFFFF) {
|
if((instance->generic.cnt + 0x1) > 0xFFFF) {
|
||||||
instance->generic.cnt = 0;
|
instance->generic.cnt = 0;
|
||||||
} else if(instance->generic.cnt >= 0x1 && instance->generic.cnt != 0xFFFE) {
|
} else if(instance->generic.cnt >= 0x1 && instance->generic.cnt != 0xFFFE) {
|
||||||
instance->generic.cnt = furi_hal_subghz_get_rolling_counter_mult();
|
instance->generic.cnt = 0xFFFE;
|
||||||
|
} else {
|
||||||
|
instance->generic.cnt++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Mode 2
|
||||||
|
// 0x0000 / 0x0001 / 0x0002 / 0x0003 / 0x0004 / 0x0005
|
||||||
|
if(instance->generic.cnt >= 0x0005) {
|
||||||
|
instance->generic.cnt = 0;
|
||||||
} else {
|
} else {
|
||||||
instance->generic.cnt++;
|
instance->generic.cnt++;
|
||||||
}
|
}
|
||||||
@@ -449,6 +471,18 @@ SubGhzProtocolStatus subghz_protocol_encoder_alutech_at_4n_deserialize(
|
|||||||
flipper_format_read_uint32(
|
flipper_format_read_uint32(
|
||||||
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
|
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
|
||||||
|
|
||||||
|
if(!flipper_format_rewind(flipper_format)) {
|
||||||
|
FURI_LOG_E(TAG, "Rewind error");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t tmp_counter_mode;
|
||||||
|
if(flipper_format_read_uint32(flipper_format, "CounterMode", &tmp_counter_mode, 1)) {
|
||||||
|
alutech_at4n_counter_mode = (uint8_t)tmp_counter_mode;
|
||||||
|
} else {
|
||||||
|
alutech_at4n_counter_mode = 0;
|
||||||
|
}
|
||||||
|
|
||||||
subghz_protocol_alutech_at_4n_remote_controller(
|
subghz_protocol_alutech_at_4n_remote_controller(
|
||||||
&instance->generic, instance->crc, instance->alutech_at_4n_rainbow_table_file_name);
|
&instance->generic, instance->crc, instance->alutech_at_4n_rainbow_table_file_name);
|
||||||
|
|
||||||
@@ -722,6 +756,18 @@ SubGhzProtocolStatus subghz_protocol_decoder_alutech_at_4n_deserialize(
|
|||||||
ret = SubGhzProtocolStatusErrorParserOthers;
|
ret = SubGhzProtocolStatusErrorParserOthers;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if(!flipper_format_rewind(flipper_format)) {
|
||||||
|
FURI_LOG_E(TAG, "Rewind error");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t tmp_counter_mode;
|
||||||
|
if(flipper_format_read_uint32(flipper_format, "CounterMode", &tmp_counter_mode, 1)) {
|
||||||
|
alutech_at4n_counter_mode = (uint8_t)tmp_counter_mode;
|
||||||
|
} else {
|
||||||
|
alutech_at4n_counter_mode = 0;
|
||||||
|
}
|
||||||
|
|
||||||
} while(false);
|
} while(false);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,6 +39,8 @@ typedef enum {
|
|||||||
CameAtomoDecoderStepDecoderData,
|
CameAtomoDecoderStepDecoderData,
|
||||||
} CameAtomoDecoderStep;
|
} CameAtomoDecoderStep;
|
||||||
|
|
||||||
|
static uint8_t came_atomo_counter_mode = 0;
|
||||||
|
|
||||||
const SubGhzProtocolDecoder subghz_protocol_came_atomo_decoder = {
|
const SubGhzProtocolDecoder subghz_protocol_came_atomo_decoder = {
|
||||||
.alloc = subghz_protocol_decoder_came_atomo_alloc,
|
.alloc = subghz_protocol_decoder_came_atomo_alloc,
|
||||||
.free = subghz_protocol_decoder_came_atomo_free,
|
.free = subghz_protocol_decoder_came_atomo_free,
|
||||||
@@ -187,27 +189,52 @@ static void subghz_protocol_encoder_came_atomo_get_upload(
|
|||||||
|
|
||||||
uint8_t pack[8] = {};
|
uint8_t pack[8] = {};
|
||||||
|
|
||||||
// Check for OFEX (overflow experimental) mode
|
if(came_atomo_counter_mode == 0) {
|
||||||
if(furi_hal_subghz_get_rolling_counter_mult() != 0xFFFE) {
|
// Check for OFEX (overflow experimental) mode
|
||||||
if(instance->generic.cnt < 0xFFFF) {
|
if(furi_hal_subghz_get_rolling_counter_mult() != 0xFFFE) {
|
||||||
if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) > 0xFFFF) {
|
if(instance->generic.cnt < 0xFFFF) {
|
||||||
|
if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) > 0xFFFF) {
|
||||||
|
instance->generic.cnt = 0;
|
||||||
|
} else {
|
||||||
|
instance->generic.cnt += furi_hal_subghz_get_rolling_counter_mult();
|
||||||
|
}
|
||||||
|
} else if(
|
||||||
|
(instance->generic.cnt >= 0xFFFF) &&
|
||||||
|
(furi_hal_subghz_get_rolling_counter_mult() != 0)) {
|
||||||
instance->generic.cnt = 0;
|
instance->generic.cnt = 0;
|
||||||
} else {
|
|
||||||
instance->generic.cnt += furi_hal_subghz_get_rolling_counter_mult();
|
|
||||||
}
|
}
|
||||||
} else if(
|
} else {
|
||||||
(instance->generic.cnt >= 0xFFFF) &&
|
if((instance->generic.cnt + 0x1) > 0xFFFF) {
|
||||||
(furi_hal_subghz_get_rolling_counter_mult() != 0)) {
|
instance->generic.cnt = 0;
|
||||||
instance->generic.cnt = 0;
|
} else if(instance->generic.cnt >= 0x1 && instance->generic.cnt != 0xFFFE) {
|
||||||
|
instance->generic.cnt = furi_hal_subghz_get_rolling_counter_mult();
|
||||||
|
} else {
|
||||||
|
instance->generic.cnt++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else if(came_atomo_counter_mode == 1) {
|
||||||
|
// Mode 1
|
||||||
|
// 0000 / 0001 / FFFE / FFFF
|
||||||
if((instance->generic.cnt + 0x1) > 0xFFFF) {
|
if((instance->generic.cnt + 0x1) > 0xFFFF) {
|
||||||
instance->generic.cnt = 0;
|
instance->generic.cnt = 0;
|
||||||
} else if(instance->generic.cnt >= 0x1 && instance->generic.cnt != 0xFFFE) {
|
} else if(instance->generic.cnt >= 0x1 && instance->generic.cnt != 0xFFFE) {
|
||||||
instance->generic.cnt = furi_hal_subghz_get_rolling_counter_mult();
|
instance->generic.cnt = 0xFFFE;
|
||||||
} else {
|
} else {
|
||||||
instance->generic.cnt++;
|
instance->generic.cnt++;
|
||||||
}
|
}
|
||||||
|
} else if(came_atomo_counter_mode == 2) {
|
||||||
|
// Mode 2
|
||||||
|
// 0x807B / 0x807C / 0x007B / 0x007C
|
||||||
|
if(instance->generic.cnt != 0x807B && instance->generic.cnt != 0x807C &&
|
||||||
|
instance->generic.cnt != 0x007B) {
|
||||||
|
instance->generic.cnt = 0x807B;
|
||||||
|
} else if(instance->generic.cnt == 0x807C) {
|
||||||
|
instance->generic.cnt = 0x007B;
|
||||||
|
} else {
|
||||||
|
instance->generic.cnt++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Mode 3 - Freeze counter
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save original button for later use
|
// Save original button for later use
|
||||||
@@ -354,6 +381,18 @@ SubGhzProtocolStatus
|
|||||||
flipper_format_read_uint32(
|
flipper_format_read_uint32(
|
||||||
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
|
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
|
||||||
|
|
||||||
|
if(!flipper_format_rewind(flipper_format)) {
|
||||||
|
FURI_LOG_E(TAG, "Rewind error");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t tmp_counter_mode;
|
||||||
|
if(flipper_format_read_uint32(flipper_format, "CounterMode", &tmp_counter_mode, 1)) {
|
||||||
|
came_atomo_counter_mode = (uint8_t)tmp_counter_mode;
|
||||||
|
} else {
|
||||||
|
came_atomo_counter_mode = 0;
|
||||||
|
}
|
||||||
|
|
||||||
subghz_protocol_came_atomo_remote_controller(&instance->generic);
|
subghz_protocol_came_atomo_remote_controller(&instance->generic);
|
||||||
subghz_protocol_encoder_came_atomo_get_upload(instance, instance->generic.btn);
|
subghz_protocol_encoder_came_atomo_get_upload(instance, instance->generic.btn);
|
||||||
|
|
||||||
@@ -754,10 +793,32 @@ SubGhzProtocolStatus
|
|||||||
subghz_protocol_decoder_came_atomo_deserialize(void* context, FlipperFormat* flipper_format) {
|
subghz_protocol_decoder_came_atomo_deserialize(void* context, FlipperFormat* flipper_format) {
|
||||||
furi_assert(context);
|
furi_assert(context);
|
||||||
SubGhzProtocolDecoderCameAtomo* instance = context;
|
SubGhzProtocolDecoderCameAtomo* instance = context;
|
||||||
return subghz_block_generic_deserialize_check_count_bit(
|
|
||||||
&instance->generic,
|
SubGhzProtocolStatus status = SubGhzProtocolStatusOk;
|
||||||
flipper_format,
|
status = subghz_block_generic_deserialize(&instance->generic, flipper_format);
|
||||||
subghz_protocol_came_atomo_const.min_count_bit_for_found);
|
if(status != SubGhzProtocolStatusOk) {
|
||||||
|
FURI_LOG_E(TAG, "Deserialize error");
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
if(instance->generic.data_count_bit !=
|
||||||
|
subghz_protocol_came_atomo_const.min_count_bit_for_found) {
|
||||||
|
FURI_LOG_E(TAG, "Wrong number of bits in key");
|
||||||
|
return SubGhzProtocolStatusErrorValueBitCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!flipper_format_rewind(flipper_format)) {
|
||||||
|
FURI_LOG_E(TAG, "Rewind error");
|
||||||
|
return SubGhzProtocolStatusError;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t tmp_counter_mode;
|
||||||
|
if(flipper_format_read_uint32(flipper_format, "CounterMode", &tmp_counter_mode, 1)) {
|
||||||
|
came_atomo_counter_mode = (uint8_t)tmp_counter_mode;
|
||||||
|
} else {
|
||||||
|
came_atomo_counter_mode = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
void subghz_protocol_decoder_came_atomo_get_string(void* context, FuriString* output) {
|
void subghz_protocol_decoder_came_atomo_get_string(void* context, FuriString* output) {
|
||||||
|
|||||||
@@ -54,6 +54,8 @@ typedef enum {
|
|||||||
KeeloqDecoderStepCheckDuration,
|
KeeloqDecoderStepCheckDuration,
|
||||||
} KeeloqDecoderStep;
|
} KeeloqDecoderStep;
|
||||||
|
|
||||||
|
static uint8_t keeloq_counter_mode = 0;
|
||||||
|
|
||||||
const SubGhzProtocolDecoder subghz_protocol_keeloq_decoder = {
|
const SubGhzProtocolDecoder subghz_protocol_keeloq_decoder = {
|
||||||
.alloc = subghz_protocol_decoder_keeloq_alloc,
|
.alloc = subghz_protocol_decoder_keeloq_alloc,
|
||||||
.free = subghz_protocol_decoder_keeloq_free,
|
.free = subghz_protocol_decoder_keeloq_free,
|
||||||
@@ -184,29 +186,83 @@ static bool subghz_protocol_keeloq_gen_data(
|
|||||||
if(counter_up && prog_mode == PROG_MODE_OFF) {
|
if(counter_up && prog_mode == PROG_MODE_OFF) {
|
||||||
// Counter increment conditions
|
// Counter increment conditions
|
||||||
|
|
||||||
// Check for OFEX (overflow experimental) mode
|
if(keeloq_counter_mode == 0) {
|
||||||
if(furi_hal_subghz_get_rolling_counter_mult() != 0xFFFE) {
|
// Check for OFEX (overflow experimental) mode
|
||||||
// If counter is 0xFFFF we will reset it to 0
|
if(furi_hal_subghz_get_rolling_counter_mult() != 0xFFFE) {
|
||||||
if(instance->generic.cnt < 0xFFFF) {
|
// If counter is 0xFFFF we will reset it to 0
|
||||||
// Increase counter with value set in global settings (mult)
|
if(instance->generic.cnt < 0xFFFF) {
|
||||||
if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) > 0xFFFF) {
|
// Increase counter with value set in global settings (mult)
|
||||||
|
if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) >
|
||||||
|
0xFFFF) {
|
||||||
|
instance->generic.cnt = 0;
|
||||||
|
} else {
|
||||||
|
instance->generic.cnt += furi_hal_subghz_get_rolling_counter_mult();
|
||||||
|
}
|
||||||
|
} else if(
|
||||||
|
(instance->generic.cnt >= 0xFFFF) &&
|
||||||
|
(furi_hal_subghz_get_rolling_counter_mult() != 0)) {
|
||||||
instance->generic.cnt = 0;
|
instance->generic.cnt = 0;
|
||||||
} else {
|
|
||||||
instance->generic.cnt += furi_hal_subghz_get_rolling_counter_mult();
|
|
||||||
}
|
}
|
||||||
} else if(
|
} else {
|
||||||
(instance->generic.cnt >= 0xFFFF) &&
|
if((instance->generic.cnt + 0x1) > 0xFFFF) {
|
||||||
(furi_hal_subghz_get_rolling_counter_mult() != 0)) {
|
instance->generic.cnt = 0;
|
||||||
instance->generic.cnt = 0;
|
} else if(instance->generic.cnt >= 0x1 && instance->generic.cnt != 0xFFFE) {
|
||||||
|
instance->generic.cnt = furi_hal_subghz_get_rolling_counter_mult();
|
||||||
|
} else {
|
||||||
|
instance->generic.cnt++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else if(keeloq_counter_mode == 1) {
|
||||||
|
// Mode 1
|
||||||
|
// 0000 / 0001 / FFFE / FFFF
|
||||||
if((instance->generic.cnt + 0x1) > 0xFFFF) {
|
if((instance->generic.cnt + 0x1) > 0xFFFF) {
|
||||||
instance->generic.cnt = 0;
|
instance->generic.cnt = 0;
|
||||||
} else if(instance->generic.cnt >= 0x1 && instance->generic.cnt != 0xFFFE) {
|
} else if(instance->generic.cnt >= 0x1 && instance->generic.cnt != 0xFFFE) {
|
||||||
instance->generic.cnt = furi_hal_subghz_get_rolling_counter_mult();
|
instance->generic.cnt = 0xFFFE;
|
||||||
} else {
|
} else {
|
||||||
instance->generic.cnt++;
|
instance->generic.cnt++;
|
||||||
}
|
}
|
||||||
|
} else if(keeloq_counter_mode == 2) {
|
||||||
|
// Mode 2
|
||||||
|
// + 0x3333 each time
|
||||||
|
if((instance->generic.cnt + 0x3333) > 0xFFFF) {
|
||||||
|
instance->generic.cnt = 0;
|
||||||
|
} else {
|
||||||
|
instance->generic.cnt += 0x3333;
|
||||||
|
}
|
||||||
|
} else if(keeloq_counter_mode == 3) {
|
||||||
|
// Mode 3
|
||||||
|
// 0x8006 / 0x8007 / 0x0006 / 0x0007
|
||||||
|
if(instance->generic.cnt != 0x8006 && instance->generic.cnt != 0x8007 &&
|
||||||
|
instance->generic.cnt != 0x0006) {
|
||||||
|
instance->generic.cnt = 0x8006;
|
||||||
|
} else if(instance->generic.cnt == 0x8007) {
|
||||||
|
instance->generic.cnt = 0x0006;
|
||||||
|
} else {
|
||||||
|
instance->generic.cnt++;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if(keeloq_counter_mode == 4) {
|
||||||
|
// Mode 4
|
||||||
|
// 0x807B / 0x807C / 0x007B / 0x007C
|
||||||
|
if(instance->generic.cnt != 0x807B && instance->generic.cnt != 0x807C &&
|
||||||
|
instance->generic.cnt != 0x007B) {
|
||||||
|
instance->generic.cnt = 0x807B;
|
||||||
|
} else if(instance->generic.cnt == 0x807C) {
|
||||||
|
instance->generic.cnt = 0x007B;
|
||||||
|
} else {
|
||||||
|
instance->generic.cnt++;
|
||||||
|
}
|
||||||
|
} else if(keeloq_counter_mode == 5) {
|
||||||
|
// Mode 5
|
||||||
|
// 0000 / FFFF
|
||||||
|
if((instance->generic.cnt + 0x1) > 0xFFFF) {
|
||||||
|
instance->generic.cnt = 0;
|
||||||
|
} else {
|
||||||
|
instance->generic.cnt = 0xFFFF;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Mode 6 - Freeze counter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(prog_mode == PROG_MODE_OFF) {
|
if(prog_mode == PROG_MODE_OFF) {
|
||||||
@@ -464,6 +520,8 @@ static bool
|
|||||||
klq_last_custom_btn = 0x9;
|
klq_last_custom_btn = 0x9;
|
||||||
} else if((strcmp(instance->manufacture_name, "EcoStar") == 0)) {
|
} else if((strcmp(instance->manufacture_name, "EcoStar") == 0)) {
|
||||||
klq_last_custom_btn = 0x6;
|
klq_last_custom_btn = 0x6;
|
||||||
|
} else if((strcmp(instance->manufacture_name, "AN-Motors") == 0)) {
|
||||||
|
klq_last_custom_btn = 0xC;
|
||||||
}
|
}
|
||||||
|
|
||||||
btn = subghz_protocol_keeloq_get_btn_code(klq_last_custom_btn);
|
btn = subghz_protocol_keeloq_get_btn_code(klq_last_custom_btn);
|
||||||
@@ -573,6 +631,18 @@ SubGhzProtocolStatus
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t tmp_counter_mode;
|
||||||
|
if(flipper_format_read_uint32(flipper_format, "CounterMode", &tmp_counter_mode, 1)) {
|
||||||
|
keeloq_counter_mode = (uint8_t)tmp_counter_mode;
|
||||||
|
} else {
|
||||||
|
keeloq_counter_mode = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!flipper_format_rewind(flipper_format)) {
|
||||||
|
FURI_LOG_E(TAG, "Rewind error");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
subghz_protocol_keeloq_check_remote_controller(
|
subghz_protocol_keeloq_check_remote_controller(
|
||||||
&instance->generic, instance->keystore, &instance->manufacture_name);
|
&instance->generic, instance->keystore, &instance->manufacture_name);
|
||||||
|
|
||||||
@@ -1212,6 +1282,18 @@ SubGhzProtocolStatus
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t tmp_counter_mode;
|
||||||
|
if(flipper_format_read_uint32(flipper_format, "CounterMode", &tmp_counter_mode, 1)) {
|
||||||
|
keeloq_counter_mode = (uint8_t)tmp_counter_mode;
|
||||||
|
} else {
|
||||||
|
keeloq_counter_mode = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!flipper_format_rewind(flipper_format)) {
|
||||||
|
FURI_LOG_E(TAG, "Rewind error");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
res = SubGhzProtocolStatusOk;
|
res = SubGhzProtocolStatusOk;
|
||||||
} while(false);
|
} while(false);
|
||||||
|
|
||||||
|
|||||||
@@ -53,6 +53,8 @@ typedef enum {
|
|||||||
NiceFlorSDecoderStepCheckDuration,
|
NiceFlorSDecoderStepCheckDuration,
|
||||||
} NiceFlorSDecoderStep;
|
} NiceFlorSDecoderStep;
|
||||||
|
|
||||||
|
static uint8_t nice_flors_counter_mode = 0;
|
||||||
|
|
||||||
const SubGhzProtocolDecoder subghz_protocol_nice_flor_s_decoder = {
|
const SubGhzProtocolDecoder subghz_protocol_nice_flor_s_decoder = {
|
||||||
.alloc = subghz_protocol_decoder_nice_flor_s_alloc,
|
.alloc = subghz_protocol_decoder_nice_flor_s_alloc,
|
||||||
.free = subghz_protocol_decoder_nice_flor_s_free,
|
.free = subghz_protocol_decoder_nice_flor_s_free,
|
||||||
@@ -154,25 +156,42 @@ static void subghz_protocol_encoder_nice_flor_s_get_upload(
|
|||||||
} else {
|
} else {
|
||||||
instance->encoder.size_upload = size_upload;
|
instance->encoder.size_upload = size_upload;
|
||||||
}
|
}
|
||||||
|
if(nice_flors_counter_mode == 0) {
|
||||||
// Check for OFEX (overflow experimental) mode
|
// Check for OFEX (overflow experimental) mode
|
||||||
if(furi_hal_subghz_get_rolling_counter_mult() != 0xFFFE) {
|
if(furi_hal_subghz_get_rolling_counter_mult() != 0xFFFE) {
|
||||||
if(instance->generic.cnt < 0xFFFF) {
|
if(instance->generic.cnt < 0xFFFF) {
|
||||||
if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) > 0xFFFF) {
|
if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) > 0xFFFF) {
|
||||||
|
instance->generic.cnt = 0;
|
||||||
|
} else {
|
||||||
|
instance->generic.cnt += furi_hal_subghz_get_rolling_counter_mult();
|
||||||
|
}
|
||||||
|
} else if(
|
||||||
|
(instance->generic.cnt >= 0xFFFF) &&
|
||||||
|
(furi_hal_subghz_get_rolling_counter_mult() != 0)) {
|
||||||
instance->generic.cnt = 0;
|
instance->generic.cnt = 0;
|
||||||
} else {
|
|
||||||
instance->generic.cnt += furi_hal_subghz_get_rolling_counter_mult();
|
|
||||||
}
|
}
|
||||||
} else if(
|
} else {
|
||||||
(instance->generic.cnt >= 0xFFFF) &&
|
if((instance->generic.cnt + 0x1) > 0xFFFF) {
|
||||||
(furi_hal_subghz_get_rolling_counter_mult() != 0)) {
|
instance->generic.cnt = 0;
|
||||||
instance->generic.cnt = 0;
|
} else if(instance->generic.cnt >= 0x1 && instance->generic.cnt != 0xFFFE) {
|
||||||
|
instance->generic.cnt = furi_hal_subghz_get_rolling_counter_mult();
|
||||||
|
} else {
|
||||||
|
instance->generic.cnt++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if(nice_flors_counter_mode == 1) {
|
||||||
|
// Mode 1 (floxi2r)
|
||||||
|
// 0001 / FFFE
|
||||||
|
if(instance->generic.cnt == 0xFFFE) {
|
||||||
|
instance->generic.cnt = 0x0001;
|
||||||
|
} else {
|
||||||
|
instance->generic.cnt = 0xFFFE;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if((instance->generic.cnt + 0x1) > 0xFFFF) {
|
// Mode 2 (ox2)
|
||||||
|
// 0x0000 / 0x0001
|
||||||
|
if(instance->generic.cnt >= 0x0001) {
|
||||||
instance->generic.cnt = 0;
|
instance->generic.cnt = 0;
|
||||||
} else if(instance->generic.cnt >= 0x1 && instance->generic.cnt != 0xFFFE) {
|
|
||||||
instance->generic.cnt = furi_hal_subghz_get_rolling_counter_mult();
|
|
||||||
} else {
|
} else {
|
||||||
instance->generic.cnt++;
|
instance->generic.cnt++;
|
||||||
}
|
}
|
||||||
@@ -270,6 +289,17 @@ SubGhzProtocolStatus
|
|||||||
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
|
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
|
||||||
// flipper_format_read_uint32(
|
// flipper_format_read_uint32(
|
||||||
// flipper_format, "Data", (uint32_t*)&instance->generic.data_2, 1);
|
// flipper_format, "Data", (uint32_t*)&instance->generic.data_2, 1);
|
||||||
|
if(!flipper_format_rewind(flipper_format)) {
|
||||||
|
FURI_LOG_E(TAG, "Rewind error");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t tmp_counter_mode;
|
||||||
|
if(flipper_format_read_uint32(flipper_format, "CounterMode", &tmp_counter_mode, 1)) {
|
||||||
|
nice_flors_counter_mode = (uint8_t)tmp_counter_mode;
|
||||||
|
} else {
|
||||||
|
nice_flors_counter_mode = 0;
|
||||||
|
}
|
||||||
|
|
||||||
subghz_protocol_nice_flor_s_remote_controller(
|
subghz_protocol_nice_flor_s_remote_controller(
|
||||||
&instance->generic, instance->nice_flor_s_rainbow_table_file_name);
|
&instance->generic, instance->nice_flor_s_rainbow_table_file_name);
|
||||||
@@ -770,6 +800,17 @@ SubGhzProtocolStatus
|
|||||||
}
|
}
|
||||||
instance->data = (uint64_t)temp;
|
instance->data = (uint64_t)temp;
|
||||||
}
|
}
|
||||||
|
if(!flipper_format_rewind(flipper_format)) {
|
||||||
|
FURI_LOG_E(TAG, "Rewind error");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t tmp_counter_mode;
|
||||||
|
if(flipper_format_read_uint32(flipper_format, "CounterMode", &tmp_counter_mode, 1)) {
|
||||||
|
nice_flors_counter_mode = (uint8_t)tmp_counter_mode;
|
||||||
|
} else {
|
||||||
|
nice_flors_counter_mode = 0;
|
||||||
|
}
|
||||||
} while(false);
|
} while(false);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user