Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/ClusterM/flipperzero-firmware.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgornekich <n.gorbadey@gmail.com>2021-07-22 09:05:07 +0300
committerGitHub <noreply@github.com>2021-07-22 09:05:07 +0300
commit49af516ec720d9378fb294ec792f6bd8f489678d (patch)
tree90388e0e3a2abb5682ac05fec05fd3972e040811 /applications/nfc
parent7ca89256eb9714de1d2fe4d899900f0f7349baaa (diff)
[FL-1547], [FL-1500] NFC app v1 (#593)
* nfc: remove mifare read debug view and scene * nfc: change mifare ultralight data structure * mifare_ultralight: add more commands * nfc: add emulate mifare ul scene * nfc: rework data structures, remove debug scenes and views * nfc: add read emv scenes * nfc: mifare emulation wip * nfc cli: increase detecting time * nfc: save nfc files with new format * nfc: store Mifare Ultralight * nfc: start loading mifare ultralight * nfc: add delete scenes * nfc: add edit UID and name * nfc: finish parsing uid and mifare ul data * nfc: delete success fix * gui_widget: introduce GuiWidget * gui_widget: add string element * gui_widget: add button element * gui_widget: move free elements into gui_widget * nfc: rework info scene with GuiWidget * nfc: rework device info scene * nfc: rework delete scene gui * nfc: add compatible script support * nfc: rework emv reading scenes * nfc: rework bank card save * nfc: add bank card custom view * gui_widget: add icon element * nfc: add icon to bank card * nfc: start worker after switching view Co-authored-by: あく <alleteam@gmail.com>
Diffstat (limited to 'applications/nfc')
-rw-r--r--applications/nfc/gui_widget/gui_element_button.c84
-rw-r--r--applications/nfc/gui_widget/gui_element_button.h24
-rw-r--r--applications/nfc/gui_widget/gui_element_i.h21
-rw-r--r--applications/nfc/gui_widget/gui_element_icon.c51
-rw-r--r--applications/nfc/gui_widget/gui_element_icon.h13
-rwxr-xr-xapplications/nfc/gui_widget/gui_element_string.c72
-rwxr-xr-xapplications/nfc/gui_widget/gui_element_string.h21
-rwxr-xr-xapplications/nfc/gui_widget/gui_widget.c141
-rwxr-xr-xapplications/nfc/gui_widget/gui_widget.h76
-rwxr-xr-xapplications/nfc/nfc.c99
-rwxr-xr-xapplications/nfc/nfc_cli.c6
-rwxr-xr-xapplications/nfc/nfc_device.c400
-rw-r--r--applications/nfc/nfc_device.h40
-rw-r--r--applications/nfc/nfc_device_i.h16
-rwxr-xr-xapplications/nfc/nfc_i.h30
-rw-r--r--applications/nfc/nfc_types.h21
-rwxr-xr-xapplications/nfc/nfc_worker.c252
-rwxr-xr-xapplications/nfc/nfc_worker.h16
-rwxr-xr-x[-rw-r--r--]applications/nfc/nfc_worker_i.h10
-rwxr-xr-xapplications/nfc/scenes/nfc_scene_card_menu.c27
-rwxr-xr-xapplications/nfc/scenes/nfc_scene_config.h14
-rwxr-xr-xapplications/nfc/scenes/nfc_scene_debug_detect.c14
-rwxr-xr-xapplications/nfc/scenes/nfc_scene_debug_emulate.c14
-rwxr-xr-xapplications/nfc/scenes/nfc_scene_debug_menu.c72
-rwxr-xr-xapplications/nfc/scenes/nfc_scene_debug_read_emv.c14
-rwxr-xr-xapplications/nfc/scenes/nfc_scene_debug_read_mifare_ul.c14
-rw-r--r--applications/nfc/scenes/nfc_scene_delete.c95
-rw-r--r--applications/nfc/scenes/nfc_scene_delete_success.c47
-rwxr-xr-xapplications/nfc/scenes/nfc_scene_device_info.c185
-rwxr-xr-xapplications/nfc/scenes/nfc_scene_emulate_mifare_ul.c60
-rwxr-xr-x[-rw-r--r--]applications/nfc/scenes/nfc_scene_emulate_uid.c14
-rwxr-xr-xapplications/nfc/scenes/nfc_scene_file_select.c2
-rw-r--r--applications/nfc/scenes/nfc_scene_mifare_ul_menu.c7
-rw-r--r--applications/nfc/scenes/nfc_scene_not_implemented.c4
-rwxr-xr-xapplications/nfc/scenes/nfc_scene_read_card.c17
-rwxr-xr-xapplications/nfc/scenes/nfc_scene_read_card_success.c10
-rwxr-xr-xapplications/nfc/scenes/nfc_scene_read_emv_app.c54
-rwxr-xr-xapplications/nfc/scenes/nfc_scene_read_emv_app_success.c69
-rw-r--r--applications/nfc/scenes/nfc_scene_read_emv_data.c57
-rwxr-xr-xapplications/nfc/scenes/nfc_scene_read_emv_data_success.c89
-rwxr-xr-xapplications/nfc/scenes/nfc_scene_read_mifare_ul.c17
-rwxr-xr-xapplications/nfc/scenes/nfc_scene_read_mifare_ul_success.c26
-rwxr-xr-xapplications/nfc/scenes/nfc_scene_run_emv_app_confirm.c56
-rwxr-xr-xapplications/nfc/scenes/nfc_scene_save_name.c14
-rwxr-xr-xapplications/nfc/scenes/nfc_scene_save_success.c5
-rwxr-xr-xapplications/nfc/scenes/nfc_scene_saved_menu.c16
-rwxr-xr-xapplications/nfc/scenes/nfc_scene_scripts_menu.c6
-rwxr-xr-xapplications/nfc/scenes/nfc_scene_set_atqa.c12
-rwxr-xr-xapplications/nfc/scenes/nfc_scene_set_sak.c11
-rwxr-xr-xapplications/nfc/scenes/nfc_scene_set_type.c10
-rwxr-xr-xapplications/nfc/scenes/nfc_scene_set_uid.c8
-rwxr-xr-xapplications/nfc/scenes/nfc_scene_start.c11
-rwxr-xr-xapplications/nfc/views/bank_card.c65
-rw-r--r--applications/nfc/views/bank_card.h23
-rwxr-xr-xapplications/nfc/views/nfc_detect.c142
-rw-r--r--applications/nfc/views/nfc_detect.h12
-rwxr-xr-xapplications/nfc/views/nfc_emulate.c79
-rw-r--r--applications/nfc/views/nfc_emulate.h12
-rwxr-xr-xapplications/nfc/views/nfc_emv.c133
-rw-r--r--applications/nfc/views/nfc_emv.h12
-rwxr-xr-xapplications/nfc/views/nfc_mifare_ul.c162
-rw-r--r--applications/nfc/views/nfc_mifare_ul.h12
62 files changed, 2063 insertions, 1053 deletions
diff --git a/applications/nfc/gui_widget/gui_element_button.c b/applications/nfc/gui_widget/gui_element_button.c
new file mode 100644
index 00000000..e671d7dd
--- /dev/null
+++ b/applications/nfc/gui_widget/gui_element_button.c
@@ -0,0 +1,84 @@
+#include "gui_element_i.h"
+#include "gui_element_button.h"
+#include "gui_widget.h"
+#include <gui/elements.h>
+#include <m-string.h>
+
+typedef struct {
+ GuiButtonType button_type;
+ string_t text;
+ ButtonCallback callback;
+ void* context;
+} GuiButtonModel;
+
+static void gui_button_draw(Canvas* canvas, GuiElement* element) {
+ furi_assert(canvas);
+ furi_assert(element);
+ GuiButtonModel* model = element->model;
+
+ canvas_set_color(canvas, ColorBlack);
+ canvas_set_font(canvas, FontSecondary);
+
+ if(model->button_type == GuiButtonTypeLeft) {
+ elements_button_left(canvas, string_get_cstr(model->text));
+ } else if(model->button_type == GuiButtonTypeRight) {
+ elements_button_right(canvas, string_get_cstr(model->text));
+ } else if(model->button_type == GuiButtonTypeCenter) {
+ elements_button_center(canvas, string_get_cstr(model->text));
+ }
+}
+
+static bool gui_button_input(InputEvent* event, GuiElement* element) {
+ GuiButtonModel* model = element->model;
+ bool consumed = false;
+
+ if((event->type == InputTypeShort) && model->callback) {
+ if((model->button_type == GuiButtonTypeLeft) && (event->key == InputKeyLeft)) {
+ model->callback(model->button_type, model->context);
+ consumed = true;
+ } else if((model->button_type == GuiButtonTypeRight) && (event->key == InputKeyRight)) {
+ model->callback(model->button_type, model->context);
+ consumed = true;
+ } else if((model->button_type == GuiButtonTypeCenter) && (event->key == InputKeyOk)) {
+ model->callback(model->button_type, model->context);
+ consumed = true;
+ }
+ }
+
+ return consumed;
+}
+
+static void gui_button_free(GuiElement* gui_button) {
+ furi_assert(gui_button);
+
+ GuiButtonModel* model = gui_button->model;
+ if(gui_button->parent != NULL) {
+ // TODO deattach element
+ }
+ string_clear(model->text);
+ free(gui_button->model);
+ free(gui_button);
+}
+
+GuiElement* gui_button_create(
+ GuiButtonType button_type,
+ const char* text,
+ ButtonCallback callback,
+ void* context) {
+ // Allocate and init model
+ GuiButtonModel* model = furi_alloc(sizeof(GuiButtonModel));
+ model->button_type = button_type;
+ model->callback = callback;
+ model->context = context;
+ string_init_set_str(model->text, text);
+
+ // Allocate and init Element
+ GuiElement* gui_button = furi_alloc(sizeof(GuiElement));
+ gui_button->parent = NULL;
+ gui_button->input = gui_button_input;
+ gui_button->draw = gui_button_draw;
+ gui_button->free = gui_button_free;
+ gui_button->model = model;
+
+ return gui_button;
+}
diff --git a/applications/nfc/gui_widget/gui_element_button.h b/applications/nfc/gui_widget/gui_element_button.h
new file mode 100644
index 00000000..804c0a4e
--- /dev/null
+++ b/applications/nfc/gui_widget/gui_element_button.h
@@ -0,0 +1,24 @@
+#pragma once
+#include <stdint.h>
+
+typedef struct GuiElement GuiElement;
+
+typedef enum {
+ GuiButtonTypeLeft,
+ GuiButtonTypeCenter,
+ GuiButtonTypeRight,
+} GuiButtonType;
+
+typedef void (*ButtonCallback)(GuiButtonType button, void* context);
+
+/** Allocate Button Element
+ * @param button_type GuiButtonType instance
+ * @param text text on allocated button
+ * @param callback ButtonCallback instance
+ * @param context pointer to context
+ */
+GuiElement* gui_button_create(
+ GuiButtonType button_type,
+ const char* text,
+ ButtonCallback callback,
+ void* context);
diff --git a/applications/nfc/gui_widget/gui_element_i.h b/applications/nfc/gui_widget/gui_element_i.h
new file mode 100644
index 00000000..ee06e1c7
--- /dev/null
+++ b/applications/nfc/gui_widget/gui_element_i.h
@@ -0,0 +1,21 @@
+#pragma once
+#include <furi.h>
+#include <gui/view.h>
+
+typedef struct GuiElement GuiElement;
+typedef struct GuiWidget GuiWidget;
+
+struct GuiElement {
+ // generic draw and input callbacks
+ void (*draw)(Canvas* canvas, GuiElement* element);
+ bool (*input)(InputEvent* event, GuiElement* element);
+
+ // free callback
+ void (*free)(GuiElement* element);
+
+ // generic model holder
+ void* model;
+
+ // pointer to widget that hold our element
+ GuiWidget* parent;
+}; \ No newline at end of file
diff --git a/applications/nfc/gui_widget/gui_element_icon.c b/applications/nfc/gui_widget/gui_element_icon.c
new file mode 100644
index 00000000..f9ca4b60
--- /dev/null
+++ b/applications/nfc/gui_widget/gui_element_icon.c
@@ -0,0 +1,51 @@
+#include "gui_element_i.h"
+#include "gui_element_icon.h"
+#include "gui_widget.h"
+
+#include <m-string.h>
+
+typedef struct {
+ uint8_t x;
+ uint8_t y;
+ const Icon* icon;
+} GuiIconModel;
+
+static void gui_icon_draw(Canvas* canvas, GuiElement* element) {
+ furi_assert(canvas);
+ furi_assert(element);
+ GuiIconModel* model = element->model;
+
+ if(model->icon) {
+ canvas_draw_icon(canvas, model->x, model->y, model->icon);
+ }
+}
+
+static void gui_icon_free(GuiElement* gui_icon) {
+ furi_assert(gui_icon);
+
+ if(gui_icon->parent != NULL) {
+ // TODO deattach element
+ }
+ free(gui_icon->model);
+ free(gui_icon);
+}
+
+GuiElement* gui_icon_create(uint8_t x, uint8_t y, const Icon* icon) {
+ furi_assert(icon);
+
+ // Allocate and init model
+ GuiIconModel* model = furi_alloc(sizeof(GuiIconModel));
+ model->x = x;
+ model->y = y;
+ model->icon = icon;
+
+ // Allocate and init Element
+ GuiElement* gui_icon = furi_alloc(sizeof(GuiElement));
+ gui_icon->parent = NULL;
+ gui_icon->input = NULL;
+ gui_icon->draw = gui_icon_draw;
+ gui_icon->free = gui_icon_free;
+ gui_icon->model = model;
+
+ return gui_icon;
+}
diff --git a/applications/nfc/gui_widget/gui_element_icon.h b/applications/nfc/gui_widget/gui_element_icon.h
new file mode 100644
index 00000000..2c983858
--- /dev/null
+++ b/applications/nfc/gui_widget/gui_element_icon.h
@@ -0,0 +1,13 @@
+#pragma once
+#include <stdint.h>
+#include <gui/canvas.h>
+
+typedef struct GuiElement GuiElement;
+
+/** Allocate GuiElement element
+ * @param x - x coordinate
+ * @param y - y coordinate
+ * @param icon Icon instance
+ * @return GuiElement instance
+ */
+GuiElement* gui_icon_create(uint8_t x, uint8_t y, const Icon* icon);
diff --git a/applications/nfc/gui_widget/gui_element_string.c b/applications/nfc/gui_widget/gui_element_string.c
new file mode 100755
index 00000000..dc9e271c
--- /dev/null
+++ b/applications/nfc/gui_widget/gui_element_string.c
@@ -0,0 +1,72 @@
+#include "gui_element_i.h"
+#include "gui_element_string.h"
+#include "gui_widget.h"
+
+#include <m-string.h>
+
+typedef struct {
+ uint8_t x;
+ uint8_t y;
+ Align horizontal;
+ Align vertical;
+ Font font;
+ string_t text;
+} GuiStringModel;
+
+static void gui_string_draw(Canvas* canvas, GuiElement* element) {
+ furi_assert(canvas);
+ furi_assert(element);
+ GuiStringModel* model = element->model;
+
+ if(string_size(model->text)) {
+ canvas_set_font(canvas, model->font);
+ canvas_draw_str_aligned(
+ canvas,
+ model->x,
+ model->y,
+ model->horizontal,
+ model->vertical,
+ string_get_cstr(model->text));
+ }
+}
+
+static void gui_string_free(GuiElement* gui_string) {
+ furi_assert(gui_string);
+
+ GuiStringModel* model = gui_string->model;
+ if(gui_string->parent != NULL) {
+ // TODO deattach element
+ }
+ string_clear(model->text);
+ free(gui_string->model);
+ free(gui_string);
+}
+
+GuiElement* gui_string_create(
+ uint8_t x,
+ uint8_t y,
+ Align horizontal,
+ Align vertical,
+ Font font,
+ const char* text) {
+ furi_assert(text);
+
+ // Allocate and init model
+ GuiStringModel* model = furi_alloc(sizeof(GuiStringModel));
+ model->x = x;
+ model->y = y;
+ model->horizontal = horizontal;
+ model->vertical = vertical;
+ model->font = font;
+ string_init_set_str(model->text, text);
+
+ // Allocate and init Element
+ GuiElement* gui_string = furi_alloc(sizeof(GuiElement));
+ gui_string->parent = NULL;
+ gui_string->input = NULL;
+ gui_string->draw = gui_string_draw;
+ gui_string->free = gui_string_free;
+ gui_string->model = model;
+
+ return gui_string;
+}
diff --git a/applications/nfc/gui_widget/gui_element_string.h b/applications/nfc/gui_widget/gui_element_string.h
new file mode 100755
index 00000000..5be2ae40
--- /dev/null
+++ b/applications/nfc/gui_widget/gui_element_string.h
@@ -0,0 +1,21 @@
+#pragma once
+#include <stdint.h>
+#include <gui/canvas.h>
+
+typedef struct GuiElement GuiElement;
+
+/** Allocate GuiElement element
+ * @param x - x coordinate
+ * @param y - y coordinate
+ * @param horizontal - Align instance
+ * @param vertical - Align instance
+ * @param font Font instance
+ * @return GuiElement instance
+ */
+GuiElement* gui_string_create(
+ uint8_t x,
+ uint8_t y,
+ Align horizontal,
+ Align vertical,
+ Font font,
+ const char* text);
diff --git a/applications/nfc/gui_widget/gui_widget.c b/applications/nfc/gui_widget/gui_widget.c
new file mode 100755
index 00000000..c5b21d95
--- /dev/null
+++ b/applications/nfc/gui_widget/gui_widget.c
@@ -0,0 +1,141 @@
+#include <furi.h>
+#include "gui_element_i.h"
+#include "gui_widget.h"
+
+#define MAX_GUI_ELEMENTS 8
+
+struct GuiWidget {
+ View* view;
+ void* context;
+};
+
+// TODO rework with M-LIB container
+typedef struct {
+ GuiElement* element[MAX_GUI_ELEMENTS];
+} GuiWidgetModel;
+
+static void gui_widget_view_draw_callback(Canvas* canvas, void* _model) {
+ GuiWidgetModel* model = _model;
+ canvas_clear(canvas);
+
+ for(uint8_t i = 0; i < MAX_GUI_ELEMENTS; i++) {
+ if(model->element[i] != NULL) {
+ if(model->element[i]->draw != NULL) {
+ model->element[i]->draw(canvas, model->element[i]);
+ }
+ }
+ };
+}
+
+static bool gui_widget_view_input_callback(InputEvent* event, void* context) {
+ GuiWidget* gui_widget = context;
+ bool consumed = false;
+
+ with_view_model(
+ gui_widget->view, (GuiWidgetModel * model) {
+ for(uint8_t i = 0; i < MAX_GUI_ELEMENTS; i++) {
+ if(model->element[i] != NULL) {
+ if(model->element[i]->input != NULL) {
+ consumed = model->element[i]->input(event, model->element[i]);
+ }
+ }
+ };
+ return true;
+ });
+
+ return consumed;
+}
+
+GuiWidget* gui_widget_alloc() {
+ GuiWidget* gui_widget = furi_alloc(sizeof(GuiWidget));
+ gui_widget->view = view_alloc();
+ view_set_context(gui_widget->view, gui_widget);
+ view_allocate_model(gui_widget->view, ViewModelTypeLocking, sizeof(GuiWidgetModel));
+ view_set_draw_callback(gui_widget->view, gui_widget_view_draw_callback);
+ view_set_input_callback(gui_widget->view, gui_widget_view_input_callback);
+
+ with_view_model(
+ gui_widget->view, (GuiWidgetModel * model) {
+ for(uint8_t i = 0; i < MAX_GUI_ELEMENTS; i++) {
+ model->element[i] = NULL;
+ };
+ return true;
+ });
+
+ return gui_widget;
+}
+
+void gui_widget_free(GuiWidget* gui_widget) {
+ furi_assert(gui_widget);
+ gui_widget_clear(gui_widget);
+ view_free(gui_widget->view);
+ free(gui_widget);
+}
+
+void gui_widget_clear(GuiWidget* gui_widget) {
+ furi_assert(gui_widget);
+
+ with_view_model(
+ gui_widget->view, (GuiWidgetModel * model) {
+ for(uint8_t i = 0; i < MAX_GUI_ELEMENTS; i++) {
+ if(model->element[i]) {
+ furi_assert(model->element[i]->free);
+ model->element[i]->free(model->element[i]);
+ model->element[i] = NULL;
+ }
+ };
+ return true;
+ });
+}
+
+View* gui_widget_get_view(GuiWidget* gui_widget) {
+ furi_assert(gui_widget);
+ return gui_widget->view;
+}
+
+void gui_widget_add_element(GuiWidget* gui_widget, GuiElement* element) {
+ furi_assert(gui_widget);
+ with_view_model(
+ gui_widget->view, (GuiWidgetModel * model) {
+ // add element to first null position
+ for(uint8_t i = 0; i < MAX_GUI_ELEMENTS; i++) {
+ if(model->element[i] == NULL) {
+ model->element[i] = element;
+ element->parent = gui_widget;
+ break;
+ }
+ };
+ return true;
+ });
+}
+
+void gui_widget_add_string_element(
+ GuiWidget* gui_widget,
+ uint8_t x,
+ uint8_t y,
+ Align horizontal,
+ Align vertical,
+ Font font,
+ const char* text) {
+ furi_assert(gui_widget);
+ GuiElement* string_element = gui_string_create(x, y, horizontal, vertical, font, text);
+ gui_widget_add_element(gui_widget, string_element);
+}
+
+void gui_widget_add_button_element(
+ GuiWidget* gui_widget,
+ GuiButtonType button_type,
+ const char* text,
+ ButtonCallback callback,
+ void* context) {
+ furi_assert(gui_widget);
+ GuiElement* button_element = gui_button_create(button_type, text, callback, context);
+ gui_widget_add_element(gui_widget, button_element);
+}
+
+void gui_widget_add_icon_element(GuiWidget* gui_widget, uint8_t x, uint8_t y, const Icon* icon) {
+ furi_assert(gui_widget);
+ furi_assert(icon);
+ GuiElement* icon_element = gui_icon_create(x, y, icon);
+ gui_widget_add_element(gui_widget, icon_element);
+}
diff --git a/applications/nfc/gui_widget/gui_widget.h b/applications/nfc/gui_widget/gui_widget.h
new file mode 100755
index 00000000..6b34b1f9
--- /dev/null
+++ b/applications/nfc/gui_widget/gui_widget.h
@@ -0,0 +1,76 @@
+#pragma once
+#include <gui/view.h>
+#include "gui_element_string.h"
+#include "gui_element_button.h"
+#include "gui_element_icon.h"
+
+typedef struct GuiWidget GuiWidget;
+typedef struct GuiElement GuiElement;
+
+/** Allocate Gui Widget that holds Gui Elements
+ * @return GuiWidget instance
+ */
+GuiWidget* gui_widget_alloc();
+
+/** Free Gui Widget
+ * @note this function free Gui Elements
+ * @param gui_widget GuiWidget instance
+ */
+void gui_widget_free(GuiWidget* gui_widget);
+
+/** Clear Gui Widget
+ * @param gui_widget GuiWidget instance
+ */
+void gui_widget_clear(GuiWidget* gui_widget);
+
+/** Get Gui Widget view
+ * @param gui_widget GuiWidget instance
+ * @return View instance
+ */
+View* gui_widget_get_view(GuiWidget* gui_widget);
+
+/** Add generic Gui Elements to Gui Widget
+ * @param gui_widget GuiWidget instance
+ * @param element GuiElement element
+ */
+void gui_widget_add_element(GuiWidget* gui_widget, GuiElement* element);
+
+/** Add String Element
+ * @param gui_widget GuiWidget instance
+ * @param x - x coordinate
+ * @param y - y coordinate
+ * @param horizontal - Align instance
+ * @param vertical - Align instance
+ * @param font Font instance
+ * @return GuiElement instance
+ */
+void gui_widget_add_string_element(
+ GuiWidget* gui_widget,
+ uint8_t x,
+ uint8_t y,
+ Align horizontal,
+ Align vertical,
+ Font font,
+ const char* text);
+
+/** Add Button Element
+ * @param gui_widget GuiWidget instance
+ * @param button_type GuiButtonType instance
+ * @param text text on allocated button
+ * @param callback ButtonCallback instance
+ * @param context pointer to context
+ */
+void gui_widget_add_button_element(
+ GuiWidget* gui_widget,
+ GuiButtonType button_type,
+ const char* text,
+ ButtonCallback callback,
+ void* context);
+
+/** Add Icon Element
+ * @param gui_widget GuiWidget instance
+ * @param x - x coordinate
+ * @param y - y coordinate
+ * @param icon Icon instance
+ */
+void gui_widget_add_icon_element(GuiWidget* gui_widget, uint8_t x, uint8_t y, const Icon* icon);
diff --git a/applications/nfc/nfc.c b/applications/nfc/nfc.c
index d970eb33..68fcf358 100755
--- a/applications/nfc/nfc.c
+++ b/applications/nfc/nfc.c
@@ -22,78 +22,61 @@ void nfc_tick_event_callback(void* context) {
Nfc* nfc_alloc() {
Nfc* nfc = furi_alloc(sizeof(Nfc));
- nfc->nfc_common.worker = nfc_worker_alloc();
- nfc->nfc_common.view_dispatcher = view_dispatcher_alloc();
+ nfc->worker = nfc_worker_alloc();
+ nfc->view_dispatcher = view_dispatcher_alloc();
nfc->scene_manager = scene_manager_alloc(&nfc_scene_handlers, nfc);
- view_dispatcher_enable_queue(nfc->nfc_common.view_dispatcher);
- view_dispatcher_set_event_callback_context(nfc->nfc_common.view_dispatcher, nfc);
- view_dispatcher_set_custom_event_callback(
- nfc->nfc_common.view_dispatcher, nfc_custom_event_callback);
+ view_dispatcher_enable_queue(nfc->view_dispatcher);
+ view_dispatcher_set_event_callback_context(nfc->view_dispatcher, nfc);
+ view_dispatcher_set_custom_event_callback(nfc->view_dispatcher, nfc_custom_event_callback);
view_dispatcher_set_navigation_event_callback(
- nfc->nfc_common.view_dispatcher, nfc_navigation_event_callback);
- view_dispatcher_set_tick_event_callback(
- nfc->nfc_common.view_dispatcher, nfc_tick_event_callback, 300);
+ nfc->view_dispatcher, nfc_navigation_event_callback);
+ view_dispatcher_set_tick_event_callback(nfc->view_dispatcher, nfc_tick_event_callback, 100);
// Open GUI record
nfc->gui = furi_record_open("gui");
- view_dispatcher_attach_to_gui(
- nfc->nfc_common.view_dispatcher, nfc->gui, ViewDispatcherTypeFullscreen);
+ view_dispatcher_attach_to_gui(nfc->view_dispatcher, nfc->gui, ViewDispatcherTypeFullscreen);
// Open Notification record
nfc->notifications = furi_record_open("notification");
// Submenu
nfc->submenu = submenu_alloc();
- view_dispatcher_add_view(
- nfc->nfc_common.view_dispatcher, NfcViewMenu, submenu_get_view(nfc->submenu));
+ view_dispatcher_add_view(nfc->view_dispatcher, NfcViewMenu, submenu_get_view(nfc->submenu));
// Dialog
nfc->dialog_ex = dialog_ex_alloc();
view_dispatcher_add_view(
- nfc->nfc_common.view_dispatcher, NfcViewDialogEx, dialog_ex_get_view(nfc->dialog_ex));
+ nfc->view_dispatcher, NfcViewDialogEx, dialog_ex_get_view(nfc->dialog_ex));
// Popup
nfc->popup = popup_alloc();
- view_dispatcher_add_view(
- nfc->nfc_common.view_dispatcher, NfcViewPopup, popup_get_view(nfc->popup));
+ view_dispatcher_add_view(nfc->view_dispatcher, NfcViewPopup, popup_get_view(nfc->popup));
// Text Input
nfc->text_input = text_input_alloc();
view_dispatcher_add_view(
- nfc->nfc_common.view_dispatcher, NfcViewTextInput, text_input_get_view(nfc->text_input));
+ nfc->view_dispatcher, NfcViewTextInput, text_input_get_view(nfc->text_input));
// Byte Input
nfc->byte_input = byte_input_alloc();
view_dispatcher_add_view(
- nfc->nfc_common.view_dispatcher, NfcViewByteInput, byte_input_get_view(nfc->byte_input));
+ nfc->view_dispatcher, NfcViewByteInput, byte_input_get_view(nfc->byte_input));
// TextBox
nfc->text_box = text_box_alloc();
view_dispatcher_add_view(
- nfc->nfc_common.view_dispatcher, NfcViewTextBox, text_box_get_view(nfc->text_box));
+ nfc->view_dispatcher, NfcViewTextBox, text_box_get_view(nfc->text_box));
string_init(nfc->text_box_store);
- // Detect
- 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->nfc_emulate = nfc_emulate_alloc(&nfc->nfc_common);
+ // Custom Widget
+ nfc->widget = gui_widget_alloc();
view_dispatcher_add_view(
- nfc->nfc_common.view_dispatcher, NfcViewEmulate, nfc_emulate_get_view(nfc->nfc_emulate));
+ nfc->view_dispatcher, NfcViewWidget, gui_widget_get_view(nfc->widget));
- // EMV
- nfc->nfc_emv = nfc_emv_alloc(&nfc->nfc_common);
+ // Bank Card
+ nfc->bank_card = bank_card_alloc();
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));
+ nfc->view_dispatcher, NfcViewBankCard, bank_card_get_view(nfc->bank_card));
return nfc;
}
@@ -102,52 +85,44 @@ void nfc_free(Nfc* nfc) {
furi_assert(nfc);
// Submenu
- view_dispatcher_remove_view(nfc->nfc_common.view_dispatcher, NfcViewMenu);
+ view_dispatcher_remove_view(nfc->view_dispatcher, NfcViewMenu);
submenu_free(nfc->submenu);
// DialogEx
- view_dispatcher_remove_view(nfc->nfc_common.view_dispatcher, NfcViewDialogEx);
+ view_dispatcher_remove_view(nfc->view_dispatcher, NfcViewDialogEx);
dialog_ex_free(nfc->dialog_ex);
// Popup
- view_dispatcher_remove_view(nfc->nfc_common.view_dispatcher, NfcViewPopup);
+ view_dispatcher_remove_view(nfc->view_dispatcher, NfcViewPopup);
popup_free(nfc->popup);
// TextInput
- view_dispatcher_remove_view(nfc->nfc_common.view_dispatcher, NfcViewTextInput);
+ view_dispatcher_remove_view(nfc->view_dispatcher, NfcViewTextInput);
text_input_free(nfc->text_input);
// ByteInput
- view_dispatcher_remove_view(nfc->nfc_common.view_dispatcher, NfcViewByteInput);
+ view_dispatcher_remove_view(nfc->view_dispatcher, NfcViewByteInput);
byte_input_free(nfc->byte_input);
// TextBox
- view_dispatcher_remove_view(nfc->nfc_common.view_dispatcher, NfcViewTextBox);
+ view_dispatcher_remove_view(nfc->view_dispatcher, NfcViewTextBox);
text_box_free(nfc->text_box);
string_clear(nfc->text_box_store);
- // Detect
- view_dispatcher_remove_view(nfc->nfc_common.view_dispatcher, NfcViewDetect);
- nfc_detect_free(nfc->nfc_detect);
-
- // Emulate
- view_dispatcher_remove_view(nfc->nfc_common.view_dispatcher, NfcViewEmulate);
- nfc_emulate_free(nfc->nfc_emulate);
-
- // EMV
- view_dispatcher_remove_view(nfc->nfc_common.view_dispatcher, NfcViewEmv);
- nfc_emv_free(nfc->nfc_emv);
+ // Custom Widget
+ view_dispatcher_remove_view(nfc->view_dispatcher, NfcViewWidget);
+ gui_widget_free(nfc->widget);
- // Mifare Ultralight
- view_dispatcher_remove_view(nfc->nfc_common.view_dispatcher, NfcViewMifareUl);
- nfc_mifare_ul_free(nfc->nfc_mifare_ul);
+ // Bank Card
+ view_dispatcher_remove_view(nfc->view_dispatcher, NfcViewBankCard);
+ bank_card_free(nfc->bank_card);
// Worker
- nfc_worker_stop(nfc->nfc_common.worker);
- nfc_worker_free(nfc->nfc_common.worker);
+ nfc_worker_stop(nfc->worker);
+ nfc_worker_free(nfc->worker);
// View Dispatcher
- view_dispatcher_free(nfc->nfc_common.view_dispatcher);
+ view_dispatcher_free(nfc->view_dispatcher);
// Scene Manager
scene_manager_free(nfc->scene_manager);
@@ -167,13 +142,13 @@ int32_t nfc_task(void* p) {
Nfc* nfc = nfc_alloc();
// Check argument and run corresponding scene
- if(p && nfc_device_load(&nfc->device, p)) {
+ if(p && nfc_device_load(&nfc->dev, p)) {
scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateUid);
} else {
scene_manager_next_scene(nfc->scene_manager, NfcSceneStart);
}
- view_dispatcher_run(nfc->nfc_common.view_dispatcher);
+ view_dispatcher_run(nfc->view_dispatcher);
nfc_free(nfc);
diff --git a/applications/nfc/nfc_cli.c b/applications/nfc/nfc_cli.c
index 6f420541..7656bd31 100755
--- a/applications/nfc/nfc_cli.c
+++ b/applications/nfc/nfc_cli.c
@@ -24,7 +24,7 @@ void nfc_cli_detect(Cli* cli, string_t args, void* context) {
printf("Detecting nfc...\r\nPress Ctrl+C to abort\r\n");
while(!cmd_exit) {
cmd_exit |= cli_cmd_interrupt_received(cli);
- cmd_exit |= api_hal_nfc_detect(&dev_list, &dev_cnt, 200, true);
+ cmd_exit |= api_hal_nfc_detect(&dev_list, &dev_cnt, 400, true);
if(dev_cnt > 0) {
printf("Found %d devices\r\n", dev_cnt);
for(uint8_t i = 0; i < dev_cnt; i++) {
@@ -56,13 +56,13 @@ void nfc_cli_emulate(Cli* cli, string_t args, void* context) {
printf("Emulating NFC-A Type: T2T UID: CF72D440 SAK: 20 ATQA: 00/04\r\n");
printf("Press Ctrl+C to abort\r\n");
- NfcDeviceData params = {
+ NfcDeviceCommomData params = {
.uid = {0x36, 0x9C, 0xe7, 0xb1, 0x0A, 0xC1, 0x34},
.uid_len = 7,
.atqa = {0x44, 0x00},
.sak = 0x00,
.device = NfcDeviceNfca,
- .protocol = NfcDeviceProtocolMfUltralight,
+ .protocol = NfcDeviceProtocolMifareUl,
};
while(!cli_cmd_interrupt_received(cli)) {
diff --git a/applications/nfc/nfc_device.c b/applications/nfc/nfc_device.c
index d92d0c3d..7037044a 100755
--- a/applications/nfc/nfc_device.c
+++ b/applications/nfc/nfc_device.c
@@ -1,13 +1,246 @@
-#include "nfc_device.h"
+#include "nfc_device_i.h"
#include <file-worker.h>
#include <path.h>
+#include <hex.h>
#define NFC_DEVICE_MAX_DATA_LEN 14
static const char* nfc_app_folder = "nfc";
static const char* nfc_app_extension = ".nfc";
+static bool nfc_device_read_hex(string_t str, uint8_t* buff, uint16_t len) {
+ string_strim(str);
+ uint8_t nibble_high = 0;
+ uint8_t nibble_low = 0;
+ bool parsed = true;
+
+ for(uint16_t i = 0; i < len; i++) {
+ if(hex_char_to_hex_nibble(string_get_char(str, 0), &nibble_high) &&
+ hex_char_to_hex_nibble(string_get_char(str, 1), &nibble_low)) {
+ buff[i] = (nibble_high << 4) | nibble_low;
+ string_right(str, 3);
+ } else {
+ parsed = false;
+ break;
+ }
+ }
+ return parsed;
+}
+
+uint16_t nfc_device_prepare_format_string(NfcDevice* dev, string_t format_string) {
+ if(dev->format == NfcDeviceSaveFormatUid) {
+ string_set_str(format_string, "UID\n");
+ } else if(dev->format == NfcDeviceSaveFormatBankCard) {
+ string_set_str(format_string, "Bank card\n");
+ } else if(dev->format == NfcDeviceSaveFormatMifareUl) {
+ string_set_str(format_string, "Mifare Ultralight\n");
+ } else {
+ string_set_str(format_string, "Unknown\n");
+ }
+ return string_size(format_string);
+}
+
+bool nfc_device_parse_format_string(NfcDevice* dev, string_t format_string) {
+ if(string_start_with_str_p(format_string, "UID")) {
+ dev->format = NfcDeviceSaveFormatUid;
+ dev->dev_data.nfc_data.protocol = NfcDeviceProtocolUnknown;
+ return true;
+ } else if(string_start_with_str_p(format_string, "Bank card")) {
+ dev->format = NfcDeviceSaveFormatBankCard;
+ dev->dev_data.nfc_data.protocol = NfcDeviceProtocolEMV;
+ return true;
+ } else if(string_start_with_str_p(format_string, "Mifare Ultralight")) {
+ dev->format = NfcDeviceSaveFormatMifareUl;
+ dev->dev_data.nfc_data.protocol = NfcDeviceProtocolMifareUl;
+ return true;
+ }
+ return false;
+}
+
+uint16_t nfc_device_prepare_uid_string(NfcDevice* dev, string_t uid_string) {
+ NfcDeviceCommomData* uid_data = &dev->dev_data.nfc_data;
+ string_printf(uid_string, "UID len: %02X UID: ", dev->dev_data.nfc_data.uid_len);
+ for(uint8_t i = 0; i < uid_data->uid_len; i++) {
+ string_cat_printf(uid_string, "%02X ", uid_data->uid[i]);
+ }
+ string_cat_printf(
+ uid_string,
+ "ATQA: %02X %02X SAK: %02X\n",
+ uid_data->atqa[0],
+ uid_data->atqa[1],
+ uid_data->sak);
+ return string_size(uid_string);
+}
+
+bool nfc_device_parse_uid_string(NfcDevice* dev, string_t uid_string) {
+ NfcDeviceCommomData* uid_data = &dev->dev_data.nfc_data;
+ bool parsed = false;
+
+ do {
+ // strlen("UID len: ") = 9
+ string_right(uid_string, 9);
+ if(!nfc_device_read_hex(uid_string, &uid_data->uid_len, 1)) {
+ break;
+ }
+ // strlen("UID: ") = 5
+ string_right(uid_string, 5);
+ if(!nfc_device_read_hex(uid_string, uid_data->uid, uid_data->uid_len)) {
+ break;
+ }
+ // strlen("ATQA: ") = 6
+ string_right(uid_string, 6);
+ if(!nfc_device_read_hex(uid_string, uid_data->atqa, 2)) {
+ break;
+ }
+ // strlen("SAK: ") = 5
+ string_right(uid_string, 5);
+ if(!nfc_device_read_hex(uid_string, &uid_data->sak, 1)) {
+ break;
+ }
+ parsed = true;
+ } while(0);
+
+ return parsed;
+}
+
+uint16_t nfc_device_prepare_mifare_ul_string(NfcDevice* dev, string_t mifare_ul_string) {
+ MifareUlData* data = &dev->dev_data.mf_ul_data;
+ string_printf(mifare_ul_string, "Signature:");
+ for(uint8_t i = 0; i < sizeof(data->signature); i++) {
+ string_cat_printf(mifare_ul_string, " %02X", data->signature[i]);
+ }
+ string_cat_printf(mifare_ul_string, "\nVersion:");
+ uint8_t* version = (uint8_t*)&data->version;
+ for(uint8_t i = 0; i < sizeof(data->version); i++) {
+ string_cat_printf(mifare_ul_string, " %02X", version[i]);
+ }
+ for(uint8_t i = 0; i < 3; i++) {
+ string_cat_printf(
+ mifare_ul_string,
+ "\nCounter %d: %lu Tearing flag %d: %02X",
+ i,
+ data->counter[i],
+ i,
+ data->tearing[i]);
+ }
+ string_cat_printf(mifare_ul_string, "\nData size: %d\n", data->data_size);
+ for(uint16_t i = 0; i < data->data_size; i += 4) {
+ string_cat_printf(
+ mifare_ul_string,
+ "%02X %02X %02X %02X\n",
+ data->data[i],
+ data->data[i + 1],
+ data->data[i + 2],
+ data->data[i + 3]);
+ }
+ return string_size(mifare_ul_string);
+}
+
+bool nfc_device_parse_mifare_ul_string(NfcDevice* dev, string_t mifare_ul_string) {
+ MifareUlData* data = &dev->dev_data.mf_ul_data;
+ uint16_t tearing_tmp = 0;
+ uint16_t cnt_num = 0;
+ size_t ws = 0;
+ int res = 0;
+ bool parsed = false;
+
+ do {
+ // strlen("Signature: ") = 11
+ string_right(mifare_ul_string, 11);
+ if(!nfc_device_read_hex(mifare_ul_string, data->signature, sizeof(data->signature))) {
+ break;
+ }
+ // strlen("Version: ") = 9
+ string_right(mifare_ul_string, 9);
+ if(!nfc_device_read_hex(
+ mifare_ul_string, (uint8_t*)&data->version, sizeof(data->version))) {
+ break;
+ }
+ string_strim(mifare_ul_string);
+ // Read counters and tearing flags
+ for(uint8_t i = 0; i < 3; i++) {
+ res = sscanf(
+ string_get_cstr(mifare_ul_string),
+ "Counter %hX: %lu Tearing flag %hX: %02hX",
+ &cnt_num,
+ &data->counter[i],
+ &cnt_num,
+ &tearing_tmp);
+ if(res != 4) {
+ break;
+ }
+ data->tearing[i] = tearing_tmp;
+ ws = string_search_char(mifare_ul_string, '\n');
+ string_right(mifare_ul_string, ws + 1);
+ }
+ // Read data size
+ res = sscanf(string_get_cstr(mifare_ul_string), "Data size: %hu", &data->data_size);
+ if(res != 1) {
+ break;
+ }
+ ws = string_search_char(mifare_ul_string, '\n');
+ string_right(mifare_ul_string, ws + 1);
+ // Read data
+ for(uint16_t i = 0; i < data->data_size; i += 4) {
+ if(!nfc_device_read_hex(mifare_ul_string, &data->data[i], 4)) {
+ break;
+ }
+ }
+ parsed = true;
+ } while(0);
+
+ return parsed;
+}
+
+uint16_t nfc_device_prepare_bank_card_string(NfcDevice* dev, string_t bank_card_string) {
+ NfcEmvData* data = &dev->dev_data.emv_data;
+ string_printf(bank_card_string, "AID len: %d, AID:", data->aid_len);
+ for(uint8_t i = 0; i < data->aid_len; i++) {
+ string_cat_printf(bank_card_string, " %02X", data->aid[i]);
+ }
+ string_cat_printf(bank_card_string, "\nName: %s\nNumber:", data->name);
+ for(uint8_t i = 0; i < sizeof(data->number); i++) {
+ string_cat_printf(bank_card_string, " %02X", data->number[i]);
+ }
+ return string_size(bank_card_string);
+}
+
+bool nfc_device_parse_bank_card_string(NfcDevice* dev, string_t bank_card_string) {
+ NfcEmvData* data = &dev->dev_data.emv_data;
+ bool parsed = false;
+ int res = 0;
+ memset(data, 0, sizeof(NfcEmvData));
+
+ do {
+ res = sscanf(string_get_cstr(bank_card_string), "AID len: %hu", &data->aid_len);
+ if(res != 1) {
+ break;
+ }
+ // strlen("AID len: ") = 9
+ string_right(bank_card_string, 9);
+ size_t ws = string_search_char(bank_card_string, ':');
+ string_right(bank_card_string, ws + 1);
+ if(!nfc_device_read_hex(bank_card_string, data->aid, data->aid_len)) {
+ break;
+ }
+ res = sscanf(string_get_cstr(bank_card_string), "Name: %s\n", data->name);
+ if(res != 1) {
+ break;
+ }
+ ws = string_search_char(bank_card_string, '\n');
+ string_right(bank_card_string, ws + 1);
+ // strlen("Number: ") = 8
+ string_right(bank_card_string, 8);
+ if(!nfc_device_read_hex(bank_card_string, data->number, sizeof(data->number))) {
+ break;
+ }
+ parsed = true;
+ } while(0);
+
+ return parsed;
+}
+
void nfc_device_set_name(NfcDevice* dev, const char* name) {
furi_assert(dev);
@@ -19,37 +252,52 @@ bool nfc_device_save(NfcDevice* dev, const char* dev_name) {
FileWorker* file_worker = file_worker_alloc(false);
string_t dev_file_name;
+ string_init(dev_file_name);
+ string_t temp_str;
+ string_init(temp_str);
+ uint16_t string_len = 0;
- // Create nfc directory if necessary
- if(!file_worker_mkdir(file_worker, nfc_app_folder)) {
- return false;
- };
-
- // First remove nfc device file if it was saved
- string_init_printf(dev_file_name, "%s/%s%s", nfc_app_folder, dev_name, nfc_app_extension);
- if(!file_worker_remove(file_worker, string_get_cstr(dev_file_name))) {
- string_clear(dev_file_name);
- return false;
- };
-
- // Prepare buffer to write
- uint8_t buff[NFC_DEVICE_MAX_DATA_LEN];
- buff[0] = dev->data.uid_len;
- memcpy(&buff[1], dev->data.uid, dev->data.uid_len);
- memcpy(&buff[dev->data.uid_len + 1], dev->data.atqa, 2);
- buff[dev->data.uid_len + 3] = dev->data.sak;
-
- // Save nfc device
- bool res = file_worker_open(
- file_worker, string_get_cstr(dev_file_name), FSAM_WRITE, FSOM_CREATE_ALWAYS);
- string_clear(dev_file_name);
- if(res) {
- // Write UID length
- if(!file_worker_write_hex(file_worker, buff, dev->data.uid_len + 4)) {
- file_worker_close(file_worker);
- return false;
+ do {
+ // Create nfc directory if necessary
+ if(!file_worker_mkdir(file_worker, nfc_app_folder)) {
+ break;
+ };
+ // First remove nfc device file if it was saved
+ string_printf(dev_file_name, "%s/%s%s", nfc_app_folder, dev_name, nfc_app_extension);
+ if(!file_worker_remove(file_worker, string_get_cstr(dev_file_name))) {
+ break;
+ };
+ // Open file
+ if(!file_worker_open(
+ file_worker, string_get_cstr(dev_file_name), FSAM_WRITE, FSOM_CREATE_ALWAYS)) {
+ break;
}
- }
+ // Prepare and write format name on 1st line
+ string_len = nfc_device_prepare_format_string(dev, temp_str);
+ if(!file_worker_write(file_worker, string_get_cstr(temp_str), string_len)) {
+ break;
+ }
+ // Prepare and write UID data on 2nd line
+ string_len = nfc_device_prepare_uid_string(dev, temp_str);
+ if(!file_worker_write(file_worker, string_get_cstr(temp_str), string_len)) {
+ break;
+ }
+ // Save more data if necessary
+ if(dev->format == NfcDeviceSaveFormatMifareUl) {
+ string_len = nfc_device_prepare_mifare_ul_string(dev, temp_str);
+ if(!file_worker_write(file_worker, string_get_cstr(temp_str), string_len)) {
+ break;
+ }
+ } else if(dev->format == NfcDeviceSaveFormatBankCard) {
+ string_len = nfc_device_prepare_bank_card_string(dev, temp_str);
+ if(!file_worker_write(file_worker, string_get_cstr(temp_str), string_len)) {
+ break;
+ }
+ }
+ } while(0);
+
+ string_clear(temp_str);
+ string_clear(dev_file_name);
file_worker_close(file_worker);
file_worker_free(file_worker);
@@ -57,34 +305,52 @@ bool nfc_device_save(NfcDevice* dev, const char* dev_name) {
}
static bool nfc_device_load_data(FileWorker* file_worker, string_t path, NfcDevice* dev) {
- // Open key file
- if(!file_worker_open(file_worker, string_get_cstr(path), FSAM_READ, FSOM_OPEN_EXISTING)) {
- return false;
- }
-
- uint8_t buff[NFC_DEVICE_MAX_DATA_LEN] = {};
-
- // Load first byte - UID length
- if(!file_worker_read_hex(file_worker, buff, 1)) {
- return false;
- }
- // Read space
- uint8_t space = 0;
- if(!file_worker_read(file_worker, &space, 1)) {
- return false;
- }
+ string_t temp_string;
+ string_init(temp_string);
+ bool parsed = false;
- // Load other data
- if(!file_worker_read_hex(file_worker, &buff[1], buff[0] + 3)) {
- return false;
- }
+ do {
+ // Open key file
+ if(!file_worker_open(file_worker, string_get_cstr(path), FSAM_READ, FSOM_OPEN_EXISTING)) {
+ break;
+ }
+ // Read and parse format from 1st line
+ if(!file_worker_read_until(file_worker, temp_string, '\n')) {
+ break;
+ }
+ if(!nfc_device_parse_format_string(dev, temp_string)) {
+ break;
+ }
+ // Read and parse UID data from 2nd line
+ if(!file_worker_read_until(file_worker, temp_string, '\n')) {
+ break;
+ }
+ if(!nfc_device_parse_uid_string(dev, temp_string)) {
+ break;
+ }
+ // Parse other data
+ if(dev->format == NfcDeviceSaveFormatMifareUl) {
+ // Read until EOF
+ if(!file_worker_read_until(file_worker, temp_string, 0x05)) {
+ break;
+ }
+ if(!nfc_device_parse_mifare_ul_string(dev, temp_string)) {
+ break;
+ }
+ } else if(dev->format == NfcDeviceSaveFormatBankCard) {
+ // Read until EOF
+ if(!file_worker_read_until(file_worker, temp_string, 0x05)) {
+ break;
+ }
+ if(!nfc_device_parse_bank_card_string(dev, temp_string)) {
+ break;
+ }
+ }
+ parsed = true;
+ } while(0);
- // Set loaded data
- dev->data.uid_len = buff[0];
- memcpy(dev->data.uid, &buff[1], dev->data.uid_len);
- memcpy(dev->data.atqa, &buff[dev->data.uid_len + 1], 2);
- dev->data.sak = buff[dev->data.uid_len + 3];
- return true;
+ string_clear(temp_string);
+ return parsed;
}
bool nfc_device_load(NfcDevice* dev, const char* file_path) {
@@ -137,3 +403,25 @@ bool nfc_file_select(NfcDevice* dev) {
return res;
}
+
+void nfc_device_clear(NfcDevice* dev) {
+ furi_assert(dev);
+
+ memset(&dev->dev_data, 0, sizeof(dev->dev_data));
+ nfc_device_set_name(dev, "");
+ dev->format = NfcDeviceSaveFormatUid;
+}
+
+bool nfc_device_delete(NfcDevice* dev) {
+ furi_assert(dev);
+
+ bool result = false;
+ FileWorker* file_worker = file_worker_alloc(false);
+ string_t file_path;
+ string_init_printf(file_path, "%s/%s%s", nfc_app_folder, dev->dev_name, nfc_app_extension);
+ result = file_worker_remove(file_worker, string_get_cstr(file_path));
+ string_clear(file_path);
+ file_worker_close(file_worker);
+ file_worker_free(file_worker);
+ return result;
+}
diff --git a/applications/nfc/nfc_device.h b/applications/nfc/nfc_device.h
index 6d6486c6..ab644615 100644
--- a/applications/nfc/nfc_device.h
+++ b/applications/nfc/nfc_device.h
@@ -3,11 +3,11 @@
#include <stdint.h>
#include <stdbool.h>
+#include "mifare_ultralight.h"
+
#define NFC_DEV_NAME_MAX_LEN 22
#define NFC_FILE_NAME_MAX_LEN 120
-#define NFC_MIFARE_UL_MAX_SIZE 256
-
typedef enum {
NfcDeviceNfca,
NfcDeviceNfcb,
@@ -18,9 +18,15 @@ typedef enum {
typedef enum {
NfcDeviceProtocolUnknown,
NfcDeviceProtocolEMV,
- NfcDeviceProtocolMfUltralight,
+ NfcDeviceProtocolMifareUl,
} NfcProtocol;
+typedef enum {
+ NfcDeviceSaveFormatUid,
+ NfcDeviceSaveFormatBankCard,
+ NfcDeviceSaveFormatMifareUl,
+} NfcDeviceSaveFormat;
+
typedef struct {
uint8_t uid_len;
uint8_t uid[10];
@@ -28,27 +34,31 @@ typedef struct {
uint8_t sak;
NfcDeviceType device;
NfcProtocol protocol;
-} NfcDeviceData;
+} NfcDeviceCommomData;
typedef struct {
- NfcDeviceData nfc_data;
char name[32];
+ uint8_t aid[16];
+ uint16_t aid_len;
uint8_t number[8];
+ uint8_t exp_mon;
+ uint16_t exp_year;
+ char cardholder[32];
} NfcEmvData;
typedef struct {
- NfcDeviceData nfc_data;
- uint8_t full_dump[NFC_MIFARE_UL_MAX_SIZE];
- uint16_t dump_size;
- // TODO delete with debug view
- uint8_t man_block[12];
- uint8_t otp[4];
-} NfcMifareUlData;
+ NfcDeviceCommomData nfc_data;
+ union {
+ NfcEmvData emv_data;
+ MifareUlData mf_ul_data;
+ };
+} NfcDeviceData;
typedef struct {
- NfcDeviceData data;
+ NfcDeviceData dev_data;
char dev_name[NFC_DEV_NAME_MAX_LEN];
char file_name[NFC_FILE_NAME_MAX_LEN];
+ NfcDeviceSaveFormat format;
} NfcDevice;
void nfc_device_set_name(NfcDevice* dev, const char* name);
@@ -58,3 +68,7 @@ bool nfc_device_save(NfcDevice* dev, const char* dev_name);
bool nfc_device_load(NfcDevice* dev, const char* file_path);
bool nfc_file_select(NfcDevice* dev);
+
+void nfc_device_clear(NfcDevice* dev);
+
+bool nfc_device_delete(NfcDevice* dev);
diff --git a/applications/nfc/nfc_device_i.h b/applications/nfc/nfc_device_i.h
new file mode 100644
index 00000000..01309eb5
--- /dev/null
+++ b/applications/nfc/nfc_device_i.h
@@ -0,0 +1,16 @@
+#pragma once
+
+#include "nfc_device.h"
+#include <m-string.h>
+
+uint16_t nfc_device_prepare_format_string(NfcDevice* dev, string_t format_string);
+bool nfc_device_parse_format_string(NfcDevice* dev, string_t format_string);
+
+uint16_t nfc_device_prepare_uid_string(NfcDevice* dev, string_t uid_string);
+bool nfc_device_parse_uid_string(NfcDevice* dev, string_t uid_string);
+
+uint16_t nfc_device_prepare_mifare_ul_string(NfcDevice* dev, string_t mifare_ul_string);
+bool nfc_device_parse_mifare_ul_string(NfcDevice* dev, string_t mifare_ul_string);
+
+uint16_t nfc_device_prepare_bank_card_string(NfcDevice* dev, string_t bank_card_string);
+bool nfc_device_parse_bank_card_string(NfcDevice* dev, string_t bank_card_string); \ No newline at end of file
diff --git a/applications/nfc/nfc_i.h b/applications/nfc/nfc_i.h
index 94b361d9..5c89e782 100755
--- a/applications/nfc/nfc_i.h
+++ b/applications/nfc/nfc_i.h
@@ -21,31 +21,27 @@
#include <gui/modules/byte_input.h>
#include <gui/modules/text_box.h>
-#include <nfc/scenes/nfc_scene.h>
+#include "views/bank_card.h"
+
+#include "gui_widget/gui_widget.h"
+#include "gui_widget/gui_element_string.h"
+#include "gui_widget/gui_element_button.h"
-#include "views/nfc_detect.h"
-#include "views/nfc_emulate.h"
-#include "views/nfc_emv.h"
-#include "views/nfc_mifare_ul.h"
+#include <nfc/scenes/nfc_scene.h>
#define NFC_TEXT_STORE_SIZE 128
struct Nfc {
- NfcCommon nfc_common;
+ NfcWorker* worker;
+ ViewDispatcher* view_dispatcher;
Gui* gui;
NotificationApp* notifications;
SceneManager* scene_manager;
- NfcDevice device;
+ NfcDevice dev;
char text_store[NFC_TEXT_STORE_SIZE + 1];
string_t text_box_store;
- // Nfc Views
- NfcDetect* nfc_detect;
- NfcEmulate* nfc_emulate;
- NfcEmv* nfc_emv;
- NfcMifareUl* nfc_mifare_ul;
-
// Common Views
Submenu* submenu;
DialogEx* dialog_ex;
@@ -53,6 +49,8 @@ struct Nfc {
TextInput* text_input;
ByteInput* byte_input;
TextBox* text_box;
+ GuiWidget* widget;
+ BankCard* bank_card;
};
typedef enum {
@@ -62,10 +60,8 @@ typedef enum {
NfcViewTextInput,
NfcViewByteInput,
NfcViewTextBox,
- NfcViewDetect,
- NfcViewEmulate,
- NfcViewEmv,
- NfcViewMifareUl,
+ NfcViewWidget,
+ NfcViewBankCard,
} NfcView;
Nfc* nfc_alloc();
diff --git a/applications/nfc/nfc_types.h b/applications/nfc/nfc_types.h
index 5bf29599..46899b6d 100644
--- a/applications/nfc/nfc_types.h
+++ b/applications/nfc/nfc_types.h
@@ -6,25 +6,6 @@
#include <gui/view_dispatcher.h>
#include "nfc_worker.h"
-typedef struct {
- NfcWorker* worker;
- ViewDispatcher* view_dispatcher;
- NfcWorkerResult worker_result;
-} NfcCommon;
-
-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) {
return "NFC-A may be:";
@@ -62,7 +43,7 @@ static inline const char* nfc_get_nfca_type(rfalNfcaListenDeviceType type) {
static inline const char* nfc_get_protocol(NfcProtocol protocol) {
if(protocol == NfcDeviceProtocolEMV) {
return "EMV bank card";
- } else if(protocol == NfcDeviceProtocolMfUltralight) {
+ } else if(protocol == NfcDeviceProtocolMifareUl) {
return "Mifare Ultralight";
} else {
return "Unrecognized";
diff --git a/applications/nfc/nfc_worker.c b/applications/nfc/nfc_worker.c
index b23caccc..0e0003d6 100755
--- a/applications/nfc/nfc_worker.c
+++ b/applications/nfc/nfc_worker.c
@@ -39,26 +39,21 @@ ReturnCode nfc_worker_get_error(NfcWorker* nfc_worker) {
return nfc_worker->error;
}
-void nfc_worker_set_emulation_params(NfcWorker* nfc_worker, NfcDeviceData* data) {
- furi_assert(nfc_worker);
- furi_assert(data);
-
- nfc_worker->emulate_params = *data;
-}
-
void nfc_worker_start(
NfcWorker* nfc_worker,
NfcWorkerState state,
- NfcWorkerResult* result_dest,
+ NfcDeviceData* dev_data,
NfcWorkerCallback callback,
void* context) {
furi_assert(nfc_worker);
- furi_assert(nfc_worker->state == NfcWorkerStateReady);
- furi_assert(result_dest);
+ furi_assert(dev_data);
+ while(nfc_worker->state != NfcWorkerStateReady) {
+ osDelay(10);
+ }
nfc_worker->callback = callback;
nfc_worker->context = context;
- nfc_worker->last_result = result_dest;
+ nfc_worker->dev_data = dev_data;
nfc_worker_change_state(nfc_worker, state);
nfc_worker->thread = osThreadNew(nfc_worker_task, nfc_worker, &nfc_worker->thread_attr);
}
@@ -88,12 +83,16 @@ void nfc_worker_task(void* context) {
nfc_worker_detect(nfc_worker);
} else if(nfc_worker->state == NfcWorkerStateEmulate) {
nfc_worker_emulate(nfc_worker);
+ } else if(nfc_worker->state == NfcWorkerStateReadEMVApp) {
+ nfc_worker_read_emv_app(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 == NfcWorkerStateReadMfUltralight) {
- nfc_worker_read_mf_ultralight(nfc_worker);
+ } else if(nfc_worker->state == NfcWorkerStateReadMifareUl) {
+ nfc_worker_read_mifare_ul(nfc_worker);
+ } else if(nfc_worker->state == NfcWorkerStateEmulateMifareUl) {
+ nfc_worker_emulate_mifare_ul(nfc_worker);
} else if(nfc_worker->state == NfcWorkerStateField) {
nfc_worker_field(nfc_worker);
}
@@ -107,7 +106,7 @@ void nfc_worker_detect(NfcWorker* nfc_worker) {
rfalNfcDevice* dev_list;
rfalNfcDevice* dev;
uint8_t dev_cnt;
- NfcDeviceData* result = &nfc_worker->last_result->nfc_detect_data;
+ NfcDeviceCommomData* result = &nfc_worker->dev_data->nfc_data;
while(nfc_worker->state == NfcWorkerStateDetect) {
if(api_hal_nfc_detect(&dev_list, &dev_cnt, 1000, true)) {
@@ -124,11 +123,12 @@ void nfc_worker_detect(NfcWorker* nfc_worker) {
dev->dev.nfca.sensRes.anticollisionInfo,
dev->dev.nfca.sensRes.platformInfo,
dev->dev.nfca.selRes.sak)) {
- result->protocol = NfcDeviceProtocolMfUltralight;
+ result->protocol = NfcDeviceProtocolMifareUl;
+ } else if(dev->rfInterface == RFAL_NFC_INTERFACE_ISODEP) {
+ result->protocol = NfcDeviceProtocolEMV;
} else {
result->protocol = NfcDeviceProtocolUnknown;
}
-
} else if(dev->type == RFAL_NFC_LISTEN_TYPE_NFCB) {
result->device = NfcDeviceNfcb;
} else if(dev->type == RFAL_NFC_LISTEN_TYPE_NFCF) {
@@ -147,15 +147,77 @@ void nfc_worker_detect(NfcWorker* nfc_worker) {
}
void nfc_worker_emulate(NfcWorker* nfc_worker) {
- NfcDeviceData* param = &nfc_worker->emulate_params;
+ NfcDeviceCommomData* data = &nfc_worker->dev_data->nfc_data;
while(nfc_worker->state == NfcWorkerStateEmulate) {
- if(api_hal_nfc_listen(param->uid, param->uid_len, param->atqa, param->sak, 100)) {
+ if(api_hal_nfc_listen(data->uid, data->uid_len, data->atqa, data->sak, 100)) {
FURI_LOG_I(NFC_WORKER_TAG, "Reader detected");
}
osDelay(10);
}
}
+void nfc_worker_read_emv_app(NfcWorker* nfc_worker) {
+ ReturnCode err;
+ rfalNfcDevice* dev_list;
+ EmvApplication emv_app = {};
+ uint8_t dev_cnt = 0;
+ uint8_t tx_buff[255] = {};
+ uint16_t tx_len = 0;
+ uint8_t* rx_buff;
+ uint16_t* rx_len;
+ NfcDeviceData* result = nfc_worker->dev_data;
+
+ while(nfc_worker->state == NfcWorkerStateReadEMVApp) {
+ memset(&emv_app, 0, sizeof(emv_app));
+ if(api_hal_nfc_detect(&dev_list, &dev_cnt, 1000, false)) {
+ // Card was found. Check that it supports EMV
+ if(dev_list[0].rfInterface == RFAL_NFC_INTERFACE_ISODEP) {
+ result->nfc_data.uid_len = dev_list[0].dev.nfca.nfcId1Len;
+ result->nfc_data.atqa[0] = dev_list[0].dev.nfca.sensRes.anticollisionInfo;
+ result->nfc_data.atqa[1] = dev_list[0].dev.nfca.sensRes.platformInfo;
+ result->nfc_data.sak = dev_list[0].dev.nfca.selRes.sak;
+ memcpy(
+ result->nfc_data.uid, dev_list[0].dev.nfca.nfcId1, result->nfc_data.uid_len);
+ result->nfc_data.protocol = NfcDeviceProtocolEMV;
+
+ FURI_LOG_I(NFC_WORKER_TAG, "Send select PPSE command");
+ tx_len = emv_prepare_select_ppse(tx_buff);
+ 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);
+ api_hal_nfc_deactivate();
+ continue;
+ }
+ FURI_LOG_I(
+ NFC_WORKER_TAG, "Select PPSE response received. Start parsing response");
+ if(emv_decode_ppse_response(rx_buff, *rx_len, &emv_app)) {
+ FURI_LOG_I(NFC_WORKER_TAG, "Select PPSE responce parced");
+ // Notify caller and exit
+ result->emv_data.aid_len = emv_app.aid_len;
+ memcpy(result->emv_data.aid, emv_app.aid, emv_app.aid_len);
+ if(nfc_worker->callback) {
+ nfc_worker->callback(nfc_worker->context);
+ }
+ break;
+ } else {
+ FURI_LOG_E(NFC_WORKER_TAG, "Can't find pay application");
+ api_hal_nfc_deactivate();
+ continue;
+ }
+ } else {
+ // Can't find EMV card
+ FURI_LOG_W(NFC_WORKER_TAG, "Card doesn't support EMV");
+ api_hal_nfc_deactivate();
+ }
+ } else {
+ // Can't find EMV card
+ FURI_LOG_W(NFC_WORKER_TAG, "Can't find any cards");
+ api_hal_nfc_deactivate();
+ }
+ osDelay(20);
+ }
+}
+
void nfc_worker_read_emv(NfcWorker* nfc_worker) {
ReturnCode err;
rfalNfcDevice* dev_list;
@@ -165,13 +227,21 @@ void nfc_worker_read_emv(NfcWorker* nfc_worker) {
uint16_t tx_len = 0;
uint8_t* rx_buff;
uint16_t* rx_len;
- NfcEmvData* result = &nfc_worker->last_result->nfc_emv_data;
+ NfcDeviceData* result = nfc_worker->dev_data;
while(nfc_worker->state == NfcWorkerStateReadEMV) {
memset(&emv_app, 0, sizeof(emv_app));
if(api_hal_nfc_detect(&dev_list, &dev_cnt, 1000, false)) {
// Card was found. Check that it supports EMV
if(dev_list[0].rfInterface == RFAL_NFC_INTERFACE_ISODEP) {
+ result->nfc_data.uid_len = dev_list[0].dev.nfca.nfcId1Len;
+ result->nfc_data.atqa[0] = dev_list[0].dev.nfca.sensRes.anticollisionInfo;
+ result->nfc_data.atqa[1] = dev_list[0].dev.nfca.sensRes.platformInfo;
+ result->nfc_data.sak = dev_list[0].dev.nfca.selRes.sak;
+ memcpy(
+ result->nfc_data.uid, dev_list[0].dev.nfca.nfcId1, result->nfc_data.uid_len);
+ result->nfc_data.protocol = NfcDeviceProtocolEMV;
+
FURI_LOG_I(NFC_WORKER_TAG, "Send select PPSE command");
tx_len = emv_prepare_select_ppse(tx_buff);
err = api_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false);
@@ -203,7 +273,7 @@ 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(result->name, emv_app.name, sizeof(emv_app.name));
+ memcpy(result->emv_data.name, emv_app.name, sizeof(emv_app.name));
} else {
FURI_LOG_E(NFC_WORKER_TAG, "Can't read card name");
api_hal_nfc_deactivate();
@@ -220,7 +290,8 @@ void nfc_worker_read_emv(NfcWorker* nfc_worker) {
}
if(emv_decode_get_proc_opt(rx_buff, *rx_len, &emv_app)) {
FURI_LOG_I(NFC_WORKER_TAG, "Card number parsed");
- memcpy(result->number, emv_app.card_number, sizeof(emv_app.card_number));
+ memcpy(
+ result->emv_data.number, emv_app.card_number, sizeof(emv_app.card_number));
// Notify caller and exit
if(nfc_worker->callback) {
nfc_worker->callback(nfc_worker->context);
@@ -255,7 +326,10 @@ void nfc_worker_read_emv(NfcWorker* nfc_worker) {
}
if(pan_found) {
FURI_LOG_I(NFC_WORKER_TAG, "Card PAN found");
- memcpy(result->number, emv_app.card_number, sizeof(emv_app.card_number));
+ memcpy(
+ result->emv_data.number,
+ emv_app.card_number,
+ sizeof(emv_app.card_number));
// Notify caller and exit
if(nfc_worker->callback) {
nfc_worker->callback(nfc_worker->context);
@@ -286,7 +360,7 @@ void nfc_worker_emulate_emv(NfcWorker* nfc_worker) {
uint16_t tx_len = 0;
uint8_t* rx_buff;
uint16_t* rx_len;
- NfcDeviceData params = {
+ NfcDeviceCommomData params = {
.uid = {0xCF, 0x72, 0xd4, 0x40},
.uid_len = 4,
.atqa = {0x00, 0x04},
@@ -343,7 +417,7 @@ void nfc_worker_emulate_emv(NfcWorker* nfc_worker) {
}
}
-void nfc_worker_read_mf_ultralight(NfcWorker* nfc_worker) {
+void nfc_worker_read_mifare_ul(NfcWorker* nfc_worker) {
ReturnCode err;
rfalNfcDevice* dev_list;
uint8_t dev_cnt = 0;
@@ -351,21 +425,20 @@ void nfc_worker_read_mf_ultralight(NfcWorker* nfc_worker) {
uint16_t tx_len = 0;
uint8_t* rx_buff;
uint16_t* rx_len;
- MfUltralightRead mf_ul_read;
- NfcMifareUlData* result = &nfc_worker->last_result->nfc_mifare_ul_data;
+ MifareUlDevice mf_ul_read;
+ NfcDeviceData* result = nfc_worker->dev_data;
- while(nfc_worker->state == NfcWorkerStateReadMfUltralight) {
+ while(nfc_worker->state == NfcWorkerStateReadMifareUl) {
api_hal_nfc_deactivate();
memset(&mf_ul_read, 0, sizeof(mf_ul_read));
- if(api_hal_nfc_detect(&dev_list, &dev_cnt, 1000, false)) {
+ if(api_hal_nfc_detect(&dev_list, &dev_cnt, 300, false)) {
if(dev_list[0].type == RFAL_NFC_LISTEN_TYPE_NFCA &&
mf_ul_check_card_type(
dev_list[0].dev.nfca.sensRes.anticollisionInfo,
dev_list[0].dev.nfca.sensRes.platformInfo,
dev_list[0].dev.nfca.selRes.sak)) {
// Get Mifare Ultralight version
- FURI_LOG_I(
- NFC_WORKER_TAG, "Found Mifare Ultralight tag. Trying to get tag version");
+ FURI_LOG_I(NFC_WORKER_TAG, "Found Mifare Ultralight tag. Reading tag version");
tx_len = mf_ul_prepare_get_version(tx_buff);
err = api_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false);
if(err == ERR_NONE) {
@@ -378,7 +451,7 @@ void nfc_worker_read_mf_ultralight(NfcWorker* nfc_worker) {
} else if(err == ERR_TIMEOUT) {
FURI_LOG_W(
NFC_WORKER_TAG,
- "Card doesn't respond to GET VERSION command. Reinit card and set default read parameters");
+ "Card doesn't respond to GET VERSION command. Setting default read parameters");
err = ERR_NONE;
mf_ul_set_default_version(&mf_ul_read);
// Reinit device
@@ -395,37 +468,58 @@ void nfc_worker_read_mf_ultralight(NfcWorker* nfc_worker) {
continue;
}
- // Dump Mifare Ultralight card
- FURI_LOG_I(NFC_WORKER_TAG, "Trying to read pages");
if(mf_ul_read.support_fast_read) {
- // Read card with FAST_READ command
+ FURI_LOG_I(NFC_WORKER_TAG, "Reading pages ...");
tx_len = mf_ul_prepare_fast_read(tx_buff, 0x00, mf_ul_read.pages_to_read - 1);
- err = api_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false);
- if(err == ERR_NONE) {
- FURI_LOG_I(
- NFC_WORKER_TAG,
- "Fast read pages %d - %d succeed",
- 0,
- mf_ul_read.pages_to_read - 1);
- memcpy(mf_ul_read.dump, rx_buff, mf_ul_read.pages_to_read * 4);
- mf_ul_read.pages_readed = mf_ul_read.pages_to_read;
- } else {
- FURI_LOG_E(NFC_WORKER_TAG, "Fast read failed");
+ if(api_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false)) {
+ FURI_LOG_E(NFC_WORKER_TAG, "Failed reading pages");
continue;
+ } else {
+ mf_ul_parse_fast_read_response(
+ rx_buff, 0x00, mf_ul_read.pages_to_read - 1, &mf_ul_read);
+ }
+
+ FURI_LOG_I(NFC_WORKER_TAG, "Reading signature ...");
+ tx_len = mf_ul_prepare_read_signature(tx_buff);
+ if(api_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false)) {
+ FURI_LOG_W(NFC_WORKER_TAG, "Failed reading signature");
+ memset(mf_ul_read.data.signature, 0, sizeof(mf_ul_read.data.signature));
+ } else {
+ mf_ul_parse_read_signature_response(rx_buff, &mf_ul_read);
+ }
+
+ FURI_LOG_I(NFC_WORKER_TAG, "Reading 3 counters ...");
+ for(uint8_t i = 0; i < 3; i++) {
+ tx_len = mf_ul_prepare_read_cnt(tx_buff, i);
+ if(api_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false)) {
+ FURI_LOG_W(NFC_WORKER_TAG, "Failed reading Counter %d", i);
+ mf_ul_read.data.counter[i] = 0;
+ } else {
+ mf_ul_parse_read_cnt_response(rx_buff, i, &mf_ul_read);
+ }
+ }
+
+ FURI_LOG_I(NFC_WORKER_TAG, "Checking tearing flags ...");
+ for(uint8_t i = 0; i < 3; i++) {
+ tx_len = mf_ul_prepare_check_tearing(tx_buff, i);
+ if(api_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false)) {
+ FURI_LOG_E(NFC_WORKER_TAG, "Error checking tearing flag %d", i);
+ mf_ul_read.data.tearing[i] = MF_UL_TEARING_FLAG_DEFAULT;
+ } else {
+ mf_ul_parse_check_tearing_response(rx_buff, i, &mf_ul_read);
+ }
}
} else {
// READ card with READ command (4 pages at a time)
for(uint8_t page = 0; page < mf_ul_read.pages_to_read; page += 4) {
+ FURI_LOG_I(NFC_WORKER_TAG, "Reading pages %d - %d ...", page, page + 3);
tx_len = mf_ul_prepare_read(tx_buff, page);
- err = api_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false);
- if(err == ERR_NONE) {
- FURI_LOG_I(
- NFC_WORKER_TAG, "Read pages %d - %d succeed", page, page + 3);
- memcpy(&mf_ul_read.dump[page * 4], rx_buff, 4 * 4);
- mf_ul_read.pages_readed += 4;
- } else {
- FURI_LOG_W(
+ if(api_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false)) {
+ FURI_LOG_E(
NFC_WORKER_TAG, "Read pages %d - %d failed", page, page + 3);
+ continue;
+ } else {
+ mf_ul_parse_read_response(rx_buff, page, &mf_ul_read);
}
}
}
@@ -435,20 +529,11 @@ void nfc_worker_read_mf_ultralight(NfcWorker* nfc_worker) {
result->nfc_data.atqa[0] = dev_list[0].dev.nfca.sensRes.anticollisionInfo;
result->nfc_data.atqa[1] = dev_list[0].dev.nfca.sensRes.platformInfo;
result->nfc_data.sak = dev_list[0].dev.nfca.selRes.sak;
+ result->nfc_data.protocol = NfcDeviceProtocolMifareUl;
memcpy(
result->nfc_data.uid, dev_list[0].dev.nfca.nfcId1, result->nfc_data.uid_len);
- memcpy(result->man_block, mf_ul_read.dump, 4 * 3);
- memcpy(result->otp, &mf_ul_read.dump[4 * 3], 4);
- result->dump_size = mf_ul_read.pages_readed * 4;
- memcpy(result->full_dump, mf_ul_read.dump, result->dump_size);
-
- 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++) {
- printf("%02X ", mf_ul_read.dump[i + j]);
- }
- printf("\r\n");
- }
+ result->mf_ul_data = mf_ul_read.data;
+
// Notify caller and exit
if(nfc_worker->callback) {
nfc_worker->callback(nfc_worker->context);
@@ -464,6 +549,43 @@ void nfc_worker_read_mf_ultralight(NfcWorker* nfc_worker) {
}
}
+void nfc_worker_emulate_mifare_ul(NfcWorker* nfc_worker) {
+ ReturnCode err;
+ uint8_t tx_buff[255] = {};
+ uint16_t tx_len = 0;
+ uint8_t* rx_buff;
+ uint16_t* rx_len;
+ NfcDeviceData* data = nfc_worker->dev_data;
+
+ while(nfc_worker->state == NfcWorkerStateEmulateMifareUl) {
+ if(api_hal_nfc_listen(
+ data->nfc_data.uid,
+ data->nfc_data.uid_len,
+ data->nfc_data.atqa,
+ data->nfc_data.sak,
+ 1000)) {
+ FURI_LOG_I(NFC_WORKER_TAG, "Hello my dudes");
+ // Prepare version answer
+ tx_len = sizeof(data->mf_ul_data.version);
+ memcpy(tx_buff, &data->mf_ul_data.version, tx_len);
+ err = api_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false);
+ if(err == ERR_NONE) {
+ FURI_LOG_I(NFC_WORKER_TAG, "Received 1st message:");
+ for(uint16_t i = 0; i < *rx_len; i++) {
+ printf("%02X ", rx_buff[i]);
+ }
+ printf("\r\n");
+ } else {
+ FURI_LOG_E(NFC_WORKER_TAG, "Error in 1st data exchange: select PPSE");
+ api_hal_nfc_deactivate();
+ continue;
+ }
+ }
+ FURI_LOG_W(NFC_WORKER_TAG, "Hello my dudes");
+ osDelay(10);
+ }
+}
+
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
index d77bfd8d..7109e5f8 100755
--- a/applications/nfc/nfc_worker.h
+++ b/applications/nfc/nfc_worker.h
@@ -2,14 +2,6 @@
#include "nfc_device.h"
-typedef struct {
- union {
- NfcDeviceData nfc_detect_data;
- NfcEmvData nfc_emv_data;
- NfcMifareUlData nfc_mifare_ul_data;
- };
-} NfcWorkerResult;
-
typedef struct NfcWorker NfcWorker;
typedef enum {
@@ -20,10 +12,12 @@ typedef enum {
// Main worker states
NfcWorkerStateDetect,
NfcWorkerStateEmulate,
+ NfcWorkerStateReadEMVApp,
NfcWorkerStateReadEMV,
NfcWorkerStateEmulateEMV,
NfcWorkerStateField,
- NfcWorkerStateReadMfUltralight,
+ NfcWorkerStateReadMifareUl,
+ NfcWorkerStateEmulateMifareUl,
// Transition
NfcWorkerStateStop,
} NfcWorkerState;
@@ -36,14 +30,12 @@ NfcWorkerState nfc_worker_get_state(NfcWorker* nfc_worker);
ReturnCode nfc_worker_get_error(NfcWorker* nfc_worker);
-void nfc_worker_set_emulation_params(NfcWorker* nfc_worker, NfcDeviceData* data);
-
void nfc_worker_free(NfcWorker* nfc_worker);
void nfc_worker_start(
NfcWorker* nfc_worker,
NfcWorkerState state,
- NfcWorkerResult* result_dest,
+ NfcDeviceData* dev_data,
NfcWorkerCallback callback,
void* context);
diff --git a/applications/nfc/nfc_worker_i.h b/applications/nfc/nfc_worker_i.h
index 7bb10155..00d5e454 100644..100755
--- a/applications/nfc/nfc_worker_i.h
+++ b/applications/nfc/nfc_worker_i.h
@@ -20,10 +20,10 @@ struct NfcWorker {
osThreadAttr_t thread_attr;
osThreadId_t thread;
- NfcWorkerResult* last_result;
+ NfcDeviceData* dev_data;
+
NfcWorkerCallback callback;
void* context;
- NfcDeviceData emulate_params;
NfcWorkerState state;
ReturnCode error;
@@ -33,6 +33,8 @@ void nfc_worker_change_state(NfcWorker* nfc_worker, NfcWorkerState state);
void nfc_worker_task(void* context);
+void nfc_worker_read_emv_app(NfcWorker* nfc_worker);
+
void nfc_worker_read_emv(NfcWorker* nfc_worker);
void nfc_worker_emulate_emv(NfcWorker* nfc_worker);
@@ -43,4 +45,6 @@ void nfc_worker_emulate(NfcWorker* nfc_worker);
void nfc_worker_field(NfcWorker* nfc_worker);
-void nfc_worker_read_mf_ultralight(NfcWorker* nfc_worker);
+void nfc_worker_read_mifare_ul(NfcWorker* nfc_worker);
+
+void nfc_worker_emulate_mifare_ul(NfcWorker* nfc_worker);
diff --git a/applications/nfc/scenes/nfc_scene_card_menu.c b/applications/nfc/scenes/nfc_scene_card_menu.c
index 76e36de6..f69e0838 100755
--- a/applications/nfc/scenes/nfc_scene_card_menu.c
+++ b/applications/nfc/scenes/nfc_scene_card_menu.c
@@ -10,19 +10,21 @@ enum SubmenuIndex {
void nfc_scene_card_menu_submenu_callback(void* context, uint32_t index) {
Nfc* nfc = (Nfc*)context;
- view_dispatcher_send_custom_event(nfc->nfc_common.view_dispatcher, index);
+ view_dispatcher_send_custom_event(nfc->view_dispatcher, index);
}
const void nfc_scene_card_menu_on_enter(void* context) {
Nfc* nfc = (Nfc*)context;
Submenu* submenu = nfc->submenu;
- submenu_add_item(
- submenu,
- "Run compatible app",
- SubmenuIndexRunApp,
- nfc_scene_card_menu_submenu_callback,
- nfc);
+ if(nfc->dev.dev_data.nfc_data.protocol > NfcDeviceProtocolUnknown) {
+ submenu_add_item(
+ submenu,
+ "Run compatible app",
+ SubmenuIndexRunApp,
+ nfc_scene_card_menu_submenu_callback,
+ nfc);
+ }
submenu_add_item(
submenu,
"Additional reading scripts",
@@ -36,7 +38,7 @@ const void nfc_scene_card_menu_on_enter(void* context) {
submenu_set_selected_item(
nfc->submenu, scene_manager_get_scene_state(nfc->scene_manager, NfcSceneCardMenu));
- view_dispatcher_switch_to_view(nfc->nfc_common.view_dispatcher, NfcViewMenu);
+ view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewMenu);
}
const bool nfc_scene_card_menu_on_event(void* context, SceneManagerEvent event) {
@@ -46,12 +48,16 @@ const bool nfc_scene_card_menu_on_event(void* context, SceneManagerEvent event)
if(event.event == SubmenuIndexRunApp) {
scene_manager_set_scene_state(
nfc->scene_manager, NfcSceneCardMenu, SubmenuIndexRunApp);
- scene_manager_next_scene(nfc->scene_manager, NfcSceneNotImplemented);
+ if(nfc->dev.dev_data.nfc_data.protocol == NfcDeviceProtocolMifareUl) {
+ scene_manager_next_scene(nfc->scene_manager, NfcSceneReadMifareUl);
+ } else if(nfc->dev.dev_data.nfc_data.protocol == NfcDeviceProtocolEMV) {
+ scene_manager_next_scene(nfc->scene_manager, NfcSceneReadEmvApp);
+ }
return true;
} else if(event.event == SubmenuIndexChooseScript) {
scene_manager_set_scene_state(
nfc->scene_manager, NfcSceneCardMenu, SubmenuIndexChooseScript);
- scene_manager_next_scene(nfc->scene_manager, NfcSceneNotImplemented);
+ scene_manager_next_scene(nfc->scene_manager, NfcSceneScriptsMenu);
return true;
} else if(event.event == SubmenuIndexEmulate) {
scene_manager_set_scene_state(
@@ -60,6 +66,7 @@ const bool nfc_scene_card_menu_on_event(void* context, SceneManagerEvent event)
return true;
} else if(event.event == SubmenuIndexSave) {
scene_manager_set_scene_state(nfc->scene_manager, NfcSceneCardMenu, SubmenuIndexSave);
+ nfc->dev.format = NfcDeviceSaveFormatUid;
scene_manager_next_scene(nfc->scene_manager, NfcSceneSaveName);
return true;
}
diff --git a/applications/nfc/scenes/nfc_scene_config.h b/applications/nfc/scenes/nfc_scene_config.h
index 4ad3637f..385b84a3 100755
--- a/applications/nfc/scenes/nfc_scene_config.h
+++ b/applications/nfc/scenes/nfc_scene_config.h
@@ -16,8 +16,12 @@ ADD_SCENE(nfc, scripts_menu, ScriptsMenu)
ADD_SCENE(nfc, read_mifare_ul, ReadMifareUl)
ADD_SCENE(nfc, read_mifare_ul_success, ReadMifareUlSuccess)
ADD_SCENE(nfc, mifare_ul_menu, MifareUlMenu)
-ADD_SCENE(nfc, debug_menu, DebugMenu)
-ADD_SCENE(nfc, debug_detect, DebugDetect)
-ADD_SCENE(nfc, debug_emulate, DebugEmulate)
-ADD_SCENE(nfc, debug_read_emv, DebugReadEmv)
-ADD_SCENE(nfc, debug_read_mifare_ul, DebugReadMifareUl)
+ADD_SCENE(nfc, emulate_mifare_ul, EmulateMifareUl)
+ADD_SCENE(nfc, read_emv_app, ReadEmvApp)
+ADD_SCENE(nfc, read_emv_app_success, ReadEmvAppSuccess)
+ADD_SCENE(nfc, device_info, DeviceInfo)
+ADD_SCENE(nfc, delete, Delete)
+ADD_SCENE(nfc, delete_success, DeleteSuccess)
+ADD_SCENE(nfc, run_emv_app_confirm, RunEmvAppConfirm)
+ADD_SCENE(nfc, read_emv_data, ReadEmvData)
+ADD_SCENE(nfc, read_emv_data_success, ReadEmvDataSuccess)
diff --git a/applications/nfc/scenes/nfc_scene_debug_detect.c b/applications/nfc/scenes/nfc_scene_debug_detect.c
deleted file mode 100755
index 650ffec5..00000000
--- a/applications/nfc/scenes/nfc_scene_debug_detect.c
+++ /dev/null
@@ -1,14 +0,0 @@
-#include "../nfc_i.h"
-
-const void nfc_scene_debug_detect_on_enter(void* context) {
- Nfc* nfc = (Nfc*)context;
-
- view_dispatcher_switch_to_view(nfc->nfc_common.view_dispatcher, NfcViewDetect);
-}
-
-const bool nfc_scene_debug_detect_on_event(void* context, SceneManagerEvent event) {
- return false;
-}
-
-const void nfc_scene_debug_detect_on_exit(void* context) {
-}
diff --git a/applications/nfc/scenes/nfc_scene_debug_emulate.c b/applications/nfc/scenes/nfc_scene_debug_emulate.c
deleted file mode 100755
index ab15ed68..00000000
--- a/applications/nfc/scenes/nfc_scene_debug_emulate.c
+++ /dev/null
@@ -1,14 +0,0 @@
-#include "../nfc_i.h"
-
-const void nfc_scene_debug_emulate_on_enter(void* context) {
- Nfc* nfc = (Nfc*)context;
-
- view_dispatcher_switch_to_view(nfc->nfc_common.view_dispatcher, NfcViewEmulate);
-}
-
-const bool nfc_scene_debug_emulate_on_event(void* context, SceneManagerEvent event) {
- return false;
-}
-
-const void nfc_scene_debug_emulate_on_exit(void* context) {
-}
diff --git a/applications/nfc/scenes/nfc_scene_debug_menu.c b/applications/nfc/scenes/nfc_scene_debug_menu.c
deleted file mode 100755
index ec8737d6..00000000
--- a/applications/nfc/scenes/nfc_scene_debug_menu.c
+++ /dev/null
@@ -1,72 +0,0 @@
-#include "../nfc_i.h"
-
-enum SubmenuIndex {
- SubmenuIndexDetect,
- SubmenuIndexEmulate,
- SubmenuIndexReadEmv,
- SubmenuIndexReadMifareUl,
-};
-
-void nfc_scene_debug_menu_submenu_callback(void* context, uint32_t index) {
- Nfc* nfc = (Nfc*)context;
-
- view_dispatcher_send_custom_event(nfc->nfc_common.view_dispatcher, index);
-}
-
-const void nfc_scene_debug_menu_on_enter(void* context) {
- Nfc* nfc = (Nfc*)context;
- Submenu* submenu = nfc->submenu;
-
- submenu_add_item(
- submenu, "Detect", SubmenuIndexDetect, nfc_scene_debug_menu_submenu_callback, nfc);
- submenu_add_item(
- submenu, "Emulate", SubmenuIndexEmulate, nfc_scene_debug_menu_submenu_callback, nfc);
- submenu_add_item(
- submenu, "Read EMV", SubmenuIndexReadEmv, nfc_scene_debug_menu_submenu_callback, nfc);
- submenu_add_item(
- submenu,
- "Read Mifare Ultralight",
- SubmenuIndexReadMifareUl,
- nfc_scene_debug_menu_submenu_callback,
- nfc);
- submenu_set_selected_item(
- nfc->submenu, scene_manager_get_scene_state(nfc->scene_manager, NfcSceneDebugMenu));
-
- view_dispatcher_switch_to_view(nfc->nfc_common.view_dispatcher, NfcViewMenu);
-}
-
-const bool nfc_scene_debug_menu_on_event(void* context, SceneManagerEvent event) {
- Nfc* nfc = (Nfc*)context;
-
- if(event.type == SceneManagerEventTypeCustom) {
- if(event.event == SubmenuIndexDetect) {
- scene_manager_set_scene_state(
- nfc->scene_manager, NfcSceneDebugMenu, SubmenuIndexDetect);
- scene_manager_next_scene(nfc->scene_manager, NfcSceneDebugDetect);
- return true;
- } else if(event.event == SubmenuIndexEmulate) {
- scene_manager_set_scene_state(
- nfc->scene_manager, NfcSceneDebugMenu, SubmenuIndexEmulate);
- scene_manager_next_scene(nfc->scene_manager, NfcSceneDebugEmulate);
- return true;
- } else if(event.event == SubmenuIndexReadEmv) {
- scene_manager_set_scene_state(
- nfc->scene_manager, NfcSceneDebugMenu, SubmenuIndexReadEmv);
- scene_manager_next_scene(nfc->scene_manager, NfcSceneDebugReadEmv);
- return true;
- } else if(event.event == SubmenuIndexReadMifareUl) {
- scene_manager_set_scene_state(
- nfc->scene_manager, NfcSceneDebugMenu, SubmenuIndexReadMifareUl);
- scene_manager_next_scene(nfc->scene_manager, NfcSceneDebugReadMifareUl);
- return true;
- }
- }
-
- return false;
-}
-
-const void nfc_scene_debug_menu_on_exit(void* context) {
- Nfc* nfc = (Nfc*)context;
-
- submenu_clean(nfc->submenu);
-}
diff --git a/applications/nfc/scenes/nfc_scene_debug_read_emv.c b/applications/nfc/scenes/nfc_scene_debug_read_emv.c
deleted file mode 100755
index 5d6fba8b..00000000
--- a/applications/nfc/scenes/nfc_scene_debug_read_emv.c
+++ /dev/null
@@ -1,14 +0,0 @@
-#include "../nfc_i.h"
-
-const void nfc_scene_debug_read_emv_on_enter(void* context) {
- Nfc* nfc = (Nfc*)context;
-
- view_dispatcher_switch_to_view(nfc->nfc_common.view_dispatcher, NfcViewEmv);
-}
-
-const bool nfc_scene_debug_read_emv_on_event(void* context, SceneManagerEvent event) {
- return false;
-}
-
-const void nfc_scene_debug_read_emv_on_exit(void* context) {
-}
diff --git a/applications/nfc/scenes/nfc_scene_debug_read_mifare_ul.c b/applications/nfc/scenes/nfc_scene_debug_read_mifare_ul.c
deleted file mode 100755
index e08c843e..00000000
--- a/applications/nfc/scenes/nfc_scene_debug_read_mifare_ul.c
+++ /dev/null
@@ -1,14 +0,0 @@
-#include "../nfc_i.h"
-
-const void nfc_scene_debug_read_mifare_ul_on_enter(void* context) {
- Nfc* nfc = (Nfc*)context;
-
- view_dispatcher_switch_to_view(nfc->nfc_common.view_dispatcher, NfcViewMifareUl);
-}
-
-const bool nfc_scene_debug_read_mifare_ul_on_event(void* context, SceneManagerEvent event) {
- return false;
-}
-
-const void nfc_scene_debug_read_mifare_ul_on_exit(void* context) {
-}
diff --git a/applications/nfc/scenes/nfc_scene_delete.c b/applications/nfc/scenes/nfc_scene_delete.c
new file mode 100644
index 00000000..0517a8fa
--- /dev/null
+++ b/applications/nfc/scenes/nfc_scene_delete.c
@@ -0,0 +1,95 @@
+#include "../nfc_i.h"
+
+void nfc_scene_delete_widget_callback(GuiButtonType result, void* context) {
+ Nfc* nfc = (Nfc*)context;
+
+ view_dispatcher_send_custom_event(nfc->view_dispatcher, result);
+}
+
+void nfc_scene_delete_on_enter(void* context) {
+ Nfc* nfc = (Nfc*)context;
+
+ // Setup Custom Widget view
+ char delete_str[64];
+ snprintf(delete_str, sizeof(delete_str), "Delete %s", nfc->dev.dev_name);
+ gui_widget_add_string_element(
+ nfc->widget, 64, 6, AlignCenter, AlignTop, FontPrimary, delete_str);
+ gui_widget_add_button_element(
+ nfc->widget, GuiButtonTypeLeft, "Back", nfc_scene_delete_widget_callback, nfc);
+ gui_widget_add_button_element(
+ nfc->widget, GuiButtonTypeRight, "Delete", nfc_scene_delete_widget_callback, nfc);
+ char uid_str[32];
+ NfcDeviceCommomData* data = &nfc->dev.dev_data.nfc_data;
+ if(data->uid_len == 4) {
+ snprintf(
+ uid_str,
+ sizeof(uid_str),
+ "UID: %02X %02X %02X %02X",
+ data->uid[0],
+ data->uid[1],
+ data->uid[2],
+ data->uid[3]);
+ } else if(data->uid_len == 7) {
+ snprintf(
+ uid_str,
+ sizeof(uid_str),
+ "UID: %02X %02X %02X %02X %02X %02X %02X",
+ data->uid[0],
+ data->uid[1],
+ data->uid[2],
+ data->uid[3],
+ data->uid[4],
+ data->uid[5],
+ data->uid[6]);
+ }
+ gui_widget_add_string_element(
+ nfc->widget, 64, 21, AlignCenter, AlignTop, FontSecondary, uid_str);
+
+ if(data->protocol > NfcDeviceProtocolUnknown) {
+ gui_widget_add_string_element(
+ nfc->widget,
+ 10,
+ 32,
+ AlignLeft,
+ AlignTop,
+ FontSecondary,
+ nfc_get_protocol(data->protocol));
+ }
+ // TODO change dinamically
+ gui_widget_add_string_element(
+ nfc->widget, 118, 32, AlignRight, AlignTop, FontSecondary, "NFC-A");
+ char sak_str[16];
+ snprintf(sak_str, sizeof(sak_str), "SAK: %02X", data->sak);
+ gui_widget_add_string_element(
+ nfc->widget, 10, 42, AlignLeft, AlignTop, FontSecondary, sak_str);
+ char atqa_str[16];
+ snprintf(atqa_str, sizeof(atqa_str), "ATQA: %02X%02X", data->atqa[0], data->atqa[1]);
+ gui_widget_add_string_element(
+ nfc->widget, 118, 42, AlignRight, AlignTop, FontSecondary, atqa_str);
+
+ view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewWidget);
+}
+
+const bool nfc_scene_delete_on_event(void* context, SceneManagerEvent event) {
+ Nfc* nfc = (Nfc*)context;
+
+ if(event.type == SceneManagerEventTypeCustom) {
+ if(event.event == GuiButtonTypeLeft) {
+ return scene_manager_previous_scene(nfc->scene_manager);
+ } else if(event.event == GuiButtonTypeRight) {
+ if(nfc_device_delete(&nfc->dev)) {
+ scene_manager_next_scene(nfc->scene_manager, NfcSceneDeleteSuccess);
+ } else {
+ scene_manager_search_previous_scene(nfc->scene_manager, NfcSceneStart);
+ }
+ return true;
+ }
+ }
+ return false;
+}
+
+const void nfc_scene_delete_on_exit(void* context) {
+ Nfc* nfc = (Nfc*)context;
+
+ gui_widget_clear(nfc->widget);
+}
diff --git a/applications/nfc/scenes/nfc_scene_delete_success.c b/applications/nfc/scenes/nfc_scene_delete_success.c
new file mode 100644
index 00000000..592a16c6
--- /dev/null
+++ b/applications/nfc/scenes/nfc_scene_delete_success.c
@@ -0,0 +1,47 @@
+#include "../nfc_i.h"
+
+#define SCENE_SAVE_SUCCESS_CUSTOM_EVENT (0UL)
+
+void nfc_scene_delete_success_popup_callback(void* context) {
+ Nfc* nfc = (Nfc*)context;
+ view_dispatcher_send_custom_event(nfc->view_dispatcher, SCENE_SAVE_SUCCESS_CUSTOM_EVENT);
+}
+
+const void nfc_scene_delete_success_on_enter(void* context) {
+ Nfc* nfc = (Nfc*)context;
+
+ // Setup view
+ Popup* popup = nfc->popup;
+ popup_set_icon(popup, 0, 2, &I_DolphinMafia_115x62);
+ popup_set_header(popup, "Deleted", 83, 19, AlignLeft, AlignBottom);
+ popup_set_timeout(popup, 1500);
+ popup_set_context(popup, nfc);
+ popup_set_callback(popup, nfc_scene_delete_success_popup_callback);
+ popup_enable_timeout(popup);
+ view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup);
+}
+
+const bool nfc_scene_delete_success_on_event(void* context, SceneManagerEvent event) {
+ Nfc* nfc = (Nfc*)context;
+
+ if(event.type == SceneManagerEventTypeCustom) {
+ if(event.event == SCENE_SAVE_SUCCESS_CUSTOM_EVENT) {
+ return scene_manager_search_previous_scene(nfc->scene_manager, NfcSceneStart);
+ }
+ }
+ return false;
+}
+
+const void nfc_scene_delete_success_on_exit(void* context) {
+ Nfc* nfc = (Nfc*)context;
+
+ // Clear view
+ Popup* popup = nfc->popup;
+ popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom);
+ popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop);
+ popup_set_icon(popup, 0, 0, NULL);
+ popup_set_callback(popup, NULL);
+ popup_set_context(popup, NULL);
+ popup_set_timeout(popup, 0);
+ popup_disable_timeout(popup);
+}
diff --git a/applications/nfc/scenes/nfc_scene_device_info.c b/applications/nfc/scenes/nfc_scene_device_info.c
new file mode 100755
index 00000000..afb65ea1
--- /dev/null
+++ b/applications/nfc/scenes/nfc_scene_device_info.c
@@ -0,0 +1,185 @@
+#include "../nfc_i.h"
+
+#define NFC_SCENE_DEVICE_INFO_TEXTBOX_CUSTOM_EVENT (0UL)
+
+enum {
+ NfcSceneDeviceInfoUid,
+ NfcSceneDeviceInfoData,
+};
+
+void nfc_scene_device_info_widget_callback(GuiButtonType result, void* context) {
+ Nfc* nfc = (Nfc*)context;
+
+ view_dispatcher_send_custom_event(nfc->view_dispatcher, result);
+}
+
+void nfc_scene_device_info_dialog_callback(DialogExResult result, void* context) {
+ Nfc* nfc = (Nfc*)context;
+
+ view_dispatcher_send_custom_event(nfc->view_dispatcher, result);
+}
+
+void nfc_scene_device_info_text_box_callback(void* context) {
+ Nfc* nfc = (Nfc*)context;
+
+ view_dispatcher_send_custom_event(
+ nfc->view_dispatcher, NFC_SCENE_DEVICE_INFO_TEXTBOX_CUSTOM_EVENT);
+}
+
+void nfc_scene_device_info_on_enter(void* context) {
+ Nfc* nfc = (Nfc*)context;
+
+ // Setup Custom Widget view
+ gui_widget_add_string_element(
+ nfc->widget, 64, 6, AlignCenter, AlignTop, FontSecondary, nfc->dev.dev_name);
+ gui_widget_add_button_element(
+ nfc->widget, GuiButtonTypeLeft, "Back", nfc_scene_device_info_widget_callback, nfc);
+ gui_widget_add_button_element(
+ nfc->widget, GuiButtonTypeRight, "Data", nfc_scene_device_info_widget_callback, nfc);
+ char uid_str[32];
+ NfcDeviceCommomData* data = &nfc->dev.dev_data.nfc_data;
+ if(data->uid_len == 4) {
+ snprintf(
+ uid_str,
+ sizeof(uid_str),
+ "UID: %02X %02X %02X %02X",
+ data->uid[0],
+ data->uid[1],
+ data->uid[2],
+ data->uid[3]);
+ } else if(data->uid_len == 7) {
+ snprintf(
+ uid_str,
+ sizeof(uid_str),
+ "UID: %02X %02X %02X %02X %02X %02X %02X",
+ data->uid[0],
+ data->uid[1],
+ data->uid[2],
+ data->uid[3],
+ data->uid[4],
+ data->uid[5],
+ data->uid[6]);
+ }
+ gui_widget_add_string_element(
+ nfc->widget, 64, 21, AlignCenter, AlignTop, FontSecondary, uid_str);
+
+ if(data->protocol > NfcDeviceProtocolUnknown) {
+ gui_widget_add_string_element(
+ nfc->widget,
+ 10,
+ 32,
+ AlignLeft,
+ AlignTop,
+ FontSecondary,
+ nfc_get_protocol(data->protocol));
+ }
+ // TODO change dinamically
+ gui_widget_add_string_element(
+ nfc->widget, 118, 32, AlignRight, AlignTop, FontSecondary, "NFC-A");
+ char sak_str[16];
+ snprintf(sak_str, sizeof(sak_str), "SAK: %02X", data->sak);
+ gui_widget_add_string_element(
+ nfc->widget, 10, 42, AlignLeft, AlignTop, FontSecondary, sak_str);
+ char atqa_str[16];
+ snprintf(atqa_str, sizeof(atqa_str), "ATQA: %02X%02X", data->atqa[0], data->atqa[1]);
+ gui_widget_add_string_element(
+ nfc->widget, 118, 42, AlignRight, AlignTop, FontSecondary, atqa_str);
+
+ // Setup Data View
+ if(nfc->dev.format == NfcDeviceSaveFormatUid) {
+ DialogEx* dialog_ex = nfc->dialog_ex;
+ dialog_ex_set_left_button_text(dialog_ex, "Back");
+ dialog_ex_set_text(dialog_ex, "No data", 64, 32, AlignCenter, AlignCenter);
+ dialog_ex_set_context(dialog_ex, nfc);
+ dialog_ex_set_result_callback(dialog_ex, nfc_scene_device_info_dialog_callback);
+ } else if(nfc->dev.format == NfcDeviceSaveFormatMifareUl) {
+ MifareUlData* mf_ul_data = (MifareUlData*)&nfc->dev.dev_data.mf_ul_data;
+ TextBox* text_box = nfc->text_box;
+ text_box_set_context(text_box, nfc);
+ text_box_set_exit_callback(text_box, nfc_scene_device_info_text_box_callback);
+ text_box_set_font(text_box, TextBoxFontHex);
+ for(uint16_t i = 0; i < mf_ul_data->data_size; i += 2) {
+ if(!(i % 8) && i) {
+ string_push_back(nfc->text_box_store, '\n');
+ }
+ string_cat_printf(
+ nfc->text_box_store, "%02X%02X ", mf_ul_data->data[i], mf_ul_data->data[i + 1]);
+ }
+ text_box_set_text(text_box, string_get_cstr(nfc->text_box_store));
+ } else if(nfc->dev.format == NfcDeviceSaveFormatBankCard) {
+ NfcEmvData* emv_data = &nfc->dev.dev_data.emv_data;
+ BankCard* bank_card = nfc->bank_card;
+ bank_card_set_name(bank_card, emv_data->name);
+ bank_card_set_number(bank_card, emv_data->number);
+ if(!strcmp(emv_data->name, "")) {
+ bank_card_set_cardholder_name(bank_card, emv_data->cardholder);
+ }
+ if(emv_data->exp_mon) {
+ bank_card_set_exp_date(bank_card, emv_data->exp_mon, emv_data->exp_year);
+ }
+ }
+ scene_manager_set_scene_state(nfc->scene_manager, NfcSceneDeviceInfo, NfcSceneDeviceInfoUid);
+ view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewWidget);
+}
+
+const bool nfc_scene_device_info_on_event(void* context, SceneManagerEvent event) {
+ Nfc* nfc = (Nfc*)context;
+ bool consumed = false;
+ uint32_t state = scene_manager_get_scene_state(nfc->scene_manager, NfcSceneDeviceInfo);
+
+ if(event.type == SceneManagerEventTypeCustom) {
+ if((state == NfcSceneDeviceInfoUid) && (event.event == GuiButtonTypeLeft)) {
+ consumed = scene_manager_previous_scene(nfc->scene_manager);
+ } else if((state == NfcSceneDeviceInfoUid) && (event.event == GuiButtonTypeRight)) {
+ if(nfc->dev.format == NfcDeviceSaveFormatUid) {
+ scene_manager_set_scene_state(
+ nfc->scene_manager, NfcSceneDeviceInfo, NfcSceneDeviceInfoData);
+ view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewDialogEx);
+ consumed = true;
+ } else if(nfc->dev.format == NfcDeviceSaveFormatMifareUl) {
+ scene_manager_set_scene_state(
+ nfc->scene_manager, NfcSceneDeviceInfo, NfcSceneDeviceInfoData);
+ view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewTextBox);
+ consumed = true;
+ } else if(nfc->dev.format == NfcDeviceSaveFormatBankCard) {
+ scene_manager_set_scene_state(
+ nfc->scene_manager, NfcSceneDeviceInfo, NfcSceneDeviceInfoData);
+ view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewBankCard);
+ consumed = true;
+ }
+ } else if(state == NfcSceneDeviceInfoData) {
+ scene_manager_set_scene_state(
+ nfc->scene_manager, NfcSceneDeviceInfo, NfcSceneDeviceInfoUid);
+ view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewWidget);
+ consumed = true;
+ }
+ }
+ return consumed;
+}
+
+const void nfc_scene_device_info_on_exit(void* context) {
+ Nfc* nfc = (Nfc*)context;
+
+ // Clear Custom Widget
+ gui_widget_clear(nfc->widget);
+
+ if(nfc->dev.format == NfcDeviceSaveFormatUid) {
+ // Clear Dialog
+ DialogEx* dialog_ex = nfc->dialog_ex;
+ dialog_ex_set_header(dialog_ex, NULL, 0, 0, AlignCenter, AlignCenter);
+ dialog_ex_set_text(dialog_ex, NULL, 0, 0, AlignCenter, AlignTop);
+ dialog_ex_set_icon(dialog_ex, 0, 0, NULL);
+ dialog_ex_set_left_button_text(dialog_ex, NULL);
+ dialog_ex_set_right_button_text(dialog_ex, NULL);
+ dialog_ex_set_center_button_text(dialog_ex, NULL);
+ dialog_ex_set_result_callback(dialog_ex, NULL);
+ dialog_ex_set_context(dialog_ex, NULL);
+ } else if(nfc->dev.format == NfcDeviceSaveFormatMifareUl) {
+ // Clear TextBox
+ text_box_clean(nfc->text_box);
+ string_clean(nfc->text_box_store);
+ } else if(nfc->dev.format == NfcDeviceSaveFormatBankCard) {
+ // Clear Bank Card
+ bank_card_clear(nfc->bank_card);
+ }
+}
diff --git a/applications/nfc/scenes/nfc_scene_emulate_mifare_ul.c b/applications/nfc/scenes/nfc_scene_emulate_mifare_ul.c
new file mode 100755
index 00000000..7286b7ac
--- /dev/null
+++ b/applications/nfc/scenes/nfc_scene_emulate_mifare_ul.c
@@ -0,0 +1,60 @@
+#include "../nfc_i.h"
+
+const void nfc_scene_emulate_mifare_ul_on_enter(void* context) {
+ Nfc* nfc = (Nfc*)context;
+
+ // Setup view
+ Popup* popup = nfc->popup;
+ NfcDeviceCommomData* data = &nfc->dev.dev_data.nfc_data;
+
+ if(strcmp(nfc->dev.dev_name, "")) {
+ nfc_text_store_set(nfc, "%s", nfc->dev.dev_name);
+ } else if(data->uid_len == 4) {
+ nfc_text_store_set(
+ nfc, "%02X %02X %02X %02X", data->uid[0], data->uid[1], data->uid[2], data->uid[3]);
+ } else if(data->uid_len == 7) {
+ nfc_text_store_set(
+ nfc,
+ "%02X %02X %02X %02X\n%02X %02X %02X",
+ data->uid[0],
+ data->uid[1],
+ data->uid[2],
+ data->uid[3],
+ data->uid[4],
+ data->uid[5],
+ data->uid[6]);
+ }
+
+ popup_set_icon(popup, 0, 3, &I_RFIDDolphinSend_97x61);
+ popup_set_header(popup, "Emulating Mf Ul", 56, 31, AlignLeft, AlignTop);
+ popup_set_text(popup, nfc->text_store, 56, 43, AlignLeft, AlignTop);
+
+ // Setup and start worker
+
+ view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup);
+ nfc_worker_start(nfc->worker, NfcWorkerStateEmulateMifareUl, &nfc->dev.dev_data, NULL, nfc);
+}
+
+const bool nfc_scene_emulate_mifare_ul_on_event(void* context, SceneManagerEvent event) {
+ Nfc* nfc = (Nfc*)context;
+ bool consumed = false;
+
+ if(event.type == SceneManagerEventTypeTick) {
+ notification_message(nfc->notifications, &sequence_blink_blue_10);
+ consumed = true;
+ }
+ return consumed;
+}
+
+const void nfc_scene_emulate_mifare_ul_on_exit(void* context) {
+ Nfc* nfc = (Nfc*)context;
+
+ // Stop worker
+ nfc_worker_stop(nfc->worker);
+
+ // Clear view
+ Popup* popup = nfc->popup;
+ popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom);
+ popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop);
+ popup_set_icon(popup, 0, 0, NULL);
+}
diff --git a/applications/nfc/scenes/nfc_scene_emulate_uid.c b/applications/nfc/scenes/nfc_scene_emulate_uid.c
index 8c1ed018..faaf9c7e 100644..100755
--- a/applications/nfc/scenes/nfc_scene_emulate_uid.c
+++ b/applications/nfc/scenes/nfc_scene_emulate_uid.c
@@ -5,10 +5,10 @@ const void nfc_scene_emulate_uid_on_enter(void* context) {
// Setup view
Popup* popup = nfc->popup;
- NfcDeviceData* data = &nfc->device.data;
+ NfcDeviceCommomData* data = &nfc->dev.dev_data.nfc_data;
- if(strcmp(nfc->device.dev_name, "")) {
- nfc_text_store_set(nfc, "%s", nfc->device.dev_name);
+ if(strcmp(nfc->dev.dev_name, "")) {
+ nfc_text_store_set(nfc, "%s", nfc->dev.dev_name);
} else if(data->uid_len == 4) {
nfc_text_store_set(
nfc, "%02X %02X %02X %02X", data->uid[0], data->uid[1], data->uid[2], data->uid[3]);
@@ -31,10 +31,8 @@ const void nfc_scene_emulate_uid_on_enter(void* context) {
// Setup and start worker
- nfc_worker_set_emulation_params(nfc->nfc_common.worker, data);
- nfc_worker_start(
- nfc->nfc_common.worker, NfcWorkerStateEmulate, &nfc->nfc_common.worker_result, NULL, nfc);
- view_dispatcher_switch_to_view(nfc->nfc_common.view_dispatcher, NfcViewPopup);
+ view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup);
+ nfc_worker_start(nfc->worker, NfcWorkerStateEmulate, &nfc->dev.dev_data, NULL, nfc);
}
const bool nfc_scene_emulate_uid_on_event(void* context, SceneManagerEvent event) {
@@ -51,7 +49,7 @@ const void nfc_scene_emulate_uid_on_exit(void* context) {
Nfc* nfc = (Nfc*)context;
// Stop worker
- nfc_worker_stop(nfc->nfc_common.worker);
+ nfc_worker_stop(nfc->worker);
// Clear view
Popup* popup = nfc->popup;
diff --git a/applications/nfc/scenes/nfc_scene_file_select.c b/applications/nfc/scenes/nfc_scene_file_select.c
index a74c18ed..f8af371f 100755
--- a/applications/nfc/scenes/nfc_scene_file_select.c
+++ b/applications/nfc/scenes/nfc_scene_file_select.c
@@ -3,7 +3,7 @@
const void nfc_scene_file_select_on_enter(void* context) {
Nfc* nfc = (Nfc*)context;
// Process file_select return
- if(nfc_file_select(&nfc->device)) {
+ if(nfc_file_select(&nfc->dev)) {
scene_manager_next_scene(nfc->scene_manager, NfcSceneSavedMenu);
} else {
scene_manager_search_previous_scene(nfc->scene_manager, NfcSceneStart);
diff --git a/applications/nfc/scenes/nfc_scene_mifare_ul_menu.c b/applications/nfc/scenes/nfc_scene_mifare_ul_menu.c
index a2121cad..bc639db9 100644
--- a/applications/nfc/scenes/nfc_scene_mifare_ul_menu.c
+++ b/applications/nfc/scenes/nfc_scene_mifare_ul_menu.c
@@ -8,7 +8,7 @@ enum SubmenuIndex {
void nfc_scene_mifare_ul_menu_submenu_callback(void* context, uint32_t index) {
Nfc* nfc = (Nfc*)context;
- view_dispatcher_send_custom_event(nfc->nfc_common.view_dispatcher, index);
+ view_dispatcher_send_custom_event(nfc->view_dispatcher, index);
}
const void nfc_scene_mifare_ul_menu_on_enter(void* context) {
@@ -22,7 +22,7 @@ const void nfc_scene_mifare_ul_menu_on_enter(void* context) {
submenu_set_selected_item(
nfc->submenu, scene_manager_get_scene_state(nfc->scene_manager, NfcSceneMifareUlMenu));
- view_dispatcher_switch_to_view(nfc->nfc_common.view_dispatcher, NfcViewMenu);
+ view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewMenu);
}
const bool nfc_scene_mifare_ul_menu_on_event(void* context, SceneManagerEvent event) {
@@ -32,7 +32,8 @@ const bool nfc_scene_mifare_ul_menu_on_event(void* context, SceneManagerEvent ev
if(event.event == SubmenuIndexSave) {
scene_manager_set_scene_state(
nfc->scene_manager, NfcSceneMifareUlMenu, SubmenuIndexSave);
- scene_manager_next_scene(nfc->scene_manager, NfcSceneNotImplemented);
+ nfc->dev.format = NfcDeviceSaveFormatMifareUl;
+ scene_manager_next_scene(nfc->scene_manager, NfcSceneSaveName);
return true;
} else if(event.event == SubmenuIndexEmulate) {
scene_manager_set_scene_state(
diff --git a/applications/nfc/scenes/nfc_scene_not_implemented.c b/applications/nfc/scenes/nfc_scene_not_implemented.c
index ece75c97..f23bbe4a 100644
--- a/applications/nfc/scenes/nfc_scene_not_implemented.c
+++ b/applications/nfc/scenes/nfc_scene_not_implemented.c
@@ -3,7 +3,7 @@
void nfc_scene_not_implemented_dialog_callback(DialogExResult result, void* context) {
Nfc* nfc = (Nfc*)context;
- view_dispatcher_send_custom_event(nfc->nfc_common.view_dispatcher, result);
+ view_dispatcher_send_custom_event(nfc->view_dispatcher, result);
}
const void nfc_scene_not_implemented_on_enter(void* context) {
@@ -16,7 +16,7 @@ const void nfc_scene_not_implemented_on_enter(void* context) {
dialog_ex_set_context(dialog_ex, nfc);
dialog_ex_set_result_callback(dialog_ex, nfc_scene_not_implemented_dialog_callback);
- view_dispatcher_switch_to_view(nfc->nfc_common.view_dispatcher, NfcViewDialogEx);
+ view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewDialogEx);
}
const bool nfc_scene_not_implemented_on_event(void* context, SceneManagerEvent event) {
diff --git a/applications/nfc/scenes/nfc_scene_read_card.c b/applications/nfc/scenes/nfc_scene_read_card.c
index aaf9e5b8..4b32c36d 100755
--- a/applications/nfc/scenes/nfc_scene_read_card.c
+++ b/applications/nfc/scenes/nfc_scene_read_card.c
@@ -1,8 +1,10 @@
#include "../nfc_i.h"
+#define NFC_READ_CARD_CUSTOM_EVENT (0UL)
+
void nfc_read_card_worker_callback(void* context) {
Nfc* nfc = (Nfc*)context;
- view_dispatcher_send_custom_event(nfc->nfc_common.view_dispatcher, NfcEventDetect);
+ view_dispatcher_send_custom_event(nfc->view_dispatcher, NFC_READ_CARD_CUSTOM_EVENT);
}
const void nfc_scene_read_card_on_enter(void* context) {
@@ -14,21 +16,16 @@ const void nfc_scene_read_card_on_enter(void* context) {
popup_set_icon(popup, 0, 3, &I_RFIDDolphinReceive_97x61);
// Start worker
+ view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup);
nfc_worker_start(
- nfc->nfc_common.worker,
- NfcWorkerStateDetect,
- &nfc->nfc_common.worker_result,
- nfc_read_card_worker_callback,
- nfc);
- view_dispatcher_switch_to_view(nfc->nfc_common.view_dispatcher, NfcViewPopup);
+ nfc->worker, NfcWorkerStateDetect, &nfc->dev.dev_data, nfc_read_card_worker_callback, nfc);
}
const bool nfc_scene_read_card_on_event(void* context, SceneManagerEvent event) {
Nfc* nfc = (Nfc*)context;
if(event.type == SceneManagerEventTypeCustom) {
- if(event.event == NfcEventDetect) {
- nfc->device.data = nfc->nfc_common.worker_result.nfc_detect_data;
+ if(event.event == NFC_READ_CARD_CUSTOM_EVENT) {
scene_manager_next_scene(nfc->scene_manager, NfcSceneReadCardSuccess);
return true;
}
@@ -43,7 +40,7 @@ const void nfc_scene_read_card_on_exit(void* context) {
Nfc* nfc = (Nfc*)context;
// Stop worker
- nfc_worker_stop(nfc->nfc_common.worker);
+ nfc_worker_stop(nfc->worker);
// Clear view
Popup* popup = nfc->popup;
diff --git a/applications/nfc/scenes/nfc_scene_read_card_success.c b/applications/nfc/scenes/nfc_scene_read_card_success.c
index 3e841df3..42d5cbee 100755
--- a/applications/nfc/scenes/nfc_scene_read_card_success.c
+++ b/applications/nfc/scenes/nfc_scene_read_card_success.c
@@ -5,20 +5,20 @@
void nfc_scene_read_card_success_dialog_callback(DialogExResult result, void* context) {
Nfc* nfc = (Nfc*)context;
- view_dispatcher_send_custom_event(nfc->nfc_common.view_dispatcher, result);
+ view_dispatcher_send_custom_event(nfc->view_dispatcher, result);
}
-const void nfc_scene_read_card_success_on_enter(void* context) {
+void nfc_scene_read_card_success_on_enter(void* context) {
Nfc* nfc = (Nfc*)context;
// Clear device name
- nfc_device_set_name(&nfc->device, "");
+ nfc_device_set_name(&nfc->dev, "");
// Send notification
notification_message(nfc->notifications, &sequence_success);
// Setup view
- NfcDeviceData* data = (NfcDeviceData*)&nfc->nfc_common.worker_result;
+ NfcDeviceCommomData* data = (NfcDeviceCommomData*)&nfc->dev.dev_data.nfc_data;
DialogEx* dialog_ex = nfc->dialog_ex;
dialog_ex_set_left_button_text(dialog_ex, "Retry");
dialog_ex_set_right_button_text(dialog_ex, "More");
@@ -60,7 +60,7 @@ const void nfc_scene_read_card_success_on_enter(void* context) {
dialog_ex_set_context(dialog_ex, nfc);
dialog_ex_set_result_callback(dialog_ex, nfc_scene_read_card_success_dialog_callback);
- view_dispatcher_switch_to_view(nfc->nfc_common.view_dispatcher, NfcViewDialogEx);
+ view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewDialogEx);
}
const bool nfc_scene_read_card_success_on_event(void* context, SceneManagerEvent event) {
diff --git a/applications/nfc/scenes/nfc_scene_read_emv_app.c b/applications/nfc/scenes/nfc_scene_read_emv_app.c
new file mode 100755
index 00000000..ae00431b
--- /dev/null
+++ b/applications/nfc/scenes/nfc_scene_read_emv_app.c
@@ -0,0 +1,54 @@
+#include "../nfc_i.h"
+
+#define NFC_READ_EMV_APP_CUSTOM_EVENT (0UL)
+
+void nfc_read_emv_app_worker_callback(void* context) {
+ Nfc* nfc = (Nfc*)context;
+ view_dispatcher_send_custom_event(nfc->view_dispatcher, NFC_READ_EMV_APP_CUSTOM_EVENT);
+}
+
+const void nfc_scene_read_emv_app_on_enter(void* context) {
+ Nfc* nfc = (Nfc*)context;
+
+ // Setup view
+ Popup* popup = nfc->popup;
+ popup_set_header(popup, "Reading\nbank card", 70, 34, AlignLeft, AlignTop);
+ popup_set_icon(popup, 0, 3, &I_RFIDDolphinReceive_97x61);
+
+ view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup);
+ // Start worker
+ nfc_worker_start(
+ nfc->worker,
+ NfcWorkerStateReadEMVApp,
+ &nfc->dev.dev_data,
+ nfc_read_emv_app_worker_callback,
+ nfc);
+}
+
+const bool nfc_scene_read_emv_app_on_event(void* context, SceneManagerEvent event) {
+ Nfc* nfc = (Nfc*)context;
+
+ if(event.type == SceneManagerEventTypeCustom) {
+ if(event.event == NFC_READ_EMV_APP_CUSTOM_EVENT) {
+ scene_manager_next_scene(nfc->scene_manager, NfcSceneReadEmvAppSuccess);
+ return true;
+ }
+ } else if(event.type == SceneManagerEventTypeTick) {
+ notification_message(nfc->notifications, &sequence_blink_blue_10);
+ return true;
+ }
+ return false;
+}
+
+const void nfc_scene_read_emv_app_on_exit(void* context) {
+ Nfc* nfc = (Nfc*)context;
+
+ // Stop worker
+ nfc_worker_stop(nfc->worker);
+
+ // Clear view
+ Popup* popup = nfc->popup;
+ popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom);
+ popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop);
+ popup_set_icon(popup, 0, 0, NULL);
+}
diff --git a/applications/nfc/scenes/nfc_scene_read_emv_app_success.c b/applications/nfc/scenes/nfc_scene_read_emv_app_success.c
new file mode 100755
index 00000000..631b0456
--- /dev/null
+++ b/applications/nfc/scenes/nfc_scene_read_emv_app_success.c
@@ -0,0 +1,69 @@
+#include "../nfc_i.h"
+
+#define NFC_SCENE_READ_SUCCESS_SHIFT " "
+
+void nfc_scene_read_emv_app_success_dialog_callback(DialogExResult result, void* context) {
+ Nfc* nfc = (Nfc*)context;
+
+ view_dispatcher_send_custom_event(nfc->view_dispatcher, result);
+}
+
+void nfc_scene_read_emv_app_success_on_enter(void* context) {
+ Nfc* nfc = (Nfc*)context;
+
+ // Setup view
+ NfcDeviceCommomData* nfc_data = &nfc->dev.dev_data.nfc_data;
+ NfcEmvData* emv_data = &nfc->dev.dev_data.emv_data;
+ DialogEx* dialog_ex = nfc->dialog_ex;
+ dialog_ex_set_left_button_text(dialog_ex, "Retry");
+ dialog_ex_set_right_button_text(dialog_ex, "Run app");
+ dialog_ex_set_header(dialog_ex, "Found EMV App", 36, 8, AlignLeft, AlignCenter);
+ dialog_ex_set_icon(dialog_ex, 8, 13, &I_Medium_chip_22x21);
+ // Display UID and AID
+ string_t aid;
+ string_init_printf(aid, "AID:");
+ for(uint8_t i = 0; i < emv_data->aid_len; i++) {
+ string_cat_printf(aid, " %02X", emv_data->aid[i]);
+ }
+ nfc_text_store_set(
+ nfc,
+ NFC_SCENE_READ_SUCCESS_SHIFT "UID: %02X %02X %02X %02X \n\n%s",
+ nfc_data->uid[0],
+ nfc_data->uid[1],
+ nfc_data->uid[2],
+ nfc_data->uid[3],
+ string_get_cstr(aid));
+ string_clear(aid);
+ dialog_ex_set_text(dialog_ex, nfc->text_store, 8, 16, AlignLeft, AlignTop);
+ dialog_ex_set_context(dialog_ex, nfc);
+ dialog_ex_set_result_callback(dialog_ex, nfc_scene_read_emv_app_success_dialog_callback);
+
+ view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewDialogEx);
+}
+
+const bool nfc_scene_read_emv_app_success_on_event(void* context, SceneManagerEvent event) {
+ Nfc* nfc = (Nfc*)context;
+
+ if(event.type == SceneManagerEventTypeCustom) {
+ if(event.event == DialogExResultLeft) {
+ return scene_manager_previous_scene(nfc->scene_manager);
+ } else if(event.event == DialogExResultRight) {
+ scene_manager_next_scene(nfc->scene_manager, NfcSceneRunEmvAppConfirm);
+ return true;
+ }
+ }
+ return false;
+}
+
+const void nfc_scene_read_emv_app_success_on_exit(void* context) {
+ Nfc* nfc = (Nfc*)context;
+
+ DialogEx* dialog_ex = nfc->dialog_ex;
+ dialog_ex_set_header(dialog_ex, NULL, 0, 0, AlignCenter, AlignCenter);
+ dialog_ex_set_text(dialog_ex, NULL, 0, 0, AlignCenter, AlignTop);
+ dialog_ex_set_icon(dialog_ex, 0, 0, NULL);
+ dialog_ex_set_left_button_text(dialog_ex, NULL);
+ dialog_ex_set_right_button_text(dialog_ex, NULL);
+ dialog_ex_set_result_callback(dialog_ex, NULL);
+ dialog_ex_set_context(dialog_ex, NULL);
+}
diff --git a/applications/nfc/scenes/nfc_scene_read_emv_data.c b/applications/nfc/scenes/nfc_scene_read_emv_data.c
new file mode 100644
index 00000000..38c5008e
--- /dev/null
+++ b/applications/nfc/scenes/nfc_scene_read_emv_data.c
@@ -0,0 +1,57 @@
+#include "../nfc_i.h"
+
+#define NFC_READ_EMV_DATA_CUSTOM_EVENT (0UL)
+
+void nfc_read_emv_data_worker_callback(void* context) {
+ Nfc* nfc = (Nfc*)context;
+ view_dispatcher_send_custom_event(nfc->view_dispatcher, NFC_READ_EMV_DATA_CUSTOM_EVENT);
+}
+
+const void nfc_scene_read_emv_data_on_enter(void* context) {
+ Nfc* nfc = (Nfc*)context;
+
+ // Setup view
+ Popup* popup = nfc->popup;
+ popup_set_header(popup, "Reading\nbank card", 70, 34, AlignLeft, AlignTop);
+ popup_set_icon(popup, 0, 3, &I_RFIDDolphinReceive_97x61);
+
+ view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup);
+ // Start worker
+ nfc_worker_start(
+ nfc->worker,
+ NfcWorkerStateReadEMV,
+ &nfc->dev.dev_data,
+ nfc_read_emv_data_worker_callback,
+ nfc);
+}
+
+const bool nfc_scene_read_emv_data_on_event(void* context, SceneManagerEvent event) {
+ Nfc* nfc = (Nfc*)context;
+
+ if(event.type == SceneManagerEventTypeCustom) {
+ if(event.event == NFC_READ_EMV_DATA_CUSTOM_EVENT) {
+ scene_manager_next_scene(nfc->scene_manager, NfcSceneReadEmvDataSuccess);
+ return true;
+ }
+ } else if(event.type == SceneManagerEventTypeTick) {
+ notification_message(nfc->notifications, &sequence_blink_blue_10);
+ return true;
+ }
+ return false;
+}
+
+const void nfc_scene_read_emv_data_on_exit(void* context) {
+ Nfc* nfc = (Nfc*)context;
+
+ // Stop worker
+ nfc_worker_stop(nfc->worker);
+
+ // Send notification
+ notification_message(nfc->notifications, &sequence_success);
+
+ // Clear view
+ Popup* popup = nfc->popup;
+ popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom);
+ popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop);
+ popup_set_icon(popup, 0, 0, NULL);
+}
diff --git a/applications/nfc/scenes/nfc_scene_read_emv_data_success.c b/applications/nfc/scenes/nfc_scene_read_emv_data_success.c
new file mode 100755
index 00000000..f8f37f7a
--- /dev/null
+++ b/applications/nfc/scenes/nfc_scene_read_emv_data_success.c
@@ -0,0 +1,89 @@
+#include "../nfc_i.h"
+
+void nfc_scene_read_emv_data_success_widget_callback(GuiButtonType result, void* context) {
+ Nfc* nfc = (Nfc*)context;
+
+ view_dispatcher_send_custom_event(nfc->view_dispatcher, result);
+}
+
+void nfc_scene_read_emv_data_success_on_enter(void* context) {
+ Nfc* nfc = (Nfc*)context;
+ NfcEmvData* emv_data = &nfc->dev.dev_data.emv_data;
+ NfcDeviceCommomData* nfc_data = &nfc->dev.dev_data.nfc_data;
+
+ // Clear device name
+ nfc_device_set_name(&nfc->dev, "");
+
+ // Setup Custom Widget view
+ gui_widget_add_button_element(
+ nfc->widget,
+ GuiButtonTypeLeft,
+ "Back",
+ nfc_scene_read_emv_data_success_widget_callback,
+ nfc);
+ gui_widget_add_button_element(
+ nfc->widget,
+ GuiButtonTypeRight,
+ "Save",
+ nfc_scene_read_emv_data_success_widget_callback,
+ nfc);
+ gui_widget_add_string_element(
+ nfc->widget, 64, 3, AlignCenter, AlignTop, FontSecondary, nfc->dev.dev_data.emv_data.name);
+ char pan_str[32];
+ snprintf(
+ pan_str,
+ sizeof(pan_str),
+ "%02X%02X %02X%02X %02X%02X %02X%02X",
+ emv_data->number[0],
+ emv_data->number[1],
+ emv_data->number[2],
+ emv_data->number[3],
+ emv_data->number[4],
+ emv_data->number[5],
+ emv_data->number[6],
+ emv_data->number[7]);
+ gui_widget_add_string_element(
+ nfc->widget, 64, 13, AlignCenter, AlignTop, FontSecondary, pan_str);
+ char atqa_str[16];
+ snprintf(atqa_str, sizeof(atqa_str), "ATQA: %02X%02X", nfc_data->atqa[0], nfc_data->atqa[1]);
+ gui_widget_add_string_element(
+ nfc->widget, 121, 32, AlignRight, AlignTop, FontSecondary, atqa_str);
+ char uid_str[32];
+ snprintf(
+ uid_str,
+ sizeof(uid_str),
+ "UID: %02X %02X %02X %02X",
+ nfc_data->uid[0],
+ nfc_data->uid[1],
+ nfc_data->uid[2],
+ nfc_data->uid[3]);
+ gui_widget_add_string_element(nfc->widget, 7, 42, AlignLeft, AlignTop, FontSecondary, uid_str);
+ char sak_str[16];
+ snprintf(sak_str, sizeof(sak_str), "SAK: %02X", nfc_data->sak);
+ gui_widget_add_string_element(
+ nfc->widget, 121, 42, AlignRight, AlignTop, FontSecondary, sak_str);
+
+ view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewWidget);
+}
+
+const bool nfc_scene_read_emv_data_success_on_event(void* context, SceneManagerEvent event) {
+ Nfc* nfc = (Nfc*)context;
+
+ if(event.type == SceneManagerEventTypeCustom) {
+ if(event.event == GuiButtonTypeLeft) {
+ return scene_manager_search_previous_scene(
+ nfc->scene_manager, NfcSceneReadEmvAppSuccess);
+ } else if(event.event == GuiButtonTypeRight) {
+ nfc->dev.format = NfcDeviceSaveFormatBankCard;
+ scene_manager_next_scene(nfc->scene_manager, NfcSceneSaveName);
+ return true;
+ }
+ }
+ return false;
+}
+
+const void nfc_scene_read_emv_data_success_on_exit(void* context) {
+ Nfc* nfc = (Nfc*)context;
+
+ gui_widget_clear(nfc->widget);
+}
diff --git a/applications/nfc/scenes/nfc_scene_read_mifare_ul.c b/applications/nfc/scenes/nfc_scene_read_mifare_ul.c
index 90367a77..d1997d51 100755
--- a/applications/nfc/scenes/nfc_scene_read_mifare_ul.c
+++ b/applications/nfc/scenes/nfc_scene_read_mifare_ul.c
@@ -1,8 +1,10 @@
#include "../nfc_i.h"
+#define NFC_READ_MIFARE_UL_CUSTOM_EVENT (0UL)
+
void nfc_read_mifare_ul_worker_callback(void* context) {
Nfc* nfc = (Nfc*)context;
- view_dispatcher_send_custom_event(nfc->nfc_common.view_dispatcher, NfcEventMifareUl);
+ view_dispatcher_send_custom_event(nfc->view_dispatcher, NFC_READ_MIFARE_UL_CUSTOM_EVENT);
}
const void nfc_scene_read_mifare_ul_on_enter(void* context) {
@@ -13,22 +15,21 @@ const void nfc_scene_read_mifare_ul_on_enter(void* context) {
popup_set_header(popup, "Detecting\nultralight", 70, 34, AlignLeft, AlignTop);
popup_set_icon(popup, 0, 3, &I_RFIDDolphinReceive_97x61);
+ view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup);
// Start worker
nfc_worker_start(
- nfc->nfc_common.worker,
- NfcWorkerStateReadMfUltralight,
- &nfc->nfc_common.worker_result,
+ nfc->worker,
+ NfcWorkerStateReadMifareUl,
+ &nfc->dev.dev_data,
nfc_read_mifare_ul_worker_callback,
nfc);
- view_dispatcher_switch_to_view(nfc->nfc_common.view_dispatcher, NfcViewPopup);
}
const bool nfc_scene_read_mifare_ul_on_event(void* context, SceneManagerEvent event) {
Nfc* nfc = (Nfc*)context;
if(event.type == SceneManagerEventTypeCustom) {
- if(event.event == NfcEventMifareUl) {
- nfc->device.data = nfc->nfc_common.worker_result.nfc_detect_data;
+ if(event.event == NFC_READ_MIFARE_UL_CUSTOM_EVENT) {
scene_manager_next_scene(nfc->scene_manager, NfcSceneReadMifareUlSuccess);
return true;
}
@@ -43,7 +44,7 @@ const void nfc_scene_read_mifare_ul_on_exit(void* context) {
Nfc* nfc = (Nfc*)context;
// Stop worker
- nfc_worker_stop(nfc->nfc_common.worker);
+ nfc_worker_stop(nfc->worker);
// Clear view
Popup* popup = nfc->popup;
diff --git a/applications/nfc/scenes/nfc_scene_read_mifare_ul_success.c b/applications/nfc/scenes/nfc_scene_read_mifare_ul_success.c
index 7303fd09..caf9f5b5 100755
--- a/applications/nfc/scenes/nfc_scene_read_mifare_ul_success.c
+++ b/applications/nfc/scenes/nfc_scene_read_mifare_ul_success.c
@@ -11,28 +11,26 @@ enum {
void nfc_scene_read_mifare_ul_success_dialog_callback(DialogExResult result, void* context) {
Nfc* nfc = (Nfc*)context;
- view_dispatcher_send_custom_event(nfc->nfc_common.view_dispatcher, result);
+ view_dispatcher_send_custom_event(nfc->view_dispatcher, result);
}
void nfc_scene_read_mifare_ul_success_text_box_callback(void* context) {
Nfc* nfc = (Nfc*)context;
- view_dispatcher_send_custom_event(
- nfc->nfc_common.view_dispatcher, NFC_SCENE_READ_MF_UL_CUSTOM_EVENT);
+ view_dispatcher_send_custom_event(nfc->view_dispatcher, NFC_SCENE_READ_MF_UL_CUSTOM_EVENT);
}
const void nfc_scene_read_mifare_ul_success_on_enter(void* context) {
Nfc* nfc = (Nfc*)context;
// Clear device name
- nfc_device_set_name(&nfc->device, "");
+ nfc_device_set_name(&nfc->dev, "");
// Send notification
notification_message(nfc->notifications, &sequence_success);
// Setup dialog view
- NfcDeviceData* data =
- (NfcDeviceData*)&nfc->nfc_common.worker_result.nfc_mifare_ul_data.nfc_data;
+ NfcDeviceCommomData* data = (NfcDeviceCommomData*)&nfc->dev.dev_data.nfc_data;
DialogEx* dialog_ex = nfc->dialog_ex;
dialog_ex_set_left_button_text(dialog_ex, "Retry");
dialog_ex_set_right_button_text(dialog_ex, "More");
@@ -59,27 +57,23 @@ const void nfc_scene_read_mifare_ul_success_on_enter(void* context) {
dialog_ex_set_result_callback(dialog_ex, nfc_scene_read_mifare_ul_success_dialog_callback);
// Setup TextBox view
- NfcMifareUlData* mf_ul_data =
- (NfcMifareUlData*)&nfc->nfc_common.worker_result.nfc_mifare_ul_data;
+ MifareUlData* mf_ul_data = (MifareUlData*)&nfc->dev.dev_data.mf_ul_data;
TextBox* text_box = nfc->text_box;
text_box_set_context(text_box, nfc);
text_box_set_exit_callback(text_box, nfc_scene_read_mifare_ul_success_text_box_callback);
text_box_set_font(text_box, TextBoxFontHex);
- for(uint16_t i = 0; i < mf_ul_data->dump_size; i += 2) {
+ for(uint16_t i = 0; i < mf_ul_data->data_size; i += 2) {
if(!(i % 8) && i) {
string_push_back(nfc->text_box_store, '\n');
}
string_cat_printf(
- nfc->text_box_store,
- "%02X%02X ",
- mf_ul_data->full_dump[i],
- mf_ul_data->full_dump[i + 1]);
+ nfc->text_box_store, "%02X%02X ", mf_ul_data->data[i], mf_ul_data->data[i + 1]);
}
text_box_set_text(text_box, string_get_cstr(nfc->text_box_store));
scene_manager_set_scene_state(
nfc->scene_manager, NfcSceneReadMifareUlSuccess, ReadMifareUlStateShowUID);
- view_dispatcher_switch_to_view(nfc->nfc_common.view_dispatcher, NfcViewDialogEx);
+ view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewDialogEx);
}
const bool nfc_scene_read_mifare_ul_success_on_event(void* context, SceneManagerEvent event) {
@@ -101,7 +95,7 @@ const bool nfc_scene_read_mifare_ul_success_on_event(void* context, SceneManager
(scene_manager_get_scene_state(nfc->scene_manager, NfcSceneReadMifareUlSuccess) ==
ReadMifareUlStateShowUID) &&
(event.event == DialogExResultCenter)) {
- view_dispatcher_switch_to_view(nfc->nfc_common.view_dispatcher, NfcViewTextBox);
+ view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewTextBox);
scene_manager_set_scene_state(
nfc->scene_manager, NfcSceneReadMifareUlSuccess, ReadMifareUlStateShowData);
return true;
@@ -109,7 +103,7 @@ const bool nfc_scene_read_mifare_ul_success_on_event(void* context, SceneManager
(scene_manager_get_scene_state(nfc->scene_manager, NfcSceneReadMifareUlSuccess) ==
ReadMifareUlStateShowData) &&
(event.event == NFC_SCENE_READ_MF_UL_CUSTOM_EVENT)) {
- view_dispatcher_switch_to_view(nfc->nfc_common.view_dispatcher, NfcViewDialogEx);
+ view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewDialogEx);
scene_manager_set_scene_state(
nfc->scene_manager, NfcSceneReadMifareUlSuccess, ReadMifareUlStateShowUID);
return true;
diff --git a/applications/nfc/scenes/nfc_scene_run_emv_app_confirm.c b/applications/nfc/scenes/nfc_scene_run_emv_app_confirm.c
new file mode 100755
index 00000000..609ccfc5
--- /dev/null
+++ b/applications/nfc/scenes/nfc_scene_run_emv_app_confirm.c
@@ -0,0 +1,56 @@
+#include "../nfc_i.h"
+
+#define NFC_SCENE_READ_SUCCESS_SHIFT " "
+
+void nfc_scene_run_emv_app_confirm_dialog_callback(DialogExResult result, void* context) {
+ Nfc* nfc = (Nfc*)context;
+
+ view_dispatcher_send_custom_event(nfc->view_dispatcher, result);
+}
+
+void nfc_scene_run_emv_app_confirm_on_enter(void* context) {
+ Nfc* nfc = (Nfc*)context;
+
+ DialogEx* dialog_ex = nfc->dialog_ex;
+ dialog_ex_set_left_button_text(dialog_ex, "Back");
+ dialog_ex_set_right_button_text(dialog_ex, "Run");
+ dialog_ex_set_header(dialog_ex, "Run EMV app?", 64, 8, AlignCenter, AlignCenter);
+ dialog_ex_set_text(
+ dialog_ex,
+ "It will try to run card's app\nand detect unencrypred\ndata",
+ 64,
+ 18,
+ AlignCenter,
+ AlignTop);
+ dialog_ex_set_context(dialog_ex, nfc);
+ dialog_ex_set_result_callback(dialog_ex, nfc_scene_run_emv_app_confirm_dialog_callback);
+
+ view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewDialogEx);
+}
+
+const bool nfc_scene_run_emv_app_confirm_on_event(void* context, SceneManagerEvent event) {
+ Nfc* nfc = (Nfc*)context;
+
+ if(event.type == SceneManagerEventTypeCustom) {
+ if(event.event == DialogExResultLeft) {
+ return scene_manager_previous_scene(nfc->scene_manager);
+ } else if(event.event == DialogExResultRight) {
+ scene_manager_next_scene(nfc->scene_manager, NfcSceneReadEmvData);
+ return true;
+ }
+ }
+ return false;
+}
+
+const void nfc_scene_run_emv_app_confirm_on_exit(void* context) {
+ Nfc* nfc = (Nfc*)context;
+
+ DialogEx* dialog_ex = nfc->dialog_ex;
+ dialog_ex_set_header(dialog_ex, NULL, 0, 0, AlignCenter, AlignCenter);
+ dialog_ex_set_text(dialog_ex, NULL, 0, 0, AlignCenter, AlignTop);
+ dialog_ex_set_icon(dialog_ex, 0, 0, NULL);
+ dialog_ex_set_left_button_text(dialog_ex, NULL);
+ dialog_ex_set_right_button_text(dialog_ex, NULL);
+ dialog_ex_set_result_callback(dialog_ex, NULL);
+ dialog_ex_set_context(dialog_ex, NULL);
+}
diff --git a/applications/nfc/scenes/nfc_scene_save_name.c b/applications/nfc/scenes/nfc_scene_save_name.c
index 956fe8ae..af448ef1 100755
--- a/applications/nfc/scenes/nfc_scene_save_name.c
+++ b/applications/nfc/scenes/nfc_scene_save_name.c
@@ -5,8 +5,7 @@
void nfc_scene_save_name_text_input_callback(void* context) {
Nfc* nfc = (Nfc*)context;
- view_dispatcher_send_custom_event(
- nfc->nfc_common.view_dispatcher, SCENE_SAVE_NAME_CUSTOM_EVENT);
+ view_dispatcher_send_custom_event(nfc->view_dispatcher, SCENE_SAVE_NAME_CUSTOM_EVENT);
}
const void nfc_scene_save_name_on_enter(void* context) {
@@ -14,7 +13,10 @@ const void nfc_scene_save_name_on_enter(void* context) {
// Setup view
TextInput* text_input = nfc->text_input;
- nfc_text_store_clear(nfc);
+ if(nfc->dev.dev_name) {
+ nfc_device_delete(&nfc->dev);
+ }
+ nfc_text_store_set(nfc, nfc->dev.dev_name);
text_input_set_header_text(text_input, "Name the card");
text_input_set_result_callback(
text_input,
@@ -22,7 +24,7 @@ const void nfc_scene_save_name_on_enter(void* context) {
nfc,
nfc->text_store,
sizeof(nfc->text_store));
- view_dispatcher_switch_to_view(nfc->nfc_common.view_dispatcher, NfcViewTextInput);
+ view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewTextInput);
}
const bool nfc_scene_save_name_on_event(void* context, SceneManagerEvent event) {
@@ -30,8 +32,8 @@ const bool nfc_scene_save_name_on_event(void* context, SceneManagerEvent event)
if(event.type == SceneManagerEventTypeCustom) {
if(event.event == SCENE_SAVE_NAME_CUSTOM_EVENT) {
- memcpy(&nfc->device.dev_name, nfc->text_store, strlen(nfc->text_store));
- if(nfc_device_save(&nfc->device, nfc->text_store)) {
+ memcpy(&nfc->dev.dev_name, nfc->text_store, strlen(nfc->text_store));
+ if(nfc_device_save(&nfc->dev, nfc->text_store)) {
scene_manager_next_scene(nfc->scene_manager, NfcSceneSaveSuccess);
return true;
} else {
diff --git a/applications/nfc/scenes/nfc_scene_save_success.c b/applications/nfc/scenes/nfc_scene_save_success.c
index 20a1cd7e..cd36871a 100755
--- a/applications/nfc/scenes/nfc_scene_save_success.c
+++ b/applications/nfc/scenes/nfc_scene_save_success.c
@@ -4,8 +4,7 @@
void nfc_scene_save_success_popup_callback(void* context) {
Nfc* nfc = (Nfc*)context;
- view_dispatcher_send_custom_event(
- nfc->nfc_common.view_dispatcher, SCENE_SAVE_SUCCESS_CUSTOM_EVENT);
+ view_dispatcher_send_custom_event(nfc->view_dispatcher, SCENE_SAVE_SUCCESS_CUSTOM_EVENT);
}
const void nfc_scene_save_success_on_enter(void* context) {
@@ -19,7 +18,7 @@ const void nfc_scene_save_success_on_enter(void* context) {
popup_set_context(popup, nfc);
popup_set_callback(popup, nfc_scene_save_success_popup_callback);
popup_enable_timeout(popup);
- view_dispatcher_switch_to_view(nfc->nfc_common.view_dispatcher, NfcViewPopup);
+ view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup);
}
const bool nfc_scene_save_success_on_event(void* context, SceneManagerEvent event) {
diff --git a/applications/nfc/scenes/nfc_scene_saved_menu.c b/applications/nfc/scenes/nfc_scene_saved_menu.c
index 46e64691..24d03fbc 100755
--- a/applications/nfc/scenes/nfc_scene_saved_menu.c
+++ b/applications/nfc/scenes/nfc_scene_saved_menu.c
@@ -10,15 +10,17 @@ enum SubmenuIndex {
void nfc_scene_saved_menu_submenu_callback(void* context, uint32_t index) {
Nfc* nfc = (Nfc*)context;
- view_dispatcher_send_custom_event(nfc->nfc_common.view_dispatcher, index);
+ view_dispatcher_send_custom_event(nfc->view_dispatcher, index);
}
const void nfc_scene_saved_menu_on_enter(void* context) {
Nfc* nfc = (Nfc*)context;
Submenu* submenu = nfc->submenu;
- submenu_add_item(
- submenu, "Emulate", SubmenuIndexEmulate, nfc_scene_saved_menu_submenu_callback, nfc);
+ if(nfc->dev.format != NfcDeviceSaveFormatBankCard) {
+ submenu_add_item(
+ submenu, "Emulate", SubmenuIndexEmulate, nfc_scene_saved_menu_submenu_callback, nfc);
+ }
submenu_add_item(
submenu, "Edit UID and name", SubmenuIndexEdit, nfc_scene_saved_menu_submenu_callback, nfc);
submenu_add_item(
@@ -28,7 +30,7 @@ const void nfc_scene_saved_menu_on_enter(void* context) {
submenu_set_selected_item(
nfc->submenu, scene_manager_get_scene_state(nfc->scene_manager, NfcSceneSavedMenu));
- view_dispatcher_switch_to_view(nfc->nfc_common.view_dispatcher, NfcViewMenu);
+ view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewMenu);
}
const bool nfc_scene_saved_menu_on_event(void* context, SceneManagerEvent event) {
@@ -42,16 +44,16 @@ const bool nfc_scene_saved_menu_on_event(void* context, SceneManagerEvent event)
return true;
} else if(event.event == SubmenuIndexEdit) {
scene_manager_set_scene_state(nfc->scene_manager, NfcSceneSavedMenu, SubmenuIndexEdit);
- scene_manager_next_scene(nfc->scene_manager, NfcSceneNotImplemented);
+ scene_manager_next_scene(nfc->scene_manager, NfcSceneSetUid);
return true;
} else if(event.event == SubmenuIndexDelete) {
scene_manager_set_scene_state(
nfc->scene_manager, NfcSceneSavedMenu, SubmenuIndexDelete);
- scene_manager_next_scene(nfc->scene_manager, NfcSceneNotImplemented);
+ scene_manager_next_scene(nfc->scene_manager, NfcSceneDelete);
return true;
} else if(event.event == SubmenuIndexInfo) {
scene_manager_set_scene_state(nfc->scene_manager, NfcSceneSavedMenu, SubmenuIndexInfo);
- scene_manager_next_scene(nfc->scene_manager, NfcSceneNotImplemented);
+ scene_manager_next_scene(nfc->scene_manager, NfcSceneDeviceInfo);
return true;
}
}
diff --git a/applications/nfc/scenes/nfc_scene_scripts_menu.c b/applications/nfc/scenes/nfc_scene_scripts_menu.c
index b8e43528..327d32c6 100755
--- a/applications/nfc/scenes/nfc_scene_scripts_menu.c
+++ b/applications/nfc/scenes/nfc_scene_scripts_menu.c
@@ -8,7 +8,7 @@ enum SubmenuIndex {
void nfc_scene_scripts_menu_submenu_callback(void* context, uint32_t index) {
Nfc* nfc = (Nfc*)context;
- view_dispatcher_send_custom_event(nfc->nfc_common.view_dispatcher, index);
+ view_dispatcher_send_custom_event(nfc->view_dispatcher, index);
}
const void nfc_scene_scripts_menu_on_enter(void* context) {
@@ -29,7 +29,7 @@ const void nfc_scene_scripts_menu_on_enter(void* context) {
nfc);
submenu_set_selected_item(
nfc->submenu, scene_manager_get_scene_state(nfc->scene_manager, NfcSceneScriptsMenu));
- view_dispatcher_switch_to_view(nfc->nfc_common.view_dispatcher, NfcViewMenu);
+ view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewMenu);
}
const bool nfc_scene_scripts_menu_on_event(void* context, SceneManagerEvent event) {
@@ -39,7 +39,7 @@ const bool nfc_scene_scripts_menu_on_event(void* context, SceneManagerEvent even
if(event.event == SubmenuIndexBankCard) {
scene_manager_set_scene_state(
nfc->scene_manager, NfcSceneScriptsMenu, SubmenuIndexBankCard);
- scene_manager_next_scene(nfc->scene_manager, NfcSceneNotImplemented);
+ scene_manager_next_scene(nfc->scene_manager, NfcSceneReadEmvApp);
return true;
} else if(event.event == SubmenuIndexMifareUltralight) {
scene_manager_set_scene_state(
diff --git a/applications/nfc/scenes/nfc_scene_set_atqa.c b/applications/nfc/scenes/nfc_scene_set_atqa.c
index ebb0bb8f..80ceea17 100755
--- a/applications/nfc/scenes/nfc_scene_set_atqa.c
+++ b/applications/nfc/scenes/nfc_scene_set_atqa.c
@@ -5,8 +5,7 @@
void nfc_scene_set_atqa_byte_input_callback(void* context) {
Nfc* nfc = (Nfc*)context;
- view_dispatcher_send_custom_event(
- nfc->nfc_common.view_dispatcher, SCENE_SET_ATQA_CUSTOM_EVENT);
+ view_dispatcher_send_custom_event(nfc->view_dispatcher, SCENE_SET_ATQA_CUSTOM_EVENT);
}
const void nfc_scene_set_atqa_on_enter(void* context) {
@@ -16,8 +15,13 @@ const void nfc_scene_set_atqa_on_enter(void* context) {
ByteInput* byte_input = nfc->byte_input;
byte_input_set_header_text(byte_input, "Enter atqa in hex");
byte_input_set_result_callback(
- byte_input, nfc_scene_set_atqa_byte_input_callback, NULL, nfc, nfc->device.data.atqa, 2);
- view_dispatcher_switch_to_view(nfc->nfc_common.view_dispatcher, NfcViewByteInput);
+ byte_input,
+ nfc_scene_set_atqa_byte_input_callback,
+ NULL,
+ nfc,
+ nfc->dev.dev_data.nfc_data.atqa,
+ 2);
+ view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewByteInput);
}
const bool nfc_scene_set_atqa_on_event(void* context, SceneManagerEvent event) {
diff --git a/applications/nfc/scenes/nfc_scene_set_sak.c b/applications/nfc/scenes/nfc_scene_set_sak.c
index 1b20afbc..27646cc6 100755
--- a/applications/nfc/scenes/nfc_scene_set_sak.c
+++ b/applications/nfc/scenes/nfc_scene_set_sak.c
@@ -5,7 +5,7 @@
void nfc_scene_set_sak_byte_input_callback(void* context) {
Nfc* nfc = (Nfc*)context;
- view_dispatcher_send_custom_event(nfc->nfc_common.view_dispatcher, SCENE_SET_SAK_CUSTOM_EVENT);
+ view_dispatcher_send_custom_event(nfc->view_dispatcher, SCENE_SET_SAK_CUSTOM_EVENT);
}
const void nfc_scene_set_sak_on_enter(void* context) {
@@ -15,8 +15,13 @@ const void nfc_scene_set_sak_on_enter(void* context) {
ByteInput* byte_input = nfc->byte_input;
byte_input_set_header_text(byte_input, "Enter SAK in hex");
byte_input_set_result_callback(
- byte_input, nfc_scene_set_sak_byte_input_callback, NULL, nfc, &nfc->device.data.sak, 1);
- view_dispatcher_switch_to_view(nfc->nfc_common.view_dispatcher, NfcViewByteInput);
+ byte_input,
+ nfc_scene_set_sak_byte_input_callback,
+ NULL,
+ nfc,
+ &nfc->dev.dev_data.nfc_data.sak,
+ 1);
+ view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewByteInput);
}
const bool nfc_scene_set_sak_on_event(void* context, SceneManagerEvent event) {
diff --git a/applications/nfc/scenes/nfc_scene_set_type.c b/applications/nfc/scenes/nfc_scene_set_type.c
index 951464e0..9798b8f7 100755
--- a/applications/nfc/scenes/nfc_scene_set_type.c
+++ b/applications/nfc/scenes/nfc_scene_set_type.c
@@ -8,7 +8,7 @@ enum SubmenuIndex {
void nfc_scene_set_type_submenu_callback(void* context, uint32_t index) {
Nfc* nfc = (Nfc*)context;
- view_dispatcher_send_custom_event(nfc->nfc_common.view_dispatcher, index);
+ view_dispatcher_send_custom_event(nfc->view_dispatcher, index);
}
const void nfc_scene_set_type_on_enter(void* context) {
@@ -19,7 +19,7 @@ const void nfc_scene_set_type_on_enter(void* context) {
submenu, "NFC-A 7-bytes UID", SubmenuIndexNFCA7, nfc_scene_set_type_submenu_callback, nfc);
submenu_add_item(
submenu, "NFC-A 4-bytes UID", SubmenuIndexNFCA4, nfc_scene_set_type_submenu_callback, nfc);
- view_dispatcher_switch_to_view(nfc->nfc_common.view_dispatcher, NfcViewMenu);
+ view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewMenu);
}
const bool nfc_scene_set_type_on_event(void* context, SceneManagerEvent event) {
@@ -27,11 +27,13 @@ const bool nfc_scene_set_type_on_event(void* context, SceneManagerEvent event) {
if(event.type == SceneManagerEventTypeCustom) {
if(event.event == SubmenuIndexNFCA7) {
- nfc->device.data.uid_len = 7;
+ nfc->dev.dev_data.nfc_data.uid_len = 7;
+ nfc->dev.format = NfcDeviceSaveFormatUid;
scene_manager_next_scene(nfc->scene_manager, NfcSceneSetSak);
return true;
} else if(event.event == SubmenuIndexNFCA4) {
- nfc->device.data.uid_len = 4;
+ nfc->dev.dev_data.nfc_data.uid_len = 4;
+ nfc->dev.format = NfcDeviceSaveFormatUid;
scene_manager_next_scene(nfc->scene_manager, NfcSceneSetSak);
return true;
}
diff --git a/applications/nfc/scenes/nfc_scene_set_uid.c b/applications/nfc/scenes/nfc_scene_set_uid.c
index 1c48c8df..6e1a8d7c 100755
--- a/applications/nfc/scenes/nfc_scene_set_uid.c
+++ b/applications/nfc/scenes/nfc_scene_set_uid.c
@@ -5,7 +5,7 @@
void nfc_scene_set_uid_byte_input_callback(void* context) {
Nfc* nfc = (Nfc*)context;
- view_dispatcher_send_custom_event(nfc->nfc_common.view_dispatcher, SCENE_SET_UID_CUSTOM_EVENT);
+ view_dispatcher_send_custom_event(nfc->view_dispatcher, SCENE_SET_UID_CUSTOM_EVENT);
}
const void nfc_scene_set_uid_on_enter(void* context) {
@@ -19,9 +19,9 @@ const void nfc_scene_set_uid_on_enter(void* context) {
nfc_scene_set_uid_byte_input_callback,
NULL,
nfc,
- nfc->device.data.uid,
- nfc->device.data.uid_len);
- view_dispatcher_switch_to_view(nfc->nfc_common.view_dispatcher, NfcViewByteInput);
+ nfc->dev.dev_data.nfc_data.uid,
+ nfc->dev.dev_data.nfc_data.uid_len);
+ view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewByteInput);
}
const bool nfc_scene_set_uid_on_event(void* context, SceneManagerEvent event) {
diff --git a/applications/nfc/scenes/nfc_scene_start.c b/applications/nfc/scenes/nfc_scene_start.c
index d171b0c3..78a4d923 100755
--- a/applications/nfc/scenes/nfc_scene_start.c
+++ b/applications/nfc/scenes/nfc_scene_start.c
@@ -5,13 +5,12 @@ enum SubmenuIndex {
SubmenuIndexRunScript,
SubmenuIndexSaved,
SubmenuIndexAddManualy,
- SubmenuIndexDebug,
};
void nfc_scene_start_submenu_callback(void* context, uint32_t index) {
Nfc* nfc = (Nfc*)context;
- view_dispatcher_send_custom_event(nfc->nfc_common.view_dispatcher, index);
+ view_dispatcher_send_custom_event(nfc->view_dispatcher, index);
}
const void nfc_scene_start_on_enter(void* context) {
@@ -30,11 +29,11 @@ const void nfc_scene_start_on_enter(void* context) {
submenu, "Saved cards", SubmenuIndexSaved, nfc_scene_start_submenu_callback, nfc);
submenu_add_item(
submenu, "Add manually", SubmenuIndexAddManualy, nfc_scene_start_submenu_callback, nfc);
- submenu_add_item(submenu, "Debug", SubmenuIndexDebug, nfc_scene_start_submenu_callback, nfc);
submenu_set_selected_item(
submenu, scene_manager_get_scene_state(nfc->scene_manager, NfcSceneStart));
- view_dispatcher_switch_to_view(nfc->nfc_common.view_dispatcher, NfcViewMenu);
+ nfc_device_clear(&nfc->dev);
+ view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewMenu);
}
const bool nfc_scene_start_on_event(void* context, SceneManagerEvent event) {
@@ -59,10 +58,6 @@ const bool nfc_scene_start_on_event(void* context, SceneManagerEvent event) {
nfc->scene_manager, NfcSceneStart, SubmenuIndexAddManualy);
scene_manager_next_scene(nfc->scene_manager, NfcSceneSetType);
return true;
- } else if(event.event == SubmenuIndexDebug) {
- scene_manager_set_scene_state(nfc->scene_manager, NfcSceneStart, SubmenuIndexDebug);
- scene_manager_next_scene(nfc->scene_manager, NfcSceneDebugMenu);
- return true;
}
}
return false;
diff --git a/applications/nfc/views/bank_card.c b/applications/nfc/views/bank_card.c
new file mode 100755
index 00000000..3d78da26
--- /dev/null
+++ b/applications/nfc/views/bank_card.c
@@ -0,0 +1,65 @@
+#include "bank_card.h"
+#include "../gui_widget/gui_widget.h"
+#include <m-string.h>
+
+struct BankCard {
+ GuiWidget* widget;
+};
+
+BankCard* bank_card_alloc() {
+ BankCard* bank_card = furi_alloc(sizeof(BankCard));
+ bank_card->widget = gui_widget_alloc();
+ return bank_card;
+}
+
+void bank_card_free(BankCard* bank_card) {
+ furi_assert(bank_card);
+ gui_widget_free(bank_card->widget);
+ free(bank_card);
+}
+
+View* bank_card_get_view(BankCard* bank_card) {
+ furi_assert(bank_card);
+ return gui_widget_get_view(bank_card->widget);
+}
+
+void bank_card_clear(BankCard* bank_card) {
+ furi_assert(bank_card);
+ gui_widget_clear(bank_card->widget);
+}
+
+void bank_card_set_name(BankCard* bank_card, char* name) {
+ furi_assert(bank_card);
+ furi_assert(name);
+ gui_widget_add_string_element(
+ bank_card->widget, 64, 6, AlignCenter, AlignTop, FontSecondary, name);
+}
+
+void bank_card_set_number(BankCard* bank_card, uint8_t* number) {
+ furi_assert(bank_card);
+ furi_assert(number);
+ string_t num_str;
+ string_init(num_str);
+ for(uint8_t i = 0; i < 8; i += 2) {
+ string_cat_printf(num_str, "%02X%02X ", number[i], number[i + 1]);
+ }
+ gui_widget_add_string_element(
+ bank_card->widget, 25, 22, AlignLeft, AlignTop, FontSecondary, string_get_cstr(num_str));
+ gui_widget_add_icon_element(bank_card->widget, 6, 20, &I_EMV_Chip_14x11);
+ string_clear(num_str);
+}
+
+void bank_card_set_exp_date(BankCard* bank_card, uint8_t mon, uint16_t year) {
+ furi_assert(bank_card);
+ char exp_date_str[16];
+ snprintf(exp_date_str, sizeof(exp_date_str), "Exp: %02d/%02d", mon, year % 100);
+ gui_widget_add_string_element(
+ bank_card->widget, 122, 54, AlignRight, AlignBottom, FontSecondary, exp_date_str);
+}
+
+void bank_card_set_cardholder_name(BankCard* bank_card, char* name) {
+ furi_assert(bank_card);
+ furi_assert(name);
+ gui_widget_add_string_element(
+ bank_card->widget, 6, 37, AlignLeft, AlignTop, FontSecondary, name);
+}
diff --git a/applications/nfc/views/bank_card.h b/applications/nfc/views/bank_card.h
new file mode 100644
index 00000000..40472c87
--- /dev/null
+++ b/applications/nfc/views/bank_card.h
@@ -0,0 +1,23 @@
+#pragma once
+#include <stdint.h>
+#include <gui/view.h>
+
+typedef struct BankCard BankCard;
+
+typedef void (*BankCardBackCallback)(void);
+
+BankCard* bank_card_alloc();
+
+void bank_card_free(BankCard* bank_card);
+
+void bank_card_clear(BankCard* bank_card);
+
+View* bank_card_get_view(BankCard* bank_card);
+
+void bank_card_set_name(BankCard* bank_card, char* name);
+
+void bank_card_set_number(BankCard* bank_card, uint8_t* number);
+
+void bank_card_set_exp_date(BankCard* bank_card, uint8_t mon, uint16_t year);
+
+void bank_card_set_cardholder_name(BankCard* bank_card, char* name);
diff --git a/applications/nfc/views/nfc_detect.c b/applications/nfc/views/nfc_detect.c
deleted file mode 100755
index 8069ce77..00000000
--- a/applications/nfc/views/nfc_detect.c
+++ /dev/null
@@ -1,142 +0,0 @@
-#include "nfc_detect.h"
-
-#include <furi.h>
-#include <api-hal.h>
-#include <input/input.h>
-
-#include "../nfc_i.h"
-
-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);
-}
-
-bool nfc_detect_view_custom(uint32_t event, void* context) {
- furi_assert(context);
-
- NfcDetect* nfc_detect = (NfcDetect*)context;
- if(event == NfcEventDetect) {
- NfcDeviceData* data = (NfcDeviceData*)&nfc_detect->nfc_common->worker_result;
-
- with_view_model(
- nfc_detect->view, (NfcDetectModel * model) {
- model->found = true;
- model->data = *data;
- return true;
- });
- // TODO add and configure next view model
- return false;
- }
-
- return false;
-}
-
-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->nfc_common->worker_result,
- 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);
-}
-
-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_custom_callback(nfc_detect->view, nfc_detect_view_custom);
- view_set_enter_callback(nfc_detect->view, nfc_detect_enter);
- view_set_exit_callback(nfc_detect->view, nfc_detect_exit);
-
- 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/views/nfc_detect.h b/applications/nfc/views/nfc_detect.h
deleted file mode 100644
index 5ae6660f..00000000
--- a/applications/nfc/views/nfc_detect.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#pragma once
-
-#include <gui/view.h>
-#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);
diff --git a/applications/nfc/views/nfc_emulate.c b/applications/nfc/views/nfc_emulate.c
deleted file mode 100755
index 7dcac2da..00000000
--- a/applications/nfc/views/nfc_emulate.c
+++ /dev/null
@@ -1,79 +0,0 @@
-#include "nfc_emulate.h"
-
-#include <furi.h>
-#include <api-hal.h>
-#include <input/input.h>
-
-#include "../nfc_i.h"
-
-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,
- &nfc_emulate->nfc_common->worker_result,
- NULL,
- NULL);
-}
-
-void nfc_emulate_exit(void* context) {
- furi_assert(context);
-
- NfcEmulate* nfc_emulate = (NfcEmulate*)context;
- nfc_worker_stop(nfc_emulate->nfc_common->worker);
-}
-
-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);
-
- 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/views/nfc_emulate.h b/applications/nfc/views/nfc_emulate.h
deleted file mode 100644
index 660fdae7..00000000
--- a/applications/nfc/views/nfc_emulate.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#pragma once
-
-#include <gui/view.h>
-#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/views/nfc_emv.c b/applications/nfc/views/nfc_emv.c
deleted file mode 100755
index 7e9dc026..00000000
--- a/applications/nfc/views/nfc_emv.c
+++ /dev/null
@@ -1,133 +0,0 @@
-#include "nfc_emv.h"
-
-#include <furi.h>
-#include <api-hal.h>
-#include <input/input.h>
-
-#include "../nfc_i.h"
-
-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);
-}
-
-bool nfc_emv_custom(uint32_t event, void* context) {
- furi_assert(context);
-
- NfcEmv* nfc_emv = (NfcEmv*)context;
- if(event == NfcEventEmv) {
- NfcEmvData* data = (NfcEmvData*)&nfc_emv->nfc_common->worker_result;
-
- with_view_model(
- nfc_emv->view, (NfcEmvModel * model) {
- model->found = true;
- model->emv_data = *data;
- return true;
- });
- // TODO add and configure next view model
- return true;
- }
-
- return false;
-}
-
-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->nfc_common->worker_result,
- 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);
-}
-
-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_custom_callback(nfc_emv->view, nfc_emv_custom);
- view_set_enter_callback(nfc_emv->view, nfc_emv_enter);
- view_set_exit_callback(nfc_emv->view, nfc_emv_exit);
-
- 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/views/nfc_emv.h b/applications/nfc/views/nfc_emv.h
deleted file mode 100644
index e348ce98..00000000
--- a/applications/nfc/views/nfc_emv.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#pragma once
-
-#include <gui/view.h>
-#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);
diff --git a/applications/nfc/views/nfc_mifare_ul.c b/applications/nfc/views/nfc_mifare_ul.c
deleted file mode 100755
index ea47b6fd..00000000
--- a/applications/nfc/views/nfc_mifare_ul.c
+++ /dev/null
@@ -1,162 +0,0 @@
-#include "nfc_mifare_ul.h"
-
-#include <furi.h>
-#include <api-hal.h>
-#include <input/input.h>
-
-#include "../nfc_i.h"
-
-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);
-}
-
-bool nfc_mifare_ul_custom(uint32_t event, void* context) {
- furi_assert(context);
-
- NfcMifareUl* nfc_mifare_ul = (NfcMifareUl*)context;
- if(event == NfcEventMifareUl) {
- NfcMifareUlData* data = (NfcMifareUlData*)&nfc_mifare_ul->nfc_common->worker_result;
-
- with_view_model(
- nfc_mifare_ul->view, (NfcMifareUlModel * model) {
- model->found = true;
- model->nfc_mf_ul_data = *data;
- return true;
- });
- // TODO add and configure next view model
- return true;
- }
-
- return false;
-}
-
-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->nfc_common->worker_result,
- 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);
-}
-
-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_custom_callback(nfc_mifare_ul->view, nfc_mifare_ul_custom);
- view_set_enter_callback(nfc_mifare_ul->view, nfc_mifare_ul_enter);
- view_set_exit_callback(nfc_mifare_ul->view, nfc_mifare_ul_exit);
-
- 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/views/nfc_mifare_ul.h b/applications/nfc/views/nfc_mifare_ul.h
deleted file mode 100644
index eb666e08..00000000
--- a/applications/nfc/views/nfc_mifare_ul.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#pragma once
-
-#include <gui/view.h>
-#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);