2020#include <t5577_config.h>
2121#include <t5577_writer.h>
2222#include <dolphin/dolphin.h>
23+ #include <flipper_format.h>
2324
2425#define TAG "T5577 Writer"
2526#define MAX_REPEAT_WRITING_FRAMES 10
@@ -259,24 +260,6 @@ static void t5577_writer_edit_block_slc_change(VariableItem* item) {
259260 furi_string_free (buffer );
260261}
261262
262- void ensure_dir_exists (Storage * storage ) {
263- // If apps_data directory doesn't exist, create it.
264- if (!storage_dir_exists (storage , T5577_WRITER_APPS_DATA_FOLDER )) {
265- FURI_LOG_I (TAG , "Creating directory: %s" , T5577_WRITER_APPS_DATA_FOLDER );
266- storage_simply_mkdir (storage , T5577_WRITER_APPS_DATA_FOLDER );
267- } else {
268- FURI_LOG_I (TAG , "Directory exists: %s" , T5577_WRITER_APPS_DATA_FOLDER );
269- }
270-
271- // If t5577_writer directory doesn't exist, create it.
272- if (!storage_dir_exists (storage , T5577_WRITER_FILE_FOLDER )) {
273- FURI_LOG_I (TAG , "Creating directory: %s" , T5577_WRITER_FILE_FOLDER );
274- storage_simply_mkdir (storage , T5577_WRITER_FILE_FOLDER );
275- } else {
276- FURI_LOG_I (TAG , "Directory exists: %s" , T5577_WRITER_FILE_FOLDER );
277- }
278- }
279-
280263static const char * tag_name_entry_text = "Enter name" ;
281264static const char * tag_name_default_value = "Tag_1" ;
282265static void t5577_writer_file_saver (void * context ) {
@@ -292,40 +275,45 @@ static void t5577_writer_file_saver(void* context) {
292275 T5577WriterModel * model ,
293276 { furi_string_set (model -> tag_name_str , app -> temp_buffer ); },
294277 redraw );
295- FuriString * buffer = furi_string_alloc ();
296278 FuriString * file_path = furi_string_alloc ();
297279 furi_string_printf (
298280 file_path ,
299281 "%s/%s%s" ,
300- T5577_WRITER_FILE_FOLDER ,
282+ STORAGE_APP_DATA_PATH_PREFIX ,
301283 furi_string_get_cstr (model -> tag_name_str ),
302284 T5577_WRITER_FILE_EXTENSION );
303285
304286 Storage * storage = furi_record_open (RECORD_STORAGE );
305- ensure_dir_exists (storage );
306- File * data_file = storage_file_alloc (storage );
307- if (storage_file_open (
308- data_file , furi_string_get_cstr (file_path ), FSAM_WRITE , FSOM_OPEN_ALWAYS )) {
309- furi_string_printf (buffer , "Filetype: Flipper T5577 Raw File\n" );
310- storage_file_write (data_file , furi_string_get_cstr (buffer ), furi_string_size (buffer ));
311- furi_string_printf (buffer , "Version: 1.0\n" );
312- storage_file_write (data_file , furi_string_get_cstr (buffer ), furi_string_size (buffer ));
313- furi_string_printf (buffer , "Modulation: %s\n" , model -> modulation .modulation_name );
314- storage_file_write (data_file , furi_string_get_cstr (buffer ), furi_string_size (buffer ));
315- furi_string_printf (buffer , "RF Clock: %u\n" , model -> rf_clock .rf_clock_num );
316- storage_file_write (data_file , furi_string_get_cstr (buffer ), furi_string_size (buffer ));
317- furi_string_printf (buffer , "Number of User Blocks: %u\n" , model -> user_block_num );
318- storage_file_write (data_file , furi_string_get_cstr (buffer ), furi_string_size (buffer ));
319- furi_string_printf (buffer , "\nRaw Data:\n" );
287+ storage_simply_mkdir (storage , STORAGE_APP_DATA_PATH_PREFIX );
288+ FuriString * buffer = furi_string_alloc ();
289+ FlipperFormat * format = flipper_format_file_alloc (storage );
290+ do {
291+ const uint32_t version = 2 ;
292+ const uint32_t clock_buffer = (uint32_t )model -> rf_clock .rf_clock_num ;
293+ const uint32_t block_num_buffer = (uint32_t )model -> user_block_num ;
294+ if (!flipper_format_file_open_always (format , furi_string_get_cstr (file_path ))) break ;
295+ if (!flipper_format_write_header_cstr (format , "Flipper T5577 Raw File" , version )) break ;
296+ if (!flipper_format_write_string_cstr (
297+ format , "Modulation" , model -> modulation .modulation_name ))
298+ break ;
299+ if (!flipper_format_write_uint32 (format , "RF Clock" , & clock_buffer , 1 )) break ;
300+ if (!flipper_format_write_uint32 (format , "Number of User Blocks" , & block_num_buffer , 1 ))
301+ break ;
302+ if (!flipper_format_write_string_cstr (format , "Raw Data" , "" )) break ; // raw data begins
320303 for (int i = 0 ; i < LFRFID_T5577_BLOCK_COUNT ; i ++ ) {
321- furi_string_cat_printf (buffer , "Block %u: %08lX\n" , i , model -> content [i ]);
304+ furi_string_printf (buffer , "Block %u" , i );
305+ uint8_t byte_array_buffer [app -> bytes_count ];
306+ uint32_to_byte_buffer (model -> content [i ], byte_array_buffer );
307+ if (!flipper_format_write_hex (
308+ format , furi_string_get_cstr (buffer ), byte_array_buffer , app -> bytes_count ))
309+ break ;
322310 }
323- furi_string_push_back ( buffer , '\n' );
324- storage_file_write ( data_file , furi_string_get_cstr ( buffer ), furi_string_size ( buffer ) );
325- storage_file_close ( data_file );
326- view_dispatcher_switch_to_view (
327- app -> view_dispatcher , T5577WriterViewSubmenu ); // maybe add a pop up later
328- }
311+ // signal that the file was written successfully
312+ } while ( 0 );
313+ flipper_format_free ( format );
314+
315+ view_dispatcher_switch_to_view (
316+ app -> view_dispatcher , T5577WriterViewSubmenu ); // maybe add a pop up later
329317}
330318
331319void t5577_writer_update_config_from_load (void * context ) {
@@ -350,21 +338,6 @@ void t5577_writer_update_config_from_load(void* context) {
350338}
351339
352340static const char * edit_block_data_config_label = "Block Data" ;
353- void uint32_to_byte_buffer (uint32_t block_data , uint8_t byte_buffer [4 ]) {
354- byte_buffer [0 ] = (block_data >> 24 ) & 0xFF ;
355- byte_buffer [1 ] = (block_data >> 16 ) & 0xFF ;
356- byte_buffer [2 ] = (block_data >> 8 ) & 0xFF ;
357- byte_buffer [3 ] = block_data & 0xFF ;
358- }
359-
360- uint32_t byte_buffer_to_uint32 (uint8_t byte_buffer [4 ]) {
361- uint32_t block_data = 0 ;
362- block_data |= ((uint32_t )byte_buffer [0 ] << 24 );
363- block_data |= ((uint32_t )byte_buffer [1 ] << 16 );
364- block_data |= ((uint32_t )byte_buffer [2 ] << 8 );
365- block_data |= ((uint32_t )byte_buffer [3 ]);
366- return block_data ;
367- }
368341
369342static void t5577_writer_content_byte_input_confirmed (void * context ) {
370343 T5577WriterApp * app = (T5577WriterApp * )context ;
@@ -469,55 +442,29 @@ void t5577_writer_view_load_callback(void* context) {
469442 T5577WriterModel * model = view_get_model (app -> view_write );
470443 DialogsFileBrowserOptions browser_options ;
471444 Storage * storage = furi_record_open (RECORD_STORAGE );
472- ensure_dir_exists (storage );
473- File * data_file = storage_file_alloc (storage );
445+ storage_simply_mkdir (storage , STORAGE_APP_DATA_PATH_PREFIX );
474446 dialog_file_browser_set_basic_options (& browser_options , T5577_WRITER_FILE_EXTENSION , & I_icon );
475- browser_options .base_path = T5577_WRITER_FILE_FOLDER ;
447+ browser_options .base_path = STORAGE_APP_DATA_PATH_PREFIX ;
476448 furi_string_set (app -> file_path , browser_options .base_path );
477449 FuriString * buffer = furi_string_alloc ();
478450 if (dialog_file_browser_show (app -> dialogs , app -> file_path , app -> file_path , & browser_options )) {
479- if (storage_file_open (
480- data_file , furi_string_get_cstr (app -> file_path ), FSAM_READ , FSOM_OPEN_EXISTING )) {
481- while (!storage_file_eof (data_file )) { // fill buffer with every line because ch == '\n'
482- char ch ;
483- furi_string_reset (buffer );
484- while (storage_file_read (data_file , & ch , 1 ) && !storage_file_eof (data_file )) {
485- furi_string_push_back (buffer , ch );
486- if (ch == '\n' ) {
487- break ;
488- }
489- }
490- if (furi_string_start_with (buffer , "Block " )) {
491- uint32_t row_data_buffer = 0 ;
492- char row_data_char_buffer [] = "00000000" ;
493- uint32_t row_num_buffer = 0 ;
494- char row_num_char_buffer [] = "0" ;
495- int length = furi_string_size (buffer );
496- char ch ;
497- int i = 0 ;
498- while (i < length ) {
499- if (furi_string_get_char (buffer , i ) == ':' ) {
500- row_num_char_buffer [0 ] = furi_string_get_char (buffer , i - 1 );
501- //the number before ":" is block num
502- i += 2 ; // skip a space
503- for (size_t j = 0 ; j < sizeof (row_data_char_buffer ); j ++ ) {
504- ch = furi_string_get_char (buffer , i );
505- row_data_char_buffer [j ] = ch ;
506- i ++ ;
507- }
508- break ;
509- }
510- i ++ ;
511- }
512- sscanf (row_num_char_buffer , "%lx" , & row_num_buffer );
513- sscanf (row_data_char_buffer , "%lx" , & row_data_buffer );
514- model -> content [row_num_buffer ] = row_data_buffer ;
515- }
451+ FlipperFormat * format = flipper_format_file_alloc (storage );
452+ do {
453+ if (!flipper_format_file_open_existing (format , furi_string_get_cstr (app -> file_path )))
454+ break ;
455+ uint8_t byte_array_buffer [app -> bytes_count ];
456+ for (int i = 0 ; i < LFRFID_T5577_BLOCK_COUNT ; i ++ ) {
457+ furi_string_printf (buffer , "Block %u" , i );
458+ if (!flipper_format_read_hex (
459+ format , furi_string_get_cstr (buffer ), byte_array_buffer , app -> bytes_count ))
460+ break ;
461+ model -> content [i ] = byte_buffer_to_uint32 (
462+ byte_array_buffer ); // we only extract the raw data. configs are then updated from block 0
516463 }
517- storage_file_close ( data_file );
518- t5577_writer_update_config_from_load ( app );
519- }
520- storage_file_free ( data_file );
464+ // signal that the file was read successfully
465+ } while ( 0 );
466+ flipper_format_free ( format );
467+ t5577_writer_update_config_from_load ( app );
521468 furi_record_close (RECORD_STORAGE );
522469 }
523470 view_dispatcher_switch_to_view (app -> view_dispatcher , T5577WriterViewSubmenu );
0 commit comments