@@ -34,6 +34,59 @@ void picopass_device_set_name(PicopassDevice* dev, const char* name) {
3434 strlcpy (dev -> dev_name , name , PICOPASS_DEV_NAME_MAX_LEN );
3535}
3636
37+ // For use with Seader's virtual card processing.
38+ static bool picopass_device_save_file_seader (
39+ PicopassDevice * dev ,
40+ FlipperFormat * file ,
41+ FuriString * file_path ) {
42+ furi_assert (dev );
43+ PicopassPacs * pacs = & dev -> dev_data .pacs ;
44+ PicopassBlock * AA1 = dev -> dev_data .AA1 ;
45+ bool result = false;
46+
47+ const char * seader_file_header = "Flipper Seader Credential" ;
48+ const uint32_t seader_file_version = 1 ;
49+
50+ do {
51+ FURI_LOG_D (
52+ TAG ,
53+ "Save %s %ld to %s" ,
54+ seader_file_header ,
55+ seader_file_version ,
56+ furi_string_get_cstr (file_path ));
57+ if (!flipper_format_file_open_always (file , furi_string_get_cstr (file_path ))) break ;
58+ if (!flipper_format_write_header_cstr (file , seader_file_header , seader_file_version )) break ;
59+ if (!flipper_format_write_uint32 (file , "Bits" , (uint32_t * )& pacs -> bitLength , 1 )) break ;
60+ if (!flipper_format_write_hex (file , "Credential" , pacs -> credential , PICOPASS_BLOCK_LEN ))
61+ break ;
62+
63+ FURI_LOG_D (TAG , "Pre-sio" );
64+ // Seader only captures 64 byte SIO so I'm going to leave it at that
65+ uint8_t sio [64 ];
66+
67+ // TODO: save SR vs SE more properly
68+ if (pacs -> sio ) { // SR
69+ for (uint8_t i = 0 ; i < 8 ; i ++ ) {
70+ memcpy (sio + (i * 8 ), AA1 [10 + i ].data , PICOPASS_BLOCK_LEN );
71+ }
72+ if (!flipper_format_write_hex (file , "SIO" , sio , sizeof (sio ))) break ;
73+ } else if (pacs -> se_enabled ) { //SE
74+ for (uint8_t i = 0 ; i < 8 ; i ++ ) {
75+ memcpy (sio + (i * 8 ), AA1 [6 + i ].data , PICOPASS_BLOCK_LEN );
76+ }
77+ if (!flipper_format_write_hex (file , "SIO" , sio , sizeof (sio ))) break ;
78+ }
79+ FURI_LOG_D (TAG , "post sio" );
80+ if (!flipper_format_write_hex (
81+ file , "Diversifier" , AA1 [PICOPASS_CSN_BLOCK_INDEX ].data , PICOPASS_BLOCK_LEN ))
82+ break ;
83+
84+ result = true;
85+ } while (false);
86+
87+ return result ;
88+ }
89+
3790static bool picopass_device_save_file_lfrfid (PicopassDevice * dev , FuriString * file_path ) {
3891 furi_assert (dev );
3992 PicopassPacs * pacs = & dev -> dev_data .pacs ;
@@ -151,11 +204,13 @@ static bool picopass_device_save_file(
151204 }
152205 }
153206 if (!block_saved ) break ;
207+ saved = true;
154208 } else if (dev -> format == PicopassDeviceSaveFormatLF ) {
155209 saved = picopass_device_save_file_lfrfid (dev , temp_str );
210+ } else if (dev -> format == PicopassDeviceSaveFormatSeader ) {
211+ saved = picopass_device_save_file_seader (dev , file , temp_str );
156212 }
157- saved = true;
158- } while (0 );
213+ } while (false);
159214
160215 if (!saved ) {
161216 dialog_message_show_storage_error (dev -> dialogs , "Can not save\nfile" );
@@ -171,6 +226,9 @@ bool picopass_device_save(PicopassDevice* dev, const char* dev_name) {
171226 dev , dev_name , STORAGE_APP_DATA_PATH_PREFIX , PICOPASS_APP_EXTENSION , true);
172227 } else if (dev -> format == PicopassDeviceSaveFormatLF ) {
173228 return picopass_device_save_file (dev , dev_name , ANY_PATH ("lfrfid" ), ".rfid" , true);
229+ } else if (dev -> format == PicopassDeviceSaveFormatSeader ) {
230+ return picopass_device_save_file (
231+ dev , dev_name , EXT_PATH ("apps_data/seader" ), ".credential" , true);
174232 }
175233
176234 return false;
0 commit comments