📄 ctapi.c
字号:
/* Copyright (C) 1998 Gregor A. Panstruga see ctapi.h for details*/#include <stdio.h>#include <stdlib.h>#include "scio.h"#include "block.h"#include "ctapi.h"#define RESET_CT 0x11#define REQUEST_ICC 0x12#define GET_STATUS 0x13#define EJECT_ICC 0x15#define STS_MSB 0x80#define STS_CardDetect 0x40#define STS_Channel 0x20#define STS_ISOCard 0x10#define STS_T 0x08#define STS_Powered 0x04#define STS_ReaderErr 0x02#define STS_Undefined 0x01#define CTL_Destination 0x80#define CTL_Direction 0x40#define CTL_MSB 0x20#define CTL_PCSC 0x10int ctn2fd[255]= {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};unsigned char SP_SEL_CHAN[] = {0x00, 0x00, 0x00, 0x00, 0x00};unsigned char SP_RESET[] = {0x00, 0x02, 0x00, 0x00, 0x00};unsigned char SP_POWER[] = {0x00, 0x14, 0x00, 0x00, 0x00};unsigned char SP_STATUS[] = {0x00, 0x16, 0x00, 0x00, 0x00};char CT_init ( unsigned short ctn, unsigned short pn ){ int fd, i, retval; if (ctn2fd[ctn] == 0) { fd = scopen (pn, SCODCD, NULL); if (fd < 0) return ERR_INVALID; scsleep(100); } ctn2fd[ctn] = fd; return OK;} char CT_data ( unsigned short ctn, unsigned char * dad, unsigned char * sad, unsigned short lenc, unsigned char * command, unsigned short * lenr, unsigned char * response ){ int fd, retval; unsigned char block2send[300]; unsigned char LEN; unsigned char block2recv[300]; unsigned char STS; unsigned char CTL; unsigned char CLA; unsigned char INS; unsigned char P1; unsigned char P2; unsigned char Lc = 0; unsigned char *DataField = NULL; unsigned char *Le = NULL; int i, timing; int ObjCount; struct TLVObject TLV[10]; if (*lenr < 2) { *lenr = 0; return (ERR_MEMORY); } if (lenc > 261) { *lenr = 2; response[0] = 0x67; response[1] = 0x00; return OK; } // Check wether a serial port is open if ((fd = ctn2fd[ctn]) < 1) { *lenr = 0; return ERR_CT; } // Check for vaild 'dad' if (*dad > 1) { *lenr = 0; return ERR_INVALID; } //Check for valid 'sad' if (*sad != 2) { *lenr = 0; return ERR_INVALID; } // Zerlege 'command' CLA = command[0]; INS = command[1]; P1 = command[2]; P2 = command[3]; if (lenc > 4) { if (lenc == 5) { Le = &command[4]; } else { Lc = command[4]; if (lenc == (Lc + 4)) { DataField = &command[5]; Le = NULL; } if (lenc == (Lc + 5)) { DataField = &command[5]; Le = &command[lenc-1]; } else { *lenr = 2; *sad = CT; *dad = HOST; response[0] = 0x67; response[1] = 0x00; return OK; } } } if (lenc < 4) { *lenr = 2; *sad = CT; *dad = HOST; response[0] = 0x67; response[2] = 0x00; } // Directing command switch (*dad) { case 1: // CT // Check for correct Class if (CLA != 0x20) { *lenr = 2; response[0] = 0x6e; response[1] = 0x00; return (OK); } *sad = CT; *dad = HOST; switch (INS) // INS { case RESET_CT: switch (P1) // P1 { case 0x00: // CT if (P2 != 0) { *lenr = 2; response[0] = 0x6a; response[1] = 0x00; } else { *lenr = 2; response[0] = 0x90; response[1] = 0x00; } return OK; break; case 0x01: // ICC1 CTL = CTL_Destination | CTL_Direction; retval = SendBlock(fd, CTL, sizeof(SP_RESET), SP_RESET); if (retval != 0) { *lenr = 0; return (ERR_TRANS); } retval = GetBlock(fd, &STS, &LEN, block2recv, 1000); if (retval != 0) { *lenr = 0; return (ERR_TRANS); } if ((block2recv[LEN-2] == 0x67) && (block2recv[LEN-1] == 0x04)) { *lenr = 2; response[0] = 0x64; response[1] = 0x00; return OK; } if ((block2recv[LEN-2] == 0x67) && (block2recv[LEN-1] == 0x09)) { *lenr = 2; response[0] = 0x64; response[1] = 0x00; return OK; } if ((block2recv[LEN-2] != 0x90) || (block2recv[LEN-1] != 0x00)) { *lenr = 2; response[0] = 0x64; response[1] = 0x00; return OK; } P2 = P2 & 0x03; if (P2 > 0) { if (*lenr < LEN) { *lenr = 0; return (ERR_MEMORY); } memcpy (response, block2recv, LEN); *lenr = LEN; } else { *lenr = 2; response[0] = 0x90; } if ((STS & STS_ISOCard) == STS_ISOCard) { response[*lenr-1] = 0x01; } else { response[*lenr-1] = 0x00; } return OK; break; default: *lenr = 2; response[0] = 0x6a; response[1] = 0x00; return OK; } break; case REQUEST_ICC: if (P1 != 0x01) { *lenr = 2; response[0] = 0x6a; response[1] = 0x00; return OK; } timing = 0; if (Lc == 1) { timing = DataField[0]*10; } if (Lc > 1) { ObjCount = DecodeTLV(TLV, Lc, DataField); if (ObjCount < 1) { timing = 0; } else { for (i=0; i<ObjCount; i++) { if ((TLV[i].Tag) == 0x80) { timing = TLV[i].Value[0]*10; break; } else { timing = 0; } } } } for (i=1; i<timing; i++) { retval = SendBlock(fd, 0xc0, sizeof(SP_STATUS), SP_STATUS); if (retval != 0) { *lenr = 0; return (ERR_TRANS); } retval = GetBlock(fd, &STS, &LEN, block2recv, 1000); if (retval != 0) { *lenr = 0; return (ERR_TRANS); } if ((STS & STS_Powered) == STS_Powered) { *lenr = 2; response[0] = 0x62; response[1] = 0x01; return OK; } if ((STS & STS_CardDetect) == STS_CardDetect) { break; } scsleep (100); } if ((STS & STS_CardDetect) != STS_CardDetect)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -