mirror of
https://protopirate.net/ProtoPirate/ProtoPirate.git
synced 2026-03-29 14:30:23 +00:00
Merge pull request 'gull-parse-scenes' (#15) from gullradriel/ProtoPirate:gull-parse-scenes into main
All checks were successful
FAP Build / ufbt: Build for Momentum release (push) Successful in 39s
FAP Build / ufbt: Build for OFW dev channel (push) Successful in 40s
FAP Build / ufbt: Build for Momentum dev (push) Successful in 1m2s
FAP Build / ufbt: Build for OFW release channel (push) Successful in 37s
FAP Build / ufbt: Build for Unleashed dev (push) Successful in 46s
FAP Build / ufbt: Build for Unleashed release (push) Successful in 56s
All checks were successful
FAP Build / ufbt: Build for Momentum release (push) Successful in 39s
FAP Build / ufbt: Build for OFW dev channel (push) Successful in 40s
FAP Build / ufbt: Build for Momentum dev (push) Successful in 1m2s
FAP Build / ufbt: Build for OFW release channel (push) Successful in 37s
FAP Build / ufbt: Build for Unleashed dev (push) Successful in 46s
FAP Build / ufbt: Build for Unleashed release (push) Successful in 56s
Reviewed-on: http://protopirate.net/ProtoPirate/ProtoPirate/pulls/15 Reviewed-by: MMX <mmx@no-reply.protopirate.net>
This commit is contained in:
@@ -19,6 +19,7 @@ typedef struct {
|
||||
SubGhzTransmitter* transmitter;
|
||||
bool is_transmitting;
|
||||
bool flag_stop_called;
|
||||
Storage* storage;
|
||||
} EmulateContext;
|
||||
|
||||
static EmulateContext* emulate_context = NULL;
|
||||
@@ -77,6 +78,11 @@ static void emulate_context_free(void) {
|
||||
emulate_context->protocol_name = NULL;
|
||||
}
|
||||
|
||||
if(emulate_context->storage) {
|
||||
furi_record_close(RECORD_STORAGE);
|
||||
emulate_context->storage = NULL;
|
||||
}
|
||||
|
||||
free(emulate_context);
|
||||
emulate_context = NULL;
|
||||
}
|
||||
@@ -372,33 +378,46 @@ void protopirate_scene_emulate_on_enter(void* context) {
|
||||
// Load the file
|
||||
if(app->loaded_file_path) {
|
||||
// Open storage once and keep track of it
|
||||
Storage* storage = furi_record_open(RECORD_STORAGE);
|
||||
FlipperFormat* ff = flipper_format_file_alloc(storage);
|
||||
|
||||
if(!flipper_format_file_open_existing(ff, furi_string_get_cstr(app->loaded_file_path))) {
|
||||
FURI_LOG_E(
|
||||
TAG, "Failed to open file: %s", furi_string_get_cstr(app->loaded_file_path));
|
||||
flipper_format_free(ff);
|
||||
furi_record_close(RECORD_STORAGE);
|
||||
emulate_context->storage = furi_record_open(RECORD_STORAGE);
|
||||
if(!emulate_context->storage) {
|
||||
FURI_LOG_E(TAG, "Failed to open storage");
|
||||
emulate_context_free();
|
||||
notification_message(app->notifications, &sequence_error);
|
||||
scene_manager_previous_scene(app->scene_manager);
|
||||
return;
|
||||
}
|
||||
|
||||
emulate_context->flipper_format = ff;
|
||||
emulate_context->flipper_format = flipper_format_file_alloc(emulate_context->storage);
|
||||
if(!emulate_context->flipper_format) {
|
||||
FURI_LOG_E(TAG, "Failed to allocate FlipperFormat");
|
||||
emulate_context_free();
|
||||
notification_message(app->notifications, &sequence_error);
|
||||
scene_manager_previous_scene(app->scene_manager);
|
||||
return;
|
||||
}
|
||||
|
||||
if(!flipper_format_file_open_existing(
|
||||
emulate_context->flipper_format, furi_string_get_cstr(app->loaded_file_path))) {
|
||||
FURI_LOG_E(
|
||||
TAG, "Failed to open file: %s", furi_string_get_cstr(app->loaded_file_path));
|
||||
emulate_context_free();
|
||||
notification_message(app->notifications, &sequence_error);
|
||||
scene_manager_previous_scene(app->scene_manager);
|
||||
return;
|
||||
}
|
||||
|
||||
// Read frequency and preset from the saved file
|
||||
uint32_t frequency = 433920000;
|
||||
FuriString* preset_str = furi_string_alloc();
|
||||
|
||||
flipper_format_rewind(ff);
|
||||
if(!flipper_format_read_uint32(ff, "Frequency", &frequency, 1)) {
|
||||
flipper_format_rewind(emulate_context->flipper_format);
|
||||
if(!flipper_format_read_uint32(
|
||||
emulate_context->flipper_format, "Frequency", &frequency, 1)) {
|
||||
FURI_LOG_W(TAG, "Failed to read frequency, using default 433.92MHz");
|
||||
}
|
||||
|
||||
flipper_format_rewind(ff);
|
||||
if(!flipper_format_read_string(ff, "Preset", preset_str)) {
|
||||
flipper_format_rewind(emulate_context->flipper_format);
|
||||
if(!flipper_format_read_string(emulate_context->flipper_format, "Preset", preset_str)) {
|
||||
FURI_LOG_W(TAG, "Failed to read preset, using AM650");
|
||||
furi_string_set(preset_str, "AM650");
|
||||
}
|
||||
@@ -415,29 +434,32 @@ void protopirate_scene_emulate_on_enter(void* context) {
|
||||
furi_string_free(preset_str);
|
||||
|
||||
// Read protocol name
|
||||
flipper_format_rewind(ff);
|
||||
if(!flipper_format_read_string(ff, "Protocol", emulate_context->protocol_name)) {
|
||||
flipper_format_rewind(emulate_context->flipper_format);
|
||||
if(!flipper_format_read_string(
|
||||
emulate_context->flipper_format, "Protocol", emulate_context->protocol_name)) {
|
||||
FURI_LOG_E(TAG, "Failed to read protocol name");
|
||||
furi_string_set(emulate_context->protocol_name, "Unknown");
|
||||
}
|
||||
|
||||
// Read serial
|
||||
flipper_format_rewind(ff);
|
||||
if(!flipper_format_read_uint32(ff, "Serial", &emulate_context->serial, 1)) {
|
||||
flipper_format_rewind(emulate_context->flipper_format);
|
||||
if(!flipper_format_read_uint32(
|
||||
emulate_context->flipper_format, "Serial", &emulate_context->serial, 1)) {
|
||||
FURI_LOG_W(TAG, "Failed to read serial");
|
||||
emulate_context->serial = 0;
|
||||
}
|
||||
|
||||
// Read original button
|
||||
flipper_format_rewind(ff);
|
||||
flipper_format_rewind(emulate_context->flipper_format);
|
||||
uint32_t btn_temp = 0;
|
||||
if(flipper_format_read_uint32(ff, "Btn", &btn_temp, 1)) {
|
||||
if(flipper_format_read_uint32(emulate_context->flipper_format, "Btn", &btn_temp, 1)) {
|
||||
emulate_context->original_button = (uint8_t)btn_temp;
|
||||
}
|
||||
|
||||
// Read counter
|
||||
flipper_format_rewind(ff);
|
||||
if(flipper_format_read_uint32(ff, "Cnt", &emulate_context->original_counter, 1)) {
|
||||
flipper_format_rewind(emulate_context->flipper_format);
|
||||
if(flipper_format_read_uint32(
|
||||
emulate_context->flipper_format, "Cnt", &emulate_context->original_counter, 1)) {
|
||||
emulate_context->current_counter = emulate_context->original_counter;
|
||||
}
|
||||
|
||||
@@ -475,9 +497,9 @@ void protopirate_scene_emulate_on_enter(void* context) {
|
||||
FURI_LOG_I(TAG, "Transmitter allocated successfully");
|
||||
|
||||
// Deserialize for transmission
|
||||
flipper_format_rewind(ff);
|
||||
SubGhzProtocolStatus status =
|
||||
subghz_transmitter_deserialize(emulate_context->transmitter, ff);
|
||||
flipper_format_rewind(emulate_context->flipper_format);
|
||||
SubGhzProtocolStatus status = subghz_transmitter_deserialize(
|
||||
emulate_context->transmitter, emulate_context->flipper_format);
|
||||
|
||||
if(status != SubGhzProtocolStatusOk) {
|
||||
FURI_LOG_E(TAG, "Failed to deserialize transmitter, status: %d", status);
|
||||
@@ -723,9 +745,6 @@ void protopirate_scene_emulate_on_exit(void* context) {
|
||||
// Free emulate context and all its resources
|
||||
emulate_context_free();
|
||||
|
||||
// Close storage record that was opened in on_enter
|
||||
furi_record_close(RECORD_STORAGE);
|
||||
|
||||
// Delete temp file if we were using one
|
||||
protopirate_storage_delete_temp();
|
||||
|
||||
|
||||
@@ -10,10 +10,27 @@
|
||||
void protopirate_scene_receiver_view_callback(ProtoPirateCustomEvent event, void* context);
|
||||
|
||||
static void protopirate_scene_receiver_update_statusbar(void* context) {
|
||||
furi_check(context);
|
||||
ProtoPirateApp* app = context;
|
||||
|
||||
FuriString* frequency_str = furi_string_alloc();
|
||||
if(!frequency_str) {
|
||||
FURI_LOG_E(TAG, "frequency_str allocation failed");
|
||||
return;
|
||||
}
|
||||
FuriString* modulation_str = furi_string_alloc();
|
||||
if(!modulation_str) {
|
||||
FURI_LOG_E(TAG, "modulation_str allocation failed");
|
||||
furi_string_free(frequency_str);
|
||||
return;
|
||||
}
|
||||
FuriString* history_stat_str = furi_string_alloc();
|
||||
if(!history_stat_str) {
|
||||
FURI_LOG_E(TAG, "history_stat_str allocation failed");
|
||||
furi_string_free(frequency_str);
|
||||
furi_string_free(modulation_str);
|
||||
return;
|
||||
}
|
||||
|
||||
protopirate_get_frequency_modulation(app, frequency_str, modulation_str);
|
||||
|
||||
@@ -30,12 +47,6 @@ static void protopirate_scene_receiver_update_statusbar(void* context) {
|
||||
"%u/%u",
|
||||
protopirate_history_get_item(app->txrx->history),
|
||||
PROTOPIRATE_DISPLAY_HISTORY_MAX);
|
||||
} else {
|
||||
furi_string_printf(
|
||||
history_stat_str,
|
||||
"%u/%u",
|
||||
protopirate_history_get_item(app->txrx->history),
|
||||
PROTOPIRATE_DISPLAY_HISTORY_MAX);
|
||||
}
|
||||
|
||||
// Pass actual external radio status
|
||||
@@ -56,12 +67,18 @@ static void protopirate_scene_receiver_callback(
|
||||
SubGhzProtocolDecoderBase* decoder_base,
|
||||
void* context) {
|
||||
UNUSED(receiver);
|
||||
furi_check(decoder_base);
|
||||
furi_check(context);
|
||||
ProtoPirateApp* app = context;
|
||||
|
||||
FURI_LOG_I(TAG, "=== SIGNAL DECODED ===");
|
||||
|
||||
FuriString* str_buff = furi_string_alloc();
|
||||
if(!str_buff) {
|
||||
FURI_LOG_E(TAG, "str_buff allocation failed");
|
||||
return;
|
||||
}
|
||||
|
||||
subghz_protocol_decoder_base_get_string(decoder_base, str_buff);
|
||||
FURI_LOG_I(TAG, "%s", furi_string_get_cstr(str_buff));
|
||||
|
||||
@@ -75,6 +92,11 @@ static void protopirate_scene_receiver_callback(
|
||||
protopirate_history_get_item(app->txrx->history));
|
||||
|
||||
FuriString* item_name = furi_string_alloc();
|
||||
if(!item_name) {
|
||||
FURI_LOG_E(TAG, "item_name allocation failed");
|
||||
return;
|
||||
}
|
||||
|
||||
protopirate_history_get_text_item_menu(
|
||||
app->txrx->history, item_name, protopirate_history_get_item(app->txrx->history) - 1);
|
||||
|
||||
@@ -94,6 +116,12 @@ static void protopirate_scene_receiver_callback(
|
||||
|
||||
if(ff) {
|
||||
FuriString* protocol = furi_string_alloc();
|
||||
if(!protocol) {
|
||||
FURI_LOG_E(TAG, "protocol allocation failed");
|
||||
furi_string_free(str_buff);
|
||||
return;
|
||||
}
|
||||
|
||||
flipper_format_rewind(ff);
|
||||
if(!flipper_format_read_string(ff, "Protocol", protocol)) {
|
||||
furi_string_set_str(protocol, "Unknown");
|
||||
@@ -104,6 +132,13 @@ static void protopirate_scene_receiver_callback(
|
||||
furi_string_replace_all(protocol, " ", "_");
|
||||
|
||||
FuriString* saved_path = furi_string_alloc();
|
||||
if(!protocol) {
|
||||
FURI_LOG_E(TAG, "saved_path allocation failed");
|
||||
furi_string_free(protocol);
|
||||
furi_string_free(str_buff);
|
||||
return;
|
||||
}
|
||||
|
||||
if(protopirate_storage_save_capture(
|
||||
ff, furi_string_get_cstr(protocol), saved_path)) {
|
||||
FURI_LOG_I(TAG, "Auto-saved: %s", furi_string_get_cstr(saved_path));
|
||||
@@ -133,6 +168,7 @@ static void protopirate_scene_receiver_callback(
|
||||
}
|
||||
|
||||
void protopirate_scene_receiver_on_enter(void* context) {
|
||||
furi_check(context);
|
||||
ProtoPirateApp* app = context;
|
||||
|
||||
FURI_LOG_I(TAG, "=== ENTERING RECEIVER SCENE ===");
|
||||
@@ -141,7 +177,8 @@ void protopirate_scene_receiver_on_enter(void* context) {
|
||||
#ifndef REMOVE_LOGS
|
||||
bool is_external =
|
||||
app->txrx->radio_device ? radio_device_loader_is_external(app->txrx->radio_device) : false;
|
||||
const char* device_name = subghz_devices_get_name(app->txrx->radio_device);
|
||||
const char* device_name =
|
||||
app->txrx->radio_device ? subghz_devices_get_name(app->txrx->radio_device) : NULL;
|
||||
FURI_LOG_I(TAG, "Radio device: %s", device_name ? device_name : "NULL");
|
||||
FURI_LOG_I(TAG, "Is External: %s", is_external ? "YES" : "NO");
|
||||
FURI_LOG_I(TAG, "Frequency: %lu Hz", app->txrx->preset->frequency);
|
||||
@@ -221,6 +258,7 @@ void protopirate_scene_receiver_on_enter(void* context) {
|
||||
}
|
||||
|
||||
bool protopirate_scene_receiver_on_event(void* context, SceneManagerEvent event) {
|
||||
furi_check(context);
|
||||
ProtoPirateApp* app = context;
|
||||
bool consumed = false;
|
||||
|
||||
@@ -273,7 +311,8 @@ bool protopirate_scene_receiver_on_event(void* context, SceneManagerEvent event)
|
||||
}
|
||||
|
||||
// Update RSSI from the correct radio device (only if initialized)
|
||||
if(app->radio_initialized && app->txrx->txrx_state == ProtoPirateTxRxStateRx) {
|
||||
if(app->radio_initialized && app->txrx->txrx_state == ProtoPirateTxRxStateRx &&
|
||||
app->txrx->radio_device) {
|
||||
float rssi = subghz_devices_get_rssi(app->txrx->radio_device);
|
||||
protopirate_view_receiver_set_rssi(app->protopirate_receiver, rssi);
|
||||
|
||||
@@ -300,6 +339,7 @@ bool protopirate_scene_receiver_on_event(void* context, SceneManagerEvent event)
|
||||
}
|
||||
|
||||
void protopirate_scene_receiver_on_exit(void* context) {
|
||||
furi_check(context);
|
||||
ProtoPirateApp* app = context;
|
||||
|
||||
FURI_LOG_I(TAG, "=== EXITING RECEIVER SCENE ===");
|
||||
|
||||
@@ -29,6 +29,9 @@ void protopirate_scene_receiver_info_on_enter(void* context) {
|
||||
furi_check(context);
|
||||
ProtoPirateApp* app = context;
|
||||
|
||||
// Always reset per-enter to avoid stale static state
|
||||
is_emu_off = false;
|
||||
|
||||
widget_reset(app->widget);
|
||||
|
||||
FuriString* text;
|
||||
|
||||
@@ -28,12 +28,15 @@ static void protopirate_scene_saved_info_widget_callback(
|
||||
notification_message(app->notifications, &sequence_semi_success);
|
||||
view_dispatcher_send_custom_event(
|
||||
app->view_dispatcher, ProtoPirateCustomEventSavedInfoDelete);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void protopirate_scene_saved_info_on_enter(void* context) {
|
||||
furi_check(context);
|
||||
ProtoPirateApp* app = context;
|
||||
Storage* storage = NULL;
|
||||
FlipperFormat* ff = NULL;
|
||||
@@ -104,7 +107,9 @@ void protopirate_scene_saved_info_on_enter(void* context) {
|
||||
FURI_LOG_I(TAG, "File opened, reading...");
|
||||
|
||||
// Read fields
|
||||
uint32_t temp_data;
|
||||
uint32_t temp_data = 0;
|
||||
// reset is_emu_off state before loading
|
||||
is_emu_off = false;
|
||||
|
||||
flipper_format_rewind(ff);
|
||||
if(flipper_format_read_string(ff, "Protocol", temp_str)) {
|
||||
@@ -116,8 +121,6 @@ void protopirate_scene_saved_info_on_enter(void* context) {
|
||||
is_emu_off = true;
|
||||
} else if(furi_string_cmp_str(temp_str, "Kia V6") == 0) {
|
||||
is_emu_off = true;
|
||||
} else {
|
||||
is_emu_off = false;
|
||||
}
|
||||
|
||||
flipper_format_rewind(ff);
|
||||
|
||||
@@ -378,8 +378,10 @@ static void close_file_handles(SubDecodeContext* ctx) {
|
||||
flipper_format_free(ctx->ff);
|
||||
ctx->ff = NULL;
|
||||
}
|
||||
furi_record_close(RECORD_STORAGE);
|
||||
//ctx->storage = NULL;
|
||||
if(ctx->storage) {
|
||||
furi_record_close(RECORD_STORAGE);
|
||||
ctx->storage = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Receiver view callback for history navigation
|
||||
@@ -425,6 +427,8 @@ void protopirate_scene_sub_decode_on_enter(void* context) {
|
||||
app->txrx->history = protopirate_history_alloc();
|
||||
if(!app->txrx->history) {
|
||||
FURI_LOG_E(TAG, "Failed to allocate history!");
|
||||
free(g_decode_ctx);
|
||||
g_decode_ctx = NULL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -714,7 +718,16 @@ bool protopirate_scene_sub_decode_on_event(void* context, SceneManagerEvent even
|
||||
FURI_LOG_I(TAG, "StartingWorker: Reading file metadata");
|
||||
|
||||
Storage* storage = furi_record_open(RECORD_STORAGE);
|
||||
if(!storage) {
|
||||
FURI_LOG_E(TAG, "Failed to open storage");
|
||||
break;
|
||||
}
|
||||
FlipperFormat* fff_data_file = flipper_format_file_alloc(storage);
|
||||
if(!fff_data_file) {
|
||||
FURI_LOG_E(TAG, "Failed to allocate FlipperFormat");
|
||||
break;
|
||||
}
|
||||
|
||||
FuriString* temp_str = furi_string_alloc();
|
||||
bool setup_ok = false;
|
||||
|
||||
@@ -803,9 +816,11 @@ bool protopirate_scene_sub_decode_on_event(void* context, SceneManagerEvent even
|
||||
setup_ok = true;
|
||||
} while(false);
|
||||
|
||||
flipper_format_free(fff_data_file);
|
||||
if(fff_data_file) flipper_format_free(fff_data_file);
|
||||
|
||||
if(storage) furi_record_close(RECORD_STORAGE);
|
||||
|
||||
furi_string_free(temp_str);
|
||||
furi_record_close(RECORD_STORAGE);
|
||||
|
||||
if(!setup_ok) {
|
||||
furi_string_set(ctx->result, "Failed to read file metadata");
|
||||
|
||||
@@ -607,11 +607,18 @@ static void timing_tuner_pair_callback(void* context, bool level, uint32_t durat
|
||||
}
|
||||
|
||||
void protopirate_scene_timing_tuner_on_enter(void* context) {
|
||||
furi_check(context);
|
||||
ProtoPirateApp* app = context;
|
||||
|
||||
FURI_LOG_I(TAG, "Entering Timing Tuner");
|
||||
|
||||
g_timing_ctx = malloc(sizeof(TimingTunerContext));
|
||||
if(!g_timing_ctx) {
|
||||
FURI_LOG_E(TAG, "Failed to allocate timing tuner context");
|
||||
notification_message(app->notifications, &sequence_error);
|
||||
scene_manager_previous_scene(app->scene_manager);
|
||||
return;
|
||||
}
|
||||
memset(g_timing_ctx, 0, sizeof(TimingTunerContext));
|
||||
g_timing_ctx->is_receiving = false;
|
||||
g_timing_ctx->has_match = false;
|
||||
@@ -673,8 +680,9 @@ bool protopirate_scene_timing_tuner_on_event(void* context, SceneManagerEvent ev
|
||||
}
|
||||
} else if(event.type == SceneManagerEventTypeTick) {
|
||||
if(g_timing_ctx && g_timing_ctx->is_receiving && !g_timing_ctx->has_match) {
|
||||
g_timing_ctx->rssi = subghz_devices_get_rssi(app->txrx->radio_device);
|
||||
|
||||
if(app->txrx->radio_device) {
|
||||
g_timing_ctx->rssi = subghz_devices_get_rssi(app->txrx->radio_device);
|
||||
}
|
||||
// Blink the light like the SubGHZ app
|
||||
notification_message(app->notifications, &sequence_blink_cyan_10);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user