1 /* Test application for Omron card reader
2 * Copyright (C) 2009 Nils Faerber <nils.faerber@kernelconcepts.de>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 #include <sys/select.h>
34 void send_command(int fd, char *cmd, int len)
39 unsigned int sbpos = 0;
41 sbuf = (char *)malloc(len + 5);
52 sbuf[sbpos++] = cmd[pos];
55 sbuf[sbpos++] = cmd[pos];
63 write_uart(sbuf, sbpos);
69 fprintf(stderr, "r - initial RESET, required after power-on\n");
70 fprintf(stderr, "i - C:2 insert permit request\n");
71 fprintf(stderr, "s - C10 C/R status request\n");
72 fprintf(stderr, "S - C11 sensor status\n");
73 fprintf(stderr, "1 - Reads ISO #1 and sends data\n");
74 fprintf(stderr, "2 - Reads ISO #2 and sends data\n");
75 fprintf(stderr, "3 - Reads ISO #3 and sends data\n");
76 fprintf(stderr, "m - Sends the read data in memory by this command\n");
77 fprintf(stderr, "M - Sends multi-tracks data in the memory by this command and parameter\n");
78 fprintf(stderr, "q - close serial and quite\n");
79 fprintf(stderr, "h - this help\n");
82 int process_user_cmd(char *rxbuf, int len, int ufd)
88 fprintf(stderr, "Insert permit request... ");
89 send_command(ufd, "C:2", 3);
93 fprintf(stderr, "RESET request... ");
94 send_command(ufd, "C00", 3);
98 fprintf(stderr, "Eject request... ");
99 send_command(ufd, "C30", 3);
103 fprintf(stderr, "Eject request... ");
104 send_command(ufd, "C31", 3);
108 fprintf(stderr, "Status request... ");
109 send_command(ufd, "C10", 3);
113 fprintf(stderr, "Status request... ");
114 send_command(ufd, "C11", 3);
118 fprintf(stderr, "Status request... ");
119 send_command(ufd, "C61", 3);
123 fprintf(stderr, "Status request... ");
124 send_command(ufd, "C62", 3);
128 fprintf(stderr, "Status request... ");
129 send_command(ufd, "C63", 3);
133 fprintf(stderr, "Status request... ");
134 send_command(ufd, "C687", 4);
138 fprintf(stderr, "Status request... ");
139 send_command(ufd, "C69", 3);
143 fprintf(stderr, "Status request... ");
144 send_command(ufd, "C6A7", 4);
148 fprintf(stderr, "Status request... ");
149 send_command(ufd, "C731234", 7);
157 fprintf(stderr, "Exiting...\n");
167 void print_multi_track(char *rxbuf, int len)
170 int t1len, t2len, t3len;
173 fprintf(stderr, "tracks requested: %c\n", rxbuf[bpos++]);
174 memset(tmpstr, 0, 4);
176 tmpstr[t++] = rxbuf[bpos++];
177 tmpstr[t++] = rxbuf[bpos++];
178 fprintf(stderr, "t#1 read result: %s\n", tmpstr);
180 tmpstr[t++] = rxbuf[bpos++];
181 tmpstr[t++] = rxbuf[bpos++];
182 fprintf(stderr, "t#2 read result: %s\n", tmpstr);
184 tmpstr[t++] = rxbuf[bpos++];
185 tmpstr[t++] = rxbuf[bpos++];
186 fprintf(stderr, "t#3 read result: %s\n", tmpstr);
187 memset(tmpstr, 0, 4);
190 tmpstr[t++] = rxbuf[bpos++];
191 tmpstr[t++] = rxbuf[bpos++];
192 tmpstr[t++] = rxbuf[bpos++];
193 t1len = atoi(tmpstr);
194 fprintf(stderr, "t#1 read len: %d\n", t1len);
196 tmpstr[t++] = rxbuf[bpos++];
197 tmpstr[t++] = rxbuf[bpos++];
198 tmpstr[t++] = rxbuf[bpos++];
199 t2len = atoi(tmpstr);
200 fprintf(stderr, "t#2 read len: %d\n", t2len);
202 tmpstr[t++] = rxbuf[bpos++];
203 tmpstr[t++] = rxbuf[bpos++];
204 tmpstr[t++] = rxbuf[bpos++];
205 t3len = atoi(tmpstr);
206 fprintf(stderr, "t#3 read len: %d\n", t3len);
208 fprintf(stderr, "t#1 data: '");
209 for (i=0; i<t1len; i++) {
210 unsigned char c = rxbuf[bpos++];
211 if (c > 31 || c < 128)
212 fprintf(stderr, "%c", c);
214 fprintf(stderr, "0x%02x ", c);
216 fprintf(stderr, "'\n");
218 fprintf(stderr, "t#2 data: '");
219 for (i=0; i<t2len; i++) {
220 unsigned char c = rxbuf[bpos++];
221 if (c > 31 || c < 128)
222 fprintf(stderr, "%c", c);
224 fprintf(stderr, "0x%02x ", c);
226 fprintf(stderr, "'\n");
228 fprintf(stderr, "t#3 data: '");
229 for (i=0; i<t3len; i++) {
230 unsigned char c = rxbuf[bpos++];
231 if (c > 31 || c < 128)
232 fprintf(stderr, "%c", c);
234 fprintf(stderr, "0x%02x ", c);
236 fprintf(stderr, "'\n");
239 void process_read_packet(char *rxbuf, int rxpos)
244 bpos = 2; // index into read buffer
245 if (rxbuf[bpos] == 'P') {
246 fprintf(stderr, "positive, ");
248 cmd[0] = rxbuf[bpos++];
249 cmd[1] = rxbuf[bpos++];
250 fprintf(stderr, "cmd was '%c%c', ", cmd[0], cmd[1]);
252 if (rxbuf[bpos]=='0' && rxbuf[bpos+1]=='0') {
253 fprintf(stderr, "no card present, ");
254 } else if (rxbuf[bpos]=='0' && rxbuf[bpos+1]=='1') {
255 fprintf(stderr, "card at takeout, ");
256 } else if (rxbuf[bpos]=='0' && rxbuf[bpos+1]=='2') {
257 fprintf(stderr, "card present, ");
259 fprintf(stderr, "stat is '%c%c', ", rxbuf[bpos], rxbuf[bpos+1]);
260 } else if (rxbuf[bpos] == 'N') {
261 fprintf(stderr, "negative, ");
263 fprintf(stderr, "cmd was '%c%c', ", rxbuf[bpos], rxbuf[bpos+1]);
265 if (rxbuf[bpos]=='0' && rxbuf[bpos+1]=='0') {
266 fprintf(stderr, "undefined command, ");
267 } else if (rxbuf[bpos]=='0' && rxbuf[bpos+1]=='1') {
268 fprintf(stderr, "command sequence error, ");
269 } else if (rxbuf[bpos]=='0' && rxbuf[bpos+1]=='2') {
270 fprintf(stderr, "command data error, ");
271 } else if (rxbuf[bpos]=='0' && rxbuf[bpos+1]=='3') {
272 fprintf(stderr, "write track setting error, ");
273 } else if (rxbuf[bpos]=='4' && rxbuf[bpos+1]=='0') {
274 fprintf(stderr, "SS read error, ");
275 } else if (rxbuf[bpos]=='4' && rxbuf[bpos+1]=='1') {
276 fprintf(stderr, "ES read error, ");
277 } else if (rxbuf[bpos]=='4' && rxbuf[bpos+1]=='2') {
278 fprintf(stderr, "VRC read error, ");
279 } else if (rxbuf[bpos]=='4' && rxbuf[bpos+1]=='3') {
280 fprintf(stderr, "LRC read error, ");
281 } else if (rxbuf[bpos]=='4' && rxbuf[bpos+1]=='4') {
282 fprintf(stderr, "No encode read error, ");
283 } else if (rxbuf[bpos]=='4' && rxbuf[bpos+1]=='5') {
284 fprintf(stderr, "No data read error, ");
285 } else if (rxbuf[bpos]=='4' && rxbuf[bpos+1]=='6') {
286 fprintf(stderr, "Jitter read error, ");
288 fprintf(stderr, "unknown stat '%c%c', ", rxbuf[bpos], rxbuf[bpos+1]);
292 if (bpos < rxpos-3) {
293 fprintf(stderr, "\ndata: ");
294 if (cmd[0] == '6' && cmd[1] == 'A') {
295 print_multi_track((rxbuf+bpos), rxpos-3);
297 while (bpos < rxpos-3) {
298 unsigned char c = rxbuf[bpos++];
299 if (c > 31 || c < 128)
300 fprintf(stderr, "%c", c);
302 fprintf(stderr, "0x%02x ", c);
304 fprintf(stderr, "\n");
309 int main(int argc, char **argv)
313 int ufd, rxlen=0, rxpos=0, ret=0;
321 ser_dev = "/dev/ttyS0";
322 if (open_uart(ser_dev, B9600) != 0)
325 // fprintf(stderr, "UART fd = %d\n", ufd);
331 tval.tv_usec = 5000000;
333 fprintf(stderr, "OMRON MVFW card reader terminal\non serial %s\nEnter 'h' for help\n", ser_dev);
335 ret = select((ufd+1), &rfds, NULL, NULL, &tval);
341 tval.tv_usec = 5000000;
343 fprintf(stderr, "Select tmo but buffer not empty!\n");
344 memset(rxbuf, 0, 256);
345 rxpos = 0; // invalidate buffer
346 } else if (ret > 0) {
347 if (FD_ISSET(ufd, &rfds)) {
348 // fprintf(stderr, "**** select something to read ****\n");
349 rxlen = uart_read(rxbuf+rxpos, 255-rxpos);
351 // fprintf(stderr, " read %d bytes\n", rxlen);
352 if (rxpos == 2 && rxbuf[0] == DLE && rxbuf[1] == ACK && in_cmd == 1) {
353 fprintf(stderr, "got ACK requesting execute \n");
357 memset(rxbuf, 0, 256);
359 } else if (rxpos > 2 && rxbuf[rxpos-3]==DLE && rxbuf[rxpos-2]==ETX) {
360 // data is between DLE-STX and DLE-ETX-BCC
361 process_read_packet(rxbuf, rxpos);
362 memset(rxbuf, 0, 256);
365 // fprintf(stderr, "buf not complete yet\n");
367 if (FD_ISSET(0, &rfds)) {
368 // fprintf(stderr, "**** keypress\n");
369 ret = read(0, rxbuf, 255);
371 in_cmd = process_user_cmd(rxbuf, ret, ufd);
382 fprintf(stderr, "\n> ");
384 fprintf(stderr, "select error\n");