diff --git a/scenes/seader_scene_virtual_credential.c b/scenes/seader_scene_virtual_credential.c index c51fc79..f16146d 100644 --- a/scenes/seader_scene_virtual_credential.c +++ b/scenes/seader_scene_virtual_credential.c @@ -1,24 +1,29 @@ #include "../seader_i.h" #include +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); } diff --git a/seader_credential.h b/seader_credential.h index ab9ffbf..ec8865d 100644 --- a/seader_credential.h +++ b/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 { diff --git a/seader_worker.c b/seader_worker.c index 9449298..875a1e3 100644 --- a/seader_worker.c +++ b/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); diff --git a/seader_worker.h b/seader_worker.h index 92b9301..9868b20 100644 --- a/seader_worker.h +++ b/seader_worker.h @@ -17,6 +17,7 @@ typedef enum { SeaderWorkerStateReady, // Main worker states SeaderWorkerStateCheckSam, + SeaderWorkerStateVirtualCredential, // Transition SeaderWorkerStateStop, } SeaderWorkerState;