From de9c58c92c29f9498c9e91a1a1b918261135d31b Mon Sep 17 00:00:00 2001 From: cbdev Date: Sun, 18 Jun 2023 21:10:03 +0200 Subject: Basic reader interface --- README.txt | 3 +++ commander.cfg | 4 ++-- nfcommander.c | 3 +++ nfcommander.h | 21 +++++++++++++++++ reader.c | 16 ++++++++++--- reader_yhy.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++++---- reader_yhy.h | 2 ++ 7 files changed, 113 insertions(+), 10 deletions(-) diff --git a/README.txt b/README.txt index 22dabf9..2f9e7ef 100644 --- a/README.txt +++ b/README.txt @@ -24,3 +24,6 @@ This project has three distinct APIs * Maybe we should use NDEF on the tag instead of yet another custom format * It might be useful to implement support for hardware button passthrough to commands + +* Who should manage the active tags list - plugins or core +* Should reader plugins report the full list of tags periodically or only changes in the field? diff --git a/commander.cfg b/commander.cfg index 4576bd9..f466c02 100644 --- a/commander.cfg +++ b/commander.cfg @@ -1,9 +1,9 @@ [nfc] reader=yhy -device=/dev/ttyACM0 +device=/dev/ttyUSB0 mifare.defaultkeys=FFFFFFFFFFFF,000000000000 mifare.prodkey=123456123456 -interval=2000 +interval=1000 [control] bind = 0.0.0.0 7812 diff --git a/nfcommander.c b/nfcommander.c index 4763b78..0521fc4 100644 --- a/nfcommander.c +++ b/nfcommander.c @@ -69,18 +69,21 @@ int main(int argc, char** argv){ //read configuration if(config_read(argv[1])){ + //TODO cleanup return usage(argv[0]); } //start reader api if(reader_init()){ printf("Failed to start reader\n"); + //TODO cleanup return EXIT_FAILURE; } //start control api if(control_start()){ printf("Failed to start control interface\n"); + //TODO cleanup return EXIT_FAILURE; } diff --git a/nfcommander.h b/nfcommander.h index 65ca9d2..7990198 100644 --- a/nfcommander.h +++ b/nfcommander.h @@ -6,6 +6,25 @@ #define NFCOMMANDER_VERSION "v0.1-dev" #endif +typedef enum { + tag_unset, + tag_mifare1, + tag_ntag, + tag_desfire, + tag_ultralight, + tag_ultralightc +} nfc_tag_t; + +typedef struct { + //core identifying properties + nfc_tag_t type; + uint8_t uid_length; + uint8_t uid[10]; +} nfc_tag_info_t; + +typedef int (*reader_plugin_init)(void); +typedef int (*reader_plugin_handle)(int fd); + typedef enum { system_control, system_reader, @@ -13,3 +32,5 @@ typedef enum { } notification_target_t; int core_manage_fd(int fd, int manage, notification_target_t system); +int core_tag_present(nfc_tag_info_t tag); +int core_tag_removed(nfc_tag_info_t tag); diff --git a/reader.c b/reader.c index 5472e0f..9064c80 100644 --- a/reader.c +++ b/reader.c @@ -2,11 +2,13 @@ #include #include +#include "nfcommander.h" #include "reader.h" #include "config.h" #define MAX_PLUGIN_PATH NAME_MAX void* reader_module = NULL; +reader_plugin_handle reader_backend_handle = NULL; int reader_init(){ char plugin[MAX_PLUGIN_PATH] = ""; @@ -25,18 +27,26 @@ int reader_init(){ return -1; } + reader_backend_handle = dlsym(reader_module, "handle"); + + //call initializer + reader_plugin_init init = dlsym(reader_module, "init"); + if(!reader_backend_handle || !init || init()){ + printf("Failed to initialize the reader\n"); + return 1; + } + return 0; } int reader_handle(int fd){ - //TODO - printf("Handling data on reader fd\n"); - return 0; + return reader_backend_handle(fd); } void reader_free(){ if(reader_module){ dlclose(reader_module); + reader_backend_handle = NULL; reader_module = NULL; } } diff --git a/reader_yhy.c b/reader_yhy.c index 51ac796..58bd345 100644 --- a/reader_yhy.c +++ b/reader_yhy.c @@ -1,22 +1,86 @@ #include +#include +#include #include "nfcommander.h" #include "config.h" -static void __attribute__((constructor)) init() { - printf("This is the yhy reader plugin\n"); +#include "libyhy.h" +static int reader_fd = -1; +static int timer_fd = -1; + +int init(){ + char reader_version[100]; size_t poll_timeout = 1000; + struct itimerspec timer_cfg = { + 0 + }; + if(config_get("nfc", "interval")){ poll_timeout = strtoul(config_get("nfc", "interval"), NULL, 10); } + timer_cfg.it_value.tv_sec = timer_cfg.it_interval.tv_sec = poll_timeout / 1000; + timer_cfg.it_value.tv_nsec = timer_cfg.it_interval.tv_nsec = (poll_timeout % 1000) * 1e6; + char* port = config_get("nfc", "device"); + if(!port){ + printf("Please configure nfc.device to the reader serial port\n"); + return 1; + } + + //TODO set cloexec, nonblock + printf("Opening %s with polltime %lu\n", port, poll_timeout); + reader_fd = yhy_open(port); + if(reader_fd < 0){ + printf("Failed to open reader connection at %s\n", port); + return 1; + } + + if(yhy_sync_read_version(reader_fd, reader_version, sizeof(reader_version)) > 0){ + printf("Connected YHY reader reports firmware: %s\n", reader_version); + } + + //create timerfd + timer_fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC); + if(timer_fd < 0){ + printf("Failed to create timer fd\n"); + return 1; + } + + if(timerfd_settime(timer_fd, 0, &timer_cfg, NULL)){ + printf("Failed to set timer\n"); + return 1; + } - printf("Opening %s with polltime %d\n", port, poll_timeout); + core_manage_fd(reader_fd, 1, system_reader); + core_manage_fd(timer_fd, 1, system_reader); + + return 0; +} + +int handle(int fd){ + uint8_t buffer[1024]; + + if(fd == timer_fd){ + //acknowledge the timer + read(fd, buffer, sizeof(buffer)); + + //see if there is a tag + //TODO + return 0; + } + printf("Unknown FD in reader_yhy handler\n"); + return 1; } -static void __attribute__((destructor)) cleanup() { - printf("This is the yhy reader plugin cleanup\n"); +static void __attribute__((destructor)) cleanup(){ + core_manage_fd(reader_fd, 0, system_reader); + close(reader_fd); + reader_fd = -1; + core_manage_fd(timer_fd, 0, system_reader); + close(timer_fd); + timer_fd = -1; } diff --git a/reader_yhy.h b/reader_yhy.h index e69de29..7ed6a1f 100644 --- a/reader_yhy.h +++ b/reader_yhy.h @@ -0,0 +1,2 @@ +int init(); +int handle(int fd); -- cgit v1.2.3