#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <termios.h> #include <sys/ioctl.h> #include <string.h> #define CRTSCTS 020000000000 /* flow control */ #define KDM96XX_HEADER 0x60 #define KDM96XX_CONTROL_CLA 0x43 #define KDM96XX_CONTROL_EJECT_CMD 0x31 #define KDM96XX_CONTROL_PRESPOS_CMD 0x32 #define KDM96XX_CONTROL_INIT_CMD 0x33 #define KDM96XX_CONTROL_GETVER_CMD 0x34 #define KDM96XX_MSCARD_CLA 0x4D #define KDM96XX_MSCARD_FREAD_CMD 0x31 #define KDM96XX_MSCARD_BREAD_CMD 0x32 #define KDM96XX_MSCARD_READCLEAR_CMD 0x33 char calculate_xor(char * data, int len) { char rslt = 0; int i; for(i=0; i<len; i++) rslt ^= data[i]; return rslt; } int set_interface_attribs (int fd, int speed, int parity, float timeoutSec) { struct termios tty; memset (&tty, 0, sizeof tty); if (tcgetattr (fd, &tty) != 0) { printf("error from tcgetattr"); return -1; } cfsetospeed (&tty, speed); cfsetispeed (&tty, speed); tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8; // 8-bit chars // disable IGNBRK for mismatched speed tests; otherwise receive break // as \000 chars tty.c_iflag &= ~IGNBRK; // ignore break signal tty.c_lflag = 0; // no signaling chars, no echo, // no canonical processing tty.c_oflag = 0; // no remapping, no delays tty.c_cc[VMIN] = 0; // read doesn't block tty.c_cc[VTIME] = (int)(timeoutSec * 10.0);// read timeout in sec tty.c_iflag &= ~(IXON | IXOFF | IXANY); // shut off xon/xoff ctrl tty.c_cflag |= (CLOCAL | CREAD);// ignore modem controls, // enable reading tty.c_cflag &= ~(PARENB | PARODD); // shut off parity tty.c_cflag |= parity; tty.c_cflag &= ~CSTOPB; //tty.c_cflag &= ~CRTSCTS; if (tcsetattr(fd, TCSANOW, &tty) != 0) { printf("error from tcsetattr"); return -1; } return 0; } void set_blocking (int fd, int should_block, float timeoutSec) { struct termios tty; memset (&tty, 0, sizeof tty); if (tcgetattr (fd, &tty) != 0) { printf ("error from tcgetattr"); return; } tty.c_cc[VMIN] = should_block ? 1 : 0; tty.c_cc[VTIME] = (int)(timeoutSec * 10.0); // read timeout in sec if (tcsetattr (fd, TCSANOW, &tty) != 0) printf("error setting term attributes"); } void show_char_vect_as_hex(char * buf, int size) { printf("["); int i; for(i=0; i<size; i++) { printf("x%02x", (unsigned int) buf[i]); if(i != size-1) printf(", "); } printf("]"); } void show_char_vect_as_dec(char * buf, int size) { printf("["); int i; for(i=0; i<size; i++) { printf("%02d", (unsigned int) buf[i]); if(i != size-1) printf(", "); } printf("]"); } void send_init_cmd(int fd) { int len = 6; char data[len]; data[0] = KDM96XX_HEADER;//header data[1] = 0x00; data[2] = 0x02;//data field size data[3] = KDM96XX_CONTROL_CLA;//instructions class data[4] = KDM96XX_CONTROL_INIT_CMD;//command data[5] = calculate_xor(data, len-1); int rslt = write(fd, data, len); printf("\n'init', sent bytes: "); show_char_vect_as_hex(data, len); if(rslt < 0) { printf(" write error!!"); } } void send_getver_cmd(int fd) { int len = 6; char data[len]; data[0] = KDM96XX_HEADER;//header data[1] = 0x00; data[2] = 0x02;//data field size data[3] = KDM96XX_CONTROL_CLA;//instructions class data[4] = KDM96XX_CONTROL_GETVER_CMD; //command data[5] = calculate_xor(data, len-1); int rslt = write(fd, data, len); printf("\n'getver', sent bytes: "); show_char_vect_as_hex(data, len); if(rslt < 0) { printf(" write error!!"); } } void send_report_the_presence_and_pos_cmd(int fd) { int len = 6; char data[len]; data[0] = KDM96XX_HEADER;//header data[1] = 0x00; data[2] = 0x02;//data field size data[3] = KDM96XX_CONTROL_CLA;//instructions class data[4] = KDM96XX_CONTROL_PRESPOS_CMD;//command data[5] = calculate_xor(data, len-1); int rslt = write(fd, data, len); if(rslt < 0) { printf(" send_report_the_presence_and_pos_cmd(), write error\n"); return; } printf("\n'presence and position', sent bytes: "); show_char_vect_as_hex(data, len); } void send_fread_cmd(int fd) { int len = 6; char data[len]; data[0] = KDM96XX_HEADER;//header data[1] = 0x00; data[2] = 0x02;//data field size data[3] = KDM96XX_MSCARD_CLA;//instructions class data[4] = KDM96XX_MSCARD_FREAD_CMD;//command data[5] = calculate_xor(data, len-1); int rslt = write(fd, data, len); if(rslt < 0) { printf("send_fread_cmd(), write error\n"); return; } printf("\n'fread', sent bytes: "); show_char_vect_as_hex(data, len); } void send_bread_cmd(int fd) { int len = 6; char data[len]; data[0] = KDM96XX_HEADER;//header data[1] = 0x00; data[2] = 0x02;//data field size data[3] = KDM96XX_MSCARD_CLA;//instructions class data[4] = KDM96XX_MSCARD_BREAD_CMD;//command data[5] = calculate_xor(data, len-1); int rslt = write(fd, data, len); if(rslt < 0) { printf("send_bread_cmd(), write error\n"); return; } printf("\n'bread', sent bytes: "); show_char_vect_as_hex(data, len); } void send_cread_cmd(int fd) { int len = 6; char data[len]; data[0] = KDM96XX_HEADER;//header data[1] = 0x00; data[2] = 0x02;//data field size data[3] = KDM96XX_MSCARD_CLA;//instructions class data[4] = KDM96XX_MSCARD_READCLEAR_CMD; //command data[5] = calculate_xor(data, len-1); int rslt = write(fd, data, len); if(rslt < 0) { printf("send_cread_cmd(), write error\n"); return; } printf("\n'cread', sent bytes: "); show_char_vect_as_hex(data, len); } void read_and_show_resp(int fd) { //read first 4 bytes (message header) int transmitted = -1; int headerSize = 3; char header[headerSize]; memset(header, 0, headerSize); transmitted = read(fd, header, headerSize); if(transmitted < 0) { printf("read_and_show_resp(), read header error\n"); return; } printf("\nheader: "); show_char_vect_as_hex(header, transmitted); //calculate message body size and read it int dataSize = ((unsigned int)header[1]) * 256 + (unsigned int) header[2] + 1; //plus 1 byte for LRC char data[dataSize]; memset(data, 0, dataSize); transmitted = read(fd, data, dataSize); if(transmitted < 0) { printf("read_and_show_resp(), read message body error\n"); return; } printf("\nbody: "); show_char_vect_as_hex(data, transmitted); } void show_help() { printf("program {serial port device} {command name} [timeout in seconds] \n"); printf("command name : fread, bread, cread, getver, init, pres \n"); printf("usage example: \n"); printf("./program /dev/ttyS0 fread 2.5 \n"); } void clear_buf(int fd) { set_interface_attribs (fd, B9600, 0, 0.1); // set speed to 9600 bps, 8n1 (no parity) set_blocking (fd, 0, 0.1); // set no blocking int bufSize = 1024; char buf[bufSize]; read(fd, buf, bufSize); } int main(int argc, char *argv[]) { float timeoutSec = 2.5; if(argc < 2) { printf("serial port name was omitted\n"); show_help(); return 0; } if(argc < 3) { printf("command name was omitted\n"); show_help(); return 0; } char *portname = argv[1]; // like "/dev/ttyS0" char *cmdStr = argv[2]; // "read", "init", "pres" if(argc >= 4) //if there is timeout in command line - set it { timeoutSec = atof(argv[3]); } int fd = open (portname, O_RDWR | O_NOCTTY | O_SYNC); if (fd < 0) { printf("error opening %s, retval %d\n", portname, fd); return -1; } clear_buf(fd); set_interface_attribs (fd, B9600, 0, timeoutSec); // set speed to 9600 bps, 8n1 (no parity) set_blocking (fd, 0, timeoutSec); // set no blocking if(strcmp("init", cmdStr) == 0) { send_init_cmd(fd); } if(strcmp("getver", cmdStr) == 0) { send_getver_cmd(fd); } if(strcmp("pres", cmdStr) == 0) { send_report_the_presence_and_pos_cmd(fd); } if(strcmp("fread", cmdStr) == 0) { send_fread_cmd(fd); } if(strcmp("bread", cmdStr) == 0) { send_bread_cmd(fd); } if(strcmp("cread", cmdStr) == 0) { send_cread_cmd(fd); } read_and_show_resp(fd); printf("\n"); close(fd); return 0; } //The values for speed are B115200, B230400, B9600, B19200, B38400, B57600, B1200
пятница, 21 февраля 2014 г.
Ридер для магнитных лент KDM-96XX
Ниже представлен код для карт-ридера магнитных лент KDM-96XX.
Подписаться на:
Комментарии к сообщению (Atom)
Комментариев нет:
Отправить комментарий