]> git.karo-electronics.de Git - magstrip.git/blob - lmain.c
Initial import
[magstrip.git] / lmain.c
1 /* Test application for Omron card reader
2  * Copyright (C) 2009 Nils Faerber <nils.faerber@kernelconcepts.de>
3  *
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.
8  *
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.
13  *
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.
17  */
18
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <sys/select.h>
22
23 #include "uart.h"
24
25 #define DLE     0x10
26 #define STX     0x02
27 #define ETX     0x03
28 #define ENQ     0x05
29 #define ACK     0x06
30 #define NAK     0x15
31 #define EOT     0x04
32
33
34 void send_command(int fd, char *cmd, int len)
35 {
36 unsigned char bcc;
37 int pos;
38 char *sbuf = NULL;
39 unsigned int sbpos = 0;
40
41         sbuf = (char *)malloc(len + 5);
42         if (sbuf == NULL) {
43                 perror("malloc");
44                 return;
45         }
46
47         sbuf[sbpos++] = DLE;
48         sbuf[sbpos++] = STX;
49         bcc = 0;
50         pos = 0;
51         while (pos < len) {
52                 sbuf[sbpos++] = cmd[pos];
53                 bcc ^= cmd[pos];
54                 if (cmd[pos] == DLE)
55                         sbuf[sbpos++] = cmd[pos];
56                 pos++;
57         }
58         sbuf[sbpos++] = DLE;
59         sbuf[sbpos++] = ETX;
60         bcc ^= ETX;
61         sbuf[sbpos++] = bcc;
62
63         write_uart(sbuf, sbpos);
64         free(sbuf);
65 }
66
67 int process_user_cmd(char *rxbuf, int len, int ufd)
68 {
69 int in_cmd = 0;
70
71         if (rxbuf[0] == 'i') {
72                 fprintf(stderr, "Init permit request... ");
73                 send_command(ufd, "C:2", 3);
74                 in_cmd = 1;
75         }
76         if (rxbuf[0] == 'r') {
77                 fprintf(stderr, "RESET request... ");
78                 send_command(ufd, "C00", 3);
79                 in_cmd = 1;
80         }
81         if (rxbuf[0] == 'e') {
82                 fprintf(stderr, "Eject request... ");
83                 send_command(ufd, "C30", 3);
84                 in_cmd = 1;
85         }
86         if (rxbuf[0] == 's') {
87                 fprintf(stderr, "Status request... ");
88                 send_command(ufd, "C10", 3);
89                 in_cmd = 1;
90         }
91         if (rxbuf[0] == 'S') {
92                 fprintf(stderr, "Status request... ");
93                 send_command(ufd, "C11", 3);
94                 in_cmd = 1;
95         }
96         if (rxbuf[0] == '1') {
97                 fprintf(stderr, "Status request... ");
98                 send_command(ufd, "C61", 3);
99                 in_cmd = 1;
100         }
101         if (rxbuf[0] == '2') {
102                 fprintf(stderr, "Status request... ");
103                 send_command(ufd, "C62", 3);
104                 in_cmd = 1;
105         }
106         if (rxbuf[0] == '3') {
107                 fprintf(stderr, "Status request... ");
108                 send_command(ufd, "C63", 3);
109                 in_cmd = 1;
110         }
111
112         if (rxbuf[0] == 'q') {
113                 fprintf(stderr, "Exiting...\n");
114                 in_cmd = -1;
115         }
116
117         return in_cmd;
118 }
119
120 void process_read_packet(char *rxbuf, int rxpos)
121 {
122 int bpos;
123
124         bpos = 2; // index into read buffer
125         if (rxbuf[bpos] == 'P') {
126                 fprintf(stderr, "positive, ");
127                 bpos++;
128                 fprintf(stderr, "cmd was '%c%c', ", rxbuf[bpos], rxbuf[bpos+1]);
129                 bpos+=2;
130                 if (rxbuf[bpos]=='0' && rxbuf[bpos+1]=='0') {
131                         fprintf(stderr, "no card present, ");
132                 } else if (rxbuf[bpos]=='0' && rxbuf[bpos+1]=='1') {
133                         fprintf(stderr, "card at takeout, ");
134                 } else if (rxbuf[bpos]=='0' && rxbuf[bpos+1]=='2') {
135                         fprintf(stderr, "card present, ");
136                 } else
137                         fprintf(stderr, "stat is '%c%c', ", rxbuf[bpos], rxbuf[bpos+1]);
138         } else if (rxbuf[bpos] == 'N') {
139                 fprintf(stderr, "negative, ");
140                 bpos++;
141                 fprintf(stderr, "cmd was '%c%c', ", rxbuf[bpos], rxbuf[bpos+1]);
142                 bpos+=2;
143                 if (rxbuf[bpos]=='0' && rxbuf[bpos+1]=='0') {
144                         fprintf(stderr, "undefined command, ");
145                 } else if (rxbuf[bpos]=='0' && rxbuf[bpos+1]=='1') {
146                         fprintf(stderr, "command sequence error, ");
147                 } else if (rxbuf[bpos]=='0' && rxbuf[bpos+1]=='2') {
148                         fprintf(stderr, "command data error, ");
149                 } else if (rxbuf[bpos]=='0' && rxbuf[bpos+1]=='3') {
150                         fprintf(stderr, "write track setting error, ");
151                 } else if (rxbuf[bpos]=='4' && rxbuf[bpos+1]=='0') {
152                         fprintf(stderr, "SS read error, ");
153                 } else if (rxbuf[bpos]=='4' && rxbuf[bpos+1]=='1') {
154                         fprintf(stderr, "ES read error, ");
155                 } else if (rxbuf[bpos]=='4' && rxbuf[bpos+1]=='2') {
156                         fprintf(stderr, "VRC read error, ");
157                 } else if (rxbuf[bpos]=='4' && rxbuf[bpos+1]=='3') {
158                         fprintf(stderr, "LRC read error, ");
159                 } else if (rxbuf[bpos]=='4' && rxbuf[bpos+1]=='4') {
160                         fprintf(stderr, "No encode read error, ");
161                 } else if (rxbuf[bpos]=='4' && rxbuf[bpos+1]=='5') {
162                         fprintf(stderr, "No data read error, ");
163                 } else if (rxbuf[bpos]=='4' && rxbuf[bpos+1]=='6') {
164                         fprintf(stderr, "Jitter read error, ");
165                 } else
166                         fprintf(stderr, "stat is '%c%c', ", rxbuf[bpos], rxbuf[bpos+1]);
167         }
168         bpos+=2;
169         if (bpos < rxpos-3)
170                 fprintf(stderr, "\ndata: ");
171         while (bpos < rxpos-3) {
172                 unsigned char c = rxbuf[bpos++];
173                 if (c > 31 || c < 128)
174                         fprintf(stderr, "%c", c);
175                 else
176                         fprintf(stderr, "0x%02x ", c);
177                 
178         }
179         fprintf(stderr, "\n");
180 }
181
182 int main(int argc, char **argv)
183 {
184 char rxbuf[256];
185 int ufd, rxlen=0, rxpos=0, ret;
186 int in_cmd = 0;
187 fd_set rfds;
188 struct timeval tval;
189
190         if (open_uart("/dev/ttyUSB0", B9600) != 0)
191                 return -1;
192         ufd = uart_get_fd();
193         // fprintf(stderr, "UART fd = %d\n", ufd);
194         FD_ZERO(&rfds);
195         FD_SET(ufd, &rfds);
196         FD_SET(0, &rfds);
197         tval.tv_sec = 0;
198         tval.tv_usec = 5000000;
199
200         fprintf(stderr, "OMRON MVFW card reader terminal\nEnter 'h' for help\n");
201         while (1) {
202                 ret = select((ufd+1), &rfds, NULL, NULL, &tval);
203                 if (ret == 0) {
204                         FD_ZERO(&rfds);
205                         FD_SET(ufd, &rfds);
206                         FD_SET(0, &rfds);
207                         tval.tv_sec = 0;
208                         tval.tv_usec = 5000000;
209                         if (rxpos > 0)
210                                 fprintf(stderr, "Select tmo but buffer not empty!\n");
211                         memset(rxbuf, 0, 256);
212                         rxpos = 0; // invalidate buffer
213                 } else if (ret > 0) {
214                         if (FD_ISSET(ufd, &rfds)) {
215                                 // fprintf(stderr, "**** select something to read ****\n");
216                                 rxlen = uart_read(rxbuf+rxpos, 255-rxpos);
217                                 rxpos += rxlen;
218                                 // fprintf(stderr, "  read %d bytes\n", rxlen);
219                                 if (rxpos == 2 && rxbuf[0] == DLE && rxbuf[1] == ACK && in_cmd == 1) {
220                                         fprintf(stderr, "got ACK requesting execute \n");
221                                         put_uart(DLE);
222                                         put_uart(ENQ);
223                                         in_cmd = 0;
224                                         memset(rxbuf, 0, 256);
225                                         rxpos = 0;
226                                 } else if (rxpos > 2 && rxbuf[rxpos-3]==DLE && rxbuf[rxpos-2]==ETX) {
227                                         // data is between DLE-STX and DLE-ETX-BCC
228                                         process_read_packet(rxbuf, rxpos);
229                                         memset(rxbuf, 0, 256);
230                                         rxpos = 0;
231                                 } else
232                                         fprintf(stderr, "buf not complete yet\n");
233                         }
234                         if (FD_ISSET(0, &rfds)) {
235                                 // fprintf(stderr, "**** keypress\n");
236                                 ret = read(0, rxbuf, 255);
237                                 if (ret > 0) {
238                                         in_cmd = process_user_cmd(rxbuf, ret, ufd);
239                                         if (in_cmd == -1) {
240                                                 close(ufd);
241                                                 exit(0);
242                                         }
243                                 }
244                         }
245                         FD_ZERO(&rfds);
246                         FD_SET(ufd, &rfds);
247                         FD_SET(0, &rfds);
248
249                         fprintf(stderr, "\n> ");
250                 } else {
251                         fprintf(stderr, "select error\n");
252                         break;
253                 }
254         }
255
256         close_uart();
257
258 return 0;
259 }