mirror of
https://github.com/D4C1-Labs/Flipper-ARF.git
synced 2026-03-30 16:45:38 +00:00
Compare commits
3 Commits
dev-a900ae
...
dev-41191d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
41191df7fd | ||
|
|
d5eb983caa | ||
|
|
853c609977 |
14
README.md
14
README.md
@@ -132,22 +132,10 @@ Flipper-ARF aims to achieve:
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Implemented Protocols
|
|
||||||
|
|
||||||
- [x] Mazda Siemens Protocol (5WK49365D) — ported from open-source references (testing required)
|
|
||||||
- [x] Full VAG, Fiat, Ford, Subaru, Kia, PSA support
|
|
||||||
- [x] D-Pad mapping (Lock / Unlock / Boot / Trunk) during emulation
|
|
||||||
- [x] VAG MFKey support and updated Keeloq codes
|
|
||||||
- [x] PSA XTEA brute force for saved → emulation workflow
|
|
||||||
- [x] Brute force of counter in saved → can be accellerated trough the companion app via bluetooth
|
|
||||||
- [X] Keeloq Key Manager inside firmware
|
|
||||||
- [x] RollJam app (Internal CC1101 for RX & TX captured signal; External CC1101 for jamming) — requires more real-world testing (no available yet)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## To Do / Planned Features
|
## To Do / Planned Features
|
||||||
|
|
||||||
- [ ] Add Scher Khan & Starline protocols
|
- [ ] Add Scher Khan & Starline protocols
|
||||||
|
- [ ] Marelli BSI encodere and encryption
|
||||||
- [ ] Fix and reintegrate RollJam app (future updates)
|
- [ ] Fix and reintegrate RollJam app (future updates)
|
||||||
- [ ] Expand and refine Subaru, Kia, PSA, and other manufacturer protocols
|
- [ ] Expand and refine Subaru, Kia, PSA, and other manufacturer protocols
|
||||||
- [ ] Improve collaboration workflow to avoid overlapping work
|
- [ ] Improve collaboration workflow to avoid overlapping work
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#include "subghz_txrx_i.h" // IWYU pragma: keep
|
#include "subghz_txrx_i.h" // IWYU pragma: keep
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
#include <lib/subghz/protocols/protocol_items.h>
|
#include <lib/subghz/protocols/protocol_items.h>
|
||||||
#include <applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h>
|
#include <applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h>
|
||||||
#include <lib/subghz/devices/cc1101_int/cc1101_int_interconnect.h>
|
#include <lib/subghz/devices/cc1101_int/cc1101_int_interconnect.h>
|
||||||
@@ -494,28 +495,39 @@ void subghz_txrx_hopper_pause(SubGhzTxRx* instance) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SUBGHZ_MOD_HOPPER_DWELL_TICKS 3
|
|
||||||
|
|
||||||
bool subghz_txrx_mod_hopper_get_running(SubGhzTxRx* instance) {
|
bool subghz_txrx_mod_hopper_get_running(SubGhzTxRx* instance) {
|
||||||
furi_assert(instance);
|
furi_assert(instance);
|
||||||
return instance->mod_hopper_running;
|
return instance->mod_hopper_running;
|
||||||
}
|
}
|
||||||
|
|
||||||
void subghz_txrx_mod_hopper_set_running(SubGhzTxRx* instance, bool running) {
|
void subghz_txrx_mod_hopper_set_running(
|
||||||
|
SubGhzTxRx* instance,
|
||||||
|
bool running,
|
||||||
|
uint8_t dwell_ticks,
|
||||||
|
float rssi_threshold) {
|
||||||
furi_assert(instance);
|
furi_assert(instance);
|
||||||
instance->mod_hopper_running = running;
|
instance->mod_hopper_running = running;
|
||||||
if(running) instance->mod_hopper_timer = SUBGHZ_MOD_HOPPER_DWELL_TICKS;
|
instance->mod_hopper_dwell = dwell_ticks;
|
||||||
|
instance->mod_hopper_rssi_threshold = rssi_threshold;
|
||||||
|
if(running) instance->mod_hopper_timer = dwell_ticks;
|
||||||
}
|
}
|
||||||
|
|
||||||
void subghz_txrx_mod_hopper_update(SubGhzTxRx* instance) {
|
void subghz_txrx_mod_hopper_update(SubGhzTxRx* instance, float current_rssi) {
|
||||||
furi_assert(instance);
|
furi_assert(instance);
|
||||||
if(!instance->mod_hopper_running) return;
|
if(!instance->mod_hopper_running) return;
|
||||||
|
|
||||||
|
// If RSSI gating is enabled and signal is present, pause hopping
|
||||||
|
if(!isnan(instance->mod_hopper_rssi_threshold) &&
|
||||||
|
current_rssi > instance->mod_hopper_rssi_threshold) {
|
||||||
|
instance->mod_hopper_timer = instance->mod_hopper_dwell;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if(instance->mod_hopper_timer > 0) {
|
if(instance->mod_hopper_timer > 0) {
|
||||||
instance->mod_hopper_timer--;
|
instance->mod_hopper_timer--;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
instance->mod_hopper_timer = SUBGHZ_MOD_HOPPER_DWELL_TICKS;
|
instance->mod_hopper_timer = instance->mod_hopper_dwell;
|
||||||
|
|
||||||
size_t count = subghz_setting_get_preset_count(instance->setting);
|
size_t count = subghz_setting_get_preset_count(instance->setting);
|
||||||
if(count == 0) return;
|
if(count == 0) return;
|
||||||
|
|||||||
@@ -166,19 +166,27 @@ void subghz_txrx_hopper_pause(SubGhzTxRx* instance);
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Update modulation (preset) CC1101 in automatic mode (mod hopper)
|
* Update modulation (preset) CC1101 in automatic mode (mod hopper)
|
||||||
* Cycles through available presets at a fixed dwell time.
|
* Cycles through available presets at the configured dwell time.
|
||||||
|
* Pauses hopping when current_rssi exceeds the configured threshold.
|
||||||
*
|
*
|
||||||
* @param instance Pointer to a SubGhzTxRx
|
* @param instance Pointer to a SubGhzTxRx
|
||||||
|
* @param current_rssi Current RSSI reading from the radio
|
||||||
*/
|
*/
|
||||||
void subghz_txrx_mod_hopper_update(SubGhzTxRx* instance);
|
void subghz_txrx_mod_hopper_update(SubGhzTxRx* instance, float current_rssi);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set mod hopper running state
|
* Set mod hopper running state with configuration
|
||||||
*
|
*
|
||||||
* @param instance Pointer to a SubGhzTxRx
|
* @param instance Pointer to a SubGhzTxRx
|
||||||
* @param running true to enable, false to disable
|
* @param running true to enable, false to disable
|
||||||
|
* @param dwell_ticks Ticks to dwell on each modulation (100ms per tick)
|
||||||
|
* @param rssi_threshold RSSI threshold to pause hopping (NAN = no gating)
|
||||||
*/
|
*/
|
||||||
void subghz_txrx_mod_hopper_set_running(SubGhzTxRx* instance, bool running);
|
void subghz_txrx_mod_hopper_set_running(
|
||||||
|
SubGhzTxRx* instance,
|
||||||
|
bool running,
|
||||||
|
uint8_t dwell_ticks,
|
||||||
|
float rssi_threshold);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get mod hopper running state
|
* Get mod hopper running state
|
||||||
|
|||||||
@@ -19,9 +19,11 @@ struct SubGhzTxRx {
|
|||||||
bool is_database_loaded;
|
bool is_database_loaded;
|
||||||
SubGhzHopperState hopper_state;
|
SubGhzHopperState hopper_state;
|
||||||
|
|
||||||
uint8_t mod_hopper_idx; // index into setting presets (wraps around)
|
uint8_t mod_hopper_idx; // index into setting presets (wraps around)
|
||||||
uint8_t mod_hopper_timer; // countdown ticks before advancing modulation
|
uint8_t mod_hopper_timer; // countdown ticks before advancing modulation
|
||||||
bool mod_hopper_running; // is mod hopping active
|
uint8_t mod_hopper_dwell; // stored dwell ticks (configurable)
|
||||||
|
float mod_hopper_rssi_threshold; // RSSI threshold; NAN = no RSSI gating
|
||||||
|
bool mod_hopper_running; // is mod hopping active
|
||||||
|
|
||||||
SubGhzTxRxState txrx_state;
|
SubGhzTxRxState txrx_state;
|
||||||
SubGhzSpeakerState speaker_state;
|
SubGhzSpeakerState speaker_state;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include "../subghz_i.h"
|
#include "../subghz_i.h"
|
||||||
|
#include <math.h>
|
||||||
#include <dolphin/dolphin.h>
|
#include <dolphin/dolphin.h>
|
||||||
#include <lib/subghz/protocols/bin_raw.h>
|
#include <lib/subghz/protocols/bin_raw.h>
|
||||||
|
|
||||||
@@ -213,7 +214,11 @@ void subghz_scene_receiver_on_enter(void* context) {
|
|||||||
} else {
|
} else {
|
||||||
subghz_txrx_hopper_set_state(subghz->txrx, SubGhzHopperStateOFF);
|
subghz_txrx_hopper_set_state(subghz->txrx, SubGhzHopperStateOFF);
|
||||||
}
|
}
|
||||||
subghz_txrx_mod_hopper_set_running(subghz->txrx, subghz->last_settings->enable_mod_hopping);
|
subghz_txrx_mod_hopper_set_running(
|
||||||
|
subghz->txrx,
|
||||||
|
!isnan(subghz->last_settings->mod_hopping_threshold),
|
||||||
|
(uint8_t)subghz->last_settings->mod_hopping_dwell,
|
||||||
|
subghz->last_settings->mod_hopping_threshold);
|
||||||
|
|
||||||
subghz_txrx_rx_start(subghz->txrx);
|
subghz_txrx_rx_start(subghz->txrx);
|
||||||
subghz_view_receiver_set_idx_menu(subghz->subghz_receiver, subghz->idx_menu_chosen);
|
subghz_view_receiver_set_idx_menu(subghz->subghz_receiver, subghz->idx_menu_chosen);
|
||||||
@@ -303,7 +308,8 @@ bool subghz_scene_receiver_on_event(void* context, SceneManagerEvent event) {
|
|||||||
subghz_scene_receiver_update_statusbar(subghz);
|
subghz_scene_receiver_update_statusbar(subghz);
|
||||||
}
|
}
|
||||||
if(subghz_txrx_mod_hopper_get_running(subghz->txrx)) {
|
if(subghz_txrx_mod_hopper_get_running(subghz->txrx)) {
|
||||||
subghz_txrx_mod_hopper_update(subghz->txrx);
|
float rssi = subghz_txrx_radio_device_get_rssi(subghz->txrx);
|
||||||
|
subghz_txrx_mod_hopper_update(subghz->txrx, rssi);
|
||||||
subghz_scene_receiver_update_statusbar(subghz);
|
subghz_scene_receiver_update_statusbar(subghz);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#include "../subghz_i.h"
|
#include "../subghz_i.h"
|
||||||
#include <lib/toolbox/value_index.h>
|
#include <lib/toolbox/value_index.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
#define TAG "SubGhzSceneReceiverConfig"
|
#define TAG "SubGhzSceneReceiverConfig"
|
||||||
|
|
||||||
@@ -81,6 +82,44 @@ const float hopping_mode_value[HOPPING_MODE_COUNT] = {
|
|||||||
-40.0f,
|
-40.0f,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define MOD_HOP_DBM_COUNT 8
|
||||||
|
const char* const mod_hop_dbm_text[MOD_HOP_DBM_COUNT] = {
|
||||||
|
"OFF",
|
||||||
|
"-90",
|
||||||
|
"-85",
|
||||||
|
"-80",
|
||||||
|
"-75",
|
||||||
|
"-70",
|
||||||
|
"-65",
|
||||||
|
"-60",
|
||||||
|
};
|
||||||
|
const float mod_hop_dbm_value[MOD_HOP_DBM_COUNT] = {
|
||||||
|
NAN,
|
||||||
|
-90.0f,
|
||||||
|
-85.0f,
|
||||||
|
-80.0f,
|
||||||
|
-75.0f,
|
||||||
|
-70.0f,
|
||||||
|
-65.0f,
|
||||||
|
-60.0f,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define MOD_HOP_TIME_COUNT 5
|
||||||
|
const char* const mod_hop_time_text[MOD_HOP_TIME_COUNT] = {
|
||||||
|
"0.5s",
|
||||||
|
"1s",
|
||||||
|
"2s",
|
||||||
|
"5s",
|
||||||
|
"10s",
|
||||||
|
};
|
||||||
|
const uint32_t mod_hop_time_ticks[MOD_HOP_TIME_COUNT] = {
|
||||||
|
5,
|
||||||
|
10,
|
||||||
|
20,
|
||||||
|
50,
|
||||||
|
100,
|
||||||
|
};
|
||||||
|
|
||||||
#define COMBO_BOX_COUNT 2
|
#define COMBO_BOX_COUNT 2
|
||||||
|
|
||||||
const uint32_t hopping_value[COMBO_BOX_COUNT] = {
|
const uint32_t hopping_value[COMBO_BOX_COUNT] = {
|
||||||
@@ -276,13 +315,31 @@ static void subghz_scene_receiver_config_set_hopping(VariableItem* item) {
|
|||||||
subghz->txrx, index != 0 ? SubGhzHopperStateRunning : SubGhzHopperStateOFF);
|
subghz->txrx, index != 0 ? SubGhzHopperStateRunning : SubGhzHopperStateOFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void subghz_scene_receiver_config_set_mod_hopping(VariableItem* item) {
|
static void subghz_scene_receiver_config_set_mod_hop_dbm(VariableItem* item) {
|
||||||
SubGhz* subghz = variable_item_get_context(item);
|
SubGhz* subghz = variable_item_get_context(item);
|
||||||
uint8_t index = variable_item_get_current_value_index(item);
|
uint8_t index = variable_item_get_current_value_index(item);
|
||||||
variable_item_set_current_value_text(item, combobox_text[index]);
|
variable_item_set_current_value_text(item, mod_hop_dbm_text[index]);
|
||||||
bool enabled = index == 1;
|
subghz->last_settings->mod_hopping_threshold = mod_hop_dbm_value[index];
|
||||||
subghz->last_settings->enable_mod_hopping = enabled;
|
bool enabled = index != 0;
|
||||||
subghz_txrx_mod_hopper_set_running(subghz->txrx, enabled);
|
subghz_txrx_mod_hopper_set_running(
|
||||||
|
subghz->txrx,
|
||||||
|
enabled,
|
||||||
|
(uint8_t)subghz->last_settings->mod_hopping_dwell,
|
||||||
|
mod_hop_dbm_value[index]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void subghz_scene_receiver_config_set_mod_hop_time(VariableItem* item) {
|
||||||
|
SubGhz* subghz = variable_item_get_context(item);
|
||||||
|
uint8_t index = variable_item_get_current_value_index(item);
|
||||||
|
variable_item_set_current_value_text(item, mod_hop_time_text[index]);
|
||||||
|
subghz->last_settings->mod_hopping_dwell = mod_hop_time_ticks[index];
|
||||||
|
if(subghz_txrx_mod_hopper_get_running(subghz->txrx)) {
|
||||||
|
subghz_txrx_mod_hopper_set_running(
|
||||||
|
subghz->txrx,
|
||||||
|
true,
|
||||||
|
(uint8_t)mod_hop_time_ticks[index],
|
||||||
|
subghz->last_settings->mod_hopping_threshold);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void subghz_scene_receiver_config_set_speaker(VariableItem* item) {
|
static void subghz_scene_receiver_config_set_speaker(VariableItem* item) {
|
||||||
@@ -385,8 +442,9 @@ static void subghz_scene_receiver_config_var_list_enter_callback(void* context,
|
|||||||
|
|
||||||
subghz_txrx_hopper_set_state(subghz->txrx, hopping_value[default_index]);
|
subghz_txrx_hopper_set_state(subghz->txrx, hopping_value[default_index]);
|
||||||
subghz->last_settings->enable_hopping = hopping_value[default_index];
|
subghz->last_settings->enable_hopping = hopping_value[default_index];
|
||||||
subghz->last_settings->enable_mod_hopping = false;
|
subghz->last_settings->mod_hopping_threshold = NAN;
|
||||||
subghz_txrx_mod_hopper_set_running(subghz->txrx, false);
|
subghz->last_settings->mod_hopping_dwell = 20;
|
||||||
|
subghz_txrx_mod_hopper_set_running(subghz->txrx, false, 20, NAN);
|
||||||
|
|
||||||
variable_item_list_set_selected_item(subghz->variable_item_list, default_index);
|
variable_item_list_set_selected_item(subghz->variable_item_list, default_index);
|
||||||
variable_item_list_reset(subghz->variable_item_list);
|
variable_item_list_reset(subghz->variable_item_list);
|
||||||
@@ -451,16 +509,47 @@ void subghz_scene_receiver_config_on_enter(void* context) {
|
|||||||
variable_item_set_current_value_index(item, value_index);
|
variable_item_set_current_value_index(item, value_index);
|
||||||
variable_item_set_current_value_text(item, hopping_mode_text[value_index]);
|
variable_item_set_current_value_text(item, hopping_mode_text[value_index]);
|
||||||
|
|
||||||
// Mod Hopping
|
// Mod Hop dBm
|
||||||
item = variable_item_list_add(
|
{
|
||||||
subghz->variable_item_list,
|
uint8_t mod_dbm_idx = 0; // OFF
|
||||||
"Mod Hopping",
|
float thresh = subghz->last_settings->mod_hopping_threshold;
|
||||||
COMBO_BOX_COUNT,
|
if(!isnan(thresh)) {
|
||||||
subghz_scene_receiver_config_set_mod_hopping,
|
for(uint8_t k = 1; k < MOD_HOP_DBM_COUNT; k++) {
|
||||||
subghz);
|
if(mod_hop_dbm_value[k] == thresh) {
|
||||||
value_index = subghz->last_settings->enable_mod_hopping ? 1 : 0;
|
mod_dbm_idx = k;
|
||||||
variable_item_set_current_value_index(item, value_index);
|
break;
|
||||||
variable_item_set_current_value_text(item, combobox_text[value_index]);
|
}
|
||||||
|
}
|
||||||
|
if(mod_dbm_idx == 0) mod_dbm_idx = 1; // fallback to -90
|
||||||
|
}
|
||||||
|
item = variable_item_list_add(
|
||||||
|
subghz->variable_item_list,
|
||||||
|
"Mod Hop dBm",
|
||||||
|
MOD_HOP_DBM_COUNT,
|
||||||
|
subghz_scene_receiver_config_set_mod_hop_dbm,
|
||||||
|
subghz);
|
||||||
|
variable_item_set_current_value_index(item, mod_dbm_idx);
|
||||||
|
variable_item_set_current_value_text(item, mod_hop_dbm_text[mod_dbm_idx]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mod Hop Time
|
||||||
|
{
|
||||||
|
uint8_t mod_time_idx = 2; // default 2s
|
||||||
|
for(uint8_t k = 0; k < MOD_HOP_TIME_COUNT; k++) {
|
||||||
|
if(mod_hop_time_ticks[k] == subghz->last_settings->mod_hopping_dwell) {
|
||||||
|
mod_time_idx = k;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
item = variable_item_list_add(
|
||||||
|
subghz->variable_item_list,
|
||||||
|
"Mod Hop Time",
|
||||||
|
MOD_HOP_TIME_COUNT,
|
||||||
|
subghz_scene_receiver_config_set_mod_hop_time,
|
||||||
|
subghz);
|
||||||
|
variable_item_set_current_value_index(item, mod_time_idx);
|
||||||
|
variable_item_set_current_value_text(item, mod_hop_time_text[mod_time_idx]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneReadRAW) !=
|
if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneReadRAW) !=
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#include "subghz_last_settings.h"
|
#include "subghz_last_settings.h"
|
||||||
#include "subghz_i.h"
|
#include "subghz_i.h"
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
#define TAG "SubGhzLastSettings"
|
#define TAG "SubGhzLastSettings"
|
||||||
|
|
||||||
@@ -13,7 +14,8 @@
|
|||||||
#define SUBGHZ_LAST_SETTING_FIELD_FREQUENCY_ANALYZER_TRIGGER "FATrigger"
|
#define SUBGHZ_LAST_SETTING_FIELD_FREQUENCY_ANALYZER_TRIGGER "FATrigger"
|
||||||
#define SUBGHZ_LAST_SETTING_FIELD_PROTOCOL_FILE_NAMES "ProtocolNames"
|
#define SUBGHZ_LAST_SETTING_FIELD_PROTOCOL_FILE_NAMES "ProtocolNames"
|
||||||
#define SUBGHZ_LAST_SETTING_FIELD_HOPPING_ENABLE "Hopping"
|
#define SUBGHZ_LAST_SETTING_FIELD_HOPPING_ENABLE "Hopping"
|
||||||
#define SUBGHZ_LAST_SETTING_FIELD_MOD_HOPPING "ModHopping"
|
#define SUBGHZ_LAST_SETTING_FIELD_MOD_HOP_THRESHOLD "ModHopThreshold"
|
||||||
|
#define SUBGHZ_LAST_SETTING_FIELD_MOD_HOP_DWELL "ModHopDwell"
|
||||||
#define SUBGHZ_LAST_SETTING_FIELD_IGNORE_FILTER "IgnoreFilter"
|
#define SUBGHZ_LAST_SETTING_FIELD_IGNORE_FILTER "IgnoreFilter"
|
||||||
#define SUBGHZ_LAST_SETTING_FIELD_FILTER "Filter"
|
#define SUBGHZ_LAST_SETTING_FIELD_FILTER "Filter"
|
||||||
#define SUBGHZ_LAST_SETTING_FIELD_RSSI_THRESHOLD "RSSI"
|
#define SUBGHZ_LAST_SETTING_FIELD_RSSI_THRESHOLD "RSSI"
|
||||||
@@ -46,6 +48,8 @@ void subghz_last_settings_load(SubGhzLastSettings* instance, size_t preset_count
|
|||||||
instance->filter = SubGhzProtocolFlag_Decodable;
|
instance->filter = SubGhzProtocolFlag_Decodable;
|
||||||
instance->rssi = SUBGHZ_RAW_THRESHOLD_MIN;
|
instance->rssi = SUBGHZ_RAW_THRESHOLD_MIN;
|
||||||
instance->hopping_threshold = -90.0f;
|
instance->hopping_threshold = -90.0f;
|
||||||
|
instance->mod_hopping_threshold = NAN; // disabled by default
|
||||||
|
instance->mod_hopping_dwell = 20; // 2 seconds (20 × 100ms ticks)
|
||||||
instance->leds_and_amp = true;
|
instance->leds_and_amp = true;
|
||||||
|
|
||||||
Storage* storage = furi_record_open(RECORD_STORAGE);
|
Storage* storage = furi_record_open(RECORD_STORAGE);
|
||||||
@@ -99,10 +103,17 @@ void subghz_last_settings_load(SubGhzLastSettings* instance, size_t preset_count
|
|||||||
1)) {
|
1)) {
|
||||||
flipper_format_rewind(fff_data_file);
|
flipper_format_rewind(fff_data_file);
|
||||||
}
|
}
|
||||||
if(!flipper_format_read_bool(
|
if(!flipper_format_read_float(
|
||||||
fff_data_file,
|
fff_data_file,
|
||||||
SUBGHZ_LAST_SETTING_FIELD_MOD_HOPPING,
|
SUBGHZ_LAST_SETTING_FIELD_MOD_HOP_THRESHOLD,
|
||||||
&instance->enable_mod_hopping,
|
&instance->mod_hopping_threshold,
|
||||||
|
1)) {
|
||||||
|
flipper_format_rewind(fff_data_file);
|
||||||
|
}
|
||||||
|
if(!flipper_format_read_uint32(
|
||||||
|
fff_data_file,
|
||||||
|
SUBGHZ_LAST_SETTING_FIELD_MOD_HOP_DWELL,
|
||||||
|
&instance->mod_hopping_dwell,
|
||||||
1)) {
|
1)) {
|
||||||
flipper_format_rewind(fff_data_file);
|
flipper_format_rewind(fff_data_file);
|
||||||
}
|
}
|
||||||
@@ -221,10 +232,17 @@ bool subghz_last_settings_save(SubGhzLastSettings* instance) {
|
|||||||
file, SUBGHZ_LAST_SETTING_FIELD_HOPPING_ENABLE, &instance->enable_hopping, 1)) {
|
file, SUBGHZ_LAST_SETTING_FIELD_HOPPING_ENABLE, &instance->enable_hopping, 1)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(!flipper_format_write_bool(
|
if(!flipper_format_write_float(
|
||||||
file,
|
file,
|
||||||
SUBGHZ_LAST_SETTING_FIELD_MOD_HOPPING,
|
SUBGHZ_LAST_SETTING_FIELD_MOD_HOP_THRESHOLD,
|
||||||
&instance->enable_mod_hopping,
|
&instance->mod_hopping_threshold,
|
||||||
|
1)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(!flipper_format_write_uint32(
|
||||||
|
file,
|
||||||
|
SUBGHZ_LAST_SETTING_FIELD_MOD_HOP_DWELL,
|
||||||
|
&instance->mod_hopping_dwell,
|
||||||
1)) {
|
1)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,8 @@ typedef struct {
|
|||||||
float frequency_analyzer_trigger;
|
float frequency_analyzer_trigger;
|
||||||
bool protocol_file_names;
|
bool protocol_file_names;
|
||||||
bool enable_hopping;
|
bool enable_hopping;
|
||||||
bool enable_mod_hopping;
|
float mod_hopping_threshold; // RSSI threshold for mod hopping, NAN = disabled
|
||||||
|
uint32_t mod_hopping_dwell; // Dwell time in ticks (100ms units)
|
||||||
uint32_t ignore_filter;
|
uint32_t ignore_filter;
|
||||||
uint32_t filter;
|
uint32_t filter;
|
||||||
float rssi;
|
float rssi;
|
||||||
|
|||||||
@@ -17,8 +17,9 @@
|
|||||||
//
|
//
|
||||||
// Frame layout (after stripping 16-bit 0xFFFF preamble):
|
// Frame layout (after stripping 16-bit 0xFFFF preamble):
|
||||||
// Bytes 0-3: Fixed ID / Serial (32 bits)
|
// Bytes 0-3: Fixed ID / Serial (32 bits)
|
||||||
// Byte 4: Button (upper nibble) | Type (lower nibble, always 0x2)
|
// Byte 4: Button (upper nibble) | Type (lower nibble)
|
||||||
// Bytes 5-10: Rolling/encrypted code (48 bits)
|
// Buttons: 0x7=Lock, 0xB=Unlock, 0xD=Trunk
|
||||||
|
// Bytes 5-10: Rolling/encrypted code (48 bits)
|
||||||
#define FIAT_MARELLI_PREAMBLE_MIN 200 // Min preamble pulses (100 pairs)
|
#define FIAT_MARELLI_PREAMBLE_MIN 200 // Min preamble pulses (100 pairs)
|
||||||
#define FIAT_MARELLI_GAP_MIN 2500 // Gap detection threshold (us)
|
#define FIAT_MARELLI_GAP_MIN 2500 // Gap detection threshold (us)
|
||||||
#define FIAT_MARELLI_SYNC_MIN 1500 // Sync pulse minimum (us)
|
#define FIAT_MARELLI_SYNC_MIN 1500 // Sync pulse minimum (us)
|
||||||
@@ -402,10 +403,12 @@ SubGhzProtocolStatus subghz_protocol_decoder_fiat_marelli_deserialize(
|
|||||||
|
|
||||||
static const char* fiat_marelli_button_name(uint8_t btn) {
|
static const char* fiat_marelli_button_name(uint8_t btn) {
|
||||||
switch(btn) {
|
switch(btn) {
|
||||||
case 0x2:
|
case 0x7:
|
||||||
return "Btn A";
|
return "Lock";
|
||||||
case 0x4:
|
case 0xB:
|
||||||
return "Btn B";
|
return "Unlock";
|
||||||
|
case 0xD:
|
||||||
|
return "Trunk";
|
||||||
default:
|
default:
|
||||||
return "Unknown";
|
return "Unknown";
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user