#include #include #include #include #include "nfcommander.h" #include "config.h" #include "reader.h" #include "control.h" #include "command.h" typedef union { struct { uint32_t system; uint32_t fd; } components; uint64_t u64; } epoll_private_t; static volatile sig_atomic_t shutdown_requested = 0; static int epoll_fd = -1; static void signal_handler(int signum){ shutdown_requested = 1; } static int usage(char* fn){ printf("NFCommander %s - trigger actions based on near-field tags\n", NFCOMMANDER_VERSION); printf("\tUsage: %s \n", fn); return EXIT_FAILURE; } int core_manage_fd(int fd, int manage, notification_target_t system){ epoll_private_t data = { .components.system = system, .components.fd = fd }; struct epoll_event event = { .events = EPOLLIN, .data.u64 = data.u64 }; if(epoll_ctl(epoll_fd, manage ? EPOLL_CTL_ADD : EPOLL_CTL_DEL, fd, &event)){ fprintf(stderr, "Failed to modify epoll instance\n"); shutdown_requested = 1; return 1; } return 0; } int main(int argc, char** argv){ size_t n; int event_count; epoll_private_t polldata; if(argc < 2){ return usage(argv[0]); } //set up epoll instance struct epoll_event events[10]; epoll_fd = epoll_create1(EPOLL_CLOEXEC); if(epoll_fd < 0){ printf("Failed to create epoll instance\n"); return EXIT_FAILURE; } //read configuration if(config_read(argv[1])){ return usage(argv[0]); } //start reader api reader_init(); //start control api control_start(); //handle signals signal(SIGINT, signal_handler); signal(SIGPIPE, SIG_IGN); //handle events while(!shutdown_requested){ event_count = epoll_wait(epoll_fd, events, sizeof(events) / sizeof(struct epoll_event), 1000); if(event_count < 0){ break; } for(n = 0; n < event_count; n++){ polldata.u64 = events[n].data.u64; switch(polldata.components.system){ case system_control: control_handle(polldata.components.fd); break; case system_reader: reader_handle(polldata.components.fd); break; case system_command: command_handle(polldata.components.fd); break; default: printf("Unhandled target system for fd %d\n", polldata.components.fd); break; } } } //clean up close(epoll_fd); epoll_fd = -1; reader_free(); control_free(); command_free(); config_free(); }