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

📄 ph8550_sc.c

📁 smart card智能卡的读写测试程序
💻 C
📖 第 1 页 / 共 2 页
字号:
	for(i = 0; i < sizeof(supported_baudrate)/sizeof(struct sc_baudrate); i ++)		if( (supported_baudrate[i].fi == fi) && (supported_baudrate[i].di == di))		{			find_baudrate = 1;			break;		}		else			find_baudrate = 0;	if(!find_baudrate)		return -1;	if(supported_baudrate[i].psc == 32)		UCR2 |= 0x01; 	else		UCR2 &= (~0x01); 		PDR = supported_baudrate[i].pdr;	smartcard_dev.fi = fi;	smartcard_dev.di = di;	smartcard_dev.etu = supported_baudrate[i].psc * supported_baudrate[i].pdr;	return 0;}static int sc_SetReaderParameter(sc_parameter p){/////////here, set the baudrate//////////////////////////////		if(sc_SetBaudRate(p.fi, p.di) == -1)		return -2;      //can't find the appropriate baudrate/////////here, set the guard time between of characters	//////	GTR = p.gtr_time;	smartcard_dev.gtr_time = p.gtr_time;/////////here, set the protocal /////////////////////////////		if(p.protocol)		UCR1 |= 0x10;	else		UCR1 &=(~0x10);	smartcard_dev.prot = p.protocol;/////////here, weather remove the parity bit ////////////////		if(p.rm_parity)	{		CCR |= 0x40;		smartcard_dev.remove_parity = 1;	}	else	{		CCR &= (~0x40);		smartcard_dev.remove_parity = 0;	}/////////here, set the clock card frequency ///////////////////////			if((p.div_clock_multiple >=0) && (p.div_clock_multiple < 8))		sc_SetDivClock(p.div_clock_multiple);	else 		smartcard_dev.clock = 54*1024/supported_div_Hz[CCR&0x07].multiple;    // if this happens, there is someting wrong		/* set reader baud rate and update dev->clock , so we can calcute etu */	return 0;}static int  sc_PPS(unsigned char *pps_q, unsigned int n, unsigned char *pps_r, unsigned int i){	unsigned char F, D;	int error = 0;	AtrOrWr_flag = 1;	memset(pps_r, 0 , 6);			if((error = sc_RawWrite(pps_q,&n))>0)		return error;	if((error = sc_RawRead(pps_r,&i))>0)		return error;					if(pps_r[0]==0xff)	{		smartcard_dev.prot = pps_r[1]&0x0f;		if(smartcard_dev.prot)			UCR1 |= 0x10;		else			UCR1 &=(~0x10);		if(pps_r[1]&0x10)		{ 			if(pps_r[2]==pps_q[2])			{				smartcard_dev.fi = (pps_r[2]&0xf0)>>4;				smartcard_dev.di = pps_r[2]&0x0f;				if(sc_SetBaudRate(smartcard_dev.fi, smartcard_dev.di) == -1)					return SC_ERROR_PPS_SET_BAUDRATE;			}			else				return SC_ERROR_PPS_TREAT_BAUDRATE;		}		else 		{			F = 1;			D = 1;			if(sc_SetBaudRate(smartcard_dev.fi, smartcard_dev.di) == -1)				return SC_ERROR_PPS_DEFAULT_BAUDRATE;              //can't find the appropriate baudrate		}		if(pps_r[1]&0x20)		{			if(pps_r[3]!=pps_q[3])				return SC_ERROR_PPS_GT_BAUDRATE;		}		if(pps_r[1]&0x40)		{			if(pps_r[4]!=pps_q[4])				return SC_ERROR_PPS_CHECK;		}		return 0;	}	else		return SC_ERROR_PPS_PROTOCOL;}//ATR处理static int sc_AtrProc(void){	int i = smartcard_dev.atr_len;	unsigned char  T0,TA1,TB1,TC1,TD1,TA2,TB2,TC2,TD2,TA3,TB3,TC3,TD3,TA4,TB4,TC4,TD4;	unsigned char  K=0,F=1,D=1,P=5,I=50,N=0xff,wi=10,T=0;			//参数缺省值	unsigned char  idx=0,TCK=0;	unsigned char  TA1_flg=0,TB1_flg=0,TA2_flg=0,TB2_flg=0;	int   pps_error = 0;	unsigned char  PPS_Q[4] = {0xff,0x10,0x11,0xfe};			SCIF_INT_ENABLE &= (~0x01);  //close tbe/rbf interrupt			if((smartcard_dev.atr_buffer[0]!=0x3B) && (smartcard_dev.atr_buffer[0]!=0x3F))				//接收异常		return SC_ERROR_ATR_PROTOCOL;			if((smartcard_dev.atr_buffer[0]==0x3B) || (smartcard_dev.atr_buffer[0]==0x3F))				//正常的起始字符	{		idx = 1;		T0 = smartcard_dev.atr_buffer[idx++];		K = T0 & 0x0f;		if(T0&0x10)		{			TA1 = smartcard_dev.atr_buffer[idx++];			PPS_Q[2] = smartcard_dev.atr_buffer[2];			PPS_Q[3] = PPS_Q[0]^PPS_Q[1]^PPS_Q[2];			TA1_flg=1;		}		if(T0&0x20)		{			TB1 = smartcard_dev.atr_buffer[idx++];			TB1_flg=1;		}			if(T0&0x40)		{			TC1 = smartcard_dev.atr_buffer[idx++];			N = TC1;		}		if(T0&0x80)		{			TD1 = smartcard_dev.atr_buffer[idx++];			T = TD1&0x0f;			if(TD1&0x10)			{				TA2 = smartcard_dev.atr_buffer[idx++];				TA2_flg=1;			}			if(TD1&0x20)			{				TB2 = smartcard_dev.atr_buffer[idx++];				TB2_flg=1;							}			if(TD1&0x40)			{				TC2 = smartcard_dev.atr_buffer[idx++];				wi = TC2;			}			if(TD1&0x80)			{				TD2 = smartcard_dev.atr_buffer[idx++];				T = TD2&0x0f;				if(TD2&0x10)					TA3 = smartcard_dev.atr_buffer[idx++];				if(TD2&0x20)					TB3 = smartcard_dev.atr_buffer[idx++];				if(TD2&0x40)					TC3 = smartcard_dev.atr_buffer[idx++];				if(TD2&0x80)				{					TD3 = smartcard_dev.atr_buffer[idx++];					T = TD3&0x0f;					if(TD3&0x10)						TA4 = smartcard_dev.atr_buffer[idx++];					if(TD3&0x20)						TB4 = smartcard_dev.atr_buffer[idx++];					if(TD3&0x40)						TC4 = smartcard_dev.atr_buffer[idx++];					if(TD3&0x80)					{						TD4 = smartcard_dev.atr_buffer[idx++];						T = TD4&0x0f;					}				}			}		}			if(T)			TCK = smartcard_dev.atr_buffer[i-1];		if(T==15 && TB1_flg)		{			P = TB1&0x3f;				I = (TB1&0xc0)>>6;			if(TB2_flg)				P = TB2;		}			if(T>1)		 	T = 1;		 			if(TA1_flg && TA2_flg && !(TA2&0x10))			//F/D存在,且为专用模式,b5=0		{			F = (TA1&0xf0)>>4;			D = TA1&0x0f;		}						para.gtr_time = N;		para.protocol = T;		para.cwi = 960 * wi;		if(TA1_flg && !TA2_flg)				        //F/D存在,且为协商模式		{			F = 1;			D = 1;			sc_SetBaudRate(F, D);											//PPS request			pps_error = sc_PPS(PPS_Q,4,PPS_R,4);			if(!pps_error)			{				#ifdef DEBUG					printk(KERN_INFO"PPS success!!!\n");				#endif				return 0;			}			else			{			 	#ifdef DEBUG			 		printk(KERN_INFO"PPS failed!!!\n");			 	#endif			 	return pps_error;			}		}	}	return 0;}static int sc_T0_APDU(unsigned char *pSnd, unsigned int slen, unsigned char *pRcv){	unsigned char 	ack, sw1, sw2;//, INS;	unsigned int 	i=5, le=0, lc=0, readlen =0;	char	error = 0;		if(slen == 5)								// 情况1和2		le = pSnd[4];	if(slen > 5)								// 情况3和4	{		lc = pSnd[4];		if((5+lc) < slen)			le = pSnd[slen-1];	}	error = sc_RawWrite(pSnd, &i);  // send apdu cmd	if(error > 0)		return error;	while(1)	{		//receive one ack		readlen = 1;		error = sc_RawRead(&ack,&readlen);		if(error > 0)			return error;		//analyse the ack		if(ack == 0x60)									// NULL			continue;		else if(((ack&0xF0) == 0x60) || ((ack&0xF0) == 0x90))		{			sw1 = ack;			readlen = 1;			error = sc_RawRead(&sw2,&readlen);			if(error > 0)				return error;			return  ((sw1<<8)|sw2);		}		else 		{			if(((ack^pSnd[1])== 0x00) || ((ack^pSnd[1]) == 0x01))			{				if(lc > 0)				{					error = sc_RawWrite(&pSnd[5], &lc);					if(error > 0)						return error;				}				if(le > 0)				{					error = sc_RawRead(pRcv, &le);					if(error > 0)						return error;					APDU_RESULT_MUN = le;				}				continue;			}			if(((ack^pSnd[1]) == 0xff) || ((ack^pSnd[1]) == 0xfe))			{				if((i-5)<lc)				{					readlen = 1;					error = sc_RawRead(&pSnd[i++],&readlen);					if(error > 0)						return error;				}				continue;			}		}	}}static int sc_ioctl(struct inode *inode, struct file *flip, unsigned int cmd, unsigned long arg){	int error = 0;	switch(cmd)	{		case SC_IOC_WARMACTIVATE:			if(smartcard_dev.exist == 0)				error = SC_ERROR_NOCARD;			else				warm_reset();			break;		case SC_IOC_DEACTIVATE: 			Sc_DeactivateCard();			break;		case SC_IOC_ATRPROC:			if(smartcard_dev.exist == 0)				error = SC_ERROR_NOCARD;			else				error = sc_AtrProc();			break;		case SC_IOC_GETPPSRESULT:			if(smartcard_dev.exist == 0)			{				error = SC_ERROR_NOCARD;				break;			}			if(copy_to_user((void*)arg, (void*)PPS_R, 6))				error = SC_ERROR_KNTOUSER;			break;					case SC_IOC_GETAPDUSULT:			if(smartcard_dev.exist == 0)			{				error = SC_ERROR_NOCARD;				break;			}			if(copy_to_user((void*)arg, (void*)APDU_RESULT, APDU_RESULT_MUN))				error = SC_ERROR_KNTOUSER;			else				APDU_RESULT_MUN = 0;			break;					case SC_IOC_GETCARDEXIST:			if(copy_to_user((void*)arg, (void*)&smartcard_dev.exist, sizeof(int)))				error = SC_ERROR_KNTOUSER;			break;								case SC_IOC_SETAPDUCMD:			if(smartcard_dev.exist == 0)			{				error = SC_ERROR_NOCARD;				break;			}			if(APDU_CMD_NUM <= 0)			{				error = SC_ERROR_CTL_CMDMUN;				break;			}			if(copy_from_user((void*)APDU_CMD, (void*)arg, APDU_CMD_NUM))				error = SC_ERROR_USERTOKN;			break;					case SC_IOC_SETAPDUCMDNUM:			if(smartcard_dev.exist == 0)			{				error = SC_ERROR_NOCARD;				break;			}			if(copy_from_user((void*)&APDU_CMD_NUM, (void*)arg, sizeof(int)))				error = SC_ERROR_USERTOKN;			break;		case SC_IOC_SETPARAMETER:			if(smartcard_dev.exist == 0)			{				error = SC_ERROR_NOCARD;				break;			}			if(copy_from_user((void *)&para, (void *)arg, sizeof(sc_parameter)))			{				error = SC_ERROR_USERTOKN;				break;			}			if(sc_SetReaderParameter(para)== -2)				error = SC_ERROR_SET_READERPARA;			break;		case SC_IOC_GETATR:			if(smartcard_dev.exist == 0)			{				error = SC_ERROR_NOCARD;				break;			}			if(access_ok(VERIFY_WRITE,arg,smartcard_dev.atr_len)==-EFAULT)			{				#ifdef DEBUG					printk(KERN_INFO"cann't write atrbuf\n");				#endif				error = SC_ERROR_VERIFY_ATRBUF;				break;			}			if(copy_to_user((void*)arg, (void*)smartcard_dev.atr_buffer, smartcard_dev.atr_len))				error =  SC_ERROR_KNTOUSER;			break;		case SC_IOC_EXECUTECMD:			if(smartcard_dev.exist == 0)			{				error = SC_ERROR_NOCARD;				break;			}			error = sc_T0_APDU(APDU_CMD, APDU_CMD_NUM, APDU_RESULT);			break;			case SC_IOC_GETSTATUS:			if(copy_to_user((void*)arg, (void*)&smartcard_dev, sizeof(SmartCard_Dev)))				error = SC_ERROR_KNTOUSER;			else 				error = 0;			break;					default:			return -ENOTTY;	}	if(!error)		return 0;	else		return error;}		struct file_operations sc_fops =                                                 {	owner: 		THIS_MODULE,	open:		sc_open,	ioctl:		sc_ioctl,	//read:		sc_read,	//write:	sc_write,	release:	sc_release,};//struct cdev *pnx8550_sc_cdev;static int __init smartcard_init(void){   	if(register_chrdev(SMARTCARD_MAJOR,"smcard",&sc_fops) < 0)        {                printk(KERN_INFO"Register char dev error\n");                return -1;        }        devfs_mk_cdev(MKDEV(SMARTCARD_MAJOR,0),S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP,"smcard");  	#ifdef DEBUG  		printk(KERN_INFO"Ph8550 SC Module ID = 0x%x\n", SCIF_MODULE_ID);	#endif	printk(KERN_INFO"SmartCard driver has been installed successfully!\n");		memset(&smartcard_dev,0,sizeof(SmartCard_Dev));	memset(&para,0,sizeof(sc_parameter));	return 0;}static void __exit smartcard_exit(void){	p_atr = NULL;	devfs_remove("smcard");	unregister_chrdev(SMARTCARD_MAJOR, "smcard");	printk(KERN_INFO"SmartCard driver has been canceled successfully!\n");}module_init(smartcard_init);module_exit(smartcard_exit);MODULE_DESCRIPTION("PNX8950 Smart-Uart1 Driver, Just for T0 Card");MODULE_AUTHOR("FanJie Meng:Aero-Info Corp.");MODULE_LICENSE("Proprietary");

⌨️ 快捷键说明

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