@@ -34,6 +34,59 @@ void picopass_device_set_name(PicopassDevice* dev, const char* name) {
34
34
strlcpy (dev -> dev_name , name , PICOPASS_DEV_NAME_MAX_LEN );
35
35
}
36
36
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
+
37
90
static bool picopass_device_save_file_lfrfid (PicopassDevice * dev , FuriString * file_path ) {
38
91
furi_assert (dev );
39
92
PicopassPacs * pacs = & dev -> dev_data .pacs ;
@@ -151,11 +204,13 @@ static bool picopass_device_save_file(
151
204
}
152
205
}
153
206
if (!block_saved ) break ;
207
+ saved = true;
154
208
} else if (dev -> format == PicopassDeviceSaveFormatLF ) {
155
209
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 );
156
212
}
157
- saved = true;
158
- } while (0 );
213
+ } while (false);
159
214
160
215
if (!saved ) {
161
216
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) {
171
226
dev , dev_name , STORAGE_APP_DATA_PATH_PREFIX , PICOPASS_APP_EXTENSION , true);
172
227
} else if (dev -> format == PicopassDeviceSaveFormatLF ) {
173
228
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);
174
232
}
175
233
176
234
return false;
0 commit comments