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