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