1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
#include <stdio.h>
#include <signal.h>
#include <sys/epoll.h>
#include <unistd.h>
#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 <config-file>\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(fd < 0){
return 0;
}
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])){
//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;
}
//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;
//TODO error checking
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
reader_free();
control_free();
command_free();
config_free();
close(epoll_fd);
epoll_fd = -1;
}
|