mirror of
https://protopirate.net/ProtoPirate/ProtoPirate.git
synced 2026-09-25 17:23:34 +00:00
Merge branch 'main' into fix_unlock
This commit is contained in:
@@ -17,6 +17,7 @@ void protopirate_settings_set_defaults(ProtoPirateSettings* settings) {
|
||||
settings->preset_index = 0;
|
||||
settings->tx_power = 0;
|
||||
settings->auto_save = false;
|
||||
settings->sound = false;
|
||||
settings->hopping_enabled = false;
|
||||
settings->emulate_feature_enabled = false;
|
||||
settings->check_saved = false;
|
||||
@@ -118,15 +119,22 @@ void protopirate_settings_load(ProtoPirateSettings* settings) {
|
||||
}
|
||||
settings->check_saved = (check_saved_temp == 1);
|
||||
|
||||
uint32_t sound_temp = 0;
|
||||
if(!flipper_format_read_uint32(ff, "Sound", &sound_temp, 1)) {
|
||||
check_saved_temp = 0;
|
||||
}
|
||||
settings->sound = (sound_temp == 1);
|
||||
|
||||
FURI_LOG_I(
|
||||
TAG,
|
||||
"Settings loaded: freq=%lu, preset=%u, auto_save=%d, hopping=%d, emulate=%d, check_saved=%d",
|
||||
"Settings loaded: freq=%lu, preset=%u, auto_save=%d, hopping=%d, emulate=%d, check_saved=%d, sound = %d",
|
||||
settings->frequency,
|
||||
settings->preset_index,
|
||||
settings->auto_save,
|
||||
settings->hopping_enabled,
|
||||
settings->emulate_feature_enabled,
|
||||
settings->check_saved);
|
||||
settings->check_saved,
|
||||
settings->sound);
|
||||
|
||||
} while(false);
|
||||
|
||||
@@ -200,18 +208,23 @@ void protopirate_settings_save(ProtoPirateSettings* settings) {
|
||||
FURI_LOG_E(TAG, "Failed to write check saved");
|
||||
break;
|
||||
}
|
||||
|
||||
uint32_t sound_temp = settings->sound ? 1 : 0;
|
||||
if(!flipper_format_write_uint32(ff, "Sound", &sound_temp, 1)) {
|
||||
FURI_LOG_E(TAG, "Failed to write Sound.");
|
||||
break;
|
||||
}
|
||||
write_ok = true;
|
||||
|
||||
FURI_LOG_I(
|
||||
TAG,
|
||||
"Settings saved: freq=%lu, preset=%u, auto_save=%d, hopping=%d, emulate=%d, check_saved=%d",
|
||||
"Settings saved: freq=%lu, preset=%u, auto_save=%d, hopping=%d, emulate=%d, check_saved=%d, sound=%d",
|
||||
settings->frequency,
|
||||
settings->preset_index,
|
||||
settings->auto_save,
|
||||
settings->hopping_enabled,
|
||||
settings->emulate_feature_enabled,
|
||||
settings->check_saved);
|
||||
settings->check_saved,
|
||||
settings->sound);
|
||||
|
||||
} while(false);
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ typedef struct {
|
||||
uint8_t preset_index;
|
||||
uint8_t tx_power;
|
||||
bool auto_save;
|
||||
bool sound;
|
||||
bool hopping_enabled;
|
||||
bool emulate_feature_enabled;
|
||||
bool check_saved;
|
||||
|
||||
@@ -133,6 +133,13 @@ uint32_t protopirate_rx(ProtoPirateApp* app, uint32_t frequency) {
|
||||
subghz_devices_idle(app->txrx->radio_device);
|
||||
uint32_t value = subghz_devices_set_frequency(app->txrx->radio_device, frequency);
|
||||
subghz_devices_flush_rx(app->txrx->radio_device);
|
||||
|
||||
//Enable the Speaker so I can hear the keys.
|
||||
if(app->sound) {
|
||||
if(furi_hal_speaker_is_mine() || furi_hal_speaker_acquire(1000)) {
|
||||
app->txrx->radio_device->interconnect->set_async_mirror_pin(&gpio_speaker);
|
||||
}
|
||||
}
|
||||
subghz_devices_set_rx(app->txrx->radio_device);
|
||||
|
||||
subghz_devices_start_async_rx(
|
||||
@@ -169,6 +176,13 @@ void protopirate_rx_end(ProtoPirateApp* app) {
|
||||
subghz_devices_idle(app->txrx->radio_device);
|
||||
}
|
||||
|
||||
if(app->sound) {
|
||||
if(furi_hal_speaker_is_mine()) {
|
||||
subghz_devices_set_async_mirror_pin(app->txrx->radio_device, NULL);
|
||||
furi_hal_speaker_release();
|
||||
}
|
||||
}
|
||||
|
||||
app->txrx->txrx_state = ProtoPirateTxRxStateIDLE;
|
||||
}
|
||||
|
||||
|
||||
+34
-33
@@ -65,6 +65,8 @@ struct SubGhzProtocolDecoderRenaultV1 {
|
||||
uint64_t last_data;
|
||||
uint64_t last_data_2;
|
||||
bool last_frame_valid;
|
||||
uint32_t seed;
|
||||
uint64_t data_2;
|
||||
};
|
||||
|
||||
#if PROTOPIRATE_WITH_ENCODER
|
||||
@@ -74,6 +76,8 @@ struct SubGhzProtocolEncoderRenaultV1 {
|
||||
SubGhzProtocolBlockEncoder encoder;
|
||||
SubGhzBlockGeneric generic;
|
||||
|
||||
uint32_t seed;
|
||||
uint64_t data_2;
|
||||
uint8_t recovered;
|
||||
uint8_t hitag2_key[6];
|
||||
uint8_t tail_bits;
|
||||
@@ -637,9 +641,9 @@ static void hitag2_apply_check_remote(
|
||||
static void renault_v1_check_remote_controller(SubGhzProtocolDecoderRenaultV1* instance) {
|
||||
hitag2_apply_check_remote(
|
||||
instance->generic.data,
|
||||
instance->generic.data_2,
|
||||
instance->data_2,
|
||||
instance->recovered,
|
||||
instance->generic.seed,
|
||||
instance->seed,
|
||||
&instance->generic.serial,
|
||||
&instance->generic.btn,
|
||||
&instance->generic.cnt,
|
||||
@@ -669,7 +673,7 @@ static bool hitag2_encoder_next_frame(
|
||||
uint32_t hop = hitag2_authenticator(uid, tx_btn, cnt10, instance->hitag2_key);
|
||||
|
||||
hitag2_pack_auth_frame(uid, tx_btn, cnt10, hop, tail, raw);
|
||||
hitag2_apply_raw(raw, &instance->generic.data, &instance->generic.data_2);
|
||||
hitag2_apply_raw(raw, &instance->generic.data, &instance->data_2);
|
||||
instance->generic.serial = uid;
|
||||
instance->generic.btn = tx_btn;
|
||||
instance->generic.cnt = cnt10;
|
||||
@@ -767,7 +771,7 @@ static bool renault_v1_encoder_get_upload(SubGhzProtocolEncoderRenaultV1* instan
|
||||
size_t index = 0;
|
||||
LevelDuration* upload = instance->encoder.upload;
|
||||
const uint64_t key = instance->generic.data;
|
||||
const uint64_t key_2 = instance->generic.data_2 & 0xFFFFFFULL;
|
||||
const uint64_t key_2 = instance->data_2 & 0xFFFFFFULL;
|
||||
|
||||
for(size_t i = 0; i < HITAG2_PREAMBLE_PAIRS; i++) {
|
||||
if(!hitag2_encoder_add_level(upload, &index, true, HITAG2_TE_US)) return false;
|
||||
@@ -814,10 +818,9 @@ SubGhzProtocolStatus
|
||||
ret = SubGhzProtocolStatusErrorParserOthers;
|
||||
break;
|
||||
}
|
||||
instance->generic.data_2 = hitag2_bytes_to_u64_be(key2, sizeof(key2));
|
||||
instance->data_2 = hitag2_bytes_to_u64_be(key2, sizeof(key2));
|
||||
|
||||
hitag2_read_recovered_and_seed(
|
||||
flipper_format, &instance->recovered, &instance->generic.seed);
|
||||
hitag2_read_recovered_and_seed(flipper_format, &instance->recovered, &instance->seed);
|
||||
|
||||
if(!flipper_format_rewind(flipper_format)) {
|
||||
ret = SubGhzProtocolStatusErrorParserOthers;
|
||||
@@ -831,7 +834,7 @@ SubGhzProtocolStatus
|
||||
uint16_t wire_cnt10 = 0;
|
||||
hitag2_unpack_frame(
|
||||
instance->generic.data,
|
||||
instance->generic.data_2,
|
||||
instance->data_2,
|
||||
&wire_serial,
|
||||
&wire_btn,
|
||||
&wire_cnt10,
|
||||
@@ -839,9 +842,9 @@ SubGhzProtocolStatus
|
||||
&tail);
|
||||
hitag2_apply_check_remote(
|
||||
instance->generic.data,
|
||||
instance->generic.data_2,
|
||||
instance->data_2,
|
||||
instance->recovered,
|
||||
instance->generic.seed,
|
||||
instance->seed,
|
||||
&instance->generic.serial,
|
||||
&instance->generic.btn,
|
||||
&instance->generic.cnt,
|
||||
@@ -886,14 +889,13 @@ SubGhzProtocolStatus
|
||||
instance->generic.serial,
|
||||
instance->generic.cnt,
|
||||
instance->generic.btn,
|
||||
instance->generic.seed,
|
||||
instance->seed,
|
||||
out,
|
||||
iv);
|
||||
instance->generic.data = hitag2_bytes_to_u64_be(out, 8);
|
||||
instance->generic.data_2 = ((uint64_t)out[8] << 16U) | ((uint64_t)out[9] << 8U) |
|
||||
out[10];
|
||||
instance->generic.seed = ((uint32_t)iv[0] << 24U) | ((uint32_t)iv[1] << 16U) |
|
||||
((uint32_t)iv[2] << 8U) | iv[3];
|
||||
instance->data_2 = ((uint64_t)out[8] << 16U) | ((uint64_t)out[9] << 8U) | out[10];
|
||||
instance->seed = ((uint32_t)iv[0] << 24U) | ((uint32_t)iv[1] << 16U) |
|
||||
((uint32_t)iv[2] << 8U) | iv[3];
|
||||
} else if(!instance->hitag2_key_valid && instance->recovered != HITAG2_RECOVERED_YES) {
|
||||
ret = SubGhzProtocolStatusErrorParserOthers;
|
||||
break;
|
||||
@@ -917,7 +919,7 @@ SubGhzProtocolStatus
|
||||
ret = SubGhzProtocolStatusErrorParserOthers;
|
||||
break;
|
||||
}
|
||||
hitag2_u64_to_bytes_be(instance->generic.data_2, key_data, 8);
|
||||
hitag2_u64_to_bytes_be(instance->data_2, key_data, 8);
|
||||
if(!flipper_format_insert_or_update_hex(
|
||||
flipper_format, "Key_2", key_data, sizeof(key_data))) {
|
||||
ret = SubGhzProtocolStatusErrorParserOthers;
|
||||
@@ -930,7 +932,7 @@ SubGhzProtocolStatus
|
||||
ret = SubGhzProtocolStatusErrorParserOthers;
|
||||
break;
|
||||
}
|
||||
if(!hitag2_write_hex_be(flipper_format, "Seed", instance->generic.seed, 4)) {
|
||||
if(!hitag2_write_hex_be(flipper_format, "Seed", instance->seed, 4)) {
|
||||
ret = SubGhzProtocolStatusErrorParserOthers;
|
||||
break;
|
||||
}
|
||||
@@ -939,7 +941,7 @@ SubGhzProtocolStatus
|
||||
{
|
||||
uint32_t hop = 0;
|
||||
hitag2_unpack_frame(
|
||||
instance->generic.data, instance->generic.data_2, NULL, NULL, NULL, &hop, NULL);
|
||||
instance->generic.data, instance->data_2, NULL, NULL, NULL, &hop, NULL);
|
||||
hitag2_write_named_fields(
|
||||
flipper_format,
|
||||
instance->generic.serial,
|
||||
@@ -1024,14 +1026,14 @@ static bool hitag2_accept_frame(SubGhzProtocolDecoderRenaultV1* instance, uint64
|
||||
return false;
|
||||
}
|
||||
|
||||
instance->generic.data_2 = key_2;
|
||||
instance->data_2 = key_2;
|
||||
instance->generic.data_count_bit = HITAG2_MIN_COUNT_BIT;
|
||||
instance->recovered = 0;
|
||||
instance->generic.seed = 0;
|
||||
instance->seed = 0;
|
||||
uint16_t cnt10 = 0;
|
||||
hitag2_unpack_frame(
|
||||
instance->generic.data,
|
||||
instance->generic.data_2,
|
||||
instance->data_2,
|
||||
&instance->generic.serial,
|
||||
&instance->generic.btn,
|
||||
&cnt10,
|
||||
@@ -1180,26 +1182,26 @@ SubGhzProtocolStatus subghz_protocol_decoder_renault_v1_serialize(
|
||||
const uint32_t serial = instance->generic.serial;
|
||||
const uint8_t btn = instance->generic.btn;
|
||||
const uint32_t cnt = instance->generic.cnt;
|
||||
const uint32_t seed = instance->generic.seed;
|
||||
const uint64_t data_2 = instance->generic.data_2;
|
||||
const uint32_t seed = instance->seed;
|
||||
const uint64_t data_2 = instance->data_2;
|
||||
instance->generic.serial = 0;
|
||||
instance->generic.btn = 0;
|
||||
instance->generic.cnt = 0;
|
||||
instance->generic.seed = 0;
|
||||
instance->generic.data_2 = 0;
|
||||
instance->seed = 0;
|
||||
instance->data_2 = 0;
|
||||
SubGhzProtocolStatus ret =
|
||||
subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
|
||||
instance->generic.serial = serial;
|
||||
instance->generic.btn = btn;
|
||||
instance->generic.cnt = cnt;
|
||||
instance->generic.seed = seed;
|
||||
instance->generic.data_2 = data_2;
|
||||
instance->seed = seed;
|
||||
instance->data_2 = data_2;
|
||||
if(ret != SubGhzProtocolStatusOk) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = hitag2_write_extra_fields(
|
||||
flipper_format, instance->generic.data_2, instance->recovered, instance->generic.seed);
|
||||
flipper_format, instance->data_2, instance->recovered, instance->seed);
|
||||
if(ret != SubGhzProtocolStatusOk) {
|
||||
return ret;
|
||||
}
|
||||
@@ -1231,10 +1233,9 @@ SubGhzProtocolStatus
|
||||
ret = SubGhzProtocolStatusErrorParserOthers;
|
||||
break;
|
||||
}
|
||||
instance->generic.data_2 = hitag2_bytes_to_u64_be(key2, sizeof(key2));
|
||||
instance->data_2 = hitag2_bytes_to_u64_be(key2, sizeof(key2));
|
||||
|
||||
hitag2_read_recovered_and_seed(
|
||||
flipper_format, &instance->recovered, &instance->generic.seed);
|
||||
hitag2_read_recovered_and_seed(flipper_format, &instance->recovered, &instance->seed);
|
||||
|
||||
renault_v1_check_remote_controller(instance);
|
||||
instance->hitag2_key_valid = false;
|
||||
@@ -1264,7 +1265,7 @@ void subghz_protocol_decoder_renault_v1_get_string(void* context, FuriString* ou
|
||||
"%s\r\nK1:%016llX\r\nK2:%06llX Sn:%08lX\r\nBtn:%02X [%s] %db",
|
||||
instance->generic.protocol_name,
|
||||
(unsigned long long)instance->generic.data,
|
||||
(unsigned long long)(instance->generic.data_2 & 0xFFFFFFULL),
|
||||
(unsigned long long)(instance->data_2 & 0xFFFFFFULL),
|
||||
(unsigned long)instance->generic.serial,
|
||||
instance->generic.btn,
|
||||
hitag2_get_button_name(instance->generic.btn),
|
||||
@@ -1274,7 +1275,7 @@ void subghz_protocol_decoder_renault_v1_get_string(void* context, FuriString* ou
|
||||
furi_string_cat_printf(
|
||||
output,
|
||||
"\r\nIV:%08lX Cnt:%04lX",
|
||||
(unsigned long)instance->generic.seed,
|
||||
(unsigned long)instance->seed,
|
||||
(unsigned long)(instance->generic.cnt & 0xFFFFU));
|
||||
} else if(instance->recovered == HITAG2_RECOVERED_BF_MISS) {
|
||||
furi_string_cat_printf(output, "\r\nBF not found");
|
||||
|
||||
@@ -88,6 +88,7 @@ ProtoPirateApp* protopirate_app_alloc() {
|
||||
|
||||
// Apply auto-save setting
|
||||
app->auto_save = settings.auto_save;
|
||||
app->sound = settings.sound;
|
||||
app->check_saved = settings.check_saved;
|
||||
app->tx_power = settings.tx_power;
|
||||
#ifdef ENABLE_EMULATE_FEATURE
|
||||
@@ -176,6 +177,7 @@ void protopirate_app_free(ProtoPirateApp* app) {
|
||||
ProtoPirateSettings settings;
|
||||
settings.frequency = app->txrx->preset->frequency;
|
||||
settings.auto_save = app->auto_save;
|
||||
settings.sound = app->sound;
|
||||
settings.check_saved = app->check_saved;
|
||||
settings.tx_power = app->tx_power;
|
||||
settings.hopping_enabled = (app->txrx->hopper_state != ProtoPirateHopperStateOFF);
|
||||
|
||||
@@ -83,6 +83,7 @@ struct ProtoPirateApp {
|
||||
FuriString* loaded_file_path;
|
||||
bool auto_save;
|
||||
bool check_saved;
|
||||
bool sound;
|
||||
bool radio_initialized;
|
||||
uint32_t start_tx_time;
|
||||
uint8_t tx_power;
|
||||
|
||||
@@ -56,8 +56,10 @@ static void protopirate_scene_receiver_callback(
|
||||
protopirate_history_add_to_history(app->txrx->history, decoder_base, app->txrx->preset);
|
||||
|
||||
if(added) {
|
||||
notification_message(app->notifications, &sequence_semi_success);
|
||||
|
||||
if(!(app->sound))
|
||||
notification_message(app->notifications, &sequence_semi_success);
|
||||
else
|
||||
notification_message(app->notifications, &sequence_single_vibro);
|
||||
FURI_LOG_I(
|
||||
TAG,
|
||||
"Added to history, total items: %u",
|
||||
|
||||
@@ -9,6 +9,7 @@ enum ProtoPirateSettingIndex {
|
||||
ProtoPirateSettingIndexTXPower,
|
||||
#endif
|
||||
ProtoPirateSettingIndexAutoSave,
|
||||
ProtoPirateSettingIndexSound,
|
||||
ProtoPirateSettingIndexCheckSaved,
|
||||
ProtoPirateSettingIndexLock,
|
||||
};
|
||||
@@ -188,6 +189,14 @@ static void protopirate_scene_receiver_config_set_check_saved(VariableItem* item
|
||||
variable_item_set_current_value_text(item, check_saved_text[index]);
|
||||
}
|
||||
|
||||
static void protopirate_scene_receiver_config_set_sound(VariableItem* item) {
|
||||
ProtoPirateApp* app = variable_item_get_context(item);
|
||||
uint8_t index = variable_item_get_current_value_index(item);
|
||||
app->sound = (index == 1);
|
||||
|
||||
variable_item_set_current_value_text(item, auto_save_text[index]);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_EMULATE_FEATURE
|
||||
static void protopirate_scene_receiver_config_set_tx_power(VariableItem* item) {
|
||||
ProtoPirateApp* app = variable_item_get_context(item);
|
||||
@@ -292,6 +301,16 @@ void protopirate_scene_receiver_config_on_enter(void* context) {
|
||||
variable_item_set_current_value_index(item, app->check_saved ? 1 : 0);
|
||||
variable_item_set_current_value_text(item, check_saved_text[app->check_saved ? 1 : 0]);
|
||||
|
||||
// Sound option
|
||||
item = variable_item_list_add(
|
||||
app->variable_item_list,
|
||||
"Sound:",
|
||||
AUTO_SAVE_COUNT,
|
||||
protopirate_scene_receiver_config_set_sound,
|
||||
app);
|
||||
variable_item_set_current_value_index(item, app->sound);
|
||||
variable_item_set_current_value_text(item, auto_save_text[(!app->sound) ? 0 : 1]);
|
||||
|
||||
variable_item_list_add(app->variable_item_list, "Lock Keyboard", 1, NULL, NULL);
|
||||
variable_item_list_set_enter_callback(
|
||||
app->variable_item_list, protopirate_scene_receiver_config_var_list_enter_callback, app);
|
||||
|
||||
Reference in New Issue
Block a user