PC/SC(Personal Computer/Smart Card)规范,PC/SC 规范作为读卡器和卡与计算机之间有一个标准接口,实现不同生产商的卡和读卡器之间的交互操作
Linux下运行的源码pcsc-lite 在http://pcsclite.alioth.debian.org/
其中有demo例程
- LONG SCardEstablishContext(DWORD dwScope, LPCVOID pvReserved1,LPCVOID pvReserved2, LPSCARDCONTEXT phContext);
-
- 说明:这必须是在PC / SC应用程序中调用的第一个 SCard函数,所有的应用进程都必须建立自己的上下文环境
- 参数:
- dwScope: 输入类型:表示上下文建立的范围,建立本地连接或远程连接,目前支持 SCARD_SCOPE_SYSTEM(在系统域中完成设备数据库操作)
- pvReserved1: 输入类型:保留,为NULL
- pvReserved2: 输入类型:保留,为NULL
- phContext: 输出类型:返回创建的资源管理器上下文
- 返回:
- 成功返回 SCARD_S_SUCCESS
- 失败返回其他值,定义在 pcsclite.h
-
- //@code
- SCARDCONTEXT hContext;
- LONG rv;
-
- rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &posContext);
- if(rv != SCARD_S_SUCCESS)
- {
- LOGE("SCardEstablishContext::failed!\n");
- ret = ERROR_APP_CONTEXT;
- return ret;
- }
- LONG SCardListReaders(SCARDCONTEXT hContext, /*@unused@*/ LPCSTR mszGroups,LPSTR mszReaders, LPDWORD pcchReaders);
- 说明:
- 创建上下文后,就可在上下文中获取系统安装的可用的读卡器列表
-
- 参数:
- hContext: 输入类型;ScardEstablishContext()建立的资源管理器上下文,不能为NULL
- mszGroups: 输入类型;读卡器组名,为 NULL 时,表示列出所有读卡器。
- mszReaders: 输出类型;系统中安装的读卡器的名字,各个名字之间用'\0'分隔,最后一个名字后面为两个连续的'\0'
- pcchReaders: 输入输出类型;mszReaders 的长度
-
- 这个函数在使用时有多种用法,主要是为了给读卡器列表创建空间的方法不同
- 1).当mszReaders为 NULL 时,调用一次SCardListReaders会给pcchReaders输出mszReaders所需要的空间大小,然后自己malloc申请内存空间
- 2).当mszReaders为 NULL 且pcchReaders = SCARD_AUTOALLOCATE 时,SCardListReaders会自动申请内存,但是用完后必须要使用SCardFreeMemory(hContext, mszReaders);释放
- 3).当mszReaders 不为 NULL 时,需用pcchReaders传入其长度,SCardListReaders会在已申请的空间内存放读卡器列表
-
- 返回:
- 成功返回 SCARD_S_SUCCESS
- 失败返回其他值,定义在 pcsclite.h
-
- 这里对3种创建方法做一下代码示例:
-
- //@code1
- SCARDCONTEXT hContext;
- LPSTR mszReaders;
- DWORD dwReaders;
- LONG rv;
- ...
- rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
- rv = SCardListReaders(hContext, NULL, NULL, &dwReaders);
- mszReaders = malloc(sizeof(char)*dwReaders);
- rv = SCardListReaders(hContext, NULL, mszReaders, &dwReaders);
- ...
- free(mszReaders);
-
- //@code2
- SCARDCONTEXT hContext;
- LPSTR mszReaders;
- DWORD dwReaders;
- LONG rv;
- ...
- rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
- dwReaders = SCARD_AUTOALLOCATE;
- rv = SCardListReaders(hContext, NULL, mszReaders, &dwReaders);
- ...
- rv = SCardFreeMemory(hContext, mszReaders);
-
- //@code3
- SCARDCONTEXT hContext;
- LPSTR mszReaders[512];
- DWORD dwReaders;
- LONG rv;
- ...
- rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
- dwReaders = sizeof(mszReaders);
- rv = SCardListReaders(hContext, NULL, mszReaders, &dwReaders);
- ...
-
- 下边是对读卡器名字的拾取代码
- char name[128][3];
- ptr = mszReaders;
- int count = 0;
- while ((*ptr != '\0') && (dwReaders > 0) && (count < 3))
- {
- strcpy(&name[0][count], ptr);
- lens = strlen(&name[0][count]);
- ptr += (lens + 1);
- dwReaders -= (lens + 1);
- count++;
- LOGD("SCardListReaders::Reader Count %d Name:%s\n", count, &name[0][count]);
- }
- 01-17 10:56:44.727: D/smartcardjni(2393): SCardListReaders::Reader Count 1 Name:ZNG Terminal2012-1402 00 00
- 01-17 10:56:44.727: D/smartcardjni(2393): SCardListReaders::Reader Count 2 Name:ZNG Terminal2012-1402 01 00
- LONG SCardGetStatusChange(SCARDCONTEXT hContext, DWORD dwTimeout,SCARD_READERSTATE *rgReaderStates, DWORD cReaders);
-
- 说明:
- 阻塞监听卡插入或状态发生改变
- 参数:
- hContext: 输入类型;ScardEstablishContext()建立的资源管理器上下文
- dwTimeout: 输入类型;监听等待时间,0 或 INFINITE(0xFFFFFFFF)表示永久等待
- rgReaderStates: 输入输出类型;SCARD_READERSTATE 结构体
- cReaders: 输入类型;卡通道数
- 返回:
- 成功返回 SCARD_S_SUCCESS
- 失败返回其他值,定义在 pcsclite.h
- typedef struct
- {
- const char *szReader; //读卡器名
- void *pvUserData; //私有数据
- DWORD dwCurrentState; //读卡器当前状态
- DWORD dwEventState; //读卡器状态改变后的事件
- DWORD cbAtr; //ATR长度
- unsigned char rgbAtr[MAX_ATR_SIZE];//ATR
- }
- SCARD_READERSTATE, *LPSCARD_READERSTATE;
-
- //@code
- SCARDCONTEXT hContext;
- SCARD_READERSTATE rgReaderStates[2];
- LONG rv;
- ...
- rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
- ...
- rgReaderStates[0].szReader = "Reader X";
- rgReaderStates[0].dwCurrentState = SCARD_STATE_UNAWARE;
-
- rgReaderStates[1].szReader = "\\\\?PnP?\\Notification";
- rgReaderStates[1].dwCurrentState = SCARD_STATE_UNAWARE;
- ...
- rv = SCardGetStatusChange(hContext, INFINITE, rgReaderStates, 2);
- printf("reader state: 0x%04X\n", rgReaderStates[0].dwEventState);
- printf("reader state: 0x%04X\n", rgReaderStates[1].dwEventState);
- if(rgReaderStates[0].dwEventState & SCARD_STATE_PRESENT)//卡片插入
- {
-
- }
- if(rgReaderStates[0].dwEventState & SCARD_STATE_EMPTY)//卡片移除
- {
-
- }
- //@endcode
- LONG SCardConnect(SCARDCONTEXT hContext, LPCSTR szReader,DWORD dwShareMode, DWORD dwPreferredProtocols, LPSCARDHANDLE phCard,LPDWORD pdwActiveProtocol);
- 说明:使用该接口后,读卡器上电读取ATR
-
- 参数:
- hContext: 输入类型;ScardEstablishContext()建立的资源管理器上下文
- szReader: 输入类型:要连接的读卡器名
- dwShareMode: 输入类型:连接类型 SCARD_SHARE_SHARED 多个应用共享同一个智能卡
- SCARD_SHARE_EXCLUSIVE 应用独占智能卡
- SCARD_SHARE_DIRECT 私有类型,不允许其他应用访问
- dwPreferredProtocols: 输入类型:使用的协议类型
- SCARD_PROTOCOL_T0 T=0协议
- SCARD_PROTOCOL_T1 T=1协议
- SCARD_PROTOCOL_RAW 原始协议
- phCard: 输出类型:卡的连接句柄
- pdwActiveProtocol: 输出类型:实际使用的协议
- SCARD_PROTOCOL_T0 Use the T=0 protocol.
- SCARD_PROTOCOL_T1 Use the T=1 protocol.
- 返回:
- 成功返回 SCARD_S_SUCCESS
- 失败返回其他值,定义在 pcsclite.h
-
- rv = SCardConnect(hContext, "Reader X", SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &hCard, &dwActiveProtocol);
- LONG SCardStatus(SCARDHANDLE hCard, LPSTR mszReaderName,LPDWORD pcchReaderLen, LPDWORD pdwState,LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen);
- 说明:
- 参数:
- hCard: 输入类型:SCardConnect()建立的卡连接句柄
- mszReaderName: 输入输出类型:连接的读卡器名
- pcchReaderLen: 输入输出类型:mszReaderName 的长度,使用方法同 SCardListReaders 中的 pcchReaders
- pdwState: 输出类型:读卡器的当前状态
- SCARD_UNKNOWN 0x0001 /**< Unknown state */
- SCARD_ABSENT 0x0002 /**< Card is absent */
- SCARD_PRESENT 0x0004 /**< Card is present */
- SCARD_SWALLOWED 0x0008 /**< Card not powered */
- SCARD_POWERED 0x0010 /**< Card is powered */
- SCARD_NEGOTIABLE 0x0020 /**< Ready for PTS */
- SCARD_SPECIFIC 0x0040 /**< PTS has been set */
- pdwProtocol: 输出类型:读卡器当前协议类型
- SCARD_PROTOCOL_T0 Use the T=0 protocol.
- SCARD_PROTOCOL_T1 Use the T=1 protocol.
- pbAtr: 输出类型:当前卡片的ATR
- pcbAtrLen: 输入输出类型:pbAtr 的长度,使用方法同 SCardListReaders 中的 pcchReaders
- 返回:
- 成功返回 SCARD_S_SUCCESS
- 失败返回其他值,定义在 pcsclite.h
- //@code
- ...
- dwAtrLen = sizeof(pbAtr);
- dwReaderLen = sizeof(pbReader);
- rv = SCardStatus(posReaderList.readerList[using_reader_id].hCard, pbReader, &dwReaderLen, &dwState, &dwProt, pbAtr, &dwAtrLen);
- if (rv != SCARD_S_SUCCESS)
- {
- LOGE("SCardStatus %s (0x%lX)\n" , pcsc_stringify_error(rv), rv);
- ret = SCARD_STATUS_FALSE;
- }
- LOGD("pbReader: %s\n", pbReader);
- LOGD("pbAtr: %s\n", pbAtr);
- LONG SCardTransmit(SCARDHANDLE hCard, const SCARD_IO_REQUEST *pioSendPci,LPCBYTE pbSendBuffer, DWORD cbSendLength, SCARD_IO_REQUEST *pioRecvPci, LPBYTE pbRecvBuffer,LPDWORD pcbRecvLength);
-
- 说明:从卡连接成功后就能进行APDU数据传输
- 参数:
- hCard: 输入类型:SCardConnect()建立的卡连接句柄
- pioSendPci: 输入输出类型:发送的指令协议头结构的指针,由 SCARD_IO_REQUEST 结构定义
- pbSendBuffer: 输入类型:发送给卡的APDU指令
- cbSendLength: 输入类型:APDU的长度
- pioRecvPci: 输入输出类型:接收的指令协议头结构的指针,由 SCARD_IO_REQUEST 结构定义,如果不返回可设置为NULL
- pbRecvBuffer: 输出类型:从卡返回的数据
- pcbRecvLength: 输入输出类型:pbRecvBuffer 的实际大小
- 返回:
- 成功返回 SCARD_S_SUCCESS
- 失败返回其他值,定义在 pcsclite.h
-
-
- typedef struct
- {
- unsigned long dwProtocol; /**< Protocol identifier */
- unsigned long cbPciLength; /**< Protocol Control Inf Length */
- }SCARD_IO_REQUEST, *PSCARD_IO_REQUEST, *LPSCARD_IO_REQUEST;
-
- //@code
- rv = SCardConnect(hContext, "Reader X", SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, &hCard, &dwActiveProtocol);
- dwSendLength = sizeof(pbSendBuffer);
- dwRecvLength = sizeof(pbRecvBuffer);
- rv = SCardTransmit(hCard, SCARD_PCI_T0, pbSendBuffer, dwSendLength,&pioRecvPci, pbRecvBuffer, &dwRecvLength);
这组操作一遍用于SCardTransmit() 前后,让传输操作更加安全可靠
- LONG SCardBeginTransaction(SCARDHANDLE hCard);
- 说明:启动一个事务,阻止其它应用程序访问智能卡
- 参数:
- hCard: 输入类型:SCardConnect()建立的卡连接句柄
-
-
- LONG SCardEndTransaction(SCARDHANDLE hCard, DWORD dwDisposition);
- 说明:结束一个事务,允许其它引用程序访问智能卡
- 参数:
- hCard: 输入类型:SCardConnect()建立的卡连接句柄
- dwDisposition 输入类型:结束时对读卡器的操作
- LONG SCardReconnect(SCARDHANDLE hCard, DWORD dwShareMode,DWORD dwPreferredProtocols, DWORD dwInitialization, LPDWORD pdwActiveProtocol);
- 说明:将正在连接的读卡器重新连接,等于热复位
- 参数:
- hCard: 输入类型:SCardConnect()建立的卡连接句柄
- dwShareMode: 输入类型:连接类型 SCARD_SHARE_SHARED 多个应用共享同一个智能卡
- SCARD_SHARE_EXCLUSIVE 应用独占智能卡
- SCARD_SHARE_DIRECT 私有类型,不允许其他应用访问
- dwPreferredProtocols: 输入类型:使用的协议类型
- SCARD_PROTOCOL_T0 T=0协议
- SCARD_PROTOCOL_T1 T=1协议
- SCARD_PROTOCOL_RAW 原始协议
- dwInitialization: 输入类型:读卡器指定的操作,常用作重启
- SCARD_LEAVE_CARD - Do nothing.
- SCARD_RESET_CARD - Reset the card (warm reset).
- SCARD_UNPOWER_CARD - Power down the card (cold reset).
- SCARD_EJECT_CARD - Eject the card.
- pdwActiveProtocol: 输出类型:实际使用的协议
-
- 返回:
- 成功返回 SCARD_S_SUCCESS
- 失败返回其他值,定义在 pcsclite.h
- LONG SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition);
- 说明:断开读卡器连接
- 参数:
- hCard: 输入类型:SCardConnect()建立的卡连接句柄
- dwDisposition 输入类型:断开连接时对读卡器的操作
- SCARD_LEAVE_CARD 0x0000 /**< Do nothing on close */
- SCARD_RESET_CARD 0x0001 /**< Reset on close */
- SCARD_UNPOWER_CARD 0x0002 /**< Power down on close */
- SCARD_EJECT_CARD 0x0003 /**< Eject on close */
- 返回:
- 成功返回 SCARD_S_SUCCESS
- 失败返回其他值,定义在 pcsclite.h
-
- //@code
- rv = SCardDisconnect(hCard, SCARD_UNPOWER_CARD);
- LONG SCardReleaseContext(SCARDCONTEXT hContext);
- 说明:应用程序终止前,释放资源管理器上下文
- 参数:
- hContext: 输入类型;ScardEstablishContext()建立的资源管理器上下文
- 返回:
- 成功返回 SCARD_S_SUCCESS
- 失败返回其他值,定义在 pcsclite.h
示例代码:
- //***********************************
- #define MAX_READER_COUNTS 3
-
- typedef struct _strReaderListInfo
- {
- char reader[128];
- int trans_begin;
- SCARDHANDLE hCard;
- DWORD dwActiveProtocol;
- SCARD_IO_REQUEST pioSendPci;
- SCARD_IO_REQUEST pioRecvPci;
- }StrReaderListInfo, *pStrReaderListInfo;
-
- typedef struct _strReaderList
- {
- int count;
- StrReaderListInfo readerList[MAX_READER_COUNTS];
- }StrReaderList, *pStrReaderList;
-
- unsigned int posReaderId = 1; //readerid
- StrReaderList posReaderList = {0};
- SCARDCONTEXT posContext = 0;
- DWORD posActiveProtocol[MAX_READER_COUNTS];
-
-
-
- //上下文初始化
- unsigned int Pcscd_Init()
- {
- LOGD("%s",__FUNCTION__);
- unsigned int ret = ERROR_NONE;
- LONG rv = 0;
- unsigned int lens = 0;
- DWORD dwReaders;
- unsigned char reader_list_buf[512];
- pStrReaderListInfo pStrInfo;
- unsigned char *ptr = NULL;
- unsigned int tryAgain = 0;
-
- START:
- if(posContext != 0)
- {
- LOGE("SCardEstablishContext::Context has already been created,Release!\n");
- rv = SCardReleaseContext(hContext);
- if(rv != SCARD_S_SUCCESS)
- {
- LOGE("SCardReleaseContext::failed!\n");
- }
- hContext = 0;
- }
- //建立上下文
- memset(&posReaderList, 0, sizeof(StrReaderList));
- rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &posContext);
- if(rv != SCARD_S_SUCCESS)
- {
- LOGE("SCardEstablishContext::failed!\n");
- ret = ERROR_APP_CONTEXT;
- return ret;
- }
- LOGD("SCardEstablishContext::success!\n");
-
- //获取读卡器列表
- dwReaders = sizeof(reader_list_buf);
- rv = SCardListReaders(posContext, NULL, reader_list_buf, &dwReaders);
- if(rv != SCARD_S_SUCCESS)
- {
- LOGE("SCardListReaders::native failed!(0x%x)\n",rv);
- if(posContext != 0)
- {
- SCardReleaseContext(posContext);
- posContext = 0;
-
- }
- if(rv == SCARD_E_NO_READERS_AVAILABLE)
- {
- ret = ERROR_APP_REBOOT_POS;
- }
- else
- {
- ret = ERROR_APP_LISTREADER;
- }
- return ret;
- }
- reader_list_buf[dwReaders] = 0x00;
- reader_list_buf[dwReaders + 1] = 0x00;
-
- posReaderList.count = 0;
- ptr = reader_list_buf;
- while ((*ptr != '\0') && (dwReaders > 0))
- {
- pStrInfo = &posReaderList.readerList[posReaderList.count];
- strcpy(pStrInfo->reader, ptr);
- lens = strlen(pStrInfo->reader);
- ptr += (lens + 1);
- dwReaders -= (lens + 1);
- // pStrInfo->hCard = 0;
- posReaderList.count++;
- LOGD("SCardListReaders::Reader Count %d Name:%s\n", posReaderList.count, pStrInfo->reader);
- if(posReaderList.count >= MAX_READER_COUNTS)
- {
- break;
- }
- }
- if (posReaderList.count < 2)
- {
- LOGE("[%d]::reader count = %d!!!\n",__LINE__,posReaderList.count);
- SCardStopDeamon(posContext);
- sleep(3);
- if(posContext != 0)
- {
- SCardReleaseContext(posContext);
- posContext = 0;
- }
- if(tryAgain == 0)
- {
- ret = ERROR_NONE;
- tryAgain = 1;
- LOGE("init try again");
- goto START;
- }
- else
- {
- ret = ERROR_APP_LISTREADER;
- return ret;
- }
- }
- LOGD("SCardListReaders::success!\r\n");
-
-
- ret = ERROR_NONE;
- return ret;
- }
-
- //释放上下文
- unsigned int Pcscd_Release()
- {
- LOGD("%s",__FUNCTION__);
- unsigned int ret = ERROR_NONE;
- int rv;
- pStrReaderListInfo pStrInfo;
-
- if(posContext == 0)
- {
- LOGE("SCardReleaseContext::Context has not been created!\n");
- ret = ERROR_NONE;
- return ret;
- }
- memset(&posReaderList, 0, sizeof(StrReaderList));
- rv = SCardReleaseContext(posContext);
- if(rv != SCARD_S_SUCCESS)
- {
- LOGE("SCardReleaseContext::native failed!\n");
- posContext = 0;
- ret = ERROR_APP_CONTEXT;
- return ret;
- }
- posContext = 0;
-
- LOGD("SCardReleaseContext::success!\n");
- ret = ERROR_NONE;
- return ret;
- }
-
- //断开卡连接
- int PBOC_DisConnect(unsigned int using_reader_id)
- {
- LOGD("%s(%d)",__FUNCTION__,using_reader_id);
- LONG rv;
- pStrReaderListInfo pStrInfo;
-
- if(using_reader_id < 0 || using_reader_id >= posReaderList.count)
- {
- LOGE("[%d]reader id is wrong(%d)\n",__LINE__, using_reader_id);
- // Nok_Reason = ErrorReason_PCSCD_READERS_ID;
- return FALSE;
- }
-
- pStrInfo = &posReaderList.readerList[using_reader_id];
-
- if(pStrInfo->trans_begin == 1)
- {
- rv = SCardEndTransaction(pStrInfo->hCard,SCARD_LEAVE_CARD);
- if (rv != SCARD_S_SUCCESS)
- {
- if(rv == SCARD_E_NO_SERVICE || rv == SCARD_E_UNKNOWN_READER)
- {
- Reset_Reader();
- }
- LOGE("[%d]::SCardEndTransaction: %s (0x%lX)\n",__LINE__ ,pcsc_stringify_error(rv),rv);
- }
- pStrInfo->trans_begin = 0;
- }
-
- if(pStrInfo->hCard != 0)
- {
- rv = SCardDisconnect(pStrInfo->hCard,SCARD_UNPOWER_CARD);
- if (rv != SCARD_S_SUCCESS)
- {
- if(rv == SCARD_E_NO_SERVICE || rv == SCARD_E_UNKNOWN_READER)
- {
- Reset_Reader();
- }
- LOGE("[%d]::SCardDisconnect: %s (0x%lX)\n",__LINE__ ,pcsc_stringify_error(rv),rv);
- }
- pStrInfo->hCard = 0;
- }
-
-
- return TRUE;
- }
- int PBOC_OpenCard(unsigned char* pAtr,unsigned int * pAtrlen)
- {
- int ret;
-
- LOGD("%s",__FUNCTION__);
-
- //检卡
- DWORD dwReaderLen, dwState, dwProt, dwAtrLen;
- BYTE pbAtr[MAX_ATR_SIZE] = "";
- char pbReader[MAX_READERNAME] = "";
-
- pStrReaderListInfo pStrInfo;
- SCARD_READERSTATE rgReaderStates[1];
-
- pStrInfo = &posReaderList.readerList[posReaderId];
- dwAtrLen = sizeof(pbAtr);
- dwReaderLen = sizeof(pbReader);
-
- smart_card_type = 0;
- rgReaderStates[0].szReader = posReaderList.readerList[posReaderId].reader;
- rgReaderStates[0].dwCurrentState = SCARD_STATE_UNAWARE;
- //检测是否有卡插入
- ret = SCardGetStatusChange(posContext,INFINITE,rgReaderStates,1);
- if (ret != SCARD_S_SUCCESS)
- {
- printf("SCardGetStatusChange err\r\n");
- return -1;
- }
- LOGD("SCardGetStatusChange ok\r\n");
- LOGD("rgReaderStates[0].dwEventState == %ld\r\n",rgReaderStates[0].dwEventState);
- if(rgReaderStates[0].dwEventState & SCARD_STATE_PRESENT)//卡在
- {
- ret= SCardConnect(posContext, pStrInfo->reader, SCARD_SHARE_SHARED,
- SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &pStrInfo->hCard, &posActiveProtocol[posReaderId]);
- if (ret == SCARD_S_SUCCESS)
- {
- ret = SCardStatus(pStrInfo->hCard, pbReader, &dwReaderLen, &dwState, &dwProt,pbAtr, &dwAtrLen);
- if (ret != SCARD_S_SUCCESS)
- {
- return -1;
- }
- MyPrintfBuff("CardAtr:",pbAtr, dwAtrLen);
- //判断ATR是否是非接触卡
- if((pbAtr[2] == 0x81 && pbAtr[3] == 0x01)||(pbAtr[2] == 0x11 && pbAtr[3] == 0x01) )
- {
- smart_card_type = 2;
- }
- //判断ATR 多张非接触卡
- else if((pbAtr[1] == 0x70 && pbAtr[2] == 0x11) )
- {
- smart_card_type = 3;
- }
- //判断ATR是否是接触卡
- else if(!((pbAtr[2] == 0x81 && pbAtr[3] == 0x01)||(pbAtr[2] == 0x11 && pbAtr[3] == 0x01) ||(pbAtr[1] == 0x60 && pbAtr[2] == 0x00)))
- {
- smart_card_type = 1;
- }
- else
- {
- smart_card_type = -1;
- }
- switch(posActiveProtocol[posReaderId])
- {
- case SCARD_PROTOCOL_T0:
- pStrInfo->pioSendPci = *SCARD_PCI_T0;
- LOGD("using T0");
- break;
- case SCARD_PROTOCOL_T1:
- pStrInfo->pioSendPci = *SCARD_PCI_T1;
- LOGD("using T1");
- break;
- default:
- LOGE("Unknown protocol. No card present?\n");
- }
- MyMemcpy(pAtr,pbAtr, dwAtrLen);
- *pAtrlen = dwAtrLen;
- }
- else
- {
-
- }
-
- }
-
- return smart_card_type;
-
- }
-
- //建立卡连接,并做好传输准备
- int PBOC_Connect(int using_reader_id)
- {
- LOGD("%s(%d)",__FUNCTION__,using_reader_id);
- LONG rv;
- int ret = TRUE;
- DWORD dwReaderLen, dwState, dwProt, dwAtrLen;
- BYTE pbAtr[MAX_ATR_SIZE] = "";
- char pbReader[MAX_READERNAME] = "";
- pStrReaderListInfo pStrInfo;
- unsigned int i;
- unsigned int counts = 0;
-
- if(using_reader_id < 0 || using_reader_id >= posReaderList.count)
- {
- LOGE("[%d]reader id is wrong(%d)\n",__LINE__, using_reader_id);
- ret = FALSE;
- // Nok_Reason = ErrorReason_PCSCD_READERS_ID;
- goto ERROR;
- }
- pStrInfo = &posReaderList.readerList[using_reader_id];
-
- /* connect to a reader (even without a card) */
- LOGD("[%d]Using reader: %s\n",__LINE__, posReaderList.readerList[using_reader_id].reader);
-
- while(1)
- {
- if(posReaderList.readerList[using_reader_id].hCard != 0)
- {
- LOGD("connected(%d)",(int)posActiveProtocol[using_reader_id]);
- rv = SCARD_S_SUCCESS;
- LOGD("SCardReconnect");
- rv = SCardReconnect(posReaderList.readerList[using_reader_id].hCard, /*SCARD_SHARE_SHARED*/SCARD_SHARE_SHARED,
- SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,SCARD_RESET_CARD, (DWORD*)&posActiveProtocol);
- }
- else
- {
- LOGD("connect");
- rv = SCardConnect(posContext, posReaderList.readerList[using_reader_id].reader, /*SCARD_SHARE_EXCLUSIVE*/SCARD_SHARE_SHARED,
- SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &posReaderList.readerList[using_reader_id].hCard, &posActiveProtocol[using_reader_id]);
- }
- if (rv != SCARD_S_SUCCESS)
- {
- LOGE("SCardConnect %s (0x%lX)\n" , pcsc_stringify_error(rv), rv);
- counts++;
- if(rv == SCARD_E_SHARING_VIOLATION)
- {
- if(counts < 10)
- {
- usleep(500*1000);
- LOGE("reader is busy,wait 500ms try again(%d)",counts);
- continue;
- }
- }
- else if(rv == SCARD_E_NO_SERVICE || rv == SCARD_E_UNKNOWN_READER)
- {
- Reset_Reader();
- if(counts < 2)
- {
- LOGE("try again(%d)",counts);
- continue;
- }
- }
- ret = FALSE;
- // Nok_Reason = ErrorReason_PCSCD_CONNECT_READERS;
- goto ERROR_NOTHING;
- }
- else
- {
- break;
- }
- }
- pStrInfo->dwActiveProtocol = posActiveProtocol[using_reader_id];
- /* get card status */
- dwAtrLen = sizeof(pbAtr);
- dwReaderLen = sizeof(pbReader);
-
- rv = SCardStatus(posReaderList.readerList[using_reader_id].hCard, pbReader, &dwReaderLen, &dwState, &dwProt,
- pbAtr, &dwAtrLen);
- if (rv != SCARD_S_SUCCESS)
- {
- LOGE("SCardStatus %s (0x%lX)\n" , pcsc_stringify_error(rv), rv);
- ret = FALSE;
- // Nok_Reason = ErrorReason_PCSCD_GET_READERS_STATUS;
- goto ERROR;
- }
- LOGD(" State: 0x%04lX\n", dwState);
-
- if (dwState & SCARD_ABSENT)
- {
- LOGE("No card inserted\n");
- ret = FALSE;
- // Nok_Reason = ErrorReason_PCSCD_NO_CARDS_INSIDE;
- goto ERROR;
- }
-
- switch(posActiveProtocol[using_reader_id])
- {
- case SCARD_PROTOCOL_T0:
- pStrInfo->pioSendPci = *SCARD_PCI_T0;
- LOGD("using T0");
- break;
- case SCARD_PROTOCOL_T1:
- pStrInfo->pioSendPci = *SCARD_PCI_T1;
- LOGD("using T1");
- break;
- default:
- LOGE("Unknown protocol. No card present?\n");
- ret = FALSE;
- // Nok_Reason = ErrorReason_PCSCD_NO_PROTOCOLS_SELECT;
- goto ERROR;
- }
- rv = SCardBeginTransaction(posReaderList.readerList[using_reader_id].hCard);
- if (rv != SCARD_S_SUCCESS)
- {
- if(rv == SCARD_E_NO_SERVICE || rv == SCARD_E_UNKNOWN_READER)
- {
- Reset_Reader();
- }
- LOGE("SCardBeginTransaction %s (0x%lX)\n" , pcsc_stringify_error(rv), rv);
- ret = FALSE;
- // Nok_Reason = ErrorReason_PCSCD_BEGIN_TRANSACTION;
- goto ERROR;
- }
- pStrInfo->trans_begin = 1;
- LOGD("SCardBeginTransaction::success!\n");
- return ret;
- ERROR:
- rv = SCardDisconnect(posReaderList.readerList[using_reader_id].hCard,SCARD_UNPOWER_CARD);
- if (rv != SCARD_S_SUCCESS)
- {
- if(rv == SCARD_E_NO_SERVICE || rv == SCARD_E_UNKNOWN_READER)
- {
- Reset_Reader();
- }
- LOGE("[%d]::SCardDisconnect: %s (0x%lX)\n",__LINE__ ,pcsc_stringify_error(rv),rv);
- }
- ERROR_NOTHING:
- return ret;
- }
- //卡上电连接并获取ATR
- int PBOC_PowerOn(int using_reader_id,unsigned char* pAtr,unsigned int * pAtrlen)
- {
- LOGD("%s",__FUNCTION__);
- LONG rv;
- int ret = TRUE;
- DWORD dwReaderLen, dwState, dwProt, dwAtrLen;
- BYTE pbAtr[MAX_ATR_SIZE] = "";
- char pbReader[MAX_READERNAME] = "";
- pStrReaderListInfo pStrInfo;
- unsigned int i;
- unsigned int counts = 0;
-
- if(using_reader_id < 0 || using_reader_id >= posReaderList.count)
- {
- LOGE("[%d]reader id is wrong(%d)\n",__LINE__, using_reader_id);
- ret = FALSE;
- return ret;
- }
- pStrInfo = &posReaderList.readerList[using_reader_id];
-
- /* connect to a reader (even without a card) */
- LOGD("[%d]Using reader: %s\n",__LINE__, posReaderList.readerList[using_reader_id].reader);
-
- while(1)
- {
- if(pStrInfo->hCard != 0)
- {
- LOGD("SCardConnect(%d)",(int)posActiveProtocol[using_reader_id]);
- rv = SCARD_S_SUCCESS;
- //LOGD("SCardReconnect");
- //rv = SCardReconnect(pStrInfo->hCard, /*SCARD_SHARE_SHARED*/SCARD_SHARE_EXCLUSIVE, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,
- // SCARD_RESET_CARD, &dwposActiveProtocol);
- }
- else
- {
- LOGD("SCardConnect");
- rv = SCardConnect(posContext, pStrInfo->reader, /*SCARD_SHARE_SHARED*/SCARD_SHARE_SHARED,
- SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &pStrInfo->hCard, &posActiveProtocol[using_reader_id]);
- }
- if (rv != SCARD_S_SUCCESS)
- {
- LOGE("SCardConnect %s (0x%lX)\n" , pcsc_stringify_error(rv), rv);
- counts++;
- if(rv == SCARD_E_SHARING_VIOLATION)
- {
- if(counts < 10)
- {
- usleep(500*1000);
- LOGE("reader is busy,wait 500ms try again(%d)",counts);
- continue;
- }
- }
- else if(rv == SCARD_E_NO_SERVICE || rv == SCARD_E_UNKNOWN_READER)
- {
- usleep(2000*1000);
- Pcscd_Init();
- if(counts < 2)
- {
- LOGE("try again(%d)",counts);
- continue;
- }
- }
- ret = FALSE;
- goto ERROR_NOTHING;
- }
- else
- {
- break;
- }
- }
- pStrInfo->dwActiveProtocol = posActiveProtocol[using_reader_id];
- /* get card status */
- dwAtrLen = sizeof(pbAtr);
- dwReaderLen = sizeof(pbReader);
- //获取卡状态信息
- rv = SCardStatus(pStrInfo->hCard, pbReader, &dwReaderLen, &dwState, &dwProt,
- pbAtr, &dwAtrLen);
- if (rv != SCARD_S_SUCCESS)
- {
- LOGE("SCardStatus %s (0x%lX)\n" , pcsc_stringify_error(rv), rv);
- ret = FALSE;
- goto ERROR;
- }
- LOGD(" State: 0x%04lX\n", dwState);
-
- if (dwState & SCARD_ABSENT)
- {
- LOGE("No card inserted\n");
- ret = FALSE;
- goto ERROR;
- }
-
- switch(posActiveProtocol[using_reader_id])
- {
- case SCARD_PROTOCOL_T0:
- pStrInfo->pioSendPci = *SCARD_PCI_T0;
- LOGD("using T0");
- break;
- case SCARD_PROTOCOL_T1:
- pStrInfo->pioSendPci = *SCARD_PCI_T1;
- LOGD("using T1");
- break;
- default:
- LOGE("Unknown protocol. No card present?\n");
- ret = FALSE;
- goto ERROR;
- }
- MyMemcpy(pbAtr,pAtr,dwAtrLen);
- *pAtrlen = dwAtrLen;
- //准备传输状态
- rv = SCardBeginTransaction(pStrInfo->hCard);
- if (rv != SCARD_S_SUCCESS)
- {
- if(rv == SCARD_E_NO_SERVICE || rv == SCARD_E_UNKNOWN_READER)
- {
- Reset_Reader();
- }
- LOGE("SCardBeginTransaction %s (0x%lX)\n" , pcsc_stringify_error(rv), rv);
- ret = FALSE;
- goto ERROR;
- }
- pStrInfo->trans_begin = 1;
- LOGD("SCardBeginTransaction::success!\n");
- return ret;
- ERROR:
- rv = SCardDisconnect(pStrInfo->hCard,SCARD_UNPOWER_CARD);
- if (rv != SCARD_S_SUCCESS)
- {
- if(rv == SCARD_E_NO_SERVICE || rv == SCARD_E_UNKNOWN_READER)
- {
- Reset_Reader();
- }
- LOGE("[%d]::SCardDisconnect: %s (0x%lX)\n",__LINE__ ,pcsc_stringify_error(rv),rv);
- }
- ERROR_NOTHING:
- return ret;
-
-
- }
- int PBOC_PowerOff(int using_reader_id)
- {
- LOGD("%s",__FUNCTION__);
- LONG rv;
- pStrReaderListInfo pStrInfo;
-
- pStrInfo = &posReaderList.readerList[using_reader_id];
- //结束传输
- if(pStrInfo->trans_begin == 1)
- {
- rv = SCardEndTransaction(pStrInfo->hCard,SCARD_LEAVE_CARD);
- if (rv != SCARD_S_SUCCESS)
- {
- if(rv == SCARD_E_NO_SERVICE || rv == SCARD_E_UNKNOWN_READER)
- {
- ResetReader();
- }
- LOGE("[%d]::SCardEndTransaction: %s (0x%lX)\n",__LINE__ ,pcsc_stringify_error(rv),rv);
- }
- pStrInfo->trans_begin = 0;
- }
- //断开连接
- if(posReaderList.readerList[using_reader_id].hCard != 0)
- {
- LOGD("SCardDisconnect");
- rv = SCardDisconnect(pStrInfo->hCard,SCARD_UNPOWER_CARD);
- if (rv != SCARD_S_SUCCESS)
- {
- if(rv == SCARD_E_NO_SERVICE || rv == SCARD_E_UNKNOWN_READER)
- {
- Reset_Reader();
- }
- LOGE("[%d]::CloudPos_PowerOff: %s (0x%lX)\n",__LINE__ ,pcsc_stringify_error(rv),rv);
- }
- pStrInfo->hCard = 0;
- }
- return rv;
- }
-
- int PBOC_APDU_SendAPI(unsigned int using_reader_id,unsigned char * bSendBuffer,unsigned int send_length,unsigned char * bRecvBuffer,unsigned int *length)
- {
- LOGD("%s",__FUNCTION__);
- LONG rv;
- int ret = 0;
- unsigned int i;
- unsigned char temp[64] = {0};
- //char debug_buffer[512] = {0};
-
- pStrReaderListInfo pStrInfo;
-
- if(using_reader_id < 0 || using_reader_id >= posReaderList.count)
- {
- LOGE("[%d]reader id is wrong(%d)\n",__LINE__, using_reader_id);
- ret = FALSE;
- goto SEND_ERROR;
- }
- #ifdef SE_KL81
- if(send_length%64 == 54)
- {
- LOGI("fill 0xFFFF");
- bSendBuffer[send_length] = 0xFF;
- bSendBuffer[send_length+1] = 0xFF;
- send_length += 2;
- }
- #endif
- pStrInfo = &posReaderList.readerList[using_reader_id];
-
- /* APDU select applet */
-
- LOGD("[%d]::PBOC_APDU_SendAPI()::Dev send to card:\n",__LINE__);
- if(send_length >= 256)
- {
- LOGD("send_length is bigger then print buffer length");
- }
- else
- {
- MyPrintfBuff("APDU_send:",bSendBuffer, send_length);
- }
- *length = MAX_BUFFER_SIZE_SZ;
- MyMemset(bRecvBuffer,0x00,MAX_BUFFER_SIZE_SZ);
- if(memcmp(&pStrInfo->pioSendPci,SCARD_PCI_T0,sizeof(pStrInfo->pioSendPci)) == 0)
- {
- LOGD("using T0");
- }
- else if(memcmp(&pStrInfo->pioSendPci,SCARD_PCI_T1,sizeof(pStrInfo->pioSendPci)) == 0)
- {
- LOGD("using T1");
- }
- else
- {
- LOGD("using None");
- }
- rv = SCardTransmit(pStrInfo->hCard, &pStrInfo->pioSendPci, bSendBuffer, (DWORD)send_length,
- &pStrInfo->pioRecvPci, bRecvBuffer, (DWORD *)length);
- if(rv != SCARD_S_SUCCESS)
- {
- if(rv == SCARD_E_NO_SERVICE || rv == SCARD_E_UNKNOWN_READER)
- {
- Reset_Reader();
- }
- MyMemset(bRecvBuffer,0x00,MAX_BUFFER_SIZE_SZ);
- LOGE("SCardTransmit error,try again!(0x%08x)(%d)",(unsigned int)rv,*length);
- snprintf(temp,sizeof(temp),"SCardTransmit error(0x%x)",(unsigned int)rv);
- sleep(1);
- *length = MAX_BUFFER_SIZE_SZ;
- rv = SCardTransmit(pStrInfo->hCard, &pStrInfo->pioSendPci, bSendBuffer, (DWORD )send_length,
- &pStrInfo->pioRecvPci, bRecvBuffer,(DWORD *) length);
-
- if(rv != SCARD_S_SUCCESS)
- {
- if(rv == SCARD_E_NO_SERVICE || rv == SCARD_E_UNKNOWN_READER)
- {
- Reset_Reader();
- }
- LOGE("(rv = 0x%08x)",(unsigned int)rv);
- snprintf(temp,sizeof(temp),"SCardTransmit error again(0x%x)",(unsigned int)rv);
- ret = FALSE;
- goto SEND_ERROR;
- }
- }
- LOGD("[%d]::Card response to dev:\n",__LINE__);
- if(*length >= 5120)
- {
- LOGD("length is bigger then print buffer length.");
- }
- else
- {
- MyPrintfBuff("APDU_Recv:",bRecvBuffer, *length);
- }
- if(*length > 54 && (*length+10)%64 == 2 && (bRecvBuffer[*length-2] == 0xFF && bRecvBuffer[*length-1] == 0xFF))
- {
- LOGD("clean FFFF");
- (*length) -= 2;
- }
-
- PRASE_CARD_RETURN_STATUS:
- if(bRecvBuffer[*length-2] == 0x61)
- {
- LOGD("[%d]::Dev 0x61 to card:\n",__LINE__);
- memset(bSendBuffer,0x00,MAX_BUFFER_SIZE_SZ);
- usleep(100*1000);
- LOGD("[%d]::Card with the remaining returned to %02x%02x\n",__LINE__,bRecvBuffer[0],bRecvBuffer[1]);
- send_length = 5;//00 C0 00 00 2A
- memcpy(bSendBuffer, "\x00\xC0\x00\x00",send_length-1);
-
- bSendBuffer[send_length-1] = bRecvBuffer[*length-1];
-
- LOGD("[%d]::Dev send to card:\n",__LINE__);
- MyMemset(bRecvBuffer,0x00,MAX_BUFFER_SIZE_SZ);
- *length = MAX_BUFFER_SIZE_SZ;
- rv = SCardTransmit(pStrInfo->hCard, &pStrInfo->pioSendPci, bSendBuffer, (DWORD )send_length,
- &pStrInfo->pioRecvPci, bRecvBuffer, (DWORD *)length);
- MyPrintfBuff("APDU_Recv:",bRecvBuffer, *length);
- if(rv != SCARD_S_SUCCESS)
- {
- if(rv == SCARD_E_NO_SERVICE || rv == SCARD_E_UNKNOWN_READER)
- {
- Reset_Reader();
- }
- MyMemset(bRecvBuffer,0x00,MAX_BUFFER_SIZE_SZ);
- LOGE("SCardTransmit error,try again!");
- snprintf(temp,sizeof(temp),"SCardTransmit error(0x%x)",(unsigned int)rv);
- *length = MAX_BUFFER_SIZE_SZ;
- sleep(1);
- rv = SCardTransmit(pStrInfo->hCard, &pStrInfo->pioSendPci, bSendBuffer, (DWORD )send_length,
- &pStrInfo->pioRecvPci, bRecvBuffer, (DWORD *)length);
- if(rv != SCARD_S_SUCCESS)
- {
- if(rv == SCARD_E_NO_SERVICE || rv == SCARD_E_UNKNOWN_READER)
- {
- Reset_Reader();
- }
- LOGE("SCardTransmit error!");
- snprintf(temp,sizeof(temp),"SCardTransmit error again(0x%x)",(unsigned int)rv);
- ret = FALSE;
- goto SEND_ERROR;
- }
- }
- LOGD("[%d]::Card response to dev:\n",__LINE__);
- //memset(debug_buffer,0,sizeof(debug_buffer));
- if(*length >= 5120)
- {
- LOGE("length is bigger then print buffer length");
- }
- else
- {
- // myAsciiToHex(bRecvBuffer, debug_buffer, *length);
- MyPrintfBuff("APDU_Recv:",bRecvBuffer, *length);
-
- }
- if(*length > 54 && (*length+10)%64 == 2 && (bRecvBuffer[*length-2] == 0xFF && bRecvBuffer[*length-1] == 0xFF))
- {
- LOGD("clean FFFF");
- (*length) -= 2;
- }
- }
- else if(bRecvBuffer[*length-2] == 0x6C)
- {
- LOGD("[%d]::Dev 0x6C to card:\n",__LINE__);
- bSendBuffer[send_length-1] = bRecvBuffer[*length-1];
- MyMemset(bRecvBuffer,0x00,MAX_BUFFER_SIZE_SZ);
- rv = SCardTransmit(pStrInfo->hCard, &pStrInfo->pioSendPci, bSendBuffer,(DWORD ) send_length,
- &pStrInfo->pioRecvPci, bRecvBuffer, (DWORD *)length);
- if(rv != SCARD_S_SUCCESS)
- {
- if(rv == SCARD_E_NO_SERVICE || rv == SCARD_E_UNKNOWN_READER)
- {
- Reset_Reader();
- }
- MyMemset(bRecvBuffer,0x00,MAX_BUFFER_SIZE_SZ);
- LOGE("SCardTransmit error,try again!");
- *length = MAX_BUFFER_SIZE_SZ;
- sleep(1);
- rv = SCardTransmit(pStrInfo->hCard, &pStrInfo->pioSendPci, bSendBuffer, (DWORD )send_length,
- &pStrInfo->pioRecvPci, bRecvBuffer, (DWORD*)length);
- if(rv != SCARD_S_SUCCESS)
- {
- if(rv == SCARD_E_NO_SERVICE || rv == SCARD_E_UNKNOWN_READER)
- {
- Reset_Reader();
- }
- // Nok_Reason = ErrorReason_PCSCD_TRANSMIT;
- ret = FALSE;
- goto SEND_ERROR;
- }
- }
- if(*length > 54 && (*length+10)%64 == 2 && (bRecvBuffer[*length-2] == 0xFF && bRecvBuffer[*length-1] == 0xFF))
- {
- LOGD("clean FFFF");
- (*length) -= 2;
- }
- goto PRASE_CARD_RETURN_STATUS;
- }
- else if((bRecvBuffer[*length-2] == 0x6A )&&( bRecvBuffer[*length-1] == 0x83))
- {
- LOGD("[%d]::Card response 6A83",__LINE__);
- }
- else if((bRecvBuffer[*length-2] != 0x90)||(bRecvBuffer[*length-1] != 0x00))
- {
- LOGE("Cards respont isn't 0x9000(0x%02X%02X)!\n",bRecvBuffer[*length-2],bRecvBuffer[*length-1]);
- }
- else
- {
- //LOGD("[%d]::Card response to dev:\n",__LINE__);
- //memset(debug_buffer,0,sizeof(debug_buffer));
- if(*length >= 5120)
- {
- LOGE("length is bigger then print buffer length");
- }
- else
- {
- //myAsciiToHex(bRecvBuffer, debug_buffer, *length);
- //MyPrintfBuff("APDU_Recv:",bRecvBuffer, *length);
- }
- }
- SEND_ERROR:
- return ret;
- }
-
- //main.c
- //使用test程序做PSAM卡和ICC卡通道通讯
- ret = Pcscd_Init();
- if(ret != 0)//读卡器未找到
- {
- return -1;
- }
- while(1)
- {
- printf("Please input command:\n");
- printf("################################\n");
- printf("'0' is select PSAM CARD\n");
- printf("'1' is select ICC CARD\n");
- printf("'quit' is return\n");
- printf("'break' is go back\n");
- printf("################################\n");
- MyMemset(camd_buf,0,sizeof(camd_buf));
- scanf("%s",camd_buf);
- getchar();
- if(MyMemcmp("0",camd_buf,MyStrlen("0")) == 0)
- {
- while(1)
- {
- printf("Please input APDU:\n");
- MyMemset(camd_buf,0,sizeof(camd_buf));
- scanf("%s",camd_buf);
- getchar();
- if(MyMemcmp("break",camd_buf,MyStrlen("break")) == 0)
- break;
- MyStrToHex((camd_buf),send_buf);
- ret = CloudPos_SendToPcscd((unsigned char *)send_buf,0,recv_buf,&recv_len);
-
- MyPrintfBuff("recv_buf::",recv_buf,recv_len);
- }
- }
- else if(memcmp("1",camd_buf,MyStrlen("1")) == 0)
- {
- ret = PBOC_Connect(1);
- if(ret == FALSE)
- {
- printf("Connect(1) error Please try again!\n");
- }
- else
- {
- printf("Connect(1) sucess\n");
- while(1)
- {
- printf("Please input APDU:\n");
- MyMemset(camd_buf,0,sizeof(camd_buf));
- scanf("%s",camd_buf);
- getchar();
- if(MyMemcmp("break",camd_buf,MyStrlen("break")) == 0)
- break;
- send_len = MyStrToHex((camd_buf),send_buf);
-
- ret = PBOC_APDU_SendAPI(1,send_buf,send_len,recv_buf,&recv_len);
- MyPrintfBuff("recv_buf::",recv_buf,recv_len);
-
- }
- }
- PBOC_DisConnect(1);
- }
- else if(MyMemcmp("quit",camd_buf,MyStrlen("quit")) == 0)
- {
- break;
- }
- }
- Pcscd_Release();