]> rtime.felk.cvut.cz Git - coffee/mt-apps.git/blob - mt_rfid.c
queue improved
[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 #define RFID_JSON_PRINT() do { \
90     JSON_START();         \
91     JSON_STR(type);       \
92     JSON_NEXT();          \
93     JSON_NUM(card_type);  \
94     JSON_NEXT();          \
95     JSON_NUM(sak);        \
96     JSON_NEXT();          \
97     JSON_NUM(size);       \
98     JSON_NEXT();          \
99     JSON_STR(uid);        \
100     JSON_END();           \
101 } while (0)
102
103 static void ufr_read(char *uid, int fd)
104 {
105     static char *type = "rfid";
106
107     UFR_STATUS status;
108     uint8_t card_type;
109     uint8_t sak;           //select acknowledge
110     uint8_t uid_bytes[10]; //uid as bytes
111     uint8_t size;
112
113     status = GetDlogicCardType(&card_type);
114     if (status != UFR_OK) {
115         fprintf(stderr, "GetDlogicCardType: %s\n", UFR_Status2String(status));
116         return;
117     }
118
119     status = GetCardIdEx(&sak, uid_bytes, &size);
120     if (status != UFR_OK) {
121         fprintf(stderr, "GetCardIdEx: %s\n", UFR_Status2String(status));
122         return;
123     }
124
125     RFID_JSON_PRINT();
126
127 #ifdef UFR_BEEP
128     ReaderUISignal(0, 1); // no light, one beep
129 #endif
130 }
131
132 #define UFR_ASYNC_SUFFIX 0 // keep it zero: separates uids, terminates strings
133
134 static void ufr_cb(EV_P_ ev_io *w_, int revents)
135 {
136     ev_io_ufr *w = (ev_io_ufr *)w_;
137     char uid;
138
139     read(w->w.fd, &uid, 1);
140     *(w->uid++) = uid;
141
142     if (uid == UFR_ASYNC_SUFFIX) {
143         //*(w->uid - 1) = 0; // no need if UFR_ASYNC_SUFFIX is 0
144         w->uid = w->uid_data;
145         ufr_read(w->uid, w->fd);
146     }
147 }
148
149 static int ufr_open(unsigned reader_type, char *port_name,
150                     unsigned port_interface)
151 {
152     UFR_STATUS status;
153
154     fprintf(stderr, "uFCoder version: %s\n", GetDllVersionStr());
155
156     status = ReaderOpenEx(reader_type, port_name, port_interface, 0);
157     if (status != UFR_OK) {
158         fprintf(stderr, "ReaderOpenEx: %s\n", UFR_Status2String(status));
159         return -1;
160     }
161
162     fprintf(stderr, "%s\n", GetReaderDescription());
163
164     status = SetAsyncCardIdSendConfig(
165                  1,                  //enable send
166                  0,                  //disable prefix
167                  0,                  //prefix
168                  UFR_ASYNC_SUFFIX,   //suffix
169                  0,                  //disable send removed
170                  UFR_ASYNC_BAUD_RATE
171              );
172     fprintf(stderr, "SetAsyncCardIdSendConfig: %s\n", UFR_Status2String(status));
173     if (status != UFR_OK) {
174         return -1;
175     }
176
177     return 0;
178 }
179
180 int mt_rfid_init(mt_rfid_t *self, struct ev_loop *loop, int fd)
181 {
182     if (ufr_open(UFR_READER_TYPE, UFR_PORT_NAME, UFR_PORT_INTERFACE) == -1) {
183         return -1;
184     }
185
186     int tty = tty_open(UFR_PORT_NAME, CONCAT(B, UFR_ASYNC_BAUD_RATE));
187     if (tty < 0) {
188         return -2;
189     }
190     self->fd = tty;
191
192     ev_io_ufr *w = &(self->w);
193     w->uid = w->uid_data;
194     w->fd = fd;
195     ev_io_init(&(w->w), ufr_cb, tty, EV_READ);
196     ev_io_start(loop, (ev_io *)w);
197
198     return 0;
199 }
200
201 void mt_rfid_deinit(mt_rfid_t *self)
202 {
203     if (close(self->fd) == 0) {
204         fprintf(stderr, "closed %d\n", self->fd);
205     } else {
206         perror("close");
207     }
208
209     UFR_STATUS status = ReaderClose();
210     fprintf(stderr, "ReaderClose: %s\n", UFR_Status2String(status));
211 }
212
213 #ifndef NO_MAIN
214 int main(int argc, char **argv)
215 {
216     struct ev_loop *loop = EV_DEFAULT;
217     mt_rfid_t rfid;
218
219     set_signal_exit(loop);
220
221     if (mt_rfid_init(&rfid, loop, STDOUT_FILENO) != 0) {
222         return -1;
223     }
224
225     ev_run(loop, 0);
226
227     mt_rfid_deinit(&rfid);
228
229     return 0;
230 }
231 #endif