]> rtime.felk.cvut.cz Git - coffee/mt-apps.git/blob - mt_rfid.c
Convert RFID printing to a function
[coffee/mt-apps.git] / mt_rfid.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4 #include <fcntl.h>
5 #include <termios.h>
6 #include <sys/ioctl.h>
7
8 #include <uFCoder.h>
9
10 #include "mt_rfid.h"
11 #include "signal_exit.h"
12 #include "json_helpers.h"
13
14 // shit to avoid constant repetition
15 #define CONCAT_AGAIN(A,B) A ## B
16 #define CONCAT(A,B) CONCAT_AGAIN(A,B)
17
18 static int set_nonblock(int fd)
19 {
20     int flags = fcntl(fd, F_GETFL, 0);
21     if (flags == -1) {
22         perror("fcntl (get)");
23         return -1;
24     }
25     if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) {
26         perror("fcntl (set)");
27         return -1;
28     }
29     fprintf(stderr, "set %d non-blocking\n", fd);
30     return 0;
31 }
32
33 static int set_rts(int fd, int level)
34 {
35     int uart_status;
36
37     if (ioctl(fd, TIOCMGET, &uart_status) == -1) {
38         perror("ioctl (TIOCMGET)");
39         return -1;
40     }
41
42     if (level) {
43         uart_status |= TIOCM_RTS;
44     } else {
45         uart_status &= ~TIOCM_RTS;
46     }
47
48     if (ioctl(fd, TIOCMSET, &uart_status) == -1) {
49         perror("TIOCMSET");
50         return -1;
51     }
52
53     fprintf(stderr, "set %d rts %d\n", fd, level);
54
55     return 0;
56 }
57
58 static void set_baud_rate(int fd, int br) //TODO add some checking
59 {
60     struct termios options;
61
62     tcgetattr(fd, &options);
63     cfsetispeed(&options, br);
64     cfsetospeed(&options, br);
65     tcsetattr(fd, TCSANOW, &options);
66 }
67
68 static int tty_open(const char *port, int br)
69 {
70
71     int fd = open(port, O_RDONLY | O_NOCTTY);
72     if (fd < 0) {
73         perror("open");
74         return fd;
75     } else {
76         fprintf(stderr, "opened %s as %d\n", port, fd);
77     }
78
79     set_nonblock(fd);
80     set_rts(fd, 0);        //disable
81     set_baud_rate(fd, br);
82     usleep(1200000);       //value by d-logic
83     tcflush(fd, TCIFLUSH);
84
85     return fd;
86 }
87
88 // print complete json
89 void rfid_json_print(int fd,
90                      uint8_t card_type,
91                      uint8_t sak,           //select acknowledge
92                      char *uid,
93                      uint8_t size)
94 {
95     static const char *type = "rfid";
96
97     JSON_START();
98     JSON_STR(type);
99     JSON_NEXT();
100     JSON_NUM(card_type);
101     JSON_NEXT();
102     JSON_NUM(sak);
103     JSON_NEXT();
104     JSON_NUM(size);
105     JSON_NEXT();
106     JSON_STR(uid);
107     JSON_END();
108 }
109
110 static void ufr_read(char *uid, int fd)
111 {
112     UFR_STATUS status;
113     uint8_t card_type;
114     uint8_t sak;           //select acknowledge
115     uint8_t uid_bytes[10]; //uid as bytes
116     uint8_t size;
117
118     status = GetDlogicCardType(&card_type);
119     if (status != UFR_OK) {
120         fprintf(stderr, "GetDlogicCardType: %s\n", UFR_Status2String(status));
121         return;
122     }
123
124     status = GetCardIdEx(&sak, uid_bytes, &size);
125     if (status != UFR_OK) {
126         fprintf(stderr, "GetCardIdEx: %s\n", UFR_Status2String(status));
127         return;
128     }
129
130     rfid_json_print(fd, card_type, sak, uid, size);
131
132 #ifdef UFR_BEEP
133     ReaderUISignal(0, 1); // no light, one beep
134 #endif
135 }
136
137 #define UFR_ASYNC_SUFFIX 0 // keep it zero: separates uids, terminates strings
138
139 static void ufr_cb(EV_P_ ev_io *w_, int revents)
140 {
141     ev_io_ufr *w = (ev_io_ufr *)w_;
142     char uid;
143
144     read(w->w.fd, &uid, 1);
145     *(w->uid++) = uid;
146
147     if (uid == UFR_ASYNC_SUFFIX) {
148         //*(w->uid - 1) = 0; // no need if UFR_ASYNC_SUFFIX is 0
149         w->uid = w->uid_data;
150         ufr_read(w->uid, w->fd);
151     }
152 }
153
154 static int ufr_open(unsigned reader_type, char *port_name,
155                     unsigned port_interface)
156 {
157     UFR_STATUS status;
158
159     fprintf(stderr, "uFCoder version: %s\n", GetDllVersionStr());
160
161     status = ReaderOpenEx(reader_type, port_name, port_interface, 0);
162     if (status != UFR_OK) {
163         fprintf(stderr, "ReaderOpenEx: %s\n", UFR_Status2String(status));
164         return -1;
165     }
166
167     fprintf(stderr, "%s\n", GetReaderDescription());
168
169     status = SetAsyncCardIdSendConfig(
170                  1,                  //enable send
171                  0,                  //disable prefix
172                  0,                  //prefix
173                  UFR_ASYNC_SUFFIX,   //suffix
174                  0,                  //disable send removed
175                  UFR_ASYNC_BAUD_RATE
176              );
177     fprintf(stderr, "SetAsyncCardIdSendConfig: %s\n", UFR_Status2String(status));
178     if (status != UFR_OK) {
179         return -1;
180     }
181
182     return 0;
183 }
184
185 int mt_rfid_init(mt_rfid_t *self, struct ev_loop *loop, int fd)
186 {
187     if (ufr_open(UFR_READER_TYPE, UFR_PORT_NAME, UFR_PORT_INTERFACE) == -1) {
188         return -1;
189     }
190
191     int tty = tty_open(UFR_PORT_NAME, CONCAT(B, UFR_ASYNC_BAUD_RATE));
192     if (tty < 0) {
193         return -2;
194     }
195     self->fd = tty;
196
197     ev_io_ufr *w = &(self->w);
198     w->uid = w->uid_data;
199     w->fd = fd;
200     ev_io_init(&(w->w), ufr_cb, tty, EV_READ);
201     ev_io_start(loop, (ev_io *)w);
202
203     return 0;
204 }
205
206 void mt_rfid_deinit(mt_rfid_t *self)
207 {
208     if (close(self->fd) == 0) {
209         fprintf(stderr, "closed %d\n", self->fd);
210     } else {
211         perror("close");
212     }
213
214     UFR_STATUS status = ReaderClose();
215     fprintf(stderr, "ReaderClose: %s\n", UFR_Status2String(status));
216 }
217
218 #ifndef NO_MAIN
219 int main(int argc, char **argv)
220 {
221     struct ev_loop *loop = EV_DEFAULT;
222     mt_rfid_t rfid;
223
224     set_signal_exit(loop);
225
226     if (mt_rfid_init(&rfid, loop, STDOUT_FILENO) != 0) {
227         return -1;
228     }
229
230     ev_run(loop, 0);
231
232     mt_rfid_deinit(&rfid);
233     ev_loop_destroy(loop);
234
235     return 0;
236 }
237 #endif