Просмотр исходного кода

Recreate portal logic with UID caching

Eric Betts 11 месяцев назад
Родитель
Сommit
62a6656fcf
3 измененных файлов с 64 добавлено и 9 удалено
  1. 3 9
      scenes/pof_scene_file_select.c
  2. 60 0
      virtual_portal.c
  3. 1 0
      virtual_portal.h

+ 3 - 9
scenes/pof_scene_file_select.c

@@ -7,24 +7,18 @@ void pof_scene_file_select_on_enter(void* context) {
     PoFApp* pof = context;
     VirtualPortal* virtual_portal = pof->virtual_portal;
 
-    PoFToken* pof_token = NULL;
-    for(int i = 0; i < POF_TOKEN_LIMIT; i++) {
-        if(virtual_portal->tokens[i]->loaded == false) {
-            FURI_LOG_D(TAG, "Loading to slot %d", i);
-            pof_token = virtual_portal->tokens[i];
-            break;
-        }
-    }
+    PoFToken* pof_token = pof_token_alloc();
 
     // Process file_select return
     pof_token_set_loading_callback(pof_token, pof_show_loading_popup, pof);
 
     if(pof_token && pof_file_select(pof_token)) {
+        virtual_portal_load_token(virtual_portal, pof_token);
         scene_manager_next_scene(pof->scene_manager, PoFSceneMain);
     } else {
         scene_manager_search_and_switch_to_previous_scene(pof->scene_manager, PoFSceneMain);
     }
-
+    pof_token_free(pof_token);
     pof_token_set_loading_callback(pof_token, NULL, pof);
 }
 

+ 60 - 0
virtual_portal.c

@@ -32,6 +32,66 @@ void virtual_portal_free(VirtualPortal* virtual_portal) {
     free(virtual_portal);
 }
 
+void virtual_portal_load_token(VirtualPortal* virtual_portal, PoFToken* pof_token) {
+    furi_assert(pof_token);
+    FURI_LOG_D(TAG, "virtual_portal_load_token");
+    PoFToken* target = NULL;
+    uint8_t empty[4] = {0, 0, 0, 0};
+
+    // first try to "reload" to the same slot it used before based on UID
+    for(int i = 0; i < POF_TOKEN_LIMIT; i++) {
+        if(memcmp(virtual_portal->tokens[i]->UID, pof_token->UID, sizeof(pof_token->UID)) == 0) {
+            // Found match
+            if(virtual_portal->tokens[i]->loaded) {
+                // already loaded, no-op
+                return;
+            } else {
+                FURI_LOG_D(TAG, "Found matching UID at index %d", i);
+                target = virtual_portal->tokens[i];
+                break;
+            }
+        }
+    }
+
+    // otherwise load into first slot with no set UID
+    if(target == NULL) {
+        for(int i = 0; i < POF_TOKEN_LIMIT; i++) {
+            if(memcmp(virtual_portal->tokens[i]->UID, empty, sizeof(empty)) == 0) {
+                FURI_LOG_D(TAG, "Found empty UID at index %d", i);
+                // By definition an empty UID slot would not be loaded, so I'm not checking.  Fight me.
+                target = virtual_portal->tokens[i];
+                break;
+            }
+        }
+    }
+
+    // Re-use first unloaded slot
+    if(target == NULL) {
+        for(int i = 0; i < POF_TOKEN_LIMIT; i++) {
+            if(virtual_portal->tokens[i]->loaded == false) {
+                FURI_LOG_D(TAG, "Re-using previously used slot %d", i);
+                target = virtual_portal->tokens[i];
+                break;
+            }
+        }
+    }
+
+    if(target == NULL) {
+        FURI_LOG_W(TAG, "Failed to find slot to token into");
+        return;
+    }
+    furi_assert(target);
+
+    // TODO: make pof_token_copy()
+    target->change = pof_token->change;
+    target->loaded = pof_token->loaded;
+    memcpy(target->dev_name, pof_token->dev_name, sizeof(pof_token->dev_name));
+    memcpy(target->UID, pof_token->UID, sizeof(pof_token->UID));
+
+    const NfcDeviceData* data = nfc_device_get_data(pof_token->nfc_device, NfcProtocolMfClassic);
+    nfc_device_set_data(target->nfc_device, NfcProtocolMfClassic, data);
+}
+
 uint8_t virtual_portal_next_sequence(VirtualPortal* virtual_portal) {
     if(virtual_portal->sequence_number == 0xff) {
         virtual_portal->sequence_number = 0;

+ 1 - 0
virtual_portal.h

@@ -17,6 +17,7 @@ typedef struct {
 VirtualPortal* virtual_portal_alloc(NotificationApp* notifications);
 
 void virtual_portal_free(VirtualPortal* virtual_portal);
+void virtual_portal_load_token(VirtualPortal* virtual_portal, PoFToken* pof_token);
 
 int virtual_portal_process_message(
     VirtualPortal* virtual_portal,