Implement basic scanner prototype

This commit is contained in:
Markus Koch 2019-07-23 22:10:22 +02:00
parent f473106695
commit 4aaf1ef0f8
2 changed files with 111 additions and 3 deletions

View File

@ -1,10 +1,13 @@
#include "scanner.h" #include "scanner.h"
#include <glib/glist.h>
struct _YacosScanner { struct _YacosScanner {
GObject parent_instance; GObject parent_instance;
nfc_context *nfc_ctx; nfc_context *nfc_ctx;
nfc_device *nfc_pnd; nfc_device *nfc_pnd;
GList *detected_tags;
}; };
G_DEFINE_TYPE(YacosScanner, yacos_scanner, G_TYPE_OBJECT) G_DEFINE_TYPE(YacosScanner, yacos_scanner, G_TYPE_OBJECT)
@ -15,12 +18,104 @@ enum {
}; };
guint yacos_scanner_signals[SIGNAL_COUNT]; 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); YacosScanner *self = YACOS_SCANNER(user_data);
// TODO: Scan for tags // 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; return G_SOURCE_CONTINUE;
} }
@ -55,6 +150,8 @@ static void yacos_scanner_class_init(YacosScannerClass *klass)
static void yacos_scanner_init(YacosScanner *self) static void yacos_scanner_init(YacosScanner *self)
{ {
self->detected_tags = NULL;
g_debug("Using libnfc %s", nfc_version()); g_debug("Using libnfc %s", nfc_version());
nfc_init(&self->nfc_ctx); nfc_init(&self->nfc_ctx);
if (!self->nfc_ctx) { if (!self->nfc_ctx) {
@ -67,7 +164,7 @@ static void yacos_scanner_init(YacosScanner *self)
return; 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) YacosScanner *yacos_scanner_new(void)

View File

@ -11,6 +11,17 @@ G_DECLARE_FINAL_TYPE(YacosScanner, yacos_scanner, YACOS, SCANNER, GObject)
YacosScanner *yacos_scanner_new(void); 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 G_END_DECLS
#endif // SCANNER_H #endif // SCANNER_H