Eric Betts 1 год назад
Родитель
Сommit
60d2c641cc
3 измененных файлов с 37 добавлено и 7 удалено
  1. 16 4
      picopass_device.c
  2. 2 1
      picopass_device.h
  3. 19 2
      scenes/picopass_scene_card_menu.c

+ 16 - 4
picopass_device.c

@@ -193,7 +193,8 @@ static bool picopass_device_save_file(
             furi_string_printf(temp_str, "%s/%s%s", folder, dev_name, extension);
         }
 
-        if(dev->format == PicopassDeviceSaveFormatHF ||
+        if(dev->format == PicopassDeviceSaveFormatOriginal ||
+           dev->format == PicopassDeviceSaveFormatLegacy ||
            dev->format == PicopassDeviceSaveFormatPartial) {
             // Open file
             if(!flipper_format_file_open_always(file, furi_string_get_cstr(temp_str))) break;
@@ -215,6 +216,12 @@ static bool picopass_device_save_file(
             for(size_t i = 0; i < app_limit; i++) {
                 furi_string_printf(temp_str, "Block %d", i);
                 if(card_data[i].valid) {
+                    if(dev->format == PicopassDeviceSaveFormatLegacy) {
+                        if(i == PICOPASS_ICLASS_PACS_CFG_BLOCK_INDEX) {
+                            card_data[i].data[0] = 0x03;
+                        }
+                    }
+
                     if(!flipper_format_write_hex(
                            file,
                            furi_string_get_cstr(temp_str),
@@ -249,7 +256,7 @@ static bool picopass_device_save_file(
 }
 
 bool picopass_device_save(PicopassDevice* dev, const char* dev_name) {
-    if(dev->format == PicopassDeviceSaveFormatHF) {
+    if(dev->format == PicopassDeviceSaveFormatOriginal) {
         return picopass_device_save_file(
             dev, dev_name, STORAGE_APP_DATA_PATH_PREFIX, PICOPASS_APP_EXTENSION, true);
     } else if(dev->format == PicopassDeviceSaveFormatLF) {
@@ -260,6 +267,11 @@ bool picopass_device_save(PicopassDevice* dev, const char* dev_name) {
     } else if(dev->format == PicopassDeviceSaveFormatPartial) {
         return picopass_device_save_file(
             dev, dev_name, STORAGE_APP_DATA_PATH_PREFIX, PICOPASS_APP_EXTENSION, true);
+    } else if(dev->format == PicopassDeviceSaveFormatLegacy) {
+        return picopass_device_save_file(
+            dev, dev_name, STORAGE_APP_DATA_PATH_PREFIX, PICOPASS_APP_EXTENSION, true);
+    } else {
+        FURI_LOG_E(TAG, "Unknown format");
     }
 
     return false;
@@ -382,7 +394,7 @@ void picopass_device_clear(PicopassDevice* dev) {
 
     picopass_device_data_clear(&dev->dev_data);
     memset(&dev->dev_data, 0, sizeof(dev->dev_data));
-    dev->format = PicopassDeviceSaveFormatHF;
+    dev->format = PicopassDeviceSaveFormatOriginal;
     furi_string_reset(dev->load_path);
 }
 
@@ -441,7 +453,7 @@ void picopass_device_data_clear(PicopassDeviceData* dev_data) {
 
 bool picopass_device_delete(PicopassDevice* dev, bool use_load_path) {
     furi_assert(dev);
-    if(dev->format != PicopassDeviceSaveFormatHF) {
+    if(dev->format != PicopassDeviceSaveFormatOriginal) {
         // Never delete other formats (LF, Seader, etc)
         return false;
     }

+ 2 - 1
picopass_device.h

@@ -68,7 +68,8 @@ typedef enum {
 } PicopassEncryption;
 
 typedef enum {
-    PicopassDeviceSaveFormatHF,
+    PicopassDeviceSaveFormatOriginal,
+    PicopassDeviceSaveFormatLegacy,
     PicopassDeviceSaveFormatLF,
     PicopassDeviceSaveFormatSeader,
     PicopassDeviceSaveFormatPartial,

+ 19 - 2
scenes/picopass_scene_card_menu.c

@@ -9,6 +9,7 @@ enum SubmenuIndex {
     SubmenuIndexWrite,
     SubmenuIndexEmulate,
     SubmenuIndexSavePartial,
+    SubmenuIndexSaveLegacy,
 };
 
 void picopass_scene_card_menu_submenu_callback(void* context, uint32_t index) {
@@ -27,7 +28,8 @@ void picopass_scene_card_menu_on_enter(void* context) {
 
     bool SE = card_data[PICOPASS_ICLASS_PACS_CFG_BLOCK_INDEX].valid &&
               0x30 == card_data[PICOPASS_ICLASS_PACS_CFG_BLOCK_INDEX].data[0];
-    bool SR = card_data[10].valid && 0x30 == card_data[10].data[0];
+    bool SR = card_data[PICOPASS_ICLASS_PACS_CFG_BLOCK_INDEX].data[0] == 0xA3 &&
+              card_data[10].valid && 0x30 == card_data[10].data[0];
     bool has_sio = SE || SR;
     bool secured = (card_data[PICOPASS_CONFIG_BLOCK_INDEX].data[7] & PICOPASS_FUSE_CRYPT10) !=
                    PICOPASS_FUSE_CRYPT0;
@@ -62,6 +64,15 @@ void picopass_scene_card_menu_on_enter(void* context) {
             picopass_scene_card_menu_submenu_callback,
             picopass);
 
+        if(SR) {
+            submenu_add_item(
+                submenu,
+                "Save as Legacy",
+                SubmenuIndexSaveLegacy,
+                picopass_scene_card_menu_submenu_callback,
+                picopass);
+        }
+
         if(plugin) {
             // Convert from byte array to uint64_t
             uint64_t credential = 0;
@@ -119,7 +130,7 @@ bool picopass_scene_card_menu_on_event(void* context, SceneManagerEvent event) {
             scene_manager_set_scene_state(
                 picopass->scene_manager, PicopassSceneCardMenu, SubmenuIndexSave);
             scene_manager_next_scene(picopass->scene_manager, PicopassSceneSaveName);
-            picopass->dev->format = PicopassDeviceSaveFormatHF;
+            picopass->dev->format = PicopassDeviceSaveFormatOriginal;
             consumed = true;
         } else if(event.event == SubmenuIndexSavePartial) {
             scene_manager_set_scene_state(
@@ -155,6 +166,12 @@ bool picopass_scene_card_menu_on_event(void* context, SceneManagerEvent event) {
                 picopass->scene_manager, PicopassSceneCardMenu, SubmenuIndexParse);
             scene_manager_next_scene(picopass->scene_manager, PicopassSceneFormats);
             consumed = true;
+        } else if(event.event == SubmenuIndexSaveLegacy) {
+            scene_manager_set_scene_state(
+                picopass->scene_manager, PicopassSceneCardMenu, SubmenuIndexSaveLegacy);
+            picopass->dev->format = PicopassDeviceSaveFormatLegacy;
+            scene_manager_next_scene(picopass->scene_manager, PicopassSceneSaveName);
+            consumed = true;
         }
     } else if(event.type == SceneManagerEventTypeBack) {
         consumed = scene_manager_search_and_switch_to_previous_scene(