diff --git a/applications/gui/view_dispatcher.c b/applications/gui/view_dispatcher.c index d5b805154..994bad10f 100755 --- a/applications/gui/view_dispatcher.c +++ b/applications/gui/view_dispatcher.c @@ -31,6 +31,10 @@ void view_dispatcher_free(ViewDispatcher* view_dispatcher) { ViewDict_clear(view_dispatcher->views); // Free ViewPort view_port_free(view_dispatcher->view_port); + // Free internal queue + if(view_dispatcher->queue) { + osMessageQueueDelete(view_dispatcher->queue); + } // Free dispatcher free(view_dispatcher); } diff --git a/applications/nfc/nfc.c b/applications/nfc/nfc.c index eb2c3f749..88074b403 100755 --- a/applications/nfc/nfc.c +++ b/applications/nfc/nfc.c @@ -1,262 +1,142 @@ #include "nfc_i.h" #include "api-hal-nfc.h" -osMessageQueueId_t message_queue = NULL; - -uint32_t nfc_view_stop(void* context) { - furi_assert(message_queue); - NfcMessage message; - message.type = NfcMessageTypeStop; - furi_check(osMessageQueuePut(message_queue, &message, 0, osWaitForever) == osOK); - return NfcViewMenu; -} - uint32_t nfc_view_exit(void* context) { - furi_assert(message_queue); - NfcMessage message; - message.type = NfcMessageTypeExit; - furi_check(osMessageQueuePut(message_queue, &message, 0, osWaitForever) == osOK); return VIEW_NONE; } void nfc_menu_callback(void* context, uint32_t index) { - furi_assert(message_queue); + furi_assert(context); + + Nfc* nfc = (Nfc*)context; + if(index == NfcSubmenuDetect) { + view_dispatcher_switch_to_view(nfc->nfc_common.view_dispatcher, NfcViewDetect); + } else if(index == NfcSubmenuEmulate) { + view_dispatcher_switch_to_view(nfc->nfc_common.view_dispatcher, NfcViewEmulate); + } else if(index == NfcSubmenuEMV) { + view_dispatcher_switch_to_view(nfc->nfc_common.view_dispatcher, NfcViewEmv); + } else if(index == NfcSubmenuMifareUl) { + view_dispatcher_switch_to_view(nfc->nfc_common.view_dispatcher, NfcViewMifareUl); + } +} + +void nfc_view_dispatcher_callback(uint32_t event, void* context) { + furi_assert(context); + + Nfc* nfc = (Nfc*)context; NfcMessage message; - message.type = index; - furi_check(osMessageQueuePut(message_queue, &message, 0, osWaitForever) == osOK); + osMessageQueueGet(nfc->message_queue, &message, NULL, osWaitForever); + if(event == NfcEventDetect) { + nfc_detect_view_dispatcher_callback(nfc->nfc_detect, &message); + } else if(event == NfcEventEmv) { + nfc_emv_view_dispatcher_callback(nfc->nfc_emv, &message); + } else if(event == NfcEventMifareUl) { + nfc_mifare_ul_view_dispatcher_callback(nfc->nfc_mifare_ul, &message); + } } Nfc* nfc_alloc() { Nfc* nfc = furi_alloc(sizeof(Nfc)); - message_queue = osMessageQueueNew(8, sizeof(NfcMessage), NULL); - - nfc->worker = nfc_worker_alloc(message_queue); + nfc->message_queue = osMessageQueueNew(8, sizeof(NfcMessage), NULL); + nfc->nfc_common.worker = nfc_worker_alloc(nfc->message_queue); + nfc->nfc_common.view_dispatcher = view_dispatcher_alloc(); + view_dispatcher_enable_queue(nfc->nfc_common.view_dispatcher); // Open GUI record nfc->gui = furi_record_open("gui"); - - // View Dispatcher - nfc->view_dispatcher = view_dispatcher_alloc(); - view_dispatcher_attach_to_gui(nfc->view_dispatcher, nfc->gui, ViewDispatcherTypeFullscreen); + view_dispatcher_attach_to_gui( + nfc->nfc_common.view_dispatcher, nfc->gui, ViewDispatcherTypeFullscreen); // Menu nfc->submenu = submenu_alloc(); - submenu_add_item(nfc->submenu, "Detect", NfcMessageTypeDetect, nfc_menu_callback, nfc); - submenu_add_item(nfc->submenu, "Read EMV", NfcMessageTypeReadEMV, nfc_menu_callback, nfc); + submenu_add_item(nfc->submenu, "Detect", NfcSubmenuDetect, nfc_menu_callback, nfc); + submenu_add_item(nfc->submenu, "Emulate", NfcSubmenuEmulate, nfc_menu_callback, nfc); + submenu_add_item(nfc->submenu, "Read bank card", NfcSubmenuEMV, nfc_menu_callback, nfc); submenu_add_item( - nfc->submenu, "Emulate EMV", NfcMessageTypeEmulateEMV, nfc_menu_callback, nfc); - submenu_add_item(nfc->submenu, "Emulate", NfcMessageTypeEmulate, nfc_menu_callback, nfc); - submenu_add_item(nfc->submenu, "Field", NfcMessageTypeField, nfc_menu_callback, nfc); - submenu_add_item( - nfc->submenu, "Read MfUltralight", NfcMessageTypeReadMfUltralight, nfc_menu_callback, nfc); + nfc->submenu, "Read Mifare Ultralight", NfcSubmenuMifareUl, nfc_menu_callback, nfc); View* submenu_view = submenu_get_view(nfc->submenu); view_set_previous_callback(submenu_view, nfc_view_exit); - view_dispatcher_add_view(nfc->view_dispatcher, NfcViewMenu, submenu_view); + view_dispatcher_add_view(nfc->nfc_common.view_dispatcher, NfcViewMenu, submenu_view); // Detect - nfc->view_detect = view_alloc(); - view_set_context(nfc->view_detect, nfc); - view_set_draw_callback(nfc->view_detect, nfc_view_read_draw); - view_set_previous_callback(nfc->view_detect, nfc_view_stop); - view_allocate_model(nfc->view_detect, ViewModelTypeLocking, sizeof(NfcViewReadModel)); - view_dispatcher_add_view(nfc->view_dispatcher, NfcViewRead, nfc->view_detect); - - // Read EMV - nfc->view_read_emv = view_alloc(); - view_set_context(nfc->view_read_emv, nfc); - view_set_draw_callback(nfc->view_read_emv, nfc_view_read_emv_draw); - view_set_previous_callback(nfc->view_read_emv, nfc_view_stop); - view_allocate_model(nfc->view_read_emv, ViewModelTypeLocking, sizeof(NfcViewReadModel)); - view_dispatcher_add_view(nfc->view_dispatcher, NfcViewReadEmv, nfc->view_read_emv); - - // Emulate EMV - nfc->view_emulate_emv = view_alloc(); - view_set_context(nfc->view_emulate_emv, nfc); - view_set_draw_callback(nfc->view_emulate_emv, nfc_view_emulate_emv_draw); - view_set_previous_callback(nfc->view_emulate_emv, nfc_view_stop); - view_dispatcher_add_view(nfc->view_dispatcher, NfcViewEmulateEMV, nfc->view_emulate_emv); + nfc->nfc_detect = nfc_detect_alloc(&nfc->nfc_common); + view_dispatcher_add_view( + nfc->nfc_common.view_dispatcher, NfcViewDetect, nfc_detect_get_view(nfc->nfc_detect)); // Emulate - nfc->view_emulate = view_alloc(); - view_set_context(nfc->view_emulate, nfc); - view_set_draw_callback(nfc->view_emulate, nfc_view_emulate_draw); - view_set_previous_callback(nfc->view_emulate, nfc_view_stop); - view_dispatcher_add_view(nfc->view_dispatcher, NfcViewEmulate, nfc->view_emulate); - - // Field - nfc->view_field = view_alloc(); - view_set_context(nfc->view_field, nfc); - view_set_draw_callback(nfc->view_field, nfc_view_field_draw); - view_set_previous_callback(nfc->view_field, nfc_view_stop); - view_dispatcher_add_view(nfc->view_dispatcher, NfcViewField, nfc->view_field); - - // Read Mifare Ultralight - nfc->view_read_mf_ultralight = view_alloc(); - view_set_context(nfc->view_read_mf_ultralight, nfc); - view_set_draw_callback(nfc->view_read_mf_ultralight, nfc_view_read_mf_ultralight_draw); - view_set_previous_callback(nfc->view_read_mf_ultralight, nfc_view_stop); - view_allocate_model( - nfc->view_read_mf_ultralight, ViewModelTypeLocking, sizeof(NfcViewReadModel)); + nfc->nfc_emulate = nfc_emulate_alloc(&nfc->nfc_common); view_dispatcher_add_view( - nfc->view_dispatcher, NfcViewReadMfUltralight, nfc->view_read_mf_ultralight); + nfc->nfc_common.view_dispatcher, NfcViewEmulate, nfc_emulate_get_view(nfc->nfc_emulate)); - // Error - nfc->view_error = view_alloc(); - view_set_context(nfc->view_error, nfc); - view_set_draw_callback(nfc->view_error, nfc_view_error_draw); - view_set_previous_callback(nfc->view_error, nfc_view_stop); - view_allocate_model(nfc->view_error, ViewModelTypeLockFree, sizeof(NfcViewErrorModel)); - view_dispatcher_add_view(nfc->view_dispatcher, NfcViewError, nfc->view_error); + // EMV + nfc->nfc_emv = nfc_emv_alloc(&nfc->nfc_common); + view_dispatcher_add_view( + nfc->nfc_common.view_dispatcher, NfcViewEmv, nfc_emv_get_view(nfc->nfc_emv)); + + // Mifare Ultralight + nfc->nfc_mifare_ul = nfc_mifare_ul_alloc(&nfc->nfc_common); + view_dispatcher_add_view( + nfc->nfc_common.view_dispatcher, + NfcViewMifareUl, + nfc_mifare_ul_get_view(nfc->nfc_mifare_ul)); + + // Set View Dispatcher custom event callback + view_dispatcher_set_custom_callback( + nfc->nfc_common.view_dispatcher, nfc_view_dispatcher_callback, nfc); // Switch to menu - view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewMenu); + view_dispatcher_switch_to_view(nfc->nfc_common.view_dispatcher, NfcViewMenu); return nfc; } void nfc_free(Nfc* nfc) { - // Free nfc worker - nfc_worker_free(nfc->worker); - // Free allocated queue - osMessageQueueDelete(message_queue); - message_queue = NULL; + furi_assert(nfc); - // Free allocated views - // Menu - view_dispatcher_remove_view(nfc->view_dispatcher, NfcViewMenu); + // Submenu + view_dispatcher_remove_view(nfc->nfc_common.view_dispatcher, NfcViewMenu); submenu_free(nfc->submenu); // Detect - view_dispatcher_remove_view(nfc->view_dispatcher, NfcViewRead); - view_free(nfc->view_detect); - - // Read EMV - view_dispatcher_remove_view(nfc->view_dispatcher, NfcViewReadEmv); - view_free(nfc->view_read_emv); - - // Emulate EMV - view_dispatcher_remove_view(nfc->view_dispatcher, NfcViewEmulateEMV); - view_free(nfc->view_emulate_emv); + view_dispatcher_remove_view(nfc->nfc_common.view_dispatcher, NfcViewDetect); + nfc_detect_free(nfc->nfc_detect); // Emulate - view_dispatcher_remove_view(nfc->view_dispatcher, NfcViewEmulate); - view_free(nfc->view_emulate); + view_dispatcher_remove_view(nfc->nfc_common.view_dispatcher, NfcViewEmulate); + nfc_emulate_free(nfc->nfc_emulate); - // Field - view_dispatcher_remove_view(nfc->view_dispatcher, NfcViewField); - view_free(nfc->view_field); + // EMV + view_dispatcher_remove_view(nfc->nfc_common.view_dispatcher, NfcViewEmv); + nfc_emv_free(nfc->nfc_emv); - // Read Mifare Ultralight - view_dispatcher_remove_view(nfc->view_dispatcher, NfcViewReadMfUltralight); - view_free(nfc->view_read_mf_ultralight); + // Mifare ultralight + view_dispatcher_remove_view(nfc->nfc_common.view_dispatcher, NfcViewMifareUl); + nfc_mifare_ul_free(nfc->nfc_mifare_ul); - // Error - view_dispatcher_remove_view(nfc->view_dispatcher, NfcViewError); - view_free(nfc->view_error); + // Worker + nfc_worker_stop(nfc->nfc_common.worker); + nfc_worker_free(nfc->nfc_common.worker); - // Free View Dispatcher - view_dispatcher_free(nfc->view_dispatcher); + // View dispatcher + view_dispatcher_free(nfc->nfc_common.view_dispatcher); - // Close all opened records + // GUI furi_record_close("gui"); nfc->gui = NULL; - // Free nfc object + // The rest + osMessageQueueDelete(nfc->message_queue); free(nfc); } -void nfc_start(Nfc* nfc, NfcView view_id, NfcWorkerState worker_state) { - NfcWorkerState state = nfc_worker_get_state(nfc->worker); - if(state == NfcWorkerStateBroken) { - with_view_model( - nfc->view_error, (NfcViewErrorModel * model) { - model->error = nfc_worker_get_error(nfc->worker); - return true; - }); - view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewError); - } else if(state == NfcWorkerStateReady) { - view_dispatcher_switch_to_view(nfc->view_dispatcher, view_id); - nfc_worker_start(nfc->worker, worker_state); - } -} - int32_t nfc_task(void* p) { Nfc* nfc = nfc_alloc(); - NfcMessage message; - while(1) { - furi_check(osMessageQueueGet(message_queue, &message, NULL, osWaitForever) == osOK); + view_dispatcher_run(nfc->nfc_common.view_dispatcher); - if(message.type == NfcMessageTypeDetect) { - with_view_model( - nfc->view_detect, (NfcViewReadModel * model) { - model->found = false; - return true; - }); - nfc_start(nfc, NfcViewRead, NfcWorkerStatePoll); - } else if(message.type == NfcMessageTypeReadEMV) { - with_view_model( - nfc->view_read_emv, (NfcViewReadModel * model) { - model->found = false; - return true; - }); - nfc_start(nfc, NfcViewReadEmv, NfcWorkerStateReadEMV); - } else if(message.type == NfcMessageTypeEmulateEMV) { - nfc_start(nfc, NfcViewEmulateEMV, NfcWorkerStateEmulateEMV); - } else if(message.type == NfcMessageTypeEmulate) { - nfc_start(nfc, NfcViewEmulate, NfcWorkerStateEmulate); - } else if(message.type == NfcMessageTypeField) { - nfc_start(nfc, NfcViewField, NfcWorkerStateField); - } else if(message.type == NfcMessageTypeReadMfUltralight) { - nfc_start(nfc, NfcViewReadMfUltralight, NfcWorkerStateReadMfUltralight); - } else if(message.type == NfcMessageTypeStop) { - nfc_worker_stop(nfc->worker); - } else if(message.type == NfcMessageTypeDeviceFound) { - with_view_model( - nfc->view_detect, (NfcViewReadModel * model) { - model->found = true; - model->device = message.device; - return true; - }); - } else if(message.type == NfcMessageTypeDeviceNotFound) { - with_view_model( - nfc->view_detect, (NfcViewReadModel * model) { - model->found = false; - return true; - }); - } else if(message.type == NfcMessageTypeEMVFound) { - with_view_model( - nfc->view_read_emv, (NfcViewReadModel * model) { - model->found = true; - model->device = message.device; - return true; - }); - } else if(message.type == NfcMessageTypeEMVNotFound) { - with_view_model( - nfc->view_read_emv, (NfcViewReadModel * model) { - model->found = false; - return true; - }); - } else if(message.type == NfcMessageTypeMfUlFound) { - with_view_model( - nfc->view_read_mf_ultralight, (NfcViewReadModel * model) { - model->found = true; - model->device = message.device; - return true; - }); - } else if(message.type == NfcMessageTypeMfUlNotFound) { - with_view_model( - nfc->view_read_mf_ultralight, (NfcViewReadModel * model) { - model->found = false; - return true; - }); - } else if(message.type == NfcMessageTypeExit) { - nfc_free(nfc); - break; - } - } + nfc_free(nfc); return 0; } diff --git a/applications/nfc/nfc_detect.c b/applications/nfc/nfc_detect.c new file mode 100755 index 000000000..e5beb2a17 --- /dev/null +++ b/applications/nfc/nfc_detect.c @@ -0,0 +1,145 @@ +#include "nfc_detect.h" + +#include "nfc_i.h" +#include "nfc_types.h" +#include +#include +#include + +struct NfcDetect { + NfcCommon* nfc_common; + View* view; +}; + +typedef struct { + bool found; + NfcDeviceData data; +} NfcDetectModel; + +void nfc_detect_draw(Canvas* canvas, NfcDetectModel* model) { + char buffer[32]; + canvas_clear(canvas); + canvas_set_font(canvas, FontPrimary); + if(model->found) { + canvas_draw_str(canvas, 0, 12, "Found"); + canvas_draw_str(canvas, 32, 12, nfc_get_dev_type(model->data.device)); + canvas_set_font(canvas, FontSecondary); + if(model->data.protocol != NfcDeviceProtocolUnknown) { + canvas_draw_str(canvas, 0, 22, nfc_get_protocol(model->data.protocol)); + } + // Display UID + for(uint8_t i = 0; i < model->data.uid_len; i++) { + snprintf(buffer + (i * 2), sizeof(buffer) - (i * 2), "%02X", model->data.uid[i]); + buffer[model->data.uid_len * 2] = 0; + } + canvas_draw_str(canvas, 0, 32, "UID: "); + canvas_draw_str(canvas, 22, 32, buffer); + // Display ATQA and SAK + snprintf( + buffer, + sizeof(buffer), + "ATQA: %02X %02X SAK: %02X", + model->data.atqa[1], + model->data.atqa[0], + model->data.sak); + canvas_draw_str(canvas, 0, 42, buffer); + } else { + canvas_draw_str(canvas, 0, 12, "Searching"); + canvas_set_font(canvas, FontSecondary); + canvas_draw_str(canvas, 2, 22, "Place card to the back"); + } +} + +bool nfc_detect_input(InputEvent* event, void* context) { + if(event->key == InputKeyBack) { + return false; + } + return true; +} + +void nfc_detect_worker_callback(void* context) { + furi_assert(context); + + NfcDetect* nfc_detect = (NfcDetect*)context; + view_dispatcher_send_custom_event(nfc_detect->nfc_common->view_dispatcher, NfcEventDetect); +} + +void nfc_detect_view_dispatcher_callback(NfcDetect* nfc_detect, NfcMessage* message) { + furi_assert(nfc_detect); + furi_assert(message); + + if(message->found) { + with_view_model( + nfc_detect->view, (NfcDetectModel * model) { + model->found = true; + model->data = message->nfc_detect_data; + return true; + }); + } else { + with_view_model( + nfc_detect->view, (NfcDetectModel * model) { + model->found = false; + return true; + }); + } +} + +void nfc_detect_enter(void* context) { + furi_assert(context); + + NfcDetect* nfc_detect = (NfcDetect*)context; + with_view_model( + nfc_detect->view, (NfcDetectModel * model) { + model->found = false; + model->data.protocol = NfcDeviceProtocolUnknown; + return true; + }); + nfc_worker_start( + nfc_detect->nfc_common->worker, + NfcWorkerStateDetect, + nfc_detect_worker_callback, + nfc_detect); +} + +void nfc_detect_exit(void* context) { + furi_assert(context); + + NfcDetect* nfc_detect = (NfcDetect*)context; + nfc_worker_stop(nfc_detect->nfc_common->worker); +} + +uint32_t nfc_detect_back(void* context) { + return NfcViewMenu; +} + +NfcDetect* nfc_detect_alloc(NfcCommon* nfc_common) { + furi_assert(nfc_common); + + NfcDetect* nfc_detect = furi_alloc(sizeof(NfcDetect)); + nfc_detect->nfc_common = nfc_common; + + // View allocation and configuration + nfc_detect->view = view_alloc(); + view_allocate_model(nfc_detect->view, ViewModelTypeLockFree, sizeof(NfcDetectModel)); + view_set_context(nfc_detect->view, nfc_detect); + view_set_draw_callback(nfc_detect->view, (ViewDrawCallback)nfc_detect_draw); + view_set_input_callback(nfc_detect->view, nfc_detect_input); + view_set_enter_callback(nfc_detect->view, nfc_detect_enter); + view_set_exit_callback(nfc_detect->view, nfc_detect_exit); + view_set_previous_callback(nfc_detect->view, nfc_detect_back); + + return nfc_detect; +} + +void nfc_detect_free(NfcDetect* nfc_detect) { + furi_assert(nfc_detect); + + view_free(nfc_detect->view); + free(nfc_detect); +} + +View* nfc_detect_get_view(NfcDetect* nfc_detect) { + furi_assert(nfc_detect); + + return nfc_detect->view; +} \ No newline at end of file diff --git a/applications/nfc/nfc_detect.h b/applications/nfc/nfc_detect.h new file mode 100644 index 000000000..7c61c6b4b --- /dev/null +++ b/applications/nfc/nfc_detect.h @@ -0,0 +1,14 @@ +#pragma once + +#include +#include "nfc_types.h" + +typedef struct NfcDetect NfcDetect; + +NfcDetect* nfc_detect_alloc(NfcCommon* nfc_common); + +void nfc_detect_free(NfcDetect* nfc_detect); + +View* nfc_detect_get_view(NfcDetect* nfc_detect); + +void nfc_detect_view_dispatcher_callback(NfcDetect* nfc_detect, NfcMessage* message); diff --git a/applications/nfc/nfc_emulate.c b/applications/nfc/nfc_emulate.c new file mode 100644 index 000000000..577eeec5d --- /dev/null +++ b/applications/nfc/nfc_emulate.c @@ -0,0 +1,79 @@ +#include "nfc_emulate.h" + +#include "nfc_i.h" +#include "nfc_types.h" +#include +#include +#include + +struct NfcEmulate { + NfcCommon* nfc_common; + View* view; +}; + +void nfc_emulate_draw(Canvas* canvas, void* model) { + canvas_clear(canvas); + canvas_set_font(canvas, FontPrimary); + canvas_draw_str(canvas, 0, 12, "Emulating NFC-A"); + canvas_set_font(canvas, FontSecondary); + canvas_draw_str(canvas, 2, 22, "Type: T2T"); + canvas_draw_str(canvas, 2, 32, "UID length: 7"); + canvas_draw_str(canvas, 2, 42, "UID: 36 9C E7 B1 0A C1 34"); + canvas_draw_str(canvas, 2, 52, "SAK: 00 ATQA: 00/44"); +} + +bool nfc_emulate_input(InputEvent* event, void* context) { + if(event->key == InputKeyBack) { + return false; + } + return true; +} + +void nfc_emulate_enter(void* context) { + furi_assert(context); + + NfcEmulate* nfc_emulate = (NfcEmulate*)context; + nfc_worker_start(nfc_emulate->nfc_common->worker, NfcWorkerStateEmulate, NULL, NULL); +} + +void nfc_emulate_exit(void* context) { + furi_assert(context); + + NfcEmulate* nfc_emulate = (NfcEmulate*)context; + nfc_worker_stop(nfc_emulate->nfc_common->worker); +} + +uint32_t nfc_emulate_back(void* context) { + return NfcViewMenu; +} + +NfcEmulate* nfc_emulate_alloc(NfcCommon* nfc_common) { + furi_assert(nfc_common); + + NfcEmulate* nfc_emulate = furi_alloc(sizeof(NfcEmulate)); + nfc_emulate->nfc_common = nfc_common; + + // View allocation and configuration + nfc_emulate->view = view_alloc(); + view_set_context(nfc_emulate->view, nfc_emulate); + view_set_draw_callback(nfc_emulate->view, (ViewDrawCallback)nfc_emulate_draw); + view_set_input_callback(nfc_emulate->view, nfc_emulate_input); + view_set_enter_callback(nfc_emulate->view, nfc_emulate_enter); + view_set_exit_callback(nfc_emulate->view, nfc_emulate_exit); + view_set_previous_callback(nfc_emulate->view, nfc_emulate_back); + + return nfc_emulate; +} + +void nfc_emulate_free(NfcEmulate* nfc_emulate) { + furi_assert(nfc_emulate); + + view_free(nfc_emulate->view); + free(nfc_emulate); +} + +View* nfc_emulate_get_view(NfcEmulate* nfc_emulate) { + furi_assert(nfc_emulate); + + return nfc_emulate->view; +} \ No newline at end of file diff --git a/applications/nfc/nfc_emulate.h b/applications/nfc/nfc_emulate.h new file mode 100644 index 000000000..a20dc9285 --- /dev/null +++ b/applications/nfc/nfc_emulate.h @@ -0,0 +1,12 @@ +#pragma once + +#include +#include "nfc_types.h" + +typedef struct NfcEmulate NfcEmulate; + +NfcEmulate* nfc_emulate_alloc(NfcCommon* nfc_common); + +void nfc_emulate_free(NfcEmulate* nfc_emulate); + +View* nfc_emulate_get_view(NfcEmulate* nfc_emulate); diff --git a/applications/nfc/nfc_emv.c b/applications/nfc/nfc_emv.c new file mode 100755 index 000000000..642c0ed72 --- /dev/null +++ b/applications/nfc/nfc_emv.c @@ -0,0 +1,133 @@ +#include "nfc_emv.h" + +#include "nfc_i.h" +#include "nfc_types.h" +#include +#include +#include + +struct NfcEmv { + NfcCommon* nfc_common; + View* view; +}; + +typedef struct { + bool found; + NfcEmvData emv_data; +} NfcEmvModel; + +void nfc_emv_draw(Canvas* canvas, NfcEmvModel* model) { + char buffer[32]; + canvas_clear(canvas); + canvas_set_font(canvas, FontPrimary); + if(model->found) { + canvas_draw_str(canvas, 0, 12, "Found EMV card"); + canvas_set_font(canvas, FontSecondary); + canvas_draw_str(canvas, 2, 22, "Type:"); + snprintf(buffer, sizeof(buffer), "%s", model->emv_data.name); + canvas_draw_str(canvas, 2, 32, buffer); + snprintf(buffer, sizeof(buffer), "Number:\n"); + canvas_draw_str(canvas, 2, 42, buffer); + uint8_t card_num_len = sizeof(model->emv_data.number); + for(uint8_t i = 0; i < card_num_len; i++) { + snprintf( + buffer + (i * 2), sizeof(buffer) - (i * 2), "%02X", model->emv_data.number[i]); + } + buffer[card_num_len * 2] = 0; + canvas_draw_str(canvas, 2, 52, buffer); + } else { + canvas_draw_str(canvas, 0, 12, "Searching"); + canvas_set_font(canvas, FontSecondary); + canvas_draw_str(canvas, 2, 22, "Place card to the back"); + } +} + +bool nfc_emv_input(InputEvent* event, void* context) { + if(event->key == InputKeyBack) { + return false; + } + return true; +} + +void nfc_emv_worker_callback(void* context) { + furi_assert(context); + + NfcEmv* nfc_emv = (NfcEmv*)context; + view_dispatcher_send_custom_event(nfc_emv->nfc_common->view_dispatcher, NfcEventEmv); +} + +void nfc_emv_view_dispatcher_callback(NfcEmv* nfc_emv, NfcMessage* message) { + furi_assert(nfc_emv); + furi_assert(message); + + if(message->found) { + with_view_model( + nfc_emv->view, (NfcEmvModel * model) { + model->found = true; + model->emv_data = message->nfc_emv_data; + return true; + }); + } else { + with_view_model( + nfc_emv->view, (NfcEmvModel * model) { + model->found = false; + return true; + }); + } +} + +void nfc_emv_enter(void* context) { + furi_assert(context); + + NfcEmv* nfc_emv = (NfcEmv*)context; + with_view_model( + nfc_emv->view, (NfcEmvModel * model) { + model->found = false; + return true; + }); + nfc_worker_start( + nfc_emv->nfc_common->worker, NfcWorkerStateReadEMV, nfc_emv_worker_callback, nfc_emv); +} + +void nfc_emv_exit(void* context) { + furi_assert(context); + + NfcEmv* nfc_emv = (NfcEmv*)context; + nfc_worker_stop(nfc_emv->nfc_common->worker); +} + +uint32_t nfc_emv_back(void* context) { + return NfcViewMenu; +} + +NfcEmv* nfc_emv_alloc(NfcCommon* nfc_common) { + furi_assert(nfc_common); + + NfcEmv* nfc_emv = furi_alloc(sizeof(NfcEmv)); + nfc_emv->nfc_common = nfc_common; + + // View allocation and configuration + nfc_emv->view = view_alloc(); + view_allocate_model(nfc_emv->view, ViewModelTypeLockFree, sizeof(NfcEmvModel)); + view_set_context(nfc_emv->view, nfc_emv); + view_set_draw_callback(nfc_emv->view, (ViewDrawCallback)nfc_emv_draw); + view_set_input_callback(nfc_emv->view, nfc_emv_input); + view_set_enter_callback(nfc_emv->view, nfc_emv_enter); + view_set_exit_callback(nfc_emv->view, nfc_emv_exit); + view_set_previous_callback(nfc_emv->view, nfc_emv_back); + + return nfc_emv; +} + +void nfc_emv_free(NfcEmv* nfc_emv) { + furi_assert(nfc_emv); + + view_free(nfc_emv->view); + free(nfc_emv); +} + +View* nfc_emv_get_view(NfcEmv* nfc_emv) { + furi_assert(nfc_emv); + + return nfc_emv->view; +} \ No newline at end of file diff --git a/applications/nfc/nfc_emv.h b/applications/nfc/nfc_emv.h new file mode 100644 index 000000000..28dd9d36b --- /dev/null +++ b/applications/nfc/nfc_emv.h @@ -0,0 +1,14 @@ +#pragma once + +#include +#include "nfc_types.h" + +typedef struct NfcEmv NfcEmv; + +NfcEmv* nfc_emv_alloc(NfcCommon* nfc_common); + +void nfc_emv_free(NfcEmv* nfc_emv); + +View* nfc_emv_get_view(NfcEmv* nfc_emv); + +void nfc_emv_view_dispatcher_callback(NfcEmv* nfc_emv, NfcMessage* message); diff --git a/applications/nfc/nfc_i.h b/applications/nfc/nfc_i.h index 3cac404c2..19ca200a2 100644 --- a/applications/nfc/nfc_i.h +++ b/applications/nfc/nfc_i.h @@ -2,7 +2,6 @@ #include "nfc.h" #include "nfc_types.h" -#include "nfc_views.h" #include "nfc_worker.h" #include @@ -10,35 +9,34 @@ #include #include #include -#include #include -#include -#include #include +#include "nfc_detect.h" +#include "nfc_emulate.h" +#include "nfc_emv.h" +#include "nfc_mifare_ul.h" + struct Nfc { + NfcCommon nfc_common; osMessageQueueId_t message_queue; - - NfcWorker* worker; - Gui* gui; - Submenu* submenu; - - View* view_detect; - View* view_read_emv; - View* view_emulate_emv; - View* view_emulate; - View* view_field; - View* view_read_mf_ultralight; - View* view_cli; - View* view_error; - ViewDispatcher* view_dispatcher; + NfcDetect* nfc_detect; + NfcEmulate* nfc_emulate; + NfcEmv* nfc_emv; + NfcMifareUl* nfc_mifare_ul; }; +typedef enum { + NfcViewMenu, + NfcViewDetect, + NfcViewEmulate, + NfcViewEmv, + NfcViewMifareUl, +} NfcView; + Nfc* nfc_alloc(); -void nfc_start(Nfc* nfc, NfcView view_id, NfcWorkerState worker_state); - -int32_t nfc_task(void* p); \ No newline at end of file +int32_t nfc_task(void* p); diff --git a/applications/nfc/nfc_mifare_ul.c b/applications/nfc/nfc_mifare_ul.c new file mode 100755 index 000000000..e91d7e149 --- /dev/null +++ b/applications/nfc/nfc_mifare_ul.c @@ -0,0 +1,165 @@ +#include "nfc_mifare_ul.h" + +#include "nfc_i.h" +#include "nfc_types.h" +#include +#include +#include + +struct NfcMifareUl { + NfcCommon* nfc_common; + View* view; +}; + +typedef struct { + bool found; + NfcMifareUlData nfc_mf_ul_data; +} NfcMifareUlModel; + +void nfc_mifare_ul_draw(Canvas* canvas, NfcMifareUlModel* model) { + char buffer[32]; + canvas_clear(canvas); + canvas_set_font(canvas, FontPrimary); + if(model->found) { + canvas_draw_str(canvas, 0, 12, "Found Mifare Ultralight"); + canvas_set_font(canvas, FontSecondary); + canvas_draw_str(canvas, 2, 22, "UID:"); + for(uint8_t i = 0; i < model->nfc_mf_ul_data.nfc_data.uid_len; i++) { + snprintf( + buffer + (i * 2), + sizeof(buffer) - (i * 2), + "%02X", + model->nfc_mf_ul_data.nfc_data.uid[i]); + } + buffer[model->nfc_mf_ul_data.nfc_data.uid_len * 2] = 0; + canvas_draw_str(canvas, 18, 22, buffer); + + uint8_t man_bl_size = sizeof(model->nfc_mf_ul_data.man_block); + canvas_draw_str(canvas, 2, 32, "Manufacturer block:"); + for(uint8_t i = 0; i < man_bl_size / 2; i++) { + snprintf( + buffer + (i * 2), + sizeof(buffer) - (i * 2), + "%02X", + model->nfc_mf_ul_data.man_block[i]); + } + buffer[man_bl_size] = 0; + canvas_draw_str(canvas, 2, 42, buffer); + + for(uint8_t i = 0; i < man_bl_size / 2; i++) { + snprintf( + buffer + (i * 2), + sizeof(buffer) - (i * 2), + "%02X", + model->nfc_mf_ul_data.man_block[man_bl_size / 2 + i]); + } + buffer[man_bl_size] = 0; + canvas_draw_str(canvas, 2, 52, buffer); + + canvas_draw_str(canvas, 2, 62, "OTP: "); + for(uint8_t i = 0; i < sizeof(model->nfc_mf_ul_data.otp); i++) { + snprintf( + buffer + (i * 2), sizeof(buffer) - (i * 2), "%02X", model->nfc_mf_ul_data.otp[i]); + } + buffer[sizeof(model->nfc_mf_ul_data.otp) * 2] = 0; + canvas_draw_str(canvas, 22, 62, buffer); + } else { + canvas_draw_str(canvas, 0, 12, "Searching"); + canvas_set_font(canvas, FontSecondary); + canvas_draw_str(canvas, 2, 22, "Place card to the back"); + } +} + +bool nfc_mifare_ul_input(InputEvent* event, void* context) { + if(event->key == InputKeyBack) { + return false; + } + return true; +} + +void nfc_mifare_ul_worker_callback(void* context) { + furi_assert(context); + + NfcMifareUl* nfc_mifare_ul = (NfcMifareUl*)context; + view_dispatcher_send_custom_event( + nfc_mifare_ul->nfc_common->view_dispatcher, NfcEventMifareUl); +} + +void nfc_mifare_ul_view_dispatcher_callback(NfcMifareUl* nfc_mifare_ul, NfcMessage* message) { + furi_assert(nfc_mifare_ul); + furi_assert(message); + + if(message->found) { + with_view_model( + nfc_mifare_ul->view, (NfcMifareUlModel * model) { + model->found = true; + model->nfc_mf_ul_data = message->nfc_mifare_ul_data; + return true; + }); + } else { + with_view_model( + nfc_mifare_ul->view, (NfcMifareUlModel * model) { + model->found = false; + return true; + }); + } +} + +void nfc_mifare_ul_enter(void* context) { + furi_assert(context); + + NfcMifareUl* nfc_mifare_ul = (NfcMifareUl*)context; + with_view_model( + nfc_mifare_ul->view, (NfcMifareUlModel * m) { + m->found = false; + return true; + }); + nfc_worker_start( + nfc_mifare_ul->nfc_common->worker, + NfcWorkerStateReadMfUltralight, + nfc_mifare_ul_worker_callback, + nfc_mifare_ul); +} + +void nfc_mifare_ul_exit(void* context) { + furi_assert(context); + + NfcMifareUl* nfc_mifare_ul = (NfcMifareUl*)context; + nfc_worker_stop(nfc_mifare_ul->nfc_common->worker); +} + +uint32_t nfc_mifare_ul_back(void* context) { + return NfcViewMenu; +} + +NfcMifareUl* nfc_mifare_ul_alloc(NfcCommon* nfc_common) { + furi_assert(nfc_common); + + NfcMifareUl* nfc_mifare_ul = furi_alloc(sizeof(NfcMifareUl)); + nfc_mifare_ul->nfc_common = nfc_common; + + // View allocation and configuration + nfc_mifare_ul->view = view_alloc(); + view_allocate_model(nfc_mifare_ul->view, ViewModelTypeLockFree, sizeof(NfcMifareUlModel)); + view_set_context(nfc_mifare_ul->view, nfc_mifare_ul); + view_set_draw_callback(nfc_mifare_ul->view, (ViewDrawCallback)nfc_mifare_ul_draw); + view_set_input_callback(nfc_mifare_ul->view, nfc_mifare_ul_input); + view_set_enter_callback(nfc_mifare_ul->view, nfc_mifare_ul_enter); + view_set_exit_callback(nfc_mifare_ul->view, nfc_mifare_ul_exit); + view_set_previous_callback(nfc_mifare_ul->view, nfc_mifare_ul_back); + + return nfc_mifare_ul; +} + +void nfc_mifare_ul_free(NfcMifareUl* nfc_mifare_ul) { + furi_assert(nfc_mifare_ul); + + view_free(nfc_mifare_ul->view); + free(nfc_mifare_ul); +} + +View* nfc_mifare_ul_get_view(NfcMifareUl* nfc_mifare_ul) { + furi_assert(nfc_mifare_ul); + + return nfc_mifare_ul->view; +} \ No newline at end of file diff --git a/applications/nfc/nfc_mifare_ul.h b/applications/nfc/nfc_mifare_ul.h new file mode 100644 index 000000000..3696fa01b --- /dev/null +++ b/applications/nfc/nfc_mifare_ul.h @@ -0,0 +1,14 @@ +#pragma once + +#include +#include "nfc_types.h" + +typedef struct NfcMifareUl NfcMifareUl; + +NfcMifareUl* nfc_mifare_ul_alloc(NfcCommon* nfc_common); + +void nfc_mifare_ul_free(NfcMifareUl* nfc_mifare_ul); + +View* nfc_mifare_ul_get_view(NfcMifareUl* nfc_mifare_ul); + +void nfc_mifare_ul_view_dispatcher_callback(NfcMifareUl* nfc_mifare_ul, NfcMessage* message); diff --git a/applications/nfc/nfc_types.h b/applications/nfc/nfc_types.h index 8787c38fb..fa332335b 100644 --- a/applications/nfc/nfc_types.h +++ b/applications/nfc/nfc_types.h @@ -1,7 +1,71 @@ #pragma once -#include -#include +#include "st_errno.h" +#include "rfal_nfc.h" + +#include +#include "nfc_worker.h" + +typedef struct { + NfcWorker* worker; + ViewDispatcher* view_dispatcher; +} NfcCommon; + +typedef enum { + NfcDeviceNfca, + NfcDeviceNfcb, + NfcDeviceNfcf, + NfcDeviceNfcv, +} NfcDeviceType; + +typedef enum { + NfcDeviceProtocolUnknown, + NfcDeviceProtocolEMV, + NfcDeviceProtocolMfUltralight, +} NfcProtocol; + +typedef struct { + uint8_t uid_len; + uint8_t uid[10]; + uint8_t atqa[2]; + uint8_t sak; + NfcDeviceType device; + NfcProtocol protocol; +} NfcDeviceData; + +typedef struct { + NfcDeviceData nfc_data; + char name[32]; + uint8_t number[8]; +} NfcEmvData; + +typedef struct { + NfcDeviceData nfc_data; + uint8_t man_block[12]; + uint8_t otp[4]; +} NfcMifareUlData; + +typedef struct { + bool found; + union { + NfcDeviceData nfc_detect_data; + NfcEmvData nfc_emv_data; + NfcMifareUlData nfc_mifare_ul_data; + }; +} NfcMessage; + +typedef enum { + NfcEventDetect, + NfcEventEmv, + NfcEventMifareUl, +} NfcEvent; + +typedef enum { + NfcSubmenuDetect, + NfcSubmenuEmulate, + NfcSubmenuEMV, + NfcSubmenuMifareUl, +} NfcSubmenu; static inline const char* nfc_get_dev_type(rfalNfcDevType type) { if(type == RFAL_NFC_LISTEN_TYPE_NFCA) { @@ -39,76 +103,12 @@ static inline const char* nfc_get_nfca_type(rfalNfcaListenDeviceType type) { } } -typedef enum { - NfcDeviceTypeNfca, - NfcDeviceTypeNfcb, - NfcDeviceTypeNfcf, - NfcDeviceTypeNfcv, - NfcDeviceTypeEMV, - NfcDeviceTypeMfUltralight, -} NfcDeviceType; - -typedef struct { - char name[32]; - uint8_t number[8]; -} EMVCard; - -typedef struct { - uint8_t uid[7]; - uint8_t man_block[12]; - uint8_t otp[4]; -} MfUlCard; - -typedef struct { - NfcDeviceType type; - union { - rfalNfcaListenDevice nfca; - rfalNfcbListenDevice nfcb; - rfalNfcfListenDevice nfcf; - rfalNfcvListenDevice nfcv; - EMVCard emv_card; - MfUlCard mf_ul_card; - }; -} NfcDevice; - -typedef enum { - // Init states - NfcWorkerStateNone, - NfcWorkerStateBroken, - NfcWorkerStateReady, - // Main worker states - NfcWorkerStatePoll, - NfcWorkerStateReadEMV, - NfcWorkerStateEmulateEMV, - NfcWorkerStateEmulate, - NfcWorkerStateField, - NfcWorkerStateReadMfUltralight, - // Transition - NfcWorkerStateStop, -} NfcWorkerState; - -typedef enum { - // From Menu - NfcMessageTypeDetect, - NfcMessageTypeReadEMV, - NfcMessageTypeEmulateEMV, - NfcMessageTypeEmulate, - NfcMessageTypeField, - NfcMessageTypeReadMfUltralight, - NfcMessageTypeStop, - NfcMessageTypeExit, - // From Worker - NfcMessageTypeDeviceFound, - NfcMessageTypeDeviceNotFound, - NfcMessageTypeEMVFound, - NfcMessageTypeEMVNotFound, - NfcMessageTypeMfUlFound, - NfcMessageTypeMfUlNotFound, -} NfcMessageType; - -typedef struct { - NfcMessageType type; - union { - NfcDevice device; - }; -} NfcMessage; +static inline const char* nfc_get_protocol(NfcProtocol protocol) { + if(protocol == NfcDeviceProtocolEMV) { + return "EMV"; + } else if(protocol == NfcDeviceProtocolMfUltralight) { + return "Mifare UL"; + } else { + return "Unknown"; + } +} diff --git a/applications/nfc/nfc_views.c b/applications/nfc/nfc_views.c deleted file mode 100755 index 769656b27..000000000 --- a/applications/nfc/nfc_views.c +++ /dev/null @@ -1,235 +0,0 @@ -#include "nfc_views.h" - -void nfc_view_read_draw(Canvas* canvas, void* model) { - NfcViewReadModel* m = model; - canvas_clear(canvas); - canvas_set_font(canvas, FontPrimary); - if(m->found) { - if(m->device.type == NfcDeviceTypeNfca) { - nfc_view_read_nfca_draw(canvas, m); - } else if(m->device.type == NfcDeviceTypeNfcb) { - nfc_view_read_nfcb_draw(canvas, m); - } else if(m->device.type == NfcDeviceTypeNfcv) { - nfc_view_read_nfcv_draw(canvas, m); - } else if(m->device.type == NfcDeviceTypeNfcf) { - nfc_view_read_nfcf_draw(canvas, m); - } - } else { - canvas_draw_str(canvas, 0, 12, "Searching"); - canvas_set_font(canvas, FontSecondary); - canvas_draw_str(canvas, 2, 22, "Place card to the back"); - } -} - -void nfc_view_read_nfca_draw(Canvas* canvas, NfcViewReadModel* model) { - char buffer[32]; - canvas_draw_str(canvas, 0, 12, "Found NFC-A"); - canvas_set_font(canvas, FontSecondary); - snprintf(buffer, sizeof(buffer), "Type: %s", nfc_get_nfca_type(model->device.nfca.type)); - canvas_draw_str(canvas, 2, 22, buffer); - snprintf(buffer, sizeof(buffer), "UID length: %d", model->device.nfca.nfcId1Len); - canvas_draw_str(canvas, 2, 32, buffer); - - canvas_draw_str(canvas, 2, 42, "UID:"); - for(uint8_t i = 0; i < model->device.nfca.nfcId1Len; i++) { - snprintf(buffer + (i * 2), sizeof(buffer) - (i * 2), "%02X", model->device.nfca.nfcId1[i]); - } - buffer[model->device.nfca.nfcId1Len * 2] = 0; - canvas_draw_str(canvas, 18, 42, buffer); - - snprintf( - buffer, - sizeof(buffer), - "SAK: %02X ATQA: %02X/%02X", - model->device.nfca.selRes.sak, - model->device.nfca.sensRes.anticollisionInfo, - model->device.nfca.sensRes.platformInfo); - canvas_draw_str(canvas, 2, 52, buffer); -} - -void nfc_view_read_nfcb_draw(Canvas* canvas, NfcViewReadModel* model) { - char buffer[32]; - canvas_draw_str(canvas, 0, 12, "Found NFC-B"); - canvas_set_font(canvas, FontSecondary); - - snprintf(buffer, sizeof(buffer), "UID length: %d", RFAL_NFCB_NFCID0_LEN); - canvas_draw_str(canvas, 2, 32, buffer); - - canvas_draw_str(canvas, 2, 42, "UID:"); - for(uint8_t i = 0; i < RFAL_NFCB_NFCID0_LEN; i++) { - snprintf( - buffer + (i * 2), - sizeof(buffer) - (i * 2), - "%02X", - model->device.nfcb.sensbRes.nfcid0[i]); - } - buffer[RFAL_NFCB_NFCID0_LEN * 2] = 0; - canvas_draw_str(canvas, 18, 42, buffer); -} - -void nfc_view_read_nfcf_draw(Canvas* canvas, NfcViewReadModel* model) { - char buffer[32]; - canvas_draw_str(canvas, 0, 12, "Found NFC-F"); - canvas_set_font(canvas, FontSecondary); - - snprintf(buffer, sizeof(buffer), "UID length: %d", RFAL_NFCF_NFCID2_LEN); - canvas_draw_str(canvas, 2, 32, buffer); - - canvas_draw_str(canvas, 2, 42, "UID:"); - for(uint8_t i = 0; i < RFAL_NFCF_NFCID2_LEN; i++) { - snprintf( - buffer + (i * 2), - sizeof(buffer) - (i * 2), - "%02X", - model->device.nfcf.sensfRes.NFCID2[i]); - } - buffer[RFAL_NFCF_NFCID2_LEN * 2] = 0; - canvas_draw_str(canvas, 18, 42, buffer); -} - -void nfc_view_read_nfcv_draw(Canvas* canvas, NfcViewReadModel* model) { - char buffer[32]; - canvas_draw_str(canvas, 0, 12, "Found NFC-V"); - canvas_set_font(canvas, FontSecondary); - - snprintf(buffer, sizeof(buffer), "UID length: %d", RFAL_NFCV_UID_LEN); - canvas_draw_str(canvas, 2, 32, buffer); - - canvas_draw_str(canvas, 2, 42, "UID:"); - for(uint8_t i = 0; i < RFAL_NFCV_UID_LEN; i++) { - snprintf( - buffer + (i * 2), sizeof(buffer) - (i * 2), "%02X", model->device.nfcv.InvRes.UID[i]); - } - buffer[RFAL_NFCV_UID_LEN * 2] = 0; - canvas_draw_str(canvas, 18, 42, buffer); -} - -void nfc_view_read_emv_draw(Canvas* canvas, void* model) { - NfcViewReadModel* m = model; - canvas_clear(canvas); - canvas_set_font(canvas, FontPrimary); - char buffer[32]; - - if(m->found) { - canvas_draw_str(canvas, 0, 12, "Found EMV card"); - canvas_set_font(canvas, FontSecondary); - snprintf(buffer, sizeof(buffer), "Type:\n"); - canvas_draw_str(canvas, 2, 22, buffer); - snprintf(buffer, sizeof(buffer), "%s", m->device.emv_card.name); - canvas_draw_str(canvas, 2, 32, buffer); - snprintf(buffer, sizeof(buffer), "Number:\n"); - canvas_draw_str(canvas, 2, 42, buffer); - uint8_t card_num_len = sizeof(m->device.emv_card.number); - for(uint8_t i = 0; i < card_num_len; i++) { - snprintf( - buffer + (i * 2), sizeof(buffer) - (i * 2), "%02X", m->device.emv_card.number[i]); - } - buffer[card_num_len * 2] = 0; - canvas_draw_str(canvas, 2, 52, buffer); - } else { - canvas_draw_str(canvas, 0, 12, "Searching"); - canvas_set_font(canvas, FontSecondary); - canvas_draw_str(canvas, 2, 22, "Place card to the back"); - } -} - -void nfc_view_emulate_emv_draw(Canvas* canvas, void* model) { - canvas_clear(canvas); - canvas_set_font(canvas, FontPrimary); - canvas_draw_str(canvas, 0, 12, "Emulating EMV"); -} - -void nfc_view_emulate_draw(Canvas* canvas, void* model) { - canvas_clear(canvas); - canvas_set_font(canvas, FontPrimary); - canvas_draw_str(canvas, 0, 12, "Emulating NFC-A"); - canvas_set_font(canvas, FontSecondary); - canvas_draw_str(canvas, 2, 22, "Type: T2T"); - canvas_draw_str(canvas, 2, 32, "UID length: 4"); - canvas_draw_str(canvas, 2, 42, "UID: CF72D440"); - canvas_draw_str(canvas, 2, 52, "SAK: 20 ATQA: 00/04"); -} - -void nfc_view_read_mf_ultralight_draw(Canvas* canvas, void* model) { - NfcViewReadModel* m = model; - canvas_clear(canvas); - canvas_set_font(canvas, FontPrimary); - char buffer[32]; - - if(m->found) { - canvas_draw_str(canvas, 0, 12, "Found Mifare Ultralight"); - canvas_set_font(canvas, FontSecondary); - canvas_draw_str(canvas, 2, 22, "UID:"); - for(uint8_t i = 0; i < sizeof(m->device.mf_ul_card.uid); i++) { - snprintf( - buffer + (i * 2), sizeof(buffer) - (i * 2), "%02X", m->device.mf_ul_card.uid[i]); - } - buffer[sizeof(m->device.mf_ul_card.uid) * 2] = 0; - canvas_draw_str(canvas, 18, 22, buffer); - - uint8_t man_bl_size = sizeof(m->device.mf_ul_card.man_block); - canvas_draw_str(canvas, 2, 32, "Manufacturer block:"); - for(uint8_t i = 0; i < man_bl_size / 2; i++) { - snprintf( - buffer + (i * 2), - sizeof(buffer) - (i * 2), - "%02X", - m->device.mf_ul_card.man_block[i]); - } - buffer[man_bl_size] = 0; - canvas_draw_str(canvas, 2, 42, buffer); - - for(uint8_t i = 0; i < man_bl_size / 2; i++) { - snprintf( - buffer + (i * 2), - sizeof(buffer) - (i * 2), - "%02X", - m->device.mf_ul_card.man_block[man_bl_size / 2 + i]); - } - buffer[man_bl_size] = 0; - canvas_draw_str(canvas, 2, 52, buffer); - - canvas_draw_str(canvas, 2, 62, "OTP: "); - for(uint8_t i = 0; i < sizeof(m->device.mf_ul_card.otp); i++) { - snprintf( - buffer + (i * 2), sizeof(buffer) - (i * 2), "%02X", m->device.mf_ul_card.otp[i]); - } - buffer[sizeof(m->device.mf_ul_card.otp) * 2] = 0; - canvas_draw_str(canvas, 22, 62, buffer); - } else { - canvas_draw_str(canvas, 0, 12, "Searching"); - canvas_set_font(canvas, FontSecondary); - canvas_draw_str(canvas, 2, 22, "Place card to the back"); - } -} - -void nfc_view_field_draw(Canvas* canvas, void* model) { - canvas_clear(canvas); - canvas_set_font(canvas, FontPrimary); - canvas_draw_str(canvas, 0, 12, "Field ON"); - canvas_set_font(canvas, FontSecondary); - canvas_draw_str(canvas, 2, 22, "TX/RX is disabled"); -} - -void nfc_view_error_draw(Canvas* canvas, void* model) { - NfcViewErrorModel* m = model; - char buffer[32]; - - canvas_clear(canvas); - canvas_set_font(canvas, FontPrimary); - snprintf(buffer, sizeof(buffer), "Error: %d", m->error); - canvas_draw_str(canvas, 0, 12, buffer); - - canvas_set_font(canvas, FontSecondary); - if(m->error == ERR_WRONG_STATE) { - canvas_draw_str(canvas, 2, 22, "Wrong State"); - } else if(m->error == ERR_PARAM) { - canvas_draw_str(canvas, 2, 22, "Wrong Param"); - } else if(m->error == ERR_HW_MISMATCH) { - canvas_draw_str(canvas, 2, 22, "HW mismatch"); - } else if(m->error == ERR_IO) { - canvas_draw_str(canvas, 2, 22, "IO Error"); - } else { - canvas_draw_str(canvas, 2, 22, "Details in st_errno.h"); - } -} diff --git a/applications/nfc/nfc_views.h b/applications/nfc/nfc_views.h deleted file mode 100644 index 5ba990e7b..000000000 --- a/applications/nfc/nfc_views.h +++ /dev/null @@ -1,43 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -#include "nfc_types.h" - -typedef enum { - NfcViewMenu, - NfcViewRead, - NfcViewReadEmv, - NfcViewEmulateEMV, - NfcViewEmulate, - NfcViewField, - NfcViewReadMfUltralight, - NfcViewError, -} NfcView; - -typedef struct { - bool found; - NfcDevice device; -} NfcViewReadModel; - -void nfc_view_read_draw(Canvas* canvas, void* model); -void nfc_view_read_nfca_draw(Canvas* canvas, NfcViewReadModel* model); -void nfc_view_read_nfcb_draw(Canvas* canvas, NfcViewReadModel* model); -void nfc_view_read_nfcf_draw(Canvas* canvas, NfcViewReadModel* model); -void nfc_view_read_nfcv_draw(Canvas* canvas, NfcViewReadModel* model); -void nfc_view_read_emv_draw(Canvas* canvas, void* model); - -void nfc_view_emulate_emv_draw(Canvas* canvas, void* model); -void nfc_view_emulate_draw(Canvas* canvas, void* model); -void nfc_view_read_mf_ultralight_draw(Canvas* canvas, void* model); - -void nfc_view_field_draw(Canvas* canvas, void* model); - -typedef struct { - ReturnCode error; -} NfcViewErrorModel; - -void nfc_view_error_draw(Canvas* canvas, void* model); diff --git a/applications/nfc/nfc_worker.c b/applications/nfc/nfc_worker.c index 36681ce96..4afc16892 100755 --- a/applications/nfc/nfc_worker.c +++ b/applications/nfc/nfc_worker.c @@ -5,12 +5,16 @@ #define NFC_WORKER_TAG "nfc worker" +/***************************** NFC Worker API *******************************/ + NfcWorker* nfc_worker_alloc(osMessageQueueId_t message_queue) { NfcWorker* nfc_worker = furi_alloc(sizeof(NfcWorker)); nfc_worker->message_queue = message_queue; // Worker thread attributes nfc_worker->thread_attr.name = "nfc_worker"; nfc_worker->thread_attr.stack_size = 8192; + nfc_worker->callback = NULL; + nfc_worker->context = NULL; // Initialize rfal nfc_worker->error = api_hal_nfc_init(); if(nfc_worker->error == ERR_NONE) { @@ -36,9 +40,16 @@ ReturnCode nfc_worker_get_error(NfcWorker* nfc_worker) { return nfc_worker->error; } -void nfc_worker_start(NfcWorker* nfc_worker, NfcWorkerState state) { +void nfc_worker_start( + NfcWorker* nfc_worker, + NfcWorkerState state, + NfcWorkerCallback callback, + void* context) { furi_assert(nfc_worker); furi_assert(nfc_worker->state == NfcWorkerStateReady); + + nfc_worker->callback = callback; + nfc_worker->context = context; nfc_worker_change_state(nfc_worker, state); nfc_worker->thread = osThreadNew(nfc_worker_task, nfc_worker, &nfc_worker->thread_attr); } @@ -56,24 +67,26 @@ void nfc_worker_change_state(NfcWorker* nfc_worker, NfcWorkerState state) { nfc_worker->state = state; } +/***************************** NFC Worker Thread *******************************/ + void nfc_worker_task(void* context) { NfcWorker* nfc_worker = context; api_hal_power_insomnia_enter(); api_hal_nfc_exit_sleep(); - if(nfc_worker->state == NfcWorkerStatePoll) { - nfc_worker_poll(nfc_worker); + if(nfc_worker->state == NfcWorkerStateDetect) { + nfc_worker_detect(nfc_worker); + } else if(nfc_worker->state == NfcWorkerStateEmulate) { + nfc_worker_emulate(nfc_worker); } else if(nfc_worker->state == NfcWorkerStateReadEMV) { nfc_worker_read_emv(nfc_worker); } else if(nfc_worker->state == NfcWorkerStateEmulateEMV) { - nfc_worker_emulate_emv(nfc_worker); - } else if(nfc_worker->state == NfcWorkerStateEmulate) { - nfc_worker_emulate(nfc_worker); - } else if(nfc_worker->state == NfcWorkerStateField) { nfc_worker_field(nfc_worker); } else if(nfc_worker->state == NfcWorkerStateReadMfUltralight) { nfc_worker_read_mf_ultralight(nfc_worker); + nfc_worker_emulate_emv(nfc_worker); + } else if(nfc_worker->state == NfcWorkerStateField) { } api_hal_nfc_deactivate(); nfc_worker_change_state(nfc_worker, NfcWorkerStateReady); @@ -81,6 +94,55 @@ void nfc_worker_task(void* context) { osThreadExit(); } +void nfc_worker_detect(NfcWorker* nfc_worker) { + rfalNfcDevice* dev_list; + rfalNfcDevice* dev; + uint8_t dev_cnt; + NfcMessage message; + + while(nfc_worker->state == NfcWorkerStateDetect) { + message.found = false; + if(api_hal_nfc_detect(&dev_list, &dev_cnt, 1000, true)) { + // Process first found device + dev = &dev_list[0]; + message.found = true; + message.nfc_detect_data.uid_len = dev->nfcidLen; + memcpy(message.nfc_detect_data.uid, dev->nfcid, dev->nfcidLen); + + if(dev->type == RFAL_NFC_LISTEN_TYPE_NFCA) { + message.nfc_detect_data.device = NfcDeviceNfca; + message.nfc_detect_data.atqa[0] = dev->dev.nfca.sensRes.anticollisionInfo; + message.nfc_detect_data.atqa[1] = dev->dev.nfca.sensRes.platformInfo; + message.nfc_detect_data.sak = dev->dev.nfca.selRes.sak; + // TODO check protocols + + } else if(dev->type == RFAL_NFC_LISTEN_TYPE_NFCB) { + message.nfc_detect_data.device = NfcDeviceNfcb; + } else if(dev->type == RFAL_NFC_LISTEN_TYPE_NFCF) { + message.nfc_detect_data.device = NfcDeviceNfcf; + } else if(dev->type == RFAL_NFC_LISTEN_TYPE_NFCV) { + message.nfc_detect_data.device = NfcDeviceNfcv; + } + } + if(nfc_worker->callback) { + nfc_worker->callback(nfc_worker->context); + } + furi_check( + osMessageQueuePut(nfc_worker->message_queue, &message, 0, osWaitForever) == osOK); + osDelay(100); + } +} + +void nfc_worker_emulate(NfcWorker* nfc_worker) { + while(nfc_worker->state == NfcWorkerStateEmulate) { + if(api_hal_nfc_listen(ApiHalNfcEmulateParamsMifare, 100)) { + FURI_LOG_I(NFC_WORKER_TAG, "Reader detected"); + api_hal_nfc_deactivate(); + } + osDelay(10); + } +} + void nfc_worker_read_emv(NfcWorker* nfc_worker) { ReturnCode err; rfalNfcDevice* dev_list; @@ -91,9 +153,11 @@ void nfc_worker_read_emv(NfcWorker* nfc_worker) { uint8_t* rx_buff; uint16_t* rx_len; - // Update screen before start searching - NfcMessage message = {.type = NfcMessageTypeEMVNotFound}; + NfcMessage message = {.found = false}; while(nfc_worker->state == NfcWorkerStateReadEMV) { + if(nfc_worker->callback) { + nfc_worker->callback(nfc_worker->context); + } furi_check( osMessageQueuePut(nfc_worker->message_queue, &message, 0, osWaitForever) == osOK); memset(&emv_app, 0, sizeof(emv_app)); @@ -105,7 +169,7 @@ void nfc_worker_read_emv(NfcWorker* nfc_worker) { err = api_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false); if(err != ERR_NONE) { FURI_LOG_E(NFC_WORKER_TAG, "Error during selection PPSE request: %d", err); - message.type = NfcMessageTypeEMVNotFound; + message.found = false; api_hal_nfc_deactivate(); continue; } @@ -115,7 +179,7 @@ void nfc_worker_read_emv(NfcWorker* nfc_worker) { FURI_LOG_I(NFC_WORKER_TAG, "Select PPSE responce parced"); } else { FURI_LOG_E(NFC_WORKER_TAG, "Can't find pay application"); - message.type = NfcMessageTypeEMVNotFound; + message.found = false; api_hal_nfc_deactivate(); continue; } @@ -125,7 +189,7 @@ void nfc_worker_read_emv(NfcWorker* nfc_worker) { if(err != ERR_NONE) { FURI_LOG_E( NFC_WORKER_TAG, "Error during application selection request: %d", err); - message.type = NfcMessageTypeEMVNotFound; + message.found = false; api_hal_nfc_deactivate(); continue; } @@ -134,10 +198,10 @@ void nfc_worker_read_emv(NfcWorker* nfc_worker) { "Select application response received. Start parsing response"); if(emv_decode_select_app_response(rx_buff, *rx_len, &emv_app)) { FURI_LOG_I(NFC_WORKER_TAG, "Card name: %s", emv_app.name); - memcpy(message.device.emv_card.name, emv_app.name, sizeof(emv_app.name)); + memcpy(message.nfc_emv_data.name, emv_app.name, sizeof(emv_app.name)); } else { FURI_LOG_E(NFC_WORKER_TAG, "Can't read card name"); - message.type = NfcMessageTypeEMVNotFound; + message.found = false; api_hal_nfc_deactivate(); continue; } @@ -147,15 +211,15 @@ void nfc_worker_read_emv(NfcWorker* nfc_worker) { if(err != ERR_NONE) { FURI_LOG_E( NFC_WORKER_TAG, "Error during Get Processing Options command: %d", err); - message.type = NfcMessageTypeEMVNotFound; + message.found = false; api_hal_nfc_deactivate(); continue; } if(emv_decode_get_proc_opt(rx_buff, *rx_len, &emv_app)) { FURI_LOG_I(NFC_WORKER_TAG, "Card number parsed"); - message.type = NfcMessageTypeEMVFound; + message.found = true; memcpy( - message.device.emv_card.number, + message.nfc_emv_data.number, emv_app.card_number, sizeof(emv_app.card_number)); api_hal_nfc_deactivate(); @@ -189,27 +253,27 @@ void nfc_worker_read_emv(NfcWorker* nfc_worker) { } if(pan_found) { FURI_LOG_I(NFC_WORKER_TAG, "Card PAN found"); - message.type = NfcMessageTypeEMVFound; + message.found = true; memcpy( - message.device.emv_card.number, + message.nfc_emv_data.number, emv_app.card_number, sizeof(emv_app.card_number)); } else { FURI_LOG_E(NFC_WORKER_TAG, "Can't read card number"); - message.type = NfcMessageTypeEMVNotFound; + message.found = false; } api_hal_nfc_deactivate(); } } else { // Can't find EMV card FURI_LOG_W(NFC_WORKER_TAG, "Card doesn't support EMV"); - message.type = NfcMessageTypeEMVNotFound; + message.found = false; api_hal_nfc_deactivate(); } } else { // Can't find EMV card FURI_LOG_W(NFC_WORKER_TAG, "Can't find any cards"); - message.type = NfcMessageTypeEMVNotFound; + message.found = false; api_hal_nfc_deactivate(); } osDelay(20); @@ -271,44 +335,6 @@ void nfc_worker_emulate_emv(NfcWorker* nfc_worker) { } } -void nfc_worker_poll(NfcWorker* nfc_worker) { - rfalNfcDevice* dev_list; - uint8_t dev_cnt; - // Update screen before start searching - NfcMessage message = {.type = NfcMessageTypeDeviceNotFound}; - furi_check(osMessageQueuePut(nfc_worker->message_queue, &message, 0, osWaitForever) == osOK); - - while(nfc_worker->state == NfcWorkerStatePoll) { - if(api_hal_nfc_detect(&dev_list, &dev_cnt, 1000, true)) { - // Send message with first device found - message.type = NfcMessageTypeDeviceFound; - if(dev_list[0].type == RFAL_NFC_LISTEN_TYPE_NFCA) { - message.device.type = NfcDeviceTypeNfca; - message.device.nfca = dev_list[0].dev.nfca; - } else if(dev_list[0].type == RFAL_NFC_LISTEN_TYPE_NFCB) { - message.device.type = NfcDeviceTypeNfcb; - message.device.nfcb = dev_list[0].dev.nfcb; - } else if(dev_list[0].type == RFAL_NFC_LISTEN_TYPE_NFCF) { - message.device.type = NfcDeviceTypeNfcf; - message.device.nfcf = dev_list[0].dev.nfcf; - } else if(dev_list[0].type == RFAL_NFC_LISTEN_TYPE_NFCV) { - message.device.type = NfcDeviceTypeNfcv; - message.device.nfcv = dev_list[0].dev.nfcv; - } else { - // TODO show information about all found devices - message.type = NfcMessageTypeDeviceNotFound; - } - furi_check( - osMessageQueuePut(nfc_worker->message_queue, &message, 0, osWaitForever) == osOK); - } else { - message.type = NfcMessageTypeDeviceNotFound; - furi_check( - osMessageQueuePut(nfc_worker->message_queue, &message, 0, osWaitForever) == osOK); - } - osDelay(5); - } -} - void nfc_worker_read_mf_ultralight(NfcWorker* nfc_worker) { ReturnCode err; rfalNfcDevice* dev_list; @@ -320,8 +346,11 @@ void nfc_worker_read_mf_ultralight(NfcWorker* nfc_worker) { MfUltralightRead mf_ul_read; // Update screen before start searching - NfcMessage message = {.type = NfcMessageTypeMfUlNotFound}; + NfcMessage message = {.found = false}; while(nfc_worker->state == NfcWorkerStateReadMfUltralight) { + if(nfc_worker->callback) { + nfc_worker->callback(nfc_worker->context); + } furi_check( osMessageQueuePut(nfc_worker->message_queue, &message, 0, osWaitForever) == osOK); api_hal_nfc_deactivate(); @@ -354,7 +383,7 @@ void nfc_worker_read_mf_ultralight(NfcWorker* nfc_worker) { api_hal_nfc_deactivate(); if(!api_hal_nfc_detect(&dev_list, &dev_cnt, 1000, false)) { FURI_LOG_E(NFC_WORKER_TAG, "Lost connection. Restarting search"); - message.type = NfcMessageTypeMfUlNotFound; + message.found = false; continue; } } else { @@ -362,7 +391,7 @@ void nfc_worker_read_mf_ultralight(NfcWorker* nfc_worker) { NFC_WORKER_TAG, "Error getting Mifare Ultralight version. Error code: %d", err); - message.type = NfcMessageTypeMfUlNotFound; + message.found = false; continue; } @@ -382,7 +411,7 @@ void nfc_worker_read_mf_ultralight(NfcWorker* nfc_worker) { mf_ul_read.pages_readed = mf_ul_read.pages_to_read; } else { FURI_LOG_E(NFC_WORKER_TAG, "Fast read failed"); - message.type = NfcMessageTypeMfUlNotFound; + message.found = false; continue; } } else { @@ -403,13 +432,19 @@ void nfc_worker_read_mf_ultralight(NfcWorker* nfc_worker) { } // Fill message for nfc application - message.type = NfcMessageTypeMfUlFound; + message.found = true; + message.nfc_mifare_ul_data.nfc_data.uid_len = dev_list[0].dev.nfca.nfcId1Len; + message.nfc_mifare_ul_data.nfc_data.atqa[0] = + dev_list[0].dev.nfca.sensRes.anticollisionInfo; + message.nfc_mifare_ul_data.nfc_data.atqa[1] = + dev_list[0].dev.nfca.sensRes.platformInfo; + message.nfc_mifare_ul_data.nfc_data.sak = dev_list[0].dev.nfca.selRes.sak; memcpy( - message.device.mf_ul_card.uid, + message.nfc_mifare_ul_data.nfc_data.uid, dev_list[0].dev.nfca.nfcId1, - sizeof(message.device.mf_ul_card.uid)); - memcpy(message.device.mf_ul_card.man_block, mf_ul_read.dump, 4 * 3); - memcpy(message.device.mf_ul_card.otp, &mf_ul_read.dump[4 * 3], 4); + message.nfc_mifare_ul_data.nfc_data.uid_len); + memcpy(message.nfc_mifare_ul_data.man_block, mf_ul_read.dump, 4 * 3); + memcpy(message.nfc_mifare_ul_data.otp, &mf_ul_read.dump[4 * 3], 4); for(uint8_t i = 0; i < mf_ul_read.pages_readed * 4; i += 4) { printf("Page %2d: ", i / 4); for(uint8_t j = 0; j < 4; j++) { @@ -418,27 +453,17 @@ void nfc_worker_read_mf_ultralight(NfcWorker* nfc_worker) { printf("\r\n"); } } else { - message.type = NfcMessageTypeMfUlNotFound; + message.found = false; FURI_LOG_W(NFC_WORKER_TAG, "Tag does not support Mifare Ultralight"); } } else { - message.type = NfcMessageTypeMfUlNotFound; + message.found = false; FURI_LOG_W(NFC_WORKER_TAG, "Can't find any tags"); } osDelay(100); } } -void nfc_worker_emulate(NfcWorker* nfc_worker) { - while(nfc_worker->state == NfcWorkerStateEmulate) { - if(api_hal_nfc_listen(ApiHalNfcEmulateParamsMifare, 100)) { - FURI_LOG_I(NFC_WORKER_TAG, "Reader detected"); - api_hal_nfc_deactivate(); - } - osDelay(5); - } -} - void nfc_worker_field(NfcWorker* nfc_worker) { api_hal_nfc_field_on(); while(nfc_worker->state == NfcWorkerStateField) { diff --git a/applications/nfc/nfc_worker.h b/applications/nfc/nfc_worker.h old mode 100644 new mode 100755 index ede84634f..58d29ce6f --- a/applications/nfc/nfc_worker.h +++ b/applications/nfc/nfc_worker.h @@ -2,6 +2,24 @@ typedef struct NfcWorker NfcWorker; +typedef enum { + // Init states + NfcWorkerStateNone, + NfcWorkerStateBroken, + NfcWorkerStateReady, + // Main worker states + NfcWorkerStateDetect, + NfcWorkerStateEmulate, + NfcWorkerStateReadEMV, + NfcWorkerStateEmulateEMV, + NfcWorkerStateField, + NfcWorkerStateReadMfUltralight, + // Transition + NfcWorkerStateStop, +} NfcWorkerState; + +typedef void (*NfcWorkerCallback)(void* context); + NfcWorker* nfc_worker_alloc(osMessageQueueId_t message_queue); NfcWorkerState nfc_worker_get_state(NfcWorker* nfc_worker); @@ -10,6 +28,10 @@ ReturnCode nfc_worker_get_error(NfcWorker* nfc_worker); void nfc_worker_free(NfcWorker* nfc_worker); -void nfc_worker_start(NfcWorker* nfc_worker, NfcWorkerState state); +void nfc_worker_start( + NfcWorker* nfc_worker, + NfcWorkerState state, + NfcWorkerCallback callback, + void* context); void nfc_worker_stop(NfcWorker* nfc_worker); diff --git a/applications/nfc/nfc_worker_i.h b/applications/nfc/nfc_worker_i.h index a3ae0b488..6764c2645 100644 --- a/applications/nfc/nfc_worker_i.h +++ b/applications/nfc/nfc_worker_i.h @@ -1,6 +1,6 @@ #pragma once -#include "nfc_types.h" +#include "nfc_i.h" #include "nfc_worker.h" #include @@ -17,10 +17,13 @@ #include struct NfcWorker { - osMessageQueueId_t message_queue; osThreadAttr_t thread_attr; osThreadId_t thread; + osMessageQueueId_t message_queue; + NfcWorkerCallback callback; + void* context; + NfcWorkerState state; ReturnCode error; }; @@ -33,7 +36,7 @@ void nfc_worker_read_emv(NfcWorker* nfc_worker); void nfc_worker_emulate_emv(NfcWorker* nfc_worker); -void nfc_worker_poll(NfcWorker* nfc_worker); +void nfc_worker_detect(NfcWorker* nfc_worker); void nfc_worker_emulate(NfcWorker* nfc_worker); diff --git a/firmware/targets/f5/api-hal/api-hal-nfc.c b/firmware/targets/f5/api-hal/api-hal-nfc.c index 1af00aa09..326706c12 100644 --- a/firmware/targets/f5/api-hal/api-hal-nfc.c +++ b/firmware/targets/f5/api-hal/api-hal-nfc.c @@ -52,10 +52,14 @@ static const rfalNfcDiscoverParam api_hal_nfc_emulate_params_emv = { ReturnCode api_hal_nfc_init() { // Check if Nfc worker was started - if(rfalNfcGetState() > RFAL_NFC_STATE_NOTINIT) { + rfalNfcState state = rfalNfcGetState(); + if(state == RFAL_NFC_STATE_NOTINIT) { + return rfalNfcInitialize(); + } else if(state == RFAL_NFC_STATE_IDLE) { return ERR_NONE; + } else { + return ERR_BUSY; } - return rfalNfcInitialize(); } bool api_hal_nfc_is_busy() { diff --git a/firmware/targets/f6/api-hal/api-hal-nfc.c b/firmware/targets/f6/api-hal/api-hal-nfc.c index 1af00aa09..326706c12 100644 --- a/firmware/targets/f6/api-hal/api-hal-nfc.c +++ b/firmware/targets/f6/api-hal/api-hal-nfc.c @@ -52,10 +52,14 @@ static const rfalNfcDiscoverParam api_hal_nfc_emulate_params_emv = { ReturnCode api_hal_nfc_init() { // Check if Nfc worker was started - if(rfalNfcGetState() > RFAL_NFC_STATE_NOTINIT) { + rfalNfcState state = rfalNfcGetState(); + if(state == RFAL_NFC_STATE_NOTINIT) { + return rfalNfcInitialize(); + } else if(state == RFAL_NFC_STATE_IDLE) { return ERR_NONE; + } else { + return ERR_BUSY; } - return rfalNfcInitialize(); } bool api_hal_nfc_is_busy() {