#include #include #include #include #include #include "nfcommander.h" #include "reader.h" #include "config.h" #define MAX_PLUGIN_PATH NAME_MAX static void* reader_module = NULL; static reader_plugin_handle reader_backend_handle = NULL; static reader_plugin_scan reader_backend_scan = NULL; static int timer_fd = -1; static int reader_init_backend(){ char plugin[MAX_PLUGIN_PATH] = ""; char* reader = config_get("nfc", "reader"); if(!reader){ printf("No reader plugin configured\n"); return -1; } snprintf(plugin, sizeof(plugin), "./reader_%s.so", reader); reader_module = dlopen(plugin, RTLD_NOW); if(!reader_module){ printf("Failed to load reader plugin %s: %s\n", plugin, dlerror()); return -1; } reader_backend_handle = dlsym(reader_module, "handle"); reader_backend_scan = dlsym(reader_module, "scan"); //call initializer reader_plugin_init init = dlsym(reader_module, "init"); if(!reader_backend_scan || !init || init()){ printf("Failed to initialize the reader\n"); return 1; } return 0; } int reader_init(){ //initialize poll timer 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; //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; } core_manage_fd(timer_fd, 1, system_reader); return reader_init_backend(); } int reader_handle(int fd){ uint8_t buffer[1024]; if(fd == timer_fd){ //acknowledge timer read(fd, buffer, sizeof(buffer)); //mark all tags expired //TODO //scan all tags if(reader_backend_scan()){ return 1; } //handle changes in active set //TODO } if(reader_backend_handle){ return reader_backend_handle(fd); } return 0; } void reader_free(){ if(reader_module){ dlclose(reader_module); reader_backend_handle = NULL; reader_backend_scan = NULL; reader_module = NULL; } core_manage_fd(timer_fd, 0, system_reader); close(timer_fd); timer_fd = -1; }