Eric Betts před 2 roky
rodič
revize
acb848d98e
4 změnil soubory, kde provedl 68 přidání a 22 odebrání
  1. 15 22
      scenes/seader_scene_virtual_credential.c
  2. 1 0
      seader_credential.h
  3. 51 0
      seader_worker.c
  4. 1 0
      seader_worker.h

+ 15 - 22
scenes/seader_scene_virtual_credential.c

@@ -1,24 +1,29 @@
 #include "../seader_i.h"
 #include <dolphin/dolphin.h>
 
+void seader_virtual_credential_worker_callback(SeaderWorkerEvent event, void* context) {
+    Seader* seader = context;
+    view_dispatcher_send_custom_event(seader->view_dispatcher, event);
+}
+
 void seader_scene_virtual_credential_on_enter(void* context) {
     Seader* seader = context;
-    dolphin_deed(DolphinDeedNfcRead);
 
     // Setup view
     Popup* popup = seader->popup;
-    popup_set_header(popup, "Detecting\npicopass\ncard", 68, 30, AlignLeft, AlignTop);
-    popup_set_icon(popup, 0, 3, &I_RFIDDolphinReceive_97x61);
+    popup_set_header(popup, "Processing\nvirtual\npicopass", 68, 30, AlignLeft, AlignTop);
 
     // Start worker
-    view_dispatcher_switch_to_view(seader->view_dispatcher, SeaderViewPopup);
-
-    seader->worker->stage = SeaderPollerEventTypeCardDetect;
     seader_credential_clear(seader->credential);
-    seader->picopass_poller = picopass_poller_alloc(seader->nfc);
-    picopass_poller_start(seader->picopass_poller, seader_worker_poller_callback_picopass, seader);
+    seader->credential->type = SeaderCredentialTypeVirtual;
+    seader_worker_start(
+        seader->worker,
+        SeaderWorkerStateVirtualCredential,
+        seader->uart,
+        seader_virtual_credential_worker_callback,
+        seader);
 
-    seader_blink_start(seader);
+    view_dispatcher_switch_to_view(seader->view_dispatcher, SeaderViewPopup);
 }
 
 bool seader_scene_virtual_credential_on_event(void* context, SceneManagerEvent event) {
@@ -30,15 +35,10 @@ bool seader_scene_virtual_credential_on_event(void* context, SceneManagerEvent e
             seader->credential->type = SeaderCredentialTypePicopass;
             scene_manager_next_scene(seader->scene_manager, SeaderSceneReadCardSuccess);
             consumed = true;
-        } else if(event.event == SeaderCustomEventPollerSuccess) {
-            seader->credential->type = SeaderCredentialTypePicopass;
-            scene_manager_next_scene(seader->scene_manager, SeaderSceneReadCardSuccess);
-            consumed = true;
         }
-
     } else if(event.type == SceneManagerEventTypeBack) {
         scene_manager_search_and_switch_to_previous_scene(
-            seader->scene_manager, SeaderSceneSamPresent);
+            seader->scene_manager, SeaderSceneSavedMenu);
         consumed = true;
     }
     return consumed;
@@ -47,13 +47,6 @@ bool seader_scene_virtual_credential_on_event(void* context, SceneManagerEvent e
 void seader_scene_virtual_credential_on_exit(void* context) {
     Seader* seader = context;
 
-    if(seader->picopass_poller) {
-        picopass_poller_stop(seader->picopass_poller);
-        picopass_poller_free(seader->picopass_poller);
-    }
-
     // Clear view
     popup_reset(seader->popup);
-
-    seader_blink_stop(seader);
 }

+ 1 - 0
seader_credential.h

@@ -18,6 +18,7 @@ typedef enum {
     SeaderCredentialType14A,
     // Might need to make 14a into "javacard" and add Desfire
     SeaderCredentialTypeMifareClassic,
+    SeaderCredentialTypeVirtual,
 } SeaderCredentialType;
 
 typedef enum {

+ 51 - 0
seader_worker.c

@@ -151,13 +151,64 @@ bool seader_worker_process_sam_message(Seader* seader, CCID_Message* message) {
     return false;
 }
 
+void seader_worker_virtual_credential(Seader* seader) {
+    SeaderWorker* seader_worker = seader->worker;
+
+    uint8_t csn[8] = {0xf8, 0x7c, 0xd7, 0x12, 0xff, 0xff, 0x12, 0xe0};
+
+    // Detect card
+    seader_worker_card_detect(seader, 0, NULL, csn, sizeof(PicopassSerialNum), NULL, 0);
+
+    bool running = true;
+    uint8_t loops = 0;
+
+    while(running) {
+        if(furi_mutex_acquire(seader_worker->mq_mutex, 0) == FuriStatusOk) {
+            uint32_t count = furi_message_queue_get_count(seader_worker->messages);
+            if(count > 0) {
+                FURI_LOG_D(TAG, "MessageQueue: %ld messages", count);
+
+                SeaderAPDU seaderApdu = {};
+                FuriStatus status =
+                    furi_message_queue_get(seader_worker->messages, &seaderApdu, FuriWaitForever);
+                if(status != FuriStatusOk) {
+                    FURI_LOG_W(TAG, "furi_message_queue_get fail %d", status);
+                    seader_worker->stage = SeaderPollerEventTypeComplete;
+                    view_dispatcher_send_custom_event(
+                        seader->view_dispatcher, SeaderCustomEventWorkerExit);
+                }
+            if(seader_process_success_response_i(
+                   seader, seaderApdu.buf, seaderApdu.len, true, NULL)) {
+                // no-op
+            } else {
+                FURI_LOG_I(TAG, "Response false");
+                running = false;
+            }
+
+
+                // fake being SR
+                // picopass commands
+                // pacs
+            }
+            furi_mutex_release(seader_worker->mq_mutex);
+        }
+        furi_delay_ms(1000);
+        loops++;
+        running = (loops < 10);
+    }
+}
+
 int32_t seader_worker_task(void* context) {
     SeaderWorker* seader_worker = context;
+    Seader* seader = seader_worker->context;
     SeaderUartBridge* seader_uart = seader_worker->uart;
 
     if(seader_worker->state == SeaderWorkerStateCheckSam) {
         FURI_LOG_D(TAG, "Check for SAM");
         seader_ccid_check_for_sam(seader_uart);
+    } else if(seader_worker->state == SeaderWorkerStateVirtualCredential) {
+        FURI_LOG_D(TAG, "Virtual Credential");
+        seader_worker_virtual_credential(seader);
     }
     seader_worker_change_state(seader_worker, SeaderWorkerStateReady);
 

+ 1 - 0
seader_worker.h

@@ -17,6 +17,7 @@ typedef enum {
     SeaderWorkerStateReady,
     // Main worker states
     SeaderWorkerStateCheckSam,
+    SeaderWorkerStateVirtualCredential,
     // Transition
     SeaderWorkerStateStop,
 } SeaderWorkerState;