]> rtime.felk.cvut.cz Git - coffee/mt-apps.git/blob - mt_rfid.c
2741277302ccaf6de545d475d98701e04d833866
[coffee/mt-apps.git] / mt_rfid.c
1 /**
2  * mt_rfid.c
3  * poll the uFR reader and print JSON formatted card info to stdout.
4  */
5
6 // shit to avoid constant repetition
7 #define CONCAT_AGAIN(A,B) A ## B
8 #define CONCAT(A,B) CONCAT_AGAIN(A,B)
9
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <unistd.h>
13 #include <fcntl.h>
14 #include <termios.h>
15 #include <sys/ioctl.h>
16
17 #include <ev.h>
18 #include <uFCoder.h>
19
20 #include "mt_rfid.h"
21
22 int set_nonblock(int fd)
23 {
24     int flags = fcntl(fd, F_GETFL, 0);
25     if (flags == -1) {
26         perror("fcntl (get)");
27         return -1;
28     }
29     if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) {
30         perror("fcntl (set)");
31         return -1;
32     }
33     fprintf(stderr, "set non-blocking\n");
34     return 0;
35 }
36
37 int set_rts(int fd, int level)
38 {
39     int uart_status;
40
41     if (ioctl(fd, TIOCMGET, &uart_status) == -1) {
42         perror("ioctl (TIOCMGET)");
43         return -1;
44     }
45
46     if (level) {
47         uart_status |= TIOCM_RTS;
48     } else {
49         uart_status &= ~TIOCM_RTS;
50     }
51
52     if (ioctl(fd, TIOCMSET, &uart_status) == -1) {
53         perror("TIOCMSET");
54         return -1;
55     }
56
57     fprintf(stderr, "set rts %d\n", level);
58
59     return 0;
60 }
61
62 void set_baud_rate(int fd, int br)
63 {
64     struct termios options;
65
66     tcgetattr(fd, &options);
67     cfsetispeed(&options, br);
68     cfsetospeed(&options, br);
69     tcsetattr(fd, TCSANOW, &options);
70 }
71
72 int tty_open(const char *port, int baud_rate)
73 {
74
75     int fd = open(port, O_RDONLY | O_NOCTTY);
76     if (fd < 0) {
77         perror("open");
78         return fd;
79     } else {
80         fprintf(stderr, "opened %s as %d\n", port, fd);
81     }
82
83     set_nonblock(fd);
84     set_rts(fd, 0);
85     set_baud_rate(fd, baud_rate);
86     usleep(1200000); //value by d-logic
87     tcflush(fd, TCIFLUSH);
88
89     return fd;
90 }
91
92 typedef struct ev_io_ufr {
93     ev_io w;
94     //lws_context *context;
95     //ufr_session_data *session_data;
96     char uid_data[24];
97     char *uid;
98     int fd;
99 } ev_io_ufr;
100
101 static void sigint_cb(EV_P_ ev_signal *w, int revents)
102 {
103     ev_break(EV_A_  EVBREAK_ALL);
104 }
105
106 static void ufr_read(char *uid, int fd)
107 {
108     UFR_STATUS status;
109     uint8_t card_type;
110     uint8_t sak;           //select acknowledge
111     uint8_t uid_bytes[10]; //uid as bytes
112     uint8_t size;
113         char *type = "rfid";
114
115     status = GetDlogicCardType(&card_type);
116     if (status != UFR_OK) {
117         fprintf(stderr, "GetDlogicCardType: %s\n", UFR_Status2String(status));
118         return;
119     }
120
121     status = GetCardIdEx(&sak, uid_bytes, &size);
122     if (status != UFR_OK) {
123         fprintf(stderr, "GetCardIdEx: %s\n", UFR_Status2String(status));
124         return;
125     }
126
127     JSON_START();
128         JSON_STR(type);
129         JSON_NEXT();
130     JSON_NUM(card_type);
131     JSON_NEXT();
132     JSON_NUM(sak);
133     JSON_NEXT();
134     JSON_NUM(size);
135     JSON_NEXT();
136     JSON_STR(uid);
137     JSON_END();
138
139 #ifdef UFR_BEEP
140     ReaderUISignal(0, 1); // no light, one beep
141 #endif
142
143     /*lws_callback_on_writable_all_protocol(self->context,
144                                           &protocols[PROTOCOL_DUMB_INCREMENT]);*/
145 }
146
147 static void ufr_cb(EV_P_ ev_io *w_, int revents)
148 {
149     ev_io_ufr *w = (ev_io_ufr *)w_;
150     char uid;
151     read(w->w.fd, &uid, 1);
152     *(w->uid)++ = uid;
153
154     if (uid == ASYNC_SUFFIX) {
155         //*(w->uid - 1) = 0;
156         w->uid = w->uid_data;
157         ufr_read(w->uid, w->fd);
158     }
159
160     //for one-shot events, one must manually stop the watcher with its corresponding stop function.
161     //ev_io_stop (EV_A_ w);
162
163     //this causes all nested ev_run's to stop iterating
164     //ev_break (EV_A_ EVBREAK_ALL);
165 }
166
167 ev_io_ufr ufr_watcher;
168 ev_signal int_watcher, term_watcher;
169
170 int libev_run(int fd)
171 {
172     struct ev_loop *loop = EV_DEFAULT;
173
174     ufr_watcher.uid = ufr_watcher.uid_data;
175     ufr_watcher.fd = 1;
176     ev_io_init(&(ufr_watcher.w), ufr_cb, fd, EV_READ);
177     ev_io_start(loop, (ev_io *)&ufr_watcher);
178
179     ev_signal_init(&int_watcher, sigint_cb, SIGINT);
180     ev_signal_start(loop, &int_watcher);
181     ev_signal_init(&term_watcher, sigint_cb, SIGTERM);
182     ev_signal_start(loop, &term_watcher);
183
184     ev_run(loop, 0);
185
186     return 0;
187 }
188
189 int ufr_open(unsigned reader_type, char *port_name, unsigned port_interface)
190 {
191     UFR_STATUS status;
192
193     fprintf(stderr, "uFCoder version: %s\n", GetDllVersionStr());
194
195     status = ReaderOpenEx(reader_type, port_name, port_interface, 0);
196     if (status != UFR_OK) {
197         fprintf(stderr, "ReaderOpenEx: %s\n", UFR_Status2String(status));
198         return -1;
199     }
200
201     fprintf(stderr, "%s\n", GetReaderDescription());
202
203     status = SetAsyncCardIdSendConfig(
204                  1,            //enable send
205                  0,            //disable prefix
206                  0,            //prefix
207                  ASYNC_SUFFIX, //suffix
208                  0,            //disable send removed
209                  ASYNC_BAUD_RATE
210              );
211     fprintf(stderr, "SetAsyncCardIdSendConfig: %s\n", UFR_Status2String(status));
212     if (status != UFR_OK) {
213         return -1;
214     }
215
216     return 0;
217 }
218
219 int main(int argc, char **argv)
220 {
221     if (ufr_open(READER_TYPE, PORT_NAME, PORT_INTERFACE) == -1) {
222         return -1;
223     }
224
225     int fd = tty_open(PORT_NAME, CONCAT(B, ASYNC_BAUD_RATE));
226     if (fd < 0) {
227         return -2;
228     }
229
230     libev_run(fd);
231
232     if (close(fd) == 0) {
233         fprintf(stderr, "closed %d\n", fd);
234     } else {
235         perror("close");
236     }
237
238     UFR_STATUS status;
239     status = ReaderClose();
240     fprintf(stderr, "ReaderClose: %s\n", UFR_Status2String(status));
241
242     return 0;
243 }
244
245 /* other tty options
246     //Enable the receiver and set local mode...
247     options.c_cflag |= (CLOCAL | CREAD);
248
249     options.c_cflag &= ~PARENB;
250     options.c_cflag &= ~CSTOPB;
251     options.c_cflag &= ~CSIZE;
252     options.c_cflag |= CS8;
253     options.c_cflag &= ~CRTSCTS;
254     options.c_lflag |= (ICANON | ECHO | ECHOE);
255     //Disable XON/XOFF both i/p and o/p
256     options.c_iflag &= ~(IXON | IXOFF | IXANY);
257     //Non Cannon mode
258     options.c_iflag &= ~(ICANON | ECHO | ECHOE | ISIG);
259
260     options.c_oflag |= OPOST;
261 */
262