⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ic.c

📁 对LINUX下IC卡读写操作函数
💻 C
字号:
#include     <stdio.h>      /*标准输入输出定义*/
#include     <stdlib.h>     /*标准函数库定义*/
#include     <unistd.h>     /*Unix标准函数定义*/
#include     <sys/types.h>  /**/
#include     <sys/stat.h>   /**/
#include     <fcntl.h>      /*文件控制定义*/
#include     <termios.h>    /*PPSIX终端控制定义*/
#include     <errno.h>      /*错误号定义*///#include     <linux/delay.h>
char *dev ="/dev/ttyS0";//char *dev = "/home/ic/test";
int fd;int speed_arr[] = { B38400, B19200, B9600, B4800, B2400, B1200, B300,					B38400, B19200, B9600, B4800, B2400, B1200, B300, };int name_arr[] = {38400,  19200,  9600,  4800,  2400,  1200,  300, 38400,  					19200,  9600, 4800, 2400, 1200,  300, };int mdelay(unsigned long i){	printf("......\n");	usleep( 1000*i );	usleep( 1000*i );//	sleep(1);	printf("^_^\n");}int OpenDev(char *Dev)
{
	fd = open( Dev, O_RDWR | O_NOCTTY | O_NDELAY );
	if (-1 == fd)
	{ /*设置数据位数*/
		perror("Can't Open Serial Port");
		return -1;
	}
	else
	{	    	fcntl(fd, F_SETFL, 0);		printf("Open Serial Port\n");		return fd;	}
}void set_speed(int fd, int speed){	int   i; 	int   status; 	struct termios   Opt;	tcgetattr(fd, &Opt); 	for ( i= 0;  i < sizeof(speed_arr) / sizeof(int);  i++) { 		if  (speed == name_arr[i]) {     			tcflush(fd, TCIOFLUSH);     			cfsetispeed(&Opt, speed_arr[i]);  			cfsetospeed(&Opt, speed_arr[i]);   			status = tcsetattr(fd, TCSANOW, &Opt);  			if  (status != 0) {        				perror("tcsetattr fd1");  				return;     			}    			tcflush(fd,TCIOFLUSH);   		}  	}}/***@brief   设置串口数据位,停止位和效验位*@param  fd     类型  int  打开的串口文件句柄*@param  databits 类型  int 数据位   取值 为 7 或者8*@param  stopbits 类型  int 停止位   取值为 1 或者2*@param  parity  类型  int  效验类型 取值为N,E,O,,S*/int set_Parity(int fd,int databits,int stopbits,int parity){ 	struct termios options; 	if  ( tcgetattr( fd,&options)  !=  0) { 		perror("SetupSerial 1");     		return -1;  	}	options.c_cflag &= ~CSIZE; 	switch (databits) /*设置数据位数*/	{   	case 7:				options.c_cflag |= CS7; 		break;	case 8:     		options.c_cflag |= CS8;		break;   	default:    		fprintf(stderr,"Unsupported data size\n"); return -1;  	}switch (parity) {   	case 'n':	case 'N':    		options.c_cflag &= ~PARENB;   /* Clear parity enable */		options.c_iflag &= ~INPCK;     /* Enable parity checking */ 		break;  	case 'o':   	case 'O':     		options.c_cflag |= (PARODD | PARENB); /* 设置为奇效验*/  		options.c_iflag |= INPCK;             /* Disnable parity checking */ 		break;  	case 'e':  	case 'E':   		options.c_cflag |= PARENB;     /* Enable parity */    		options.c_cflag &= ~PARODD;   /* 转换为偶效验*/     		options.c_iflag |= INPCK;       /* Disnable parity checking */		break;	case 'S': 	case 's':  /*as no parity*/   	    options.c_cflag &= ~PARENB;		options.c_cflag &= ~CSTOPB;break;  	default:   		fprintf(stderr,"Unsupported parity\n");    		return -1;  	}  /* 设置停止位*/  switch (stopbits){   	case 1:    		options.c_cflag &= ~CSTOPB;  		break;  	case 2:    		options.c_cflag |= CSTOPB;  	   break;	default:    		 fprintf(stderr,"Unsupported stop bits\n");  		 return -1; } /* Set input parity option */ if (parity != 'n')   	options.c_iflag |= INPCK; tcflush(fd,TCIFLUSH);options.c_cc[VTIME] = 150; /* 设置超时15 seconds*/   options.c_cc[VMIN] = 0; /* Update the options and do it NOW */if (tcsetattr(fd,TCSANOW,&options) != 0)   { 	perror("SetupSerial 3");   	return -1;  } return 0;  }int InitSerialPort(){printf("open dev...\n");	fd = OpenDev(dev);printf("opened dev\n");//	set_speed(fd,9600);//	if (set_Parity(fd,8,2,'N') == -1)  {//		printf("Set Parity Error\n");//		exit (0);//	}	struct termios options;	tcgetattr(fd, &options);	cfsetispeed(&options, B9600);	cfsetospeed(&options, B9600);//波特率	options.c_cflag |= (CLOCAL | CREAD);	options.c_cflag &= ~PARENB;	options.c_cflag |= CSTOPB;//2位停止位	options.c_cflag &= ~CSIZE;	options.c_cflag |= CS8;//8位数据位	options.c_cflag &= ~CRTSCTS;	options.c_lflag  &= ~(ICANON | ECHO | ECHOE | ISIG);  /*Input*/	//options.c_lflag  &= ~(IXON | IXOFF | IXANY);	options.c_oflag  &= ~OPOST;   /*Output*/	options.c_iflag &= ~(IXON | IXOFF | IXANY);	//options.c_cc[VMIN]=0;	//options.c_cc[VTIME]=10;		tcsetattr(fd, TCSANOW, &options);	return 0;}int InitIc(){	int j,i,status;	//比较设备密码,不比较是不能操作设置的	//密码是736736,如果变动,写入数据也应变化	unsigned char buf[13]={0xaa,0xb5,0x00,0x08,0x80,0x00,0x00,0x01,0x82,0x73,0x67,0x36,0x36};//unsigned char buf[10]={0xaa,0xb9,0x00,0x05,0x80,0x00,0x00,0x00,0x00,0x96};		write(fd,buf,13);//	printf("write over\n");	for( ; ; )	{		if ( (status = read(fd,buf,5))!=-1 )			break;	}//	printf("status = %x\n",status);	for( i=0; i<status; i++ )	{		printf("%x,	", buf[i]);	}	if(buf[0]==0x55 && buf[1]==0x00 && buf[2]==0x00 && buf[3]==0x00 && buf[4]==0x55)		printf("device password accepted\n");	//蜂鸣100ms	unsigned char buf3[20]={0xaa,0xb4,0x00,0x07,0x80,0x00,0x00,0x00,0x00,0x00,0x0a,0x93};	write(fd,buf3,13);	for( ; ; )	{		if ( (status = read(fd,buf,5))!=-1 )			break;	} 	for( i=0; i<status; i++ )	{		printf("%x,	", buf[i]);	}	if(buf[0]==0x55 && buf[1]==0x00 && buf[2]==0x00 && buf[3]==0x00 && buf[4]==0x55)		printf("Ring Ring\n");	//比较卡密码, 倒数第2,3,4位为六位的数字密码/*	unsigned char buf2[20]={0xaa,0x64,0x00,0x08,0x79,0x00,0x00,0x00,0x00,0x55,0x11,0x11,0xea};
	write(fd,buf2,13);	read(fd,buf2,5);	for( i=0; i<5; i++ ){		printf("%x,	", buf2[i]);	}
	if(buf2[0]==0x55 && buf2[1]==0x00 && buf2[2]==0x00 && buf2[3]==0x00 && buf2[4]==0x55)
		printf("card password accepted\n");*/}
//将data写入开始单元为pos的length个单元
int WriteIc(int region, int pos, int length, unsigned char *data)
{
	int i, j, status;
	unsigned char *buf;
	//动态分配空间, 实际大小为length+10, 其余预留
	buf = malloc( sizeof(unsigned char)*(length+16) );
	buf[0] = 0xaa;//通讯字头
	buf[1] = 0x60;//操作码:读数据
	buf[2] = 0;
	buf[3] = 1+2+2+length;//数据长度
	buf[4] = 0x6e;//卡型编号, 与实际使用相关
	buf[5] = (region >> 8) & 0xff;
	buf[6] = region & 0xff;//分区地址,与实际有关, 2字节
	buf[7] = 0;
	buf[8] = pos;//区内地址, 此处简化处理
	for( i=0; i<length; i++ )
	{
		buf[9+i] = data[i];
	}//操作数据
	j = 0;		for( i=0; i<length+9; i++ )
	{
		printf("%x,	", buf[i]);		j ^= buf[i];
	}
	buf[9+length] = j;//异或和	printf("%x,	", j);
	status = write( fd,buf,length+10 );
	if( status == -1 )
	{
		perror("error write to IC!\n");
		return -1;
	}	printf("write to IC!	\n");	for( ; ; )	{		if ( (status = read(fd,buf,length+5))!=-1 )			break;	} 	for( i=0; i<status; i++ ){		printf("%x,	", buf[i]);	}	printf("\n");	if(buf[0]==0x55 && buf[1]==0x00 && buf[2]==0x00 && buf[3]==0x00 && buf[4]==0x55)
		printf("Ic card writed\n");
	return 0;
}
//返回值:len;
//将开始单元为pos的length个单元读入data, 实际读入len个单元
int ReadIc(int region, int pos, int length, unsigned char *data)
{
	int i, j, len,status;
	unsigned char *buf;
	buf = malloc( sizeof(unsigned char)*(length + 15 ) );
//	fd = OpenDev(dev);
	buf[0] = 0xaa;//通讯字头
	buf[1] = 0x61;//操作码:读数据
	buf[2] = 0;
	buf[3] = 1+2+2+2;//数据长度
	buf[4] = 0x6e;//卡型编号, 与实际使用相关
	buf[5] = (region >> 8) & 0xff;
	buf[6] = region & 0xff;//分区地址,与实际有关, 2字节
	buf[7] = 0;
	buf[8] = pos;//区内地址, 此处简化处理, 2字节
	buf[9] = 0;
	buf[10] = length;//操作数据为长度值, 2字节
	j = 0xaa;
	for( i=1; i<11; i++ )
	{
		j ^= buf[i];
	}
	buf[11] = j;//异或和
	write( fd,buf,12 );
	mdelay(200);
	//data格式:通讯字头+状态编号+数据长度+结果数据+异或和
	//          1byte    1byte    2byte    <=144byte 1byte	for( ; ; )	{		if ( (status = read(fd,buf,length+5))!=-1 )			break;	} 	for( i=0; i<status; i++ ){		printf("%x ", buf[i]);	}	printf("\n");	printf("\n");
//	if( buf[1] == 0x00 )
//	{//		printf("Ic card readed\n");
//	}
	len = buf[3];
	for( i=0; i<len; i++ )
	{
		data[i] = buf[i+4];
	}
	return len;
}//返回值:len;
//将开始单元为pos的length个单元读入data, 实际读入len个单元
int ReadIc1byte(int region, int pos, unsigned char *data)
{
	int i, j, len,status;
	unsigned char *buf;	int length = 1;
	buf = malloc( sizeof(unsigned char)*(length + 15 ) );
//	fd = OpenDev(dev);
	buf[0] = 0xaa;//通讯字头
	buf[1] = 0x61;//操作码:读数据
	buf[2] = 0;
	buf[3] = 1+2+2+2;//数据长度
	buf[4] = 0x6e;//卡型编号, 与实际使用相关
	buf[5] = (region >> 8) & 0xff;
	buf[6] = region & 0xff;//分区地址,与实际有关, 2字节
	buf[7] = 0;
	buf[8] = pos;//区内地址, 此处简化处理, 2字节
	buf[9] = 0;
	buf[10] = length;//操作数据为长度值, 2字节
	j = 0xaa;
	for( i=1; i<11; i++ )
	{
		j ^= buf[i];
	}
	buf[11] = j;//异或和
	write( fd,buf,12 );
	mdelay(200);
	//data格式:通讯字头+状态编号+数据长度+结果数据+异或和
	//          1byte    1byte    2byte    <=144byte 1byte	for( ; ; )	{		if ( (status = read(fd,buf,length+5))!=-1 )			break;	} 	for( i=0; i<status; i++ ){		printf("%x ", buf[i]);	}	printf("\n");
	data[0] = 0x55 ^ 0x1 ^ buf[5];
	return len;
}
/*int WritePic( int length, unsigned char *buf )
{
	unsigned char len[2] = {length, 0};
	WriteIc( 0x20, 1, len );//将buffer长度写入第32个单元
	WriteIc( 0x22, length, buf );//将buffer写入开始地址为第34个单元的length个单元
	return 0;
}
int ReadPic( unsigned char *data )
{
	unsigned char *buf;
	int length;
	ReadIc( 0x20, 1, buf );
	length = buf[0];
	ReadIc( 0x22, length, data );
	return length;
}*/int main(){	int i;	unsigned char data[300];	unsigned char buf[300];	InitSerialPort();	InitIc();	for( i=0; i<144; i++ )	{		data[i] = i;	}//	WritePic(3, data);//	WriteIc(2044, 128, 144, data);/*	for(i = 0; i < 0x4; i++)	{		ReadIc(1, 128 + i, 1, &buf[i]);	}*/	ReadIc1byte(0, 0x8, &buf[0]);	ReadIc(0, 0, 150, buf);	int count = 0;	for( i=0; i<150; i++ )	{		printf("%3x ",buf[i]);		if( ++count == 16 )		{			count = 0;			printf("\n");		}			}	printf("\n");	printf("%x\n",buf[0]);	close(fd);	return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -