summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcbdev <cb@cbcdn.com>2023-06-21 00:36:33 +0200
committercbdev <cb@cbcdn.com>2023-06-21 00:36:33 +0200
commitcb686cd6314d3e181bd91c0f2d449750c9429be7 (patch)
tree4f360bb0da5648ee769fb318f4d2ad77831d5a88
parent0da2f58c7528b504ee54e380b755ea5f0801b4bb (diff)
downloadnfcommander-cb686cd6314d3e181bd91c0f2d449750c9429be7.tar.gz
nfcommander-cb686cd6314d3e181bd91c0f2d449750c9429be7.tar.bz2
nfcommander-cb686cd6314d3e181bd91c0f2d449750c9429be7.zip
Formalize tag status flags
-rw-r--r--api_reader.txt39
-rw-r--r--nfcommander.h7
-rw-r--r--reader.c56
-rw-r--r--reader_yhy.c3
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_<name>.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);