Github Copilot: pool of furi_string for scenes

This commit is contained in:
Eric Betts
2025-09-27 13:19:40 -07:00
parent 3f22b1cbc4
commit 5f41f931ba
9 changed files with 121 additions and 131 deletions
+6 -8
View File
@@ -19,10 +19,11 @@ void seader_scene_credential_info_on_enter(void* context) {
PluginWiegand* plugin = seader->plugin_wiegand;
Widget* widget = seader->widget;
FuriString* type_str = furi_string_alloc();
FuriString* bitlength_str = furi_string_alloc();
FuriString* credential_str = furi_string_alloc();
FuriString* sio_str = furi_string_alloc();
// Use reusable strings instead of allocating new ones
FuriString* type_str = seader->temp_string1;
FuriString* bitlength_str = seader->temp_string2;
FuriString* credential_str = seader->temp_string3;
FuriString* sio_str = seader->temp_string4;
furi_string_set(credential_str, "");
furi_string_set(bitlength_str, "");
@@ -86,10 +87,7 @@ void seader_scene_credential_info_on_enter(void* context) {
widget, 64, 48, AlignCenter, AlignCenter, FontSecondary, furi_string_get_cstr(sio_str));
}
furi_string_free(bitlength_str);
furi_string_free(type_str);
furi_string_free(credential_str);
furi_string_free(sio_str);
// No need to free strings as they are reused from seader struct
view_dispatcher_switch_to_view(seader->view_dispatcher, SeaderViewWidget);
}
+4 -2
View File
@@ -10,14 +10,16 @@ void seader_scene_formats_on_enter(void* context) {
furi_string_reset(str);
if(plugin) {
FuriString* description = furi_string_alloc();
// Use reusable string instead of allocating new one
FuriString* description = seader->temp_string1;
furi_string_reset(description);
size_t format_count = plugin->count(credential->bit_length, credential->credential);
for(size_t i = 0; i < format_count; i++) {
plugin->description(credential->bit_length, credential->credential, i, description);
furi_string_cat_printf(str, "%s\n", furi_string_get_cstr(description));
}
furi_string_free(description);
// No need to free description as it's reused from seader struct
}
text_box_set_font(seader->text_box, TextBoxFontHex);
+6 -8
View File
@@ -19,10 +19,11 @@ void seader_scene_read_card_success_on_enter(void* context) {
PluginWiegand* plugin = seader->plugin_wiegand;
Widget* widget = seader->widget;
FuriString* type_str = furi_string_alloc();
FuriString* bitlength_str = furi_string_alloc();
FuriString* credential_str = furi_string_alloc();
FuriString* sio_str = furi_string_alloc();
// Use reusable strings instead of allocating new ones
FuriString* type_str = seader->temp_string1;
FuriString* bitlength_str = seader->temp_string2;
FuriString* credential_str = seader->temp_string3;
FuriString* sio_str = seader->temp_string4;
dolphin_deed(DolphinDeedNfcReadSuccess);
@@ -100,10 +101,7 @@ void seader_scene_read_card_success_on_enter(void* context) {
widget, 64, 48, AlignCenter, AlignCenter, FontSecondary, furi_string_get_cstr(sio_str));
}
furi_string_free(credential_str);
furi_string_free(bitlength_str);
furi_string_free(type_str);
furi_string_free(sio_str);
// No need to free strings as they are reused from seader struct
view_dispatcher_switch_to_view(seader->view_dispatcher, SeaderViewWidget);
}
+3 -2
View File
@@ -15,7 +15,8 @@ void seader_scene_sam_info_on_enter(void* context) {
SeaderWorker* seader_worker = seader->worker;
Widget* widget = seader->widget;
FuriString* fw_str = furi_string_alloc();
// Use reusable string instead of allocating new one
FuriString* fw_str = seader->temp_string1;
furi_string_cat_printf(
fw_str, "FW %d.%d", seader_worker->sam_version[0], seader_worker->sam_version[1]);
@@ -26,7 +27,7 @@ void seader_scene_sam_info_on_enter(void* context) {
widget_add_string_element(
widget, 64, 5, AlignCenter, AlignCenter, FontSecondary, furi_string_get_cstr(fw_str));
furi_string_free(fw_str);
// No need to free fw_str as it's reused from seader struct
view_dispatcher_switch_to_view(seader->view_dispatcher, SeaderViewWidget);
}
+3 -2
View File
@@ -53,7 +53,8 @@ void seader_scene_sam_present_on_update(void* context) {
seader);
}
if(seader_worker->sam_version[0] != 0 && seader_worker->sam_version[1] != 0) {
FuriString* fw_str = furi_string_alloc();
// Use reusable string instead of allocating new one
FuriString* fw_str = seader->temp_string1;
furi_string_cat_printf(
fw_str, "FW %d.%d", seader_worker->sam_version[0], seader_worker->sam_version[1]);
submenu_add_item(
@@ -62,7 +63,7 @@ void seader_scene_sam_present_on_update(void* context) {
SubmenuIndexFwVersion,
seader_scene_sam_present_submenu_callback,
seader);
furi_string_free(fw_str);
// No need to free fw_str as it's reused from seader struct
fwChecks = 0;
}
+3 -2
View File
@@ -32,7 +32,8 @@ void seader_scene_save_name_on_enter(void* context) {
SEADER_CRED_NAME_MAX_LEN,
cred_name_empty);
FuriString* folder_path = furi_string_alloc();
// Use reusable string instead of allocating new one
FuriString* folder_path = seader->temp_string1;
if(furi_string_end_with(seader->credential->load_path, SEADER_APP_EXTENSION)) {
path_extract_dirname(furi_string_get_cstr(seader->credential->load_path), folder_path);
} else {
@@ -45,7 +46,7 @@ void seader_scene_save_name_on_enter(void* context) {
view_dispatcher_switch_to_view(seader->view_dispatcher, SeaderViewTextInput);
furi_string_free(folder_path);
// No need to free folder_path as it's reused from seader struct
}
bool seader_scene_save_name_on_event(void* context, SceneManagerEvent event) {
+12
View File
@@ -90,6 +90,12 @@ Seader* seader_alloc() {
view_dispatcher_add_view(
seader->view_dispatcher, SeaderViewWidget, widget_get_view(seader->widget));
// Allocate reusable strings for scene optimization
seader->temp_string1 = furi_string_alloc();
seader->temp_string2 = furi_string_alloc();
seader->temp_string3 = furi_string_alloc();
seader->temp_string4 = furi_string_alloc();
seader->plugin_manager =
plugin_manager_alloc(PLUGIN_APP_ID, PLUGIN_API_VERSION, firmware_api_interface);
@@ -157,6 +163,12 @@ void seader_free(Seader* seader) {
view_dispatcher_remove_view(seader->view_dispatcher, SeaderViewWidget);
widget_free(seader->widget);
// Free reusable strings
furi_string_free(seader->temp_string1);
furi_string_free(seader->temp_string2);
furi_string_free(seader->temp_string3);
furi_string_free(seader->temp_string4);
// Worker
seader_worker_stop(seader->worker);
seader_worker_free(seader->worker);
+78 -107
View File
@@ -14,6 +14,41 @@ static const char* seader_file_header = "Flipper Seader Credential";
static const uint32_t seader_file_version = 1;
extern const uint8_t picopass_iclass_key[];
// Static const arrays to optimize stack usage - moved from functions to reduce stack allocation
static const uint8_t seader_manuf_block[16] =
{0xDF, 0xC6, 0x9C, 0x05, 0x80, 0x08, 0x04, 0x00, 0x00, 0x00, 0x73, 0x65, 0x61, 0x64, 0x65, 0x72};
static const uint8_t seader_sector0_trailer[16] =
{0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0x78, 0x77, 0x88, 0xc1, 0x89, 0xec, 0xa9, 0x7f, 0x8c, 0x2a};
static const uint8_t seader_sector1_trailer[16] =
{0x48, 0x49, 0x44, 0x20, 0x49, 0x53, 0x78, 0x77, 0x88, 0xaa, 0x20, 0x47, 0x52, 0x45, 0x41, 0x54};
static const uint8_t seader_section_trailer[16] =
{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x80, 0x69, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
static const uint8_t seader_mad_block[16] =
{0x1b, 0x01, 0x4d, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
static const uint8_t seader_empty_block[16] =
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
// Picopass constants
static const uint8_t seader_picopass_fake_csn[PICOPASS_BLOCK_LEN] =
{0x7a, 0xf5, 0x31, 0x13, 0xfe, 0xff, 0x12, 0xe0};
static const uint8_t seader_picopass_cfg[PICOPASS_BLOCK_LEN] =
{0x12, 0xff, 0xff, 0xff, 0x7f, 0x1f, 0xff, 0x3c};
static const uint8_t seader_picopass_epurse[PICOPASS_BLOCK_LEN] =
{0xff, 0xff, 0xff, 0xff, 0xe3, 0xff, 0xff, 0xff};
static const uint8_t seader_picopass_aia[PICOPASS_BLOCK_LEN] =
{0xFF, 0xff, 0xff, 0xff, 0xFF, 0xFf, 0xff, 0xFF};
static const uint8_t seader_picopass_zero[PICOPASS_BLOCK_LEN] =
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
SeaderCredential* seader_credential_alloc() {
SeaderCredential* seader_dev = malloc(sizeof(SeaderCredential));
seader_dev->credential = 0;
@@ -112,92 +147,6 @@ bool seader_credential_save_mfc(SeaderCredential* cred, const char* name) {
uint8_t uid[4] = {0xDF, 0xC6, 0x9C, 0x05};
uint8_t atqa[2] = {0x00, 0x04};
uint8_t sak = 0x08;
uint8_t manuf_block[16] = {
0xDF,
0xC6,
0x9C,
0x05,
0x80,
0x08,
0x04,
0x00,
0x00,
0x00,
0x73,
0x65,
0x61,
0x64,
0x65,
0x72};
uint8_t sector0_trailer[16] = {
0xa0,
0xa1,
0xa2,
0xa3,
0xa4,
0xa5,
0x78,
0x77,
0x88,
0xc1,
0x89,
0xec,
0xa9,
0x7f,
0x8c,
0x2a};
uint8_t sector1_trailer[16] = {
0x48,
0x49,
0x44,
0x20,
0x49,
0x53,
0x78,
0x77,
0x88,
0xaa,
0x20,
0x47,
0x52,
0x45,
0x41,
0x54};
uint8_t section_trailer[16] = {
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0x07,
0x80,
0x69,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff};
uint8_t mad_block[16] = {
0x1b,
0x01,
0x4d,
0x48,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00};
uint8_t empty_block[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
uint8_t pacs_block[16] = {0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
bool saved = false;
@@ -251,13 +200,19 @@ bool seader_credential_save_mfc(SeaderCredential* cred, const char* name) {
switch(i) {
case 0:
if(!flipper_format_write_hex(
file, furi_string_get_cstr(temp_str), manuf_block, sizeof(manuf_block))) {
file,
furi_string_get_cstr(temp_str),
seader_manuf_block,
sizeof(seader_manuf_block))) {
block_saved = false;
}
break;
case 1:
if(!flipper_format_write_hex(
file, furi_string_get_cstr(temp_str), mad_block, sizeof(mad_block))) {
file,
furi_string_get_cstr(temp_str),
seader_mad_block,
sizeof(seader_mad_block))) {
block_saved = false;
}
break;
@@ -265,8 +220,8 @@ bool seader_credential_save_mfc(SeaderCredential* cred, const char* name) {
if(!flipper_format_write_hex(
file,
furi_string_get_cstr(temp_str),
sector0_trailer,
sizeof(sector0_trailer))) {
seader_sector0_trailer,
sizeof(seader_sector0_trailer))) {
block_saved = false;
}
break;
@@ -280,8 +235,8 @@ bool seader_credential_save_mfc(SeaderCredential* cred, const char* name) {
if(!flipper_format_write_hex(
file,
furi_string_get_cstr(temp_str),
sector1_trailer,
sizeof(sector1_trailer))) {
seader_sector1_trailer,
sizeof(seader_sector1_trailer))) {
block_saved = false;
}
break;
@@ -303,14 +258,17 @@ bool seader_credential_save_mfc(SeaderCredential* cred, const char* name) {
if(!flipper_format_write_hex(
file,
furi_string_get_cstr(temp_str),
section_trailer,
sizeof(section_trailer))) {
seader_section_trailer,
sizeof(seader_section_trailer))) {
block_saved = false;
}
break;
default:
if(!flipper_format_write_hex(
file, furi_string_get_cstr(temp_str), empty_block, sizeof(empty_block))) {
file,
furi_string_get_cstr(temp_str),
seader_empty_block,
sizeof(seader_empty_block))) {
block_saved = false;
}
break;
@@ -381,12 +339,7 @@ bool seader_credential_save_agnostic(SeaderCredential* cred, const char* name) {
}
bool seader_credential_save_picopass(SeaderCredential* cred, const char* name) {
uint8_t zero[PICOPASS_BLOCK_LEN] = {0};
uint8_t fake_csn[PICOPASS_BLOCK_LEN] = {0x7a, 0xf5, 0x31, 0x13, 0xfe, 0xff, 0x12, 0xe0};
uint8_t cfg[PICOPASS_BLOCK_LEN] = {0x12, 0xff, 0xff, 0xff, 0x7f, 0x1f, 0xff, 0x3c};
uint8_t epurse[PICOPASS_BLOCK_LEN] = {0xff, 0xff, 0xff, 0xff, 0xe3, 0xff, 0xff, 0xff};
uint8_t debit_key[PICOPASS_BLOCK_LEN] = {0xe3, 0xf3, 0x07, 0x84, 0x4a, 0x0b, 0x62, 0x04};
uint8_t aia[PICOPASS_BLOCK_LEN] = {0xFF, 0xff, 0xff, 0xff, 0xFF, 0xFf, 0xff, 0xFF};
uint8_t pacs_cfg[PICOPASS_BLOCK_LEN] = {0x03, 0x03, 0x03, 0x03, 0x00, 0x03, 0xe0, 0x14};
bool saved = false;
@@ -416,10 +369,13 @@ bool seader_credential_save_picopass(SeaderCredential* cred, const char* name) {
furi_string_printf(temp_str, "Block %d", i);
switch(i) {
case CSN_INDEX:
if(memcmp(cred->diversifier, zero, PICOPASS_BLOCK_LEN) == 0) {
if(memcmp(cred->diversifier, seader_picopass_zero, PICOPASS_BLOCK_LEN) == 0) {
// when doing a downgrade from a non-picopass, we need to use a fake csn
if(!flipper_format_write_hex(
file, furi_string_get_cstr(temp_str), fake_csn, sizeof(fake_csn))) {
file,
furi_string_get_cstr(temp_str),
seader_picopass_fake_csn,
sizeof(seader_picopass_fake_csn))) {
block_saved = false;
}
} else {
@@ -434,7 +390,10 @@ bool seader_credential_save_picopass(SeaderCredential* cred, const char* name) {
break;
case EPURSE_INDEX:
if(!flipper_format_write_hex(
file, furi_string_get_cstr(temp_str), epurse, PICOPASS_BLOCK_LEN)) {
file,
furi_string_get_cstr(temp_str),
seader_picopass_epurse,
PICOPASS_BLOCK_LEN)) {
block_saved = false;
}
break;
@@ -446,13 +405,19 @@ bool seader_credential_save_picopass(SeaderCredential* cred, const char* name) {
break;
case AIA_INDEX:
if(!flipper_format_write_hex(
file, furi_string_get_cstr(temp_str), aia, PICOPASS_BLOCK_LEN)) {
file,
furi_string_get_cstr(temp_str),
seader_picopass_aia,
PICOPASS_BLOCK_LEN)) {
block_saved = false;
}
break;
case CFG_INDEX:
if(!flipper_format_write_hex(
file, furi_string_get_cstr(temp_str), cfg, sizeof(cfg))) {
file,
furi_string_get_cstr(temp_str),
seader_picopass_cfg,
sizeof(seader_picopass_cfg))) {
block_saved = false;
}
break;
@@ -492,14 +457,20 @@ bool seader_credential_save_picopass(SeaderCredential* cred, const char* name) {
}
} else {
if(!flipper_format_write_hex(
file, furi_string_get_cstr(temp_str), zero, sizeof(zero))) {
file,
furi_string_get_cstr(temp_str),
seader_picopass_zero,
sizeof(seader_picopass_zero))) {
block_saved = false;
}
}
break;
default:
if(!flipper_format_write_hex(
file, furi_string_get_cstr(temp_str), zero, sizeof(zero))) {
file,
furi_string_get_cstr(temp_str),
seader_picopass_zero,
sizeof(seader_picopass_zero))) {
block_saved = false;
}
break;
+6
View File
@@ -111,6 +111,12 @@ struct Seader {
char text_store[SEADER_TEXT_STORE_SIZE + 1];
FuriString* text_box_store;
// Reusable strings to optimize scene string allocations
FuriString* temp_string1;
FuriString* temp_string2;
FuriString* temp_string3;
FuriString* temp_string4;
// Common Views
Submenu* submenu;
Popup* popup;