• Linux下对PC/SC智能卡接口编程


    PC/SC(Personal Computer/Smart Card)规范,PC/SC 规范作为读卡器和卡与计算机之间有一个标准接口,实现不同生产商的卡和读卡器之间的交互操作

    Linux下运行的源码pcsc-lite 在http://pcsclite.alioth.debian.org/
    其中有demo例程

    1.建立资源管理器上下文

    1. LONG SCardEstablishContext(DWORD dwScope, LPCVOID pvReserved1,LPCVOID pvReserved2, LPSCARDCONTEXT phContext);
    2. 说明:这必须是在PC / SC应用程序中调用的第一个 SCard函数,所有的应用进程都必须建立自己的上下文环境
    3. 参数:
    4. dwScope: 输入类型:表示上下文建立的范围,建立本地连接或远程连接,目前支持 SCARD_SCOPE_SYSTEM(在系统域中完成设备数据库操作)
    5. pvReserved1: 输入类型:保留,为NULL
    6. pvReserved2: 输入类型:保留,为NULL
    7. phContext: 输出类型:返回创建的资源管理器上下文
    8. 返回:
    9. 成功返回 SCARD_S_SUCCESS
    10. 失败返回其他值,定义在 pcsclite.h
    11. //@code
    12. SCARDCONTEXT hContext;
    13. LONG rv;
    14. rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &posContext);
    15. if(rv != SCARD_S_SUCCESS)
    16. {
    17. LOGE("SCardEstablishContext::failed!\n");
    18. ret = ERROR_APP_CONTEXT;
    19. return ret;
    20. }

    2.获取系统可用读卡器列表

    1. LONG SCardListReaders(SCARDCONTEXT hContext, /*@unused@*/ LPCSTR mszGroups,LPSTR mszReaders, LPDWORD pcchReaders);
    2. 说明:
    3. 创建上下文后,就可在上下文中获取系统安装的可用的读卡器列表
    4. 参数:
    5. hContext: 输入类型;ScardEstablishContext()建立的资源管理器上下文,不能为NULL
    6. mszGroups: 输入类型;读卡器组名,为 NULL 时,表示列出所有读卡器。
    7. mszReaders: 输出类型;系统中安装的读卡器的名字,各个名字之间用'\0'分隔,最后一个名字后面为两个连续的'\0'
    8. pcchReaders: 输入输出类型;mszReaders 的长度
    9. 这个函数在使用时有多种用法,主要是为了给读卡器列表创建空间的方法不同
    10. 1).当mszReaders为 NULL 时,调用一次SCardListReaders会给pcchReaders输出mszReaders所需要的空间大小,然后自己malloc申请内存空间
    11. 2).当mszReaders为 NULL 且pcchReaders = SCARD_AUTOALLOCATE 时,SCardListReaders会自动申请内存,但是用完后必须要使用SCardFreeMemory(hContext, mszReaders);释放
    12. 3).当mszReaders 不为 NULL 时,需用pcchReaders传入其长度,SCardListReaders会在已申请的空间内存放读卡器列表
    13. 返回:
    14. 成功返回 SCARD_S_SUCCESS
    15. 失败返回其他值,定义在 pcsclite.h
    16. 这里对3种创建方法做一下代码示例:
    17. //@code1
    18. SCARDCONTEXT hContext;
    19. LPSTR mszReaders;
    20. DWORD dwReaders;
    21. LONG rv;
    22. ...
    23. rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
    24. rv = SCardListReaders(hContext, NULL, NULL, &dwReaders);
    25. mszReaders = malloc(sizeof(char)*dwReaders);
    26. rv = SCardListReaders(hContext, NULL, mszReaders, &dwReaders);
    27. ...
    28. free(mszReaders);
    29. //@code2
    30. SCARDCONTEXT hContext;
    31. LPSTR mszReaders;
    32. DWORD dwReaders;
    33. LONG rv;
    34. ...
    35. rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
    36. dwReaders = SCARD_AUTOALLOCATE;
    37. rv = SCardListReaders(hContext, NULL, mszReaders, &dwReaders);
    38. ...
    39. rv = SCardFreeMemory(hContext, mszReaders);
    40. //@code3
    41. SCARDCONTEXT hContext;
    42. LPSTR mszReaders[512];
    43. DWORD dwReaders;
    44. LONG rv;
    45. ...
    46. rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
    47. dwReaders = sizeof(mszReaders);
    48. rv = SCardListReaders(hContext, NULL, mszReaders, &dwReaders);
    49. ...
    50. 下边是对读卡器名字的拾取代码
    51. char name[128][3];
    52. ptr = mszReaders;
    53. int count = 0;
    54. while ((*ptr != '\0') && (dwReaders > 0) && (count < 3))
    55. {
    56. strcpy(&name[0][count], ptr);
    57. lens = strlen(&name[0][count]);
    58. ptr += (lens + 1);
    59. dwReaders -= (lens + 1);
    60. count++;
    61. LOGD("SCardListReaders::Reader Count %d Name:%s\n", count, &name[0][count]);
    62. }
    63. 01-17 10:56:44.727: D/smartcardjni(2393): SCardListReaders::Reader Count 1 Name:ZNG Terminal2012-1402 00 00
    64. 01-17 10:56:44.727: D/smartcardjni(2393): SCardListReaders::Reader Count 2 Name:ZNG Terminal2012-1402 01 00

    3.监测卡片插入

    1. LONG SCardGetStatusChange(SCARDCONTEXT hContext, DWORD dwTimeout,SCARD_READERSTATE *rgReaderStates, DWORD cReaders);
    2. 说明:
    3. 阻塞监听卡插入或状态发生改变
    4. 参数:
    5. hContext: 输入类型;ScardEstablishContext()建立的资源管理器上下文
    6. dwTimeout: 输入类型;监听等待时间,0 或 INFINITE(0xFFFFFFFF)表示永久等待
    7. rgReaderStates: 输入输出类型;SCARD_READERSTATE 结构体
    8. cReaders: 输入类型;卡通道数
    9. 返回:
    10. 成功返回 SCARD_S_SUCCESS
    11. 失败返回其他值,定义在 pcsclite.h
    12. typedef struct
    13. {
    14. const char *szReader; //读卡器名
    15. void *pvUserData; //私有数据
    16. DWORD dwCurrentState; //读卡器当前状态
    17. DWORD dwEventState; //读卡器状态改变后的事件
    18. DWORD cbAtr; //ATR长度
    19. unsigned char rgbAtr[MAX_ATR_SIZE];//ATR
    20. }
    21. SCARD_READERSTATE, *LPSCARD_READERSTATE;
    22. //@code
    23. SCARDCONTEXT hContext;
    24. SCARD_READERSTATE rgReaderStates[2];
    25. LONG rv;
    26. ...
    27. rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
    28. ...
    29. rgReaderStates[0].szReader = "Reader X";
    30. rgReaderStates[0].dwCurrentState = SCARD_STATE_UNAWARE;
    31. rgReaderStates[1].szReader = "\\\\?PnP?\\Notification";
    32. rgReaderStates[1].dwCurrentState = SCARD_STATE_UNAWARE;
    33. ...
    34. rv = SCardGetStatusChange(hContext, INFINITE, rgReaderStates, 2);
    35. printf("reader state: 0x%04X\n", rgReaderStates[0].dwEventState);
    36. printf("reader state: 0x%04X\n", rgReaderStates[1].dwEventState);
    37. if(rgReaderStates[0].dwEventState & SCARD_STATE_PRESENT)//卡片插入
    38. {
    39. }
    40. if(rgReaderStates[0].dwEventState & SCARD_STATE_EMPTY)//卡片移除
    41. {
    42. }
    43. //@endcode

    4.连接读卡器

    1. LONG SCardConnect(SCARDCONTEXT hContext, LPCSTR szReader,DWORD dwShareMode, DWORD dwPreferredProtocols, LPSCARDHANDLE phCard,LPDWORD pdwActiveProtocol);
    2. 说明:使用该接口后,读卡器上电读取ATR
    3. 参数:
    4. hContext: 输入类型;ScardEstablishContext()建立的资源管理器上下文
    5. szReader: 输入类型:要连接的读卡器名
    6. dwShareMode: 输入类型:连接类型 SCARD_SHARE_SHARED 多个应用共享同一个智能卡
    7. SCARD_SHARE_EXCLUSIVE 应用独占智能卡
    8. SCARD_SHARE_DIRECT 私有类型,不允许其他应用访问
    9. dwPreferredProtocols: 输入类型:使用的协议类型
    10. SCARD_PROTOCOL_T0 T=0协议
    11. SCARD_PROTOCOL_T1 T=1协议
    12. SCARD_PROTOCOL_RAW 原始协议
    13. phCard: 输出类型:卡的连接句柄
    14. pdwActiveProtocol: 输出类型:实际使用的协议
    15. SCARD_PROTOCOL_T0 Use the T=0 protocol.
    16. SCARD_PROTOCOL_T1 Use the T=1 protocol.
    17. 返回:
    18. 成功返回 SCARD_S_SUCCESS
    19. 失败返回其他值,定义在 pcsclite.h
    20. rv = SCardConnect(hContext, "Reader X", SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &hCard, &dwActiveProtocol);

    5.获取卡片状态和ATR

    1. LONG SCardStatus(SCARDHANDLE hCard, LPSTR mszReaderName,LPDWORD pcchReaderLen, LPDWORD pdwState,LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen);
    2. 说明:
    3. 参数:
    4. hCard: 输入类型:SCardConnect()建立的卡连接句柄
    5. mszReaderName: 输入输出类型:连接的读卡器名
    6. pcchReaderLen: 输入输出类型:mszReaderName 的长度,使用方法同 SCardListReaders 中的 pcchReaders
    7. pdwState: 输出类型:读卡器的当前状态
    8. SCARD_UNKNOWN 0x0001 /**< Unknown state */
    9. SCARD_ABSENT 0x0002 /**< Card is absent */
    10. SCARD_PRESENT 0x0004 /**< Card is present */
    11. SCARD_SWALLOWED 0x0008 /**< Card not powered */
    12. SCARD_POWERED 0x0010 /**< Card is powered */
    13. SCARD_NEGOTIABLE 0x0020 /**< Ready for PTS */
    14. SCARD_SPECIFIC 0x0040 /**< PTS has been set */
    15. pdwProtocol: 输出类型:读卡器当前协议类型
    16. SCARD_PROTOCOL_T0 Use the T=0 protocol.
    17. SCARD_PROTOCOL_T1 Use the T=1 protocol.
    18. pbAtr: 输出类型:当前卡片的ATR
    19. pcbAtrLen: 输入输出类型:pbAtr 的长度,使用方法同 SCardListReaders 中的 pcchReaders
    20. 返回:
    21. 成功返回 SCARD_S_SUCCESS
    22. 失败返回其他值,定义在 pcsclite.h
    23. //@code
    24. ...
    25. dwAtrLen = sizeof(pbAtr);
    26. dwReaderLen = sizeof(pbReader);
    27. rv = SCardStatus(posReaderList.readerList[using_reader_id].hCard, pbReader, &dwReaderLen, &dwState, &dwProt, pbAtr, &dwAtrLen);
    28. if (rv != SCARD_S_SUCCESS)
    29. {
    30. LOGE("SCardStatus %s (0x%lX)\n" , pcsc_stringify_error(rv), rv);
    31. ret = SCARD_STATUS_FALSE;
    32. }
    33. LOGD("pbReader: %s\n", pbReader);
    34. LOGD("pbAtr: %s\n", pbAtr);

    6.读卡器数据传输

    1. LONG SCardTransmit(SCARDHANDLE hCard, const SCARD_IO_REQUEST *pioSendPci,LPCBYTE pbSendBuffer, DWORD cbSendLength, SCARD_IO_REQUEST *pioRecvPci, LPBYTE pbRecvBuffer,LPDWORD pcbRecvLength);
    2. 说明:从卡连接成功后就能进行APDU数据传输
    3. 参数:
    4. hCard: 输入类型:SCardConnect()建立的卡连接句柄
    5. pioSendPci: 输入输出类型:发送的指令协议头结构的指针,由 SCARD_IO_REQUEST 结构定义
    6. pbSendBuffer: 输入类型:发送给卡的APDU指令
    7. cbSendLength: 输入类型:APDU的长度
    8. pioRecvPci: 输入输出类型:接收的指令协议头结构的指针,由 SCARD_IO_REQUEST 结构定义,如果不返回可设置为NULL
    9. pbRecvBuffer: 输出类型:从卡返回的数据
    10. pcbRecvLength: 输入输出类型:pbRecvBuffer 的实际大小
    11. 返回:
    12. 成功返回 SCARD_S_SUCCESS
    13. 失败返回其他值,定义在 pcsclite.h
    14. typedef struct
    15. {
    16. unsigned long dwProtocol; /**< Protocol identifier */
    17. unsigned long cbPciLength; /**< Protocol Control Inf Length */
    18. }SCARD_IO_REQUEST, *PSCARD_IO_REQUEST, *LPSCARD_IO_REQUEST;
    19. //@code
    20. rv = SCardConnect(hContext, "Reader X", SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, &hCard, &dwActiveProtocol);
    21. dwSendLength = sizeof(pbSendBuffer);
    22. dwRecvLength = sizeof(pbRecvBuffer);
    23. rv = SCardTransmit(hCard, SCARD_PCI_T0, pbSendBuffer, dwSendLength,&pioRecvPci, pbRecvBuffer, &dwRecvLength);

    7.独占访问

    这组操作一遍用于SCardTransmit() 前后,让传输操作更加安全可靠
    
    1. LONG SCardBeginTransaction(SCARDHANDLE hCard);
    2. 说明:启动一个事务,阻止其它应用程序访问智能卡
    3. 参数:
    4. hCard: 输入类型:SCardConnect()建立的卡连接句柄
    5. LONG SCardEndTransaction(SCARDHANDLE hCard, DWORD dwDisposition);
    6. 说明:结束一个事务,允许其它引用程序访问智能卡
    7. 参数:
    8. hCard: 输入类型:SCardConnect()建立的卡连接句柄
    9. dwDisposition 输入类型:结束时对读卡器的操作

    8.重新连接读卡器

    1. LONG SCardReconnect(SCARDHANDLE hCard, DWORD dwShareMode,DWORD dwPreferredProtocols, DWORD dwInitialization, LPDWORD pdwActiveProtocol);
    2. 说明:将正在连接的读卡器重新连接,等于热复位
    3. 参数:
    4. hCard: 输入类型:SCardConnect()建立的卡连接句柄
    5. dwShareMode: 输入类型:连接类型 SCARD_SHARE_SHARED 多个应用共享同一个智能卡
    6. SCARD_SHARE_EXCLUSIVE 应用独占智能卡
    7. SCARD_SHARE_DIRECT 私有类型,不允许其他应用访问
    8. dwPreferredProtocols: 输入类型:使用的协议类型
    9. SCARD_PROTOCOL_T0 T=0协议
    10. SCARD_PROTOCOL_T1 T=1协议
    11. SCARD_PROTOCOL_RAW 原始协议
    12. dwInitialization: 输入类型:读卡器指定的操作,常用作重启
    13. SCARD_LEAVE_CARD - Do nothing.
    14. SCARD_RESET_CARD - Reset the card (warm reset).
    15. SCARD_UNPOWER_CARD - Power down the card (cold reset).
    16. SCARD_EJECT_CARD - Eject the card.
    17. pdwActiveProtocol: 输出类型:实际使用的协议
    18. 返回:
    19. 成功返回 SCARD_S_SUCCESS
    20. 失败返回其他值,定义在 pcsclite.h

    9.断开读卡器

    1. LONG SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition);
    2. 说明:断开读卡器连接
    3. 参数:
    4. hCard: 输入类型:SCardConnect()建立的卡连接句柄
    5. dwDisposition 输入类型:断开连接时对读卡器的操作
    6. SCARD_LEAVE_CARD 0x0000 /**< Do nothing on close */
    7. SCARD_RESET_CARD 0x0001 /**< Reset on close */
    8. SCARD_UNPOWER_CARD 0x0002 /**< Power down on close */
    9. SCARD_EJECT_CARD 0x0003 /**< Eject on close */
    10. 返回:
    11. 成功返回 SCARD_S_SUCCESS
    12. 失败返回其他值,定义在 pcsclite.h
    13. //@code
    14. rv = SCardDisconnect(hCard, SCARD_UNPOWER_CARD);

    10.释放上下文

    1. LONG SCardReleaseContext(SCARDCONTEXT hContext);
    2. 说明:应用程序终止前,释放资源管理器上下文
    3. 参数:
    4. hContext: 输入类型;ScardEstablishContext()建立的资源管理器上下文
    5. 返回:
    6. 成功返回 SCARD_S_SUCCESS
    7. 失败返回其他值,定义在 pcsclite.h

    示例代码:

    1. //***********************************
    2. #define MAX_READER_COUNTS 3
    3. typedef struct _strReaderListInfo
    4. {
    5. char reader[128];
    6. int trans_begin;
    7. SCARDHANDLE hCard;
    8. DWORD dwActiveProtocol;
    9. SCARD_IO_REQUEST pioSendPci;
    10. SCARD_IO_REQUEST pioRecvPci;
    11. }StrReaderListInfo, *pStrReaderListInfo;
    12. typedef struct _strReaderList
    13. {
    14. int count;
    15. StrReaderListInfo readerList[MAX_READER_COUNTS];
    16. }StrReaderList, *pStrReaderList;
    17. unsigned int posReaderId = 1; //readerid
    18. StrReaderList posReaderList = {0};
    19. SCARDCONTEXT posContext = 0;
    20. DWORD posActiveProtocol[MAX_READER_COUNTS];
    21. //上下文初始化
    22. unsigned int Pcscd_Init()
    23. {
    24. LOGD("%s",__FUNCTION__);
    25. unsigned int ret = ERROR_NONE;
    26. LONG rv = 0;
    27. unsigned int lens = 0;
    28. DWORD dwReaders;
    29. unsigned char reader_list_buf[512];
    30. pStrReaderListInfo pStrInfo;
    31. unsigned char *ptr = NULL;
    32. unsigned int tryAgain = 0;
    33. START:
    34. if(posContext != 0)
    35. {
    36. LOGE("SCardEstablishContext::Context has already been created,Release!\n");
    37. rv = SCardReleaseContext(hContext);
    38. if(rv != SCARD_S_SUCCESS)
    39. {
    40. LOGE("SCardReleaseContext::failed!\n");
    41. }
    42. hContext = 0;
    43. }
    44. //建立上下文
    45. memset(&posReaderList, 0, sizeof(StrReaderList));
    46. rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &posContext);
    47. if(rv != SCARD_S_SUCCESS)
    48. {
    49. LOGE("SCardEstablishContext::failed!\n");
    50. ret = ERROR_APP_CONTEXT;
    51. return ret;
    52. }
    53. LOGD("SCardEstablishContext::success!\n");
    54. //获取读卡器列表
    55. dwReaders = sizeof(reader_list_buf);
    56. rv = SCardListReaders(posContext, NULL, reader_list_buf, &dwReaders);
    57. if(rv != SCARD_S_SUCCESS)
    58. {
    59. LOGE("SCardListReaders::native failed!(0x%x)\n",rv);
    60. if(posContext != 0)
    61. {
    62. SCardReleaseContext(posContext);
    63. posContext = 0;
    64. }
    65. if(rv == SCARD_E_NO_READERS_AVAILABLE)
    66. {
    67. ret = ERROR_APP_REBOOT_POS;
    68. }
    69. else
    70. {
    71. ret = ERROR_APP_LISTREADER;
    72. }
    73. return ret;
    74. }
    75. reader_list_buf[dwReaders] = 0x00;
    76. reader_list_buf[dwReaders + 1] = 0x00;
    77. posReaderList.count = 0;
    78. ptr = reader_list_buf;
    79. while ((*ptr != '\0') && (dwReaders > 0))
    80. {
    81. pStrInfo = &posReaderList.readerList[posReaderList.count];
    82. strcpy(pStrInfo->reader, ptr);
    83. lens = strlen(pStrInfo->reader);
    84. ptr += (lens + 1);
    85. dwReaders -= (lens + 1);
    86. // pStrInfo->hCard = 0;
    87. posReaderList.count++;
    88. LOGD("SCardListReaders::Reader Count %d Name:%s\n", posReaderList.count, pStrInfo->reader);
    89. if(posReaderList.count >= MAX_READER_COUNTS)
    90. {
    91. break;
    92. }
    93. }
    94. if (posReaderList.count < 2)
    95. {
    96. LOGE("[%d]::reader count = %d!!!\n",__LINE__,posReaderList.count);
    97. SCardStopDeamon(posContext);
    98. sleep(3);
    99. if(posContext != 0)
    100. {
    101. SCardReleaseContext(posContext);
    102. posContext = 0;
    103. }
    104. if(tryAgain == 0)
    105. {
    106. ret = ERROR_NONE;
    107. tryAgain = 1;
    108. LOGE("init try again");
    109. goto START;
    110. }
    111. else
    112. {
    113. ret = ERROR_APP_LISTREADER;
    114. return ret;
    115. }
    116. }
    117. LOGD("SCardListReaders::success!\r\n");
    118. ret = ERROR_NONE;
    119. return ret;
    120. }
    121. //释放上下文
    122. unsigned int Pcscd_Release()
    123. {
    124. LOGD("%s",__FUNCTION__);
    125. unsigned int ret = ERROR_NONE;
    126. int rv;
    127. pStrReaderListInfo pStrInfo;
    128. if(posContext == 0)
    129. {
    130. LOGE("SCardReleaseContext::Context has not been created!\n");
    131. ret = ERROR_NONE;
    132. return ret;
    133. }
    134. memset(&posReaderList, 0, sizeof(StrReaderList));
    135. rv = SCardReleaseContext(posContext);
    136. if(rv != SCARD_S_SUCCESS)
    137. {
    138. LOGE("SCardReleaseContext::native failed!\n");
    139. posContext = 0;
    140. ret = ERROR_APP_CONTEXT;
    141. return ret;
    142. }
    143. posContext = 0;
    144. LOGD("SCardReleaseContext::success!\n");
    145. ret = ERROR_NONE;
    146. return ret;
    147. }
    148. //断开卡连接
    149. int PBOC_DisConnect(unsigned int using_reader_id)
    150. {
    151. LOGD("%s(%d)",__FUNCTION__,using_reader_id);
    152. LONG rv;
    153. pStrReaderListInfo pStrInfo;
    154. if(using_reader_id < 0 || using_reader_id >= posReaderList.count)
    155. {
    156. LOGE("[%d]reader id is wrong(%d)\n",__LINE__, using_reader_id);
    157. // Nok_Reason = ErrorReason_PCSCD_READERS_ID;
    158. return FALSE;
    159. }
    160. pStrInfo = &posReaderList.readerList[using_reader_id];
    161. if(pStrInfo->trans_begin == 1)
    162. {
    163. rv = SCardEndTransaction(pStrInfo->hCard,SCARD_LEAVE_CARD);
    164. if (rv != SCARD_S_SUCCESS)
    165. {
    166. if(rv == SCARD_E_NO_SERVICE || rv == SCARD_E_UNKNOWN_READER)
    167. {
    168. Reset_Reader();
    169. }
    170. LOGE("[%d]::SCardEndTransaction: %s (0x%lX)\n",__LINE__ ,pcsc_stringify_error(rv),rv);
    171. }
    172. pStrInfo->trans_begin = 0;
    173. }
    174. if(pStrInfo->hCard != 0)
    175. {
    176. rv = SCardDisconnect(pStrInfo->hCard,SCARD_UNPOWER_CARD);
    177. if (rv != SCARD_S_SUCCESS)
    178. {
    179. if(rv == SCARD_E_NO_SERVICE || rv == SCARD_E_UNKNOWN_READER)
    180. {
    181. Reset_Reader();
    182. }
    183. LOGE("[%d]::SCardDisconnect: %s (0x%lX)\n",__LINE__ ,pcsc_stringify_error(rv),rv);
    184. }
    185. pStrInfo->hCard = 0;
    186. }
    187. return TRUE;
    188. }
    189. int PBOC_OpenCard(unsigned char* pAtr,unsigned int * pAtrlen)
    190. {
    191. int ret;
    192. LOGD("%s",__FUNCTION__);
    193. //检卡
    194. DWORD dwReaderLen, dwState, dwProt, dwAtrLen;
    195. BYTE pbAtr[MAX_ATR_SIZE] = "";
    196. char pbReader[MAX_READERNAME] = "";
    197. pStrReaderListInfo pStrInfo;
    198. SCARD_READERSTATE rgReaderStates[1];
    199. pStrInfo = &posReaderList.readerList[posReaderId];
    200. dwAtrLen = sizeof(pbAtr);
    201. dwReaderLen = sizeof(pbReader);
    202. smart_card_type = 0;
    203. rgReaderStates[0].szReader = posReaderList.readerList[posReaderId].reader;
    204. rgReaderStates[0].dwCurrentState = SCARD_STATE_UNAWARE;
    205. //检测是否有卡插入
    206. ret = SCardGetStatusChange(posContext,INFINITE,rgReaderStates,1);
    207. if (ret != SCARD_S_SUCCESS)
    208. {
    209. printf("SCardGetStatusChange err\r\n");
    210. return -1;
    211. }
    212. LOGD("SCardGetStatusChange ok\r\n");
    213. LOGD("rgReaderStates[0].dwEventState == %ld\r\n",rgReaderStates[0].dwEventState);
    214. if(rgReaderStates[0].dwEventState & SCARD_STATE_PRESENT)//卡在
    215. {
    216. ret= SCardConnect(posContext, pStrInfo->reader, SCARD_SHARE_SHARED,
    217. SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &pStrInfo->hCard, &posActiveProtocol[posReaderId]);
    218. if (ret == SCARD_S_SUCCESS)
    219. {
    220. ret = SCardStatus(pStrInfo->hCard, pbReader, &dwReaderLen, &dwState, &dwProt,pbAtr, &dwAtrLen);
    221. if (ret != SCARD_S_SUCCESS)
    222. {
    223. return -1;
    224. }
    225. MyPrintfBuff("CardAtr:",pbAtr, dwAtrLen);
    226. //判断ATR是否是非接触卡
    227. if((pbAtr[2] == 0x81 && pbAtr[3] == 0x01)||(pbAtr[2] == 0x11 && pbAtr[3] == 0x01) )
    228. {
    229. smart_card_type = 2;
    230. }
    231. //判断ATR 多张非接触卡
    232. else if((pbAtr[1] == 0x70 && pbAtr[2] == 0x11) )
    233. {
    234. smart_card_type = 3;
    235. }
    236. //判断ATR是否是接触卡
    237. else if(!((pbAtr[2] == 0x81 && pbAtr[3] == 0x01)||(pbAtr[2] == 0x11 && pbAtr[3] == 0x01) ||(pbAtr[1] == 0x60 && pbAtr[2] == 0x00)))
    238. {
    239. smart_card_type = 1;
    240. }
    241. else
    242. {
    243. smart_card_type = -1;
    244. }
    245. switch(posActiveProtocol[posReaderId])
    246. {
    247. case SCARD_PROTOCOL_T0:
    248. pStrInfo->pioSendPci = *SCARD_PCI_T0;
    249. LOGD("using T0");
    250. break;
    251. case SCARD_PROTOCOL_T1:
    252. pStrInfo->pioSendPci = *SCARD_PCI_T1;
    253. LOGD("using T1");
    254. break;
    255. default:
    256. LOGE("Unknown protocol. No card present?\n");
    257. }
    258. MyMemcpy(pAtr,pbAtr, dwAtrLen);
    259. *pAtrlen = dwAtrLen;
    260. }
    261. else
    262. {
    263. }
    264. }
    265. return smart_card_type;
    266. }
    267. //建立卡连接,并做好传输准备
    268. int PBOC_Connect(int using_reader_id)
    269. {
    270. LOGD("%s(%d)",__FUNCTION__,using_reader_id);
    271. LONG rv;
    272. int ret = TRUE;
    273. DWORD dwReaderLen, dwState, dwProt, dwAtrLen;
    274. BYTE pbAtr[MAX_ATR_SIZE] = "";
    275. char pbReader[MAX_READERNAME] = "";
    276. pStrReaderListInfo pStrInfo;
    277. unsigned int i;
    278. unsigned int counts = 0;
    279. if(using_reader_id < 0 || using_reader_id >= posReaderList.count)
    280. {
    281. LOGE("[%d]reader id is wrong(%d)\n",__LINE__, using_reader_id);
    282. ret = FALSE;
    283. // Nok_Reason = ErrorReason_PCSCD_READERS_ID;
    284. goto ERROR;
    285. }
    286. pStrInfo = &posReaderList.readerList[using_reader_id];
    287. /* connect to a reader (even without a card) */
    288. LOGD("[%d]Using reader: %s\n",__LINE__, posReaderList.readerList[using_reader_id].reader);
    289. while(1)
    290. {
    291. if(posReaderList.readerList[using_reader_id].hCard != 0)
    292. {
    293. LOGD("connected(%d)",(int)posActiveProtocol[using_reader_id]);
    294. rv = SCARD_S_SUCCESS;
    295. LOGD("SCardReconnect");
    296. rv = SCardReconnect(posReaderList.readerList[using_reader_id].hCard, /*SCARD_SHARE_SHARED*/SCARD_SHARE_SHARED,
    297. SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,SCARD_RESET_CARD, (DWORD*)&posActiveProtocol);
    298. }
    299. else
    300. {
    301. LOGD("connect");
    302. rv = SCardConnect(posContext, posReaderList.readerList[using_reader_id].reader, /*SCARD_SHARE_EXCLUSIVE*/SCARD_SHARE_SHARED,
    303. SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &posReaderList.readerList[using_reader_id].hCard, &posActiveProtocol[using_reader_id]);
    304. }
    305. if (rv != SCARD_S_SUCCESS)
    306. {
    307. LOGE("SCardConnect %s (0x%lX)\n" , pcsc_stringify_error(rv), rv);
    308. counts++;
    309. if(rv == SCARD_E_SHARING_VIOLATION)
    310. {
    311. if(counts < 10)
    312. {
    313. usleep(500*1000);
    314. LOGE("reader is busy,wait 500ms try again(%d)",counts);
    315. continue;
    316. }
    317. }
    318. else if(rv == SCARD_E_NO_SERVICE || rv == SCARD_E_UNKNOWN_READER)
    319. {
    320. Reset_Reader();
    321. if(counts < 2)
    322. {
    323. LOGE("try again(%d)",counts);
    324. continue;
    325. }
    326. }
    327. ret = FALSE;
    328. // Nok_Reason = ErrorReason_PCSCD_CONNECT_READERS;
    329. goto ERROR_NOTHING;
    330. }
    331. else
    332. {
    333. break;
    334. }
    335. }
    336. pStrInfo->dwActiveProtocol = posActiveProtocol[using_reader_id];
    337. /* get card status */
    338. dwAtrLen = sizeof(pbAtr);
    339. dwReaderLen = sizeof(pbReader);
    340. rv = SCardStatus(posReaderList.readerList[using_reader_id].hCard, pbReader, &dwReaderLen, &dwState, &dwProt,
    341. pbAtr, &dwAtrLen);
    342. if (rv != SCARD_S_SUCCESS)
    343. {
    344. LOGE("SCardStatus %s (0x%lX)\n" , pcsc_stringify_error(rv), rv);
    345. ret = FALSE;
    346. // Nok_Reason = ErrorReason_PCSCD_GET_READERS_STATUS;
    347. goto ERROR;
    348. }
    349. LOGD(" State: 0x%04lX\n", dwState);
    350. if (dwState & SCARD_ABSENT)
    351. {
    352. LOGE("No card inserted\n");
    353. ret = FALSE;
    354. // Nok_Reason = ErrorReason_PCSCD_NO_CARDS_INSIDE;
    355. goto ERROR;
    356. }
    357. switch(posActiveProtocol[using_reader_id])
    358. {
    359. case SCARD_PROTOCOL_T0:
    360. pStrInfo->pioSendPci = *SCARD_PCI_T0;
    361. LOGD("using T0");
    362. break;
    363. case SCARD_PROTOCOL_T1:
    364. pStrInfo->pioSendPci = *SCARD_PCI_T1;
    365. LOGD("using T1");
    366. break;
    367. default:
    368. LOGE("Unknown protocol. No card present?\n");
    369. ret = FALSE;
    370. // Nok_Reason = ErrorReason_PCSCD_NO_PROTOCOLS_SELECT;
    371. goto ERROR;
    372. }
    373. rv = SCardBeginTransaction(posReaderList.readerList[using_reader_id].hCard);
    374. if (rv != SCARD_S_SUCCESS)
    375. {
    376. if(rv == SCARD_E_NO_SERVICE || rv == SCARD_E_UNKNOWN_READER)
    377. {
    378. Reset_Reader();
    379. }
    380. LOGE("SCardBeginTransaction %s (0x%lX)\n" , pcsc_stringify_error(rv), rv);
    381. ret = FALSE;
    382. // Nok_Reason = ErrorReason_PCSCD_BEGIN_TRANSACTION;
    383. goto ERROR;
    384. }
    385. pStrInfo->trans_begin = 1;
    386. LOGD("SCardBeginTransaction::success!\n");
    387. return ret;
    388. ERROR:
    389. rv = SCardDisconnect(posReaderList.readerList[using_reader_id].hCard,SCARD_UNPOWER_CARD);
    390. if (rv != SCARD_S_SUCCESS)
    391. {
    392. if(rv == SCARD_E_NO_SERVICE || rv == SCARD_E_UNKNOWN_READER)
    393. {
    394. Reset_Reader();
    395. }
    396. LOGE("[%d]::SCardDisconnect: %s (0x%lX)\n",__LINE__ ,pcsc_stringify_error(rv),rv);
    397. }
    398. ERROR_NOTHING:
    399. return ret;
    400. }
    401. //卡上电连接并获取ATR
    402. int PBOC_PowerOn(int using_reader_id,unsigned char* pAtr,unsigned int * pAtrlen)
    403. {
    404. LOGD("%s",__FUNCTION__);
    405. LONG rv;
    406. int ret = TRUE;
    407. DWORD dwReaderLen, dwState, dwProt, dwAtrLen;
    408. BYTE pbAtr[MAX_ATR_SIZE] = "";
    409. char pbReader[MAX_READERNAME] = "";
    410. pStrReaderListInfo pStrInfo;
    411. unsigned int i;
    412. unsigned int counts = 0;
    413. if(using_reader_id < 0 || using_reader_id >= posReaderList.count)
    414. {
    415. LOGE("[%d]reader id is wrong(%d)\n",__LINE__, using_reader_id);
    416. ret = FALSE;
    417. return ret;
    418. }
    419. pStrInfo = &posReaderList.readerList[using_reader_id];
    420. /* connect to a reader (even without a card) */
    421. LOGD("[%d]Using reader: %s\n",__LINE__, posReaderList.readerList[using_reader_id].reader);
    422. while(1)
    423. {
    424. if(pStrInfo->hCard != 0)
    425. {
    426. LOGD("SCardConnect(%d)",(int)posActiveProtocol[using_reader_id]);
    427. rv = SCARD_S_SUCCESS;
    428. //LOGD("SCardReconnect");
    429. //rv = SCardReconnect(pStrInfo->hCard, /*SCARD_SHARE_SHARED*/SCARD_SHARE_EXCLUSIVE, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,
    430. // SCARD_RESET_CARD, &dwposActiveProtocol);
    431. }
    432. else
    433. {
    434. LOGD("SCardConnect");
    435. rv = SCardConnect(posContext, pStrInfo->reader, /*SCARD_SHARE_SHARED*/SCARD_SHARE_SHARED,
    436. SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &pStrInfo->hCard, &posActiveProtocol[using_reader_id]);
    437. }
    438. if (rv != SCARD_S_SUCCESS)
    439. {
    440. LOGE("SCardConnect %s (0x%lX)\n" , pcsc_stringify_error(rv), rv);
    441. counts++;
    442. if(rv == SCARD_E_SHARING_VIOLATION)
    443. {
    444. if(counts < 10)
    445. {
    446. usleep(500*1000);
    447. LOGE("reader is busy,wait 500ms try again(%d)",counts);
    448. continue;
    449. }
    450. }
    451. else if(rv == SCARD_E_NO_SERVICE || rv == SCARD_E_UNKNOWN_READER)
    452. {
    453. usleep(2000*1000);
    454. Pcscd_Init();
    455. if(counts < 2)
    456. {
    457. LOGE("try again(%d)",counts);
    458. continue;
    459. }
    460. }
    461. ret = FALSE;
    462. goto ERROR_NOTHING;
    463. }
    464. else
    465. {
    466. break;
    467. }
    468. }
    469. pStrInfo->dwActiveProtocol = posActiveProtocol[using_reader_id];
    470. /* get card status */
    471. dwAtrLen = sizeof(pbAtr);
    472. dwReaderLen = sizeof(pbReader);
    473. //获取卡状态信息
    474. rv = SCardStatus(pStrInfo->hCard, pbReader, &dwReaderLen, &dwState, &dwProt,
    475. pbAtr, &dwAtrLen);
    476. if (rv != SCARD_S_SUCCESS)
    477. {
    478. LOGE("SCardStatus %s (0x%lX)\n" , pcsc_stringify_error(rv), rv);
    479. ret = FALSE;
    480. goto ERROR;
    481. }
    482. LOGD(" State: 0x%04lX\n", dwState);
    483. if (dwState & SCARD_ABSENT)
    484. {
    485. LOGE("No card inserted\n");
    486. ret = FALSE;
    487. goto ERROR;
    488. }
    489. switch(posActiveProtocol[using_reader_id])
    490. {
    491. case SCARD_PROTOCOL_T0:
    492. pStrInfo->pioSendPci = *SCARD_PCI_T0;
    493. LOGD("using T0");
    494. break;
    495. case SCARD_PROTOCOL_T1:
    496. pStrInfo->pioSendPci = *SCARD_PCI_T1;
    497. LOGD("using T1");
    498. break;
    499. default:
    500. LOGE("Unknown protocol. No card present?\n");
    501. ret = FALSE;
    502. goto ERROR;
    503. }
    504. MyMemcpy(pbAtr,pAtr,dwAtrLen);
    505. *pAtrlen = dwAtrLen;
    506. //准备传输状态
    507. rv = SCardBeginTransaction(pStrInfo->hCard);
    508. if (rv != SCARD_S_SUCCESS)
    509. {
    510. if(rv == SCARD_E_NO_SERVICE || rv == SCARD_E_UNKNOWN_READER)
    511. {
    512. Reset_Reader();
    513. }
    514. LOGE("SCardBeginTransaction %s (0x%lX)\n" , pcsc_stringify_error(rv), rv);
    515. ret = FALSE;
    516. goto ERROR;
    517. }
    518. pStrInfo->trans_begin = 1;
    519. LOGD("SCardBeginTransaction::success!\n");
    520. return ret;
    521. ERROR:
    522. rv = SCardDisconnect(pStrInfo->hCard,SCARD_UNPOWER_CARD);
    523. if (rv != SCARD_S_SUCCESS)
    524. {
    525. if(rv == SCARD_E_NO_SERVICE || rv == SCARD_E_UNKNOWN_READER)
    526. {
    527. Reset_Reader();
    528. }
    529. LOGE("[%d]::SCardDisconnect: %s (0x%lX)\n",__LINE__ ,pcsc_stringify_error(rv),rv);
    530. }
    531. ERROR_NOTHING:
    532. return ret;
    533. }
    534. int PBOC_PowerOff(int using_reader_id)
    535. {
    536. LOGD("%s",__FUNCTION__);
    537. LONG rv;
    538. pStrReaderListInfo pStrInfo;
    539. pStrInfo = &posReaderList.readerList[using_reader_id];
    540. //结束传输
    541. if(pStrInfo->trans_begin == 1)
    542. {
    543. rv = SCardEndTransaction(pStrInfo->hCard,SCARD_LEAVE_CARD);
    544. if (rv != SCARD_S_SUCCESS)
    545. {
    546. if(rv == SCARD_E_NO_SERVICE || rv == SCARD_E_UNKNOWN_READER)
    547. {
    548. ResetReader();
    549. }
    550. LOGE("[%d]::SCardEndTransaction: %s (0x%lX)\n",__LINE__ ,pcsc_stringify_error(rv),rv);
    551. }
    552. pStrInfo->trans_begin = 0;
    553. }
    554. //断开连接
    555. if(posReaderList.readerList[using_reader_id].hCard != 0)
    556. {
    557. LOGD("SCardDisconnect");
    558. rv = SCardDisconnect(pStrInfo->hCard,SCARD_UNPOWER_CARD);
    559. if (rv != SCARD_S_SUCCESS)
    560. {
    561. if(rv == SCARD_E_NO_SERVICE || rv == SCARD_E_UNKNOWN_READER)
    562. {
    563. Reset_Reader();
    564. }
    565. LOGE("[%d]::CloudPos_PowerOff: %s (0x%lX)\n",__LINE__ ,pcsc_stringify_error(rv),rv);
    566. }
    567. pStrInfo->hCard = 0;
    568. }
    569. return rv;
    570. }
    571. int PBOC_APDU_SendAPI(unsigned int using_reader_id,unsigned char * bSendBuffer,unsigned int send_length,unsigned char * bRecvBuffer,unsigned int *length)
    572. {
    573. LOGD("%s",__FUNCTION__);
    574. LONG rv;
    575. int ret = 0;
    576. unsigned int i;
    577. unsigned char temp[64] = {0};
    578. //char debug_buffer[512] = {0};
    579. pStrReaderListInfo pStrInfo;
    580. if(using_reader_id < 0 || using_reader_id >= posReaderList.count)
    581. {
    582. LOGE("[%d]reader id is wrong(%d)\n",__LINE__, using_reader_id);
    583. ret = FALSE;
    584. goto SEND_ERROR;
    585. }
    586. #ifdef SE_KL81
    587. if(send_length%64 == 54)
    588. {
    589. LOGI("fill 0xFFFF");
    590. bSendBuffer[send_length] = 0xFF;
    591. bSendBuffer[send_length+1] = 0xFF;
    592. send_length += 2;
    593. }
    594. #endif
    595. pStrInfo = &posReaderList.readerList[using_reader_id];
    596. /* APDU select applet */
    597. LOGD("[%d]::PBOC_APDU_SendAPI()::Dev send to card:\n",__LINE__);
    598. if(send_length >= 256)
    599. {
    600. LOGD("send_length is bigger then print buffer length");
    601. }
    602. else
    603. {
    604. MyPrintfBuff("APDU_send:",bSendBuffer, send_length);
    605. }
    606. *length = MAX_BUFFER_SIZE_SZ;
    607. MyMemset(bRecvBuffer,0x00,MAX_BUFFER_SIZE_SZ);
    608. if(memcmp(&pStrInfo->pioSendPci,SCARD_PCI_T0,sizeof(pStrInfo->pioSendPci)) == 0)
    609. {
    610. LOGD("using T0");
    611. }
    612. else if(memcmp(&pStrInfo->pioSendPci,SCARD_PCI_T1,sizeof(pStrInfo->pioSendPci)) == 0)
    613. {
    614. LOGD("using T1");
    615. }
    616. else
    617. {
    618. LOGD("using None");
    619. }
    620. rv = SCardTransmit(pStrInfo->hCard, &pStrInfo->pioSendPci, bSendBuffer, (DWORD)send_length,
    621. &pStrInfo->pioRecvPci, bRecvBuffer, (DWORD *)length);
    622. if(rv != SCARD_S_SUCCESS)
    623. {
    624. if(rv == SCARD_E_NO_SERVICE || rv == SCARD_E_UNKNOWN_READER)
    625. {
    626. Reset_Reader();
    627. }
    628. MyMemset(bRecvBuffer,0x00,MAX_BUFFER_SIZE_SZ);
    629. LOGE("SCardTransmit error,try again!(0x%08x)(%d)",(unsigned int)rv,*length);
    630. snprintf(temp,sizeof(temp),"SCardTransmit error(0x%x)",(unsigned int)rv);
    631. sleep(1);
    632. *length = MAX_BUFFER_SIZE_SZ;
    633. rv = SCardTransmit(pStrInfo->hCard, &pStrInfo->pioSendPci, bSendBuffer, (DWORD )send_length,
    634. &pStrInfo->pioRecvPci, bRecvBuffer,(DWORD *) length);
    635. if(rv != SCARD_S_SUCCESS)
    636. {
    637. if(rv == SCARD_E_NO_SERVICE || rv == SCARD_E_UNKNOWN_READER)
    638. {
    639. Reset_Reader();
    640. }
    641. LOGE("(rv = 0x%08x)",(unsigned int)rv);
    642. snprintf(temp,sizeof(temp),"SCardTransmit error again(0x%x)",(unsigned int)rv);
    643. ret = FALSE;
    644. goto SEND_ERROR;
    645. }
    646. }
    647. LOGD("[%d]::Card response to dev:\n",__LINE__);
    648. if(*length >= 5120)
    649. {
    650. LOGD("length is bigger then print buffer length.");
    651. }
    652. else
    653. {
    654. MyPrintfBuff("APDU_Recv:",bRecvBuffer, *length);
    655. }
    656. if(*length > 54 && (*length+10)%64 == 2 && (bRecvBuffer[*length-2] == 0xFF && bRecvBuffer[*length-1] == 0xFF))
    657. {
    658. LOGD("clean FFFF");
    659. (*length) -= 2;
    660. }
    661. PRASE_CARD_RETURN_STATUS:
    662. if(bRecvBuffer[*length-2] == 0x61)
    663. {
    664. LOGD("[%d]::Dev 0x61 to card:\n",__LINE__);
    665. memset(bSendBuffer,0x00,MAX_BUFFER_SIZE_SZ);
    666. usleep(100*1000);
    667. LOGD("[%d]::Card with the remaining returned to %02x%02x\n",__LINE__,bRecvBuffer[0],bRecvBuffer[1]);
    668. send_length = 5;//00 C0 00 00 2A
    669. memcpy(bSendBuffer, "\x00\xC0\x00\x00",send_length-1);
    670. bSendBuffer[send_length-1] = bRecvBuffer[*length-1];
    671. LOGD("[%d]::Dev send to card:\n",__LINE__);
    672. MyMemset(bRecvBuffer,0x00,MAX_BUFFER_SIZE_SZ);
    673. *length = MAX_BUFFER_SIZE_SZ;
    674. rv = SCardTransmit(pStrInfo->hCard, &pStrInfo->pioSendPci, bSendBuffer, (DWORD )send_length,
    675. &pStrInfo->pioRecvPci, bRecvBuffer, (DWORD *)length);
    676. MyPrintfBuff("APDU_Recv:",bRecvBuffer, *length);
    677. if(rv != SCARD_S_SUCCESS)
    678. {
    679. if(rv == SCARD_E_NO_SERVICE || rv == SCARD_E_UNKNOWN_READER)
    680. {
    681. Reset_Reader();
    682. }
    683. MyMemset(bRecvBuffer,0x00,MAX_BUFFER_SIZE_SZ);
    684. LOGE("SCardTransmit error,try again!");
    685. snprintf(temp,sizeof(temp),"SCardTransmit error(0x%x)",(unsigned int)rv);
    686. *length = MAX_BUFFER_SIZE_SZ;
    687. sleep(1);
    688. rv = SCardTransmit(pStrInfo->hCard, &pStrInfo->pioSendPci, bSendBuffer, (DWORD )send_length,
    689. &pStrInfo->pioRecvPci, bRecvBuffer, (DWORD *)length);
    690. if(rv != SCARD_S_SUCCESS)
    691. {
    692. if(rv == SCARD_E_NO_SERVICE || rv == SCARD_E_UNKNOWN_READER)
    693. {
    694. Reset_Reader();
    695. }
    696. LOGE("SCardTransmit error!");
    697. snprintf(temp,sizeof(temp),"SCardTransmit error again(0x%x)",(unsigned int)rv);
    698. ret = FALSE;
    699. goto SEND_ERROR;
    700. }
    701. }
    702. LOGD("[%d]::Card response to dev:\n",__LINE__);
    703. //memset(debug_buffer,0,sizeof(debug_buffer));
    704. if(*length >= 5120)
    705. {
    706. LOGE("length is bigger then print buffer length");
    707. }
    708. else
    709. {
    710. // myAsciiToHex(bRecvBuffer, debug_buffer, *length);
    711. MyPrintfBuff("APDU_Recv:",bRecvBuffer, *length);
    712. }
    713. if(*length > 54 && (*length+10)%64 == 2 && (bRecvBuffer[*length-2] == 0xFF && bRecvBuffer[*length-1] == 0xFF))
    714. {
    715. LOGD("clean FFFF");
    716. (*length) -= 2;
    717. }
    718. }
    719. else if(bRecvBuffer[*length-2] == 0x6C)
    720. {
    721. LOGD("[%d]::Dev 0x6C to card:\n",__LINE__);
    722. bSendBuffer[send_length-1] = bRecvBuffer[*length-1];
    723. MyMemset(bRecvBuffer,0x00,MAX_BUFFER_SIZE_SZ);
    724. rv = SCardTransmit(pStrInfo->hCard, &pStrInfo->pioSendPci, bSendBuffer,(DWORD ) send_length,
    725. &pStrInfo->pioRecvPci, bRecvBuffer, (DWORD *)length);
    726. if(rv != SCARD_S_SUCCESS)
    727. {
    728. if(rv == SCARD_E_NO_SERVICE || rv == SCARD_E_UNKNOWN_READER)
    729. {
    730. Reset_Reader();
    731. }
    732. MyMemset(bRecvBuffer,0x00,MAX_BUFFER_SIZE_SZ);
    733. LOGE("SCardTransmit error,try again!");
    734. *length = MAX_BUFFER_SIZE_SZ;
    735. sleep(1);
    736. rv = SCardTransmit(pStrInfo->hCard, &pStrInfo->pioSendPci, bSendBuffer, (DWORD )send_length,
    737. &pStrInfo->pioRecvPci, bRecvBuffer, (DWORD*)length);
    738. if(rv != SCARD_S_SUCCESS)
    739. {
    740. if(rv == SCARD_E_NO_SERVICE || rv == SCARD_E_UNKNOWN_READER)
    741. {
    742. Reset_Reader();
    743. }
    744. // Nok_Reason = ErrorReason_PCSCD_TRANSMIT;
    745. ret = FALSE;
    746. goto SEND_ERROR;
    747. }
    748. }
    749. if(*length > 54 && (*length+10)%64 == 2 && (bRecvBuffer[*length-2] == 0xFF && bRecvBuffer[*length-1] == 0xFF))
    750. {
    751. LOGD("clean FFFF");
    752. (*length) -= 2;
    753. }
    754. goto PRASE_CARD_RETURN_STATUS;
    755. }
    756. else if((bRecvBuffer[*length-2] == 0x6A )&&( bRecvBuffer[*length-1] == 0x83))
    757. {
    758. LOGD("[%d]::Card response 6A83",__LINE__);
    759. }
    760. else if((bRecvBuffer[*length-2] != 0x90)||(bRecvBuffer[*length-1] != 0x00))
    761. {
    762. LOGE("Cards respont isn't 0x9000(0x%02X%02X)!\n",bRecvBuffer[*length-2],bRecvBuffer[*length-1]);
    763. }
    764. else
    765. {
    766. //LOGD("[%d]::Card response to dev:\n",__LINE__);
    767. //memset(debug_buffer,0,sizeof(debug_buffer));
    768. if(*length >= 5120)
    769. {
    770. LOGE("length is bigger then print buffer length");
    771. }
    772. else
    773. {
    774. //myAsciiToHex(bRecvBuffer, debug_buffer, *length);
    775. //MyPrintfBuff("APDU_Recv:",bRecvBuffer, *length);
    776. }
    777. }
    778. SEND_ERROR:
    779. return ret;
    780. }
    781. //main.c
    782. //使用test程序做PSAM卡和ICC卡通道通讯
    783. ret = Pcscd_Init();
    784. if(ret != 0)//读卡器未找到
    785. {
    786. return -1;
    787. }
    788. while(1)
    789. {
    790. printf("Please input command:\n");
    791. printf("################################\n");
    792. printf("'0' is select PSAM CARD\n");
    793. printf("'1' is select ICC CARD\n");
    794. printf("'quit' is return\n");
    795. printf("'break' is go back\n");
    796. printf("################################\n");
    797. MyMemset(camd_buf,0,sizeof(camd_buf));
    798. scanf("%s",camd_buf);
    799. getchar();
    800. if(MyMemcmp("0",camd_buf,MyStrlen("0")) == 0)
    801. {
    802. while(1)
    803. {
    804. printf("Please input APDU:\n");
    805. MyMemset(camd_buf,0,sizeof(camd_buf));
    806. scanf("%s",camd_buf);
    807. getchar();
    808. if(MyMemcmp("break",camd_buf,MyStrlen("break")) == 0)
    809. break;
    810. MyStrToHex((camd_buf),send_buf);
    811. ret = CloudPos_SendToPcscd((unsigned char *)send_buf,0,recv_buf,&recv_len);
    812. MyPrintfBuff("recv_buf::",recv_buf,recv_len);
    813. }
    814. }
    815. else if(memcmp("1",camd_buf,MyStrlen("1")) == 0)
    816. {
    817. ret = PBOC_Connect(1);
    818. if(ret == FALSE)
    819. {
    820. printf("Connect(1) error Please try again!\n");
    821. }
    822. else
    823. {
    824. printf("Connect(1) sucess\n");
    825. while(1)
    826. {
    827. printf("Please input APDU:\n");
    828. MyMemset(camd_buf,0,sizeof(camd_buf));
    829. scanf("%s",camd_buf);
    830. getchar();
    831. if(MyMemcmp("break",camd_buf,MyStrlen("break")) == 0)
    832. break;
    833. send_len = MyStrToHex((camd_buf),send_buf);
    834. ret = PBOC_APDU_SendAPI(1,send_buf,send_len,recv_buf,&recv_len);
    835. MyPrintfBuff("recv_buf::",recv_buf,recv_len);
    836. }
    837. }
    838. PBOC_DisConnect(1);
    839. }
    840. else if(MyMemcmp("quit",camd_buf,MyStrlen("quit")) == 0)
    841. {
    842. break;
    843. }
    844. }
    845. Pcscd_Release();
  • 相关阅读:
    APS智能排产在电缆行业的应用
    springboot+vue+Elementui网络课程在线教学系统网站
    百度paddleocr检测训练
    ERROR 2003 (HY000) Can‘t connect to MySQL server on ‘localhost3306‘ (10061)解决办法
    Pytroch Nerf代码阅读笔记(LLFF 数据集pose 处理和Nerf 网络结构)
    C++ 引用的数组和数组的引用
    自用——平衡小车代码
    java二手车商城计算机毕业设计MyBatis+系统+LW文档+源码+调试部署
    FreeSWITCH dtmf事件测试
    K3S +Helm+NFS最小化测试安装部署只需十分钟
  • 原文地址:https://blog.csdn.net/apple_51426592/article/details/127384762