From 4aaf1ef0f82eac9fbafa7dac336c1305e44a5e91 Mon Sep 17 00:00:00 2001 From: Markus Koch Date: Tue, 23 Jul 2019 22:10:22 +0200 Subject: [PATCH] Implement basic scanner prototype --- src/scanner.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++++-- src/scanner.h | 11 ++++++ 2 files changed, 111 insertions(+), 3 deletions(-) diff --git a/src/scanner.c b/src/scanner.c index d9fa32e..88a17bf 100644 --- a/src/scanner.c +++ b/src/scanner.c @@ -1,10 +1,13 @@ #include "scanner.h" +#include struct _YacosScanner { GObject parent_instance; nfc_context *nfc_ctx; nfc_device *nfc_pnd; + + GList *detected_tags; }; G_DEFINE_TYPE(YacosScanner, yacos_scanner, G_TYPE_OBJECT) @@ -15,12 +18,104 @@ enum { }; guint yacos_scanner_signals[SIGNAL_COUNT]; -static gboolean *yacos_scanner_read (gpointer user_data) +static int yacos_scanner_list(YacosScanner *self) +{ + int targets_found; + int i, j; + int mod_id; +#define N_SIMUL_TARGETS 5 /* TODO: Make dynamic */ + nfc_target targets[N_SIMUL_TARGETS]; + union _tag_id { + uint8_t bytes[4]; + uint32_t word; + } tag_id; + struct yacos_scanner_tag *scanner_tag = NULL; + GList *l = NULL; + GList *detected_tags_new = NULL; + int new_tags = 0; + int found = 0; + + const nfc_modulation nmModulations[] = { + { .nmt = NMT_ISO14443A, .nbr = NBR_106 }, + //{ .nmt = NMT_ISO14443B, .nbr = NBR_106 }, + //{ .nmt = NMT_FELICA, .nbr = NBR_212 }, + //{ .nmt = NMT_FELICA, .nbr = NBR_424 }, + { .nmt = NMT_JEWEL, .nbr = NBR_106 }, + }; +#define NMODULATIONS ((int)(sizeof(nmModulations) / sizeof(nfc_modulation))) + + for (mod_id = 0; mod_id < NMODULATIONS; ++mod_id) { + targets_found = nfc_initiator_list_passive_targets(self->nfc_pnd, + nmModulations[mod_id], + targets, + N_SIMUL_TARGETS + ); + for (i = 0; i < targets_found; ++i) { + if (!scanner_tag) + scanner_tag = malloc(sizeof(scanner_tag)); + + scanner_tag->tag_id = 0; + scanner_tag->tag_type = TAG_TYPE_NONE; + + switch (targets[i].nm.nmt) { + case NMT_ISO14443A: + if (targets[i].nti.nai.szUidLen < 4) { + g_warning("Unsupported ISO14443A tag. (UID less than 4 bytes)"); + break; + } + memcpy((char*) &scanner_tag->tag_id, targets[i].nti.nai.abtUid, 4); // Dirty but should work + scanner_tag->tag_type = TAG_TYPE_ID; + break; + case NMT_JEWEL: + memcpy((char*) &scanner_tag->tag_id, targets[i].nti.nji.btId, 4); // Dirty but should work + scanner_tag->tag_type = TAG_TYPE_ITEM; + break; + default: + g_warning("Unsupported tag type: %x", targets[i].nm.nmt); + } + + if (scanner_tag->tag_type != TAG_TYPE_NONE) { + for (l = self->detected_tags; l != NULL; l = l->next) { + found = 0; + if (((struct yacos_scanner_tag*)l->data)->tag_id == scanner_tag->tag_id) { + found = 1; + break; + } + } + if (!found) { + new_tags = 1; + } + detected_tags_new = g_list_append(detected_tags_new, scanner_tag); + scanner_tag = NULL; + } + } + + if (scanner_tag) + free(scanner_tag); + } + + if (self->detected_tags) + g_list_free_full(self->detected_tags, free); + self->detected_tags = detected_tags_new; + + if (new_tags) { + for (l = self->detected_tags; l != NULL; l = l->next) { + g_warning("Found %x (%d)", + ((struct yacos_scanner_tag*)l->data)->tag_id, + ((struct yacos_scanner_tag*)l->data)->tag_type); + } + } + + return new_tags; +} + +static gboolean yacos_scanner_read(gpointer user_data) { YacosScanner *self = YACOS_SCANNER(user_data); // TODO: Scan for tags - g_signal_emit(self, yacos_scanner_signals[SIGNAL_NEWTAG], 0); + if (yacos_scanner_list(self)) // TODO: Make this a GTask + g_signal_emit(self, yacos_scanner_signals[SIGNAL_NEWTAG], 0); return G_SOURCE_CONTINUE; } @@ -55,6 +150,8 @@ static void yacos_scanner_class_init(YacosScannerClass *klass) static void yacos_scanner_init(YacosScanner *self) { + self->detected_tags = NULL; + g_debug("Using libnfc %s", nfc_version()); nfc_init(&self->nfc_ctx); if (!self->nfc_ctx) { @@ -67,7 +164,7 @@ static void yacos_scanner_init(YacosScanner *self) return; } - g_timeout_add(1000, G_SOURCE_FUNC(yacos_scanner_read), self); + g_timeout_add(100, G_SOURCE_FUNC(yacos_scanner_read), self); } YacosScanner *yacos_scanner_new(void) diff --git a/src/scanner.h b/src/scanner.h index f90d3ff..efb2fa1 100644 --- a/src/scanner.h +++ b/src/scanner.h @@ -11,6 +11,17 @@ G_DECLARE_FINAL_TYPE(YacosScanner, yacos_scanner, YACOS, SCANNER, GObject) YacosScanner *yacos_scanner_new(void); +enum YACOS_SCANNER_TAG_TYPE { + TAG_TYPE_NONE = 0, + TAG_TYPE_ITEM, + TAG_TYPE_ID +}; + +struct yacos_scanner_tag { + uint32_t tag_id; // TODO: Maybe make this a uint64 + enum YACOS_SCANNER_TAG_TYPE tag_type; +}; + G_END_DECLS #endif // SCANNER_H