From cb686cd6314d3e181bd91c0f2d449750c9429be7 Mon Sep 17 00:00:00 2001 From: cbdev Date: Wed, 21 Jun 2023 00:36:33 +0200 Subject: Formalize tag status flags --- api_reader.txt | 39 +++++++++++++++++++++++++++++++++++++++ nfcommander.h | 7 ++++++- reader.c | 56 +++++++++++++++++++++++++++++++++++++------------------- reader_yhy.c | 3 ++- 4 files changed, 84 insertions(+), 21 deletions(-) diff --git a/api_reader.txt b/api_reader.txt index 2ddc362..8e2fa5a 100644 --- a/api_reader.txt +++ b/api_reader.txt @@ -2,3 +2,42 @@ This API concerns the communication with the active NFC components used for tag reading / writing. Implementing this API allows the project to support new NFC hardware + +## Specification + +Additional readers can be connected by implementing their specifics in a shared library named +`reader_.so`. In the NFCommander configuration, specifying the `nfc.reader` configuration +option sets the reader name that is to be loaded. + +## Interface + +The shared library should export the following symbols and respective prototypes + +* `int init()` : Initialize the reader-specific data structures and communication details +* (optional) `int handle(int fd)` : Callback invoked when a registered descriptor is pending events +* `int scan()` : Invoked to request the current set of tags detectable in the field + +## Operation + +This section will describe the lifecycle of a reader implementation plugin. + +### Initialization + +After the shared library is loaded, the `init` export is called. + +The module should connect to its specific hardware interface and verify that the field is +in operating condition. + +The module may use the `config_get` NFCommander API to read specific configuration options, +such as ports to connect to. + +If necessary, file descriptors and sockets can be registered with the core using the +`core_manage_fd` API. Pending events will be signaled using the libraries `handle` export. + +### Operation + +TBD + +### Cleanup + +TBD diff --git a/nfcommander.h b/nfcommander.h index 049380d..79b8790 100644 --- a/nfcommander.h +++ b/nfcommander.h @@ -15,6 +15,11 @@ typedef enum { tag_ultralightc } nfc_tag_t; +#define FLAG_TAG_DATA_VALID 1 +#define FLAG_TAG_UNPROGRAMMED 2 +#define FLAG_TAG_LOCKED 4 +#define TAG_STATUS_FLAGS ((FLAG_TAG_DATA_VALID | FLAG_TAG_UNPROGRAMMED | FLAG_TAG_LOCKED)) + typedef struct { //core identifying properties nfc_tag_t type; @@ -42,4 +47,4 @@ int core_manage_fd(int fd, int manage, notification_target_t system); * be submitted again with the data fully read. */ #define TAG_READ_REQUESTED 1 -int reader_tag_present(nfc_tag_info_t tag); +int reader_tag_present(uint8_t flags, nfc_tag_info_t tag); diff --git a/reader.c b/reader.c index 0704fca..f37ade4 100644 --- a/reader.c +++ b/reader.c @@ -13,10 +13,8 @@ #define DEFAULT_POLL_TIMEOUT 1000 #define MAX_TAGS 5 -#define FLAG_PRESENT 1 -#define FLAG_FULLY_READ 2 -#define FLAG_UNPROGRAMMED 4 -#define FLAG_ACTIVE 8 +#define FLAG_PRESENT 8 +#define FLAG_ACTIVE 16 static void* reader_module = NULL; static reader_plugin_handle reader_backend_handle = NULL; @@ -99,20 +97,32 @@ static int reader_process(){ size_t n = 0; for(n = 0; n < MAX_TAGS; n++){ if(tags[n].flags & FLAG_PRESENT){ - //TODO verify tag is fully read before pushing - if(!(tags[n].flags & FLAG_ACTIVE)){ //new tag - //TODO - printf("Tag index %lu detected\n", n); tags[n].flags |= FLAG_ACTIVE; + if(tags[n].flags & FLAG_TAG_LOCKED){ + printf("A tag was detected (slot %lu), but no key is known\n", n); + return 0; + } + if(tags[n].flags & FLAG_TAG_UNPROGRAMMED){ + printf("Unprogrammed tag detected (slot %lu)\n", n); + //TODO + return 0; + } + if(tags[n].flags & FLAG_TAG_DATA_VALID){ + printf("Command tag detected (slot %lu)\n", n); + //TODO + return 0; + } + + printf("Tag detected (slot %lu), but no state flags set by reader\n", n); } } else{ if(tags[n].flags & FLAG_ACTIVE){ //tag was removed //TODO - printf("Tag index %lu removed\n", n); + printf("Tag in slot %lu removed\n", n); } //reset all flags @@ -122,32 +132,40 @@ static int reader_process(){ return 0; } -int reader_tag_present(nfc_tag_info_t tag){ +int reader_tag_present(uint8_t flags, nfc_tag_info_t tag){ size_t n = 0; + //sanitize input flags + flags &= (FLAG_TAG_DATA_VALID | FLAG_TAG_UNPROGRAMMED | FLAG_TAG_LOCKED); + //check if tag already known for(n = 0; n < MAX_TAGS; n++){ if((tags[n].flags & (FLAG_PRESENT | FLAG_ACTIVE)) && tags[n].info.uid_length == tag.uid_length && !memcmp(tags[n].info.uid, tag.uid, tag.uid_length)){ - //mark still active + //mark still present tags[n].flags |= FLAG_PRESENT; - //TODO if full data submitted, copy in - - //if data has not yet been fully read, request a full read - return (tags[n].flags & (FLAG_FULLY_READ | FLAG_UNPROGRAMMED)) ? 0 : TAG_READ_REQUESTED; + //if full data submitted, copy in and set flags + if(!(tags[n].flags & TAG_STATUS_FLAGS)){ + if(flags & TAG_STATUS_FLAGS){ + memcpy(&(tags[n].info), &tag, sizeof(tag)); + tags[n].flags |= flags; + return 0; + } + //if data has not yet been fully read, request a full read + return TAG_READ_REQUESTED; + } + return 0; } } //if not, add it for(n = 0; n < MAX_TAGS; n++){ if(!tags[n].flags){ - tags[n].flags |= FLAG_PRESENT; + tags[n].flags |= FLAG_PRESENT | flags; memcpy(&(tags[n].info), &tag, sizeof(tag)); - - //TODO set FULLY_READ flag if necessary - return 0; + return (tags[n].flags & TAG_STATUS_FLAGS) ? 0 : TAG_READ_REQUESTED; } } diff --git a/reader_yhy.c b/reader_yhy.c index 4c332ac..7e0d8c3 100644 --- a/reader_yhy.c +++ b/reader_yhy.c @@ -58,8 +58,9 @@ int scan(){ yhy_sync_select(reader_fd, card.uid, card.uid_length, &sak); //TODO parse ATQA and SAK to detect tag type - if(reader_tag_present(card) == TAG_READ_REQUESTED){ + if(reader_tag_present(0, card) == TAG_READ_REQUESTED){ //TODO read card data + reader_tag_present(FLAG_TAG_LOCKED, card); } yhy_sync_hlta(reader_fd); -- cgit v1.2.3