/* Test application for Omron card reader * Copyright (C) 2009 Nicole Faerber * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include "uart.h" #define DLE 0x10 #define STX 0x02 #define ETX 0x03 #define ENQ 0x05 #define ACK 0x06 #define NAK 0x15 #define EOT 0x04 void send_command(int fd, char *cmd, int len) { unsigned char bcc; int pos; char *sbuf = NULL; unsigned int sbpos = 0; sbuf = (char *)malloc(len + 5); if (sbuf == NULL) { perror("malloc"); return; } sbuf[sbpos++] = DLE; sbuf[sbpos++] = STX; bcc = 0; pos = 0; while (pos < len) { sbuf[sbpos++] = cmd[pos]; bcc ^= cmd[pos]; if (cmd[pos] == DLE) sbuf[sbpos++] = cmd[pos]; pos++; } sbuf[sbpos++] = DLE; sbuf[sbpos++] = ETX; bcc ^= ETX; sbuf[sbpos++] = bcc; write_uart(sbuf, sbpos); free(sbuf); } void print_help(void) { fprintf(stderr, "r - initial RESET, required after power-on\n"); fprintf(stderr, "i - C:2 insert permit request\n"); fprintf(stderr, "s - C10 C/R status request\n"); fprintf(stderr, "S - C11 sensor status\n"); fprintf(stderr, "1 - Reads ISO #1 and sends data\n"); fprintf(stderr, "2 - Reads ISO #2 and sends data\n"); fprintf(stderr, "3 - Reads ISO #3 and sends data\n"); fprintf(stderr, "m - Sends the read data in memory by this command\n"); fprintf(stderr, "M - Sends multi-tracks data in the memory by this command and parameter\n"); fprintf(stderr, "q - close serial and quite\n"); fprintf(stderr, "h - this help\n"); } int process_user_cmd(char *rxbuf, int len, int ufd) { int in_cmd = 0; switch (rxbuf[0]) { case 'i': fprintf(stderr, "Insert permit request... "); send_command(ufd, "C:2", 3); in_cmd = 1; break; case 'r': fprintf(stderr, "RESET request... "); send_command(ufd, "C00", 3); in_cmd = 1; break; case 'e': fprintf(stderr, "Eject request... "); send_command(ufd, "C30", 3); in_cmd = 1; break; case 'E': fprintf(stderr, "Eject request... "); send_command(ufd, "C31", 3); in_cmd = 1; break; case 's': fprintf(stderr, "Status request... "); send_command(ufd, "C10", 3); in_cmd = 1; break; case 'S': fprintf(stderr, "Status request... "); send_command(ufd, "C11", 3); in_cmd = 1; break; case '1': fprintf(stderr, "Status request... "); send_command(ufd, "C61", 3); in_cmd = 1; break; case '2': fprintf(stderr, "Status request... "); send_command(ufd, "C62", 3); in_cmd = 1; break; case '3': fprintf(stderr, "Status request... "); send_command(ufd, "C63", 3); in_cmd = 1; break; case 'R': fprintf(stderr, "Status request... "); send_command(ufd, "C687", 4); in_cmd = 1; break; case 'm': fprintf(stderr, "Status request... "); send_command(ufd, "C69", 3); in_cmd = 1; break; case 'M': fprintf(stderr, "Status request... "); send_command(ufd, "C6A7", 4); in_cmd = 1; break; case 'w': fprintf(stderr, "Status request... "); send_command(ufd, "C731234", 7); in_cmd = 1; break; case 'h': print_help(); in_cmd = 0; break; case 'q': fprintf(stderr, "Exiting...\n"); in_cmd = -1; break; default: break; } return in_cmd; } void print_multi_track(char *rxbuf, int len) { int bpos = 0, t, i; int t1len, t2len, t3len; char tmpstr[4]; fprintf(stderr, "tracks requested: %c\n", rxbuf[bpos++]); memset(tmpstr, 0, 4); t=0; tmpstr[t++] = rxbuf[bpos++]; tmpstr[t++] = rxbuf[bpos++]; fprintf(stderr, "t#1 read result: %s\n", tmpstr); t=0; tmpstr[t++] = rxbuf[bpos++]; tmpstr[t++] = rxbuf[bpos++]; fprintf(stderr, "t#2 read result: %s\n", tmpstr); t=0; tmpstr[t++] = rxbuf[bpos++]; tmpstr[t++] = rxbuf[bpos++]; fprintf(stderr, "t#3 read result: %s\n", tmpstr); memset(tmpstr, 0, 4); t=0; tmpstr[t++] = rxbuf[bpos++]; tmpstr[t++] = rxbuf[bpos++]; tmpstr[t++] = rxbuf[bpos++]; t1len = atoi(tmpstr); fprintf(stderr, "t#1 read len: %d\n", t1len); t=0; tmpstr[t++] = rxbuf[bpos++]; tmpstr[t++] = rxbuf[bpos++]; tmpstr[t++] = rxbuf[bpos++]; t2len = atoi(tmpstr); fprintf(stderr, "t#2 read len: %d\n", t2len); t=0; tmpstr[t++] = rxbuf[bpos++]; tmpstr[t++] = rxbuf[bpos++]; tmpstr[t++] = rxbuf[bpos++]; t3len = atoi(tmpstr); fprintf(stderr, "t#3 read len: %d\n", t3len); fprintf(stderr, "t#1 data: '"); for (i=0; i 31 || c < 128) fprintf(stderr, "%c", c); else fprintf(stderr, "0x%02x ", c); } fprintf(stderr, "'\n"); fprintf(stderr, "t#2 data: '"); for (i=0; i 31 || c < 128) fprintf(stderr, "%c", c); else fprintf(stderr, "0x%02x ", c); } fprintf(stderr, "'\n"); fprintf(stderr, "t#3 data: '"); for (i=0; i 31 || c < 128) fprintf(stderr, "%c", c); else fprintf(stderr, "0x%02x ", c); } fprintf(stderr, "'\n"); } void process_read_packet(char *rxbuf, int rxpos) { int bpos; char cmd[2]; bpos = 2; // index into read buffer if (rxbuf[bpos] == 'P') { fprintf(stderr, "positive, "); bpos++; cmd[0] = rxbuf[bpos++]; cmd[1] = rxbuf[bpos++]; fprintf(stderr, "cmd was '%c%c', ", cmd[0], cmd[1]); if (rxbuf[bpos]=='0' && rxbuf[bpos+1]=='0') { fprintf(stderr, "no card present, "); } else if (rxbuf[bpos]=='0' && rxbuf[bpos+1]=='1') { fprintf(stderr, "card at takeout, "); } else if (rxbuf[bpos]=='0' && rxbuf[bpos+1]=='2') { fprintf(stderr, "card present, "); } else fprintf(stderr, "stat is '%c%c', ", rxbuf[bpos], rxbuf[bpos+1]); } else if (rxbuf[bpos] == 'N') { fprintf(stderr, "negative, "); bpos++; fprintf(stderr, "cmd was '%c%c', ", rxbuf[bpos], rxbuf[bpos+1]); bpos += 2; if (rxbuf[bpos]=='0' && rxbuf[bpos+1]=='0') { fprintf(stderr, "undefined command, "); } else if (rxbuf[bpos]=='0' && rxbuf[bpos+1]=='1') { fprintf(stderr, "command sequence error, "); } else if (rxbuf[bpos]=='0' && rxbuf[bpos+1]=='2') { fprintf(stderr, "command data error, "); } else if (rxbuf[bpos]=='0' && rxbuf[bpos+1]=='3') { fprintf(stderr, "write track setting error, "); } else if (rxbuf[bpos]=='4' && rxbuf[bpos+1]=='0') { fprintf(stderr, "SS read error, "); } else if (rxbuf[bpos]=='4' && rxbuf[bpos+1]=='1') { fprintf(stderr, "ES read error, "); } else if (rxbuf[bpos]=='4' && rxbuf[bpos+1]=='2') { fprintf(stderr, "VRC read error, "); } else if (rxbuf[bpos]=='4' && rxbuf[bpos+1]=='3') { fprintf(stderr, "LRC read error, "); } else if (rxbuf[bpos]=='4' && rxbuf[bpos+1]=='4') { fprintf(stderr, "No encode read error, "); } else if (rxbuf[bpos]=='4' && rxbuf[bpos+1]=='5') { fprintf(stderr, "No data read error, "); } else if (rxbuf[bpos]=='4' && rxbuf[bpos+1]=='6') { fprintf(stderr, "Jitter read error, "); } else fprintf(stderr, "unknown stat '%c%c', ", rxbuf[bpos], rxbuf[bpos+1]); } bpos += 2; if (bpos < rxpos-3) { fprintf(stderr, "\ndata: "); if (cmd[0] == '6' && cmd[1] == 'A') { print_multi_track((rxbuf+bpos), rxpos-3); } else { while (bpos < rxpos-3) { unsigned char c = rxbuf[bpos++]; if (c > 31 || c < 128) fprintf(stderr, "%c", c); else fprintf(stderr, "0x%02x ", c); } fprintf(stderr, "\n"); } } } int main(int argc, char **argv) { char *ser_dev; char rxbuf[256]; int ufd, rxlen=0, rxpos=0, ret=0; int in_cmd = 0; fd_set rfds; struct timeval tval; if (argc > 1) ser_dev = argv[1]; else ser_dev = "/dev/ttyS0"; if (open_uart(ser_dev, B9600) != 0) return -1; ufd = uart_get_fd(); // fprintf(stderr, "UART fd = %d\n", ufd); FD_ZERO(&rfds); FD_SET(ufd, &rfds); FD_SET(0, &rfds); tval.tv_sec = 0; tval.tv_usec = 5000000; fprintf(stderr, "OMRON MVFW card reader terminal\non serial %s\nEnter 'h' for help\n", ser_dev); while (ret >= 0) { ret = select((ufd+1), &rfds, NULL, NULL, &tval); if (ret == 0) { FD_ZERO(&rfds); FD_SET(ufd, &rfds); FD_SET(0, &rfds); tval.tv_sec = 0; tval.tv_usec = 5000000; if (rxpos > 0) fprintf(stderr, "Select tmo but buffer not empty!\n"); memset(rxbuf, 0, 256); rxpos = 0; // invalidate buffer } else if (ret > 0) { if (FD_ISSET(ufd, &rfds)) { // fprintf(stderr, "**** select something to read ****\n"); rxlen = uart_read(rxbuf+rxpos, 255-rxpos); rxpos += rxlen; // fprintf(stderr, " read %d bytes\n", rxlen); if (rxpos == 2 && rxbuf[0] == DLE && rxbuf[1] == ACK && in_cmd == 1) { fprintf(stderr, "got ACK requesting execute \n"); put_uart(DLE); put_uart(ENQ); in_cmd = 0; memset(rxbuf, 0, 256); rxpos = 0; } else if (rxpos > 2 && rxbuf[rxpos-3]==DLE && rxbuf[rxpos-2]==ETX) { // data is between DLE-STX and DLE-ETX-BCC process_read_packet(rxbuf, rxpos); memset(rxbuf, 0, 256); rxpos = 0; } //else // fprintf(stderr, "buf not complete yet\n"); } if (FD_ISSET(0, &rfds)) { // fprintf(stderr, "**** keypress\n"); ret = read(0, rxbuf, 255); if (ret > 0) { in_cmd = process_user_cmd(rxbuf, ret, ufd); if (in_cmd == -1) { close(ufd); exit(0); } } } FD_ZERO(&rfds); FD_SET(ufd, &rfds); FD_SET(0, &rfds); fprintf(stderr, "\n> "); } else { fprintf(stderr, "select error\n"); break; } } close_uart(); return 0; }