First actual NFC read/poll implementation

Signed-off-by: Markus Birth <markus@birth-online.de>
This commit is contained in:
2026-03-20 10:13:10 +00:00
parent a9015c97a4
commit 066952bf72
6 changed files with 113 additions and 6 deletions
+5
View File
@@ -0,0 +1,5 @@
Sonicare Brush Head ID
======================
NTAG213
ISO 14443-3 (NFC-A)
+1
View File
@@ -1,3 +1,4 @@
ADD_SCENE(sonicare, start, Start)
ADD_SCENE(sonicare, about, About)
ADD_SCENE(sonicare, read, Read)
ADD_SCENE(sonicare, read_complete, ReadComplete)
+64 -5
View File
@@ -1,28 +1,87 @@
#include "../uk_mbirth_sonicare.h"
#include "core/core_defines.h"
#include "gui/scene_manager.h"
#include "gui/view_dispatcher.h"
#include "nfc/nfc.h"
#include "nfc/nfc_scanner.h"
#include "notification/notification.h"
#include <nfc/protocols/nfc_protocol.h>
#include <nfc/protocols/iso14443_3a/iso14443_3a_poller.h>
#include <dolphin/dolphin.h>
//#include <nfc/helpers/protocol_support/nfc_protocol_support_common.h>
void nfc_scene_detect_scan_callback(NfcScannerEvent event, void* context) {
furi_assert(context);
Sonicare* app = context;
if (event.type == NfcScannerEventTypeDetected) {
//nfc_detected_protocols_set(app->detected_protocols, event.data.protocols, event.data.protocol_num);
view_dispatcher_send_custom_event(app->view_dispatcher, NfcCustomEventWorkerExit);
}
}
NfcCommand nfc_scene_poller_callback(NfcGenericEvent event, void* context) {
furi_assert(event.protocol == NfcProtocolIso14443_3a);
Sonicare* app = context;
const Iso14443_3aPollerEvent* ev = event.event_data;
if (ev->type == Iso14443_3aPollerEventTypeReady) {
view_dispatcher_send_custom_event(app->view_dispatcher, NfcCustomEventWorkerExit);
return NfcCommandStop;
}
return NfcCommandContinue;
}
void sonicare_scene_read_on_enter(void* context) {
Sonicare* app = context;
Popup* popup = app->popup;
popup_reset(app->popup);
popup_set_header(app->popup, "Reading", 97, 15, AlignCenter, AlignTop);
popup_set_text(app->popup, "Hold brush stem next\nto Flipper's back", 94, 27, AlignCenter, AlignTop);
popup_reset(popup);
popup_set_header(popup, "Reading", 97, 15, AlignCenter, AlignTop);
popup_set_text(popup, "Hold brush stem next\nto Flipper's back", 94, 27, AlignCenter, AlignTop);
//popup_set_icon(app->popup, 0, 8, &I_NFC_manual_60x50);
view_dispatcher_switch_to_view(app->view_dispatcher, SonicareViewPopup);
//nfc_detected_protocols_reset(app->detected_protocols);
app->nfc = nfc_alloc();
// we probably don't need to "scan" but can instead directly "poll" for NTAG213 (ISO 14443-3a) data
//app->scanner = nfc_scanner_alloc(app->nfc);
//nfc_scanner_start(app->scanner, nfc_scene_detect_scan_callback, app);
app->poller = nfc_poller_alloc(app->nfc, NfcProtocolIso14443_3a);
nfc_poller_start(app->poller, nfc_scene_poller_callback, app);
}
bool sonicare_scene_read_on_event(void* context, SceneManagerEvent event) {
Sonicare* app = context;
UNUSED(app);
UNUSED(event);
bool consumed = false;
if (event.type == SceneManagerEventTypeCustom) {
if (event.event == NfcCustomEventWorkerExit) {
//if (nfc_detected_protocols_get_num(app->detected_protocols) > 1) {
if (true) {
notification_message(app->notifications, &sequence_single_vibro);
scene_manager_next_scene(app->scene_manager, SonicareSceneReadComplete);
} else {
scene_manager_next_scene(app->scene_manager, SonicareSceneReadComplete);
}
consumed = true;
}
}
return consumed;
}
void sonicare_scene_read_on_exit(void* context) {
Sonicare* app = context;
//notification_message(app->notifications, &sequence_blink_stop);
nfc_poller_stop(app->poller);
nfc_poller_free(app->poller);
//nfc_scanner_stop(app->scanner);
//nfc_scanner_free(app->scanner);
nfc_free(app->nfc);
popup_reset(app->popup);
}
+28
View File
@@ -0,0 +1,28 @@
#include "../uk_mbirth_sonicare.h"
#include "gui/canvas.h"
#include <uk_mbirth_sonicare_icons.h>
#include <dolphin/dolphin.h>
void sonicare_scene_read_complete_on_enter(void* context) {
Sonicare* app = context;
Widget* widget = app->widget;
widget_add_icon_element(widget, 128-17, 0, &I_sonicare_brush);
widget_add_string_element(widget, 0, 0, AlignLeft, AlignTop, FontPrimary, "Sonicare Brush ID");
widget_add_string_element(widget, 0, 12, AlignLeft, AlignTop, FontSecondary, "by mbirth.uk");
widget_add_icon_element(widget, 8, 35, &I_sonicare_qr);
view_dispatcher_switch_to_view(app->view_dispatcher, SonicareViewWidget);
}
bool sonicare_scene_read_complete_on_event(void* context, SceneManagerEvent event) {
UNUSED(context);
UNUSED(event);
bool consumed = false;
return consumed;
}
void sonicare_scene_read_complete_on_exit(void* context) {
Sonicare* app = context;
widget_reset(app->widget);
}
+1 -1
View File
@@ -30,7 +30,7 @@ bool sonicare_scene_start_on_event(void* context, SceneManagerEvent event) {
if (event.event == SonicareMenuIndexRead) {
scene_manager_set_scene_state(app->scene_manager, SonicareSceneStart, SonicareMenuIndexRead);
scene_manager_next_scene(app->scene_manager, SonicareSceneRead);
//dolphin_deed(DolphinDeedNfcRead);
dolphin_deed(DolphinDeedNfcRead);
consumed = true;
} else if (event.event == SonicareMenuIndexAbout) {
scene_manager_set_scene_state(app->scene_manager, SonicareSceneStart, SonicareMenuIndexAbout);
+14
View File
@@ -25,6 +25,10 @@
#include "scenes/sonicare_scene.h"
#include <nfc/nfc_poller.h>
#include <nfc/nfc_scanner.h>
#include <nfc/nfc_listener.h>
typedef struct Sonicare Sonicare;
struct Sonicare {
@@ -42,6 +46,12 @@ struct Sonicare {
Popup* popup;
TextInput* text_input;
ByteInput* byte_input;
// NFC
Nfc* nfc;
NfcPoller* poller;
NfcScanner* scanner;
NfcListener* listener;
};
typedef enum {
@@ -62,4 +72,8 @@ typedef enum {
SonicareMenuIndexExtraActions,
} SonicareMenuIndex;
typedef enum {
NfcCustomEventWorkerExit,
} NfcCustomEvent;
void sonicare_widget_callback(GuiButtonType result, InputType type, void* context);