| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361 |
- #include "contactlessimpl.h"
- #include "cmb.h"
- #define DEVICE_NAME "CREATOR CRT-603 (CZ1) CCR RF 0"
- ContactlessCardImpl::ContactlessCardImpl()
- {
- m_pConnect = new CPcscLibrary();
- m_bCardConn = false;
- }
- ContactlessCardImpl::~ContactlessCardImpl()
- {
- delete m_pConnect;
- }
- ErrorCodeEnum ContactlessCardImpl::DevOpen(DWORD dwPort,DWORD dwBaudRate)
- {
- LOG4VTM_FUNCTION();
- char cFilePath[300] = {0};
- GetCurLibsPath(m_sLibPath, cFilePath);
- sprintf(cFilePath, "DevOpen GetCurProcPath = %s", m_sLibPath);
- LOG4VTM(INFO, cFilePath);
- sprintf(cFilePath, "%s/cw/libCRT603.cw.so", m_sLibPath); //usr symbolic link to point the real so
- bool bOK = m_pConnect->Load(cFilePath, cFilePath);
- if (!bOK) return GetErrorInfo(PCSC_HARDWARE_ERROR, "DevOpen");
- int iCount = 0;
- int iRt = m_pConnect->OpenConnect(&iCount);
- if (iRt != 0)
- return GetErrorInfo(PCSC_HARDWARE_ERROR, "DevOpen OpenConnect %d", iRt);
- iRt = m_pConnect->SetReaderName(0);
- if (iRt != 0)
- return GetErrorInfo(PCSC_HARDWARE_ERROR, "DevOpen SetReaderName %d", iRt);
- return GetErrorInfo(0, "DevOpen %d", iRt);
- }
- int getFileVer(char* sFile, short& ch1, short& ch2)
- {
- ch1 = 0;
- ch2 = 0;
- char* pFind = strstr(sFile, ".so");
- char* pTemp = pFind;
- while (pTemp)
- {
- pFind = pTemp;
- pTemp = strstr(pFind + 3, ".so");
- }
- if (pFind == NULL) return 0;
- pTemp = pFind - 1;
- while(isdigit(*pTemp) && pTemp > sFile) pTemp--;
- if (*pTemp == '.')
- ch2 = atoi(pTemp+1);
- pTemp--;
- while(isdigit(*pTemp) && pTemp > sFile) pTemp--;
- if (*pTemp == '.')
- ch1 = atoi(pTemp+1);
- return 1;
- }
- ErrorCodeEnum ContactlessCardImpl::GetDevCategory(DevCategoryInfo &devCategory)
- {
- LOG4VTM_FUNCTION();
- if (!m_pConnect->IsLoadSucceed())
- return GetErrorInfo(PCSC_NOT_OPEN, "GetDevCategory");
- ErrorCodeEnum err = Error_Succeed;
- char sSer[256];
- memset(sSer, 0, sizeof(sSer));
- if (m_pConnect->GetVersionInfo(2, sSer) == 0)
- {
- sSer[32] = 0;
- strcpy(devCategory.szType, sSer);
- }
- else
- strcpy(devCategory.szType, DEVICE_NAME);
- strcpy(devCategory.szModel, "WID=Cashway001");
- strcpy(devCategory.szVendor, "cw");
- char cFilePath[300] = {0};
- GetCurLibsPath(m_sLibPath, cFilePath);
- short v1,v2;
- getFileVer(cFilePath, v1, v2);
- devCategory.version.wMajor = v1;
- devCategory.version.wMinor = v2;
- devCategory.version.wRevision = 0xffff;
- devCategory.version.wBuild = FILE_VERSION;
- char szRet[512] = {0};
- sprintf(szRet, "szType:%s,szModel:%s,szVendor:%s,version.wMajor:%d,version.wMinor:%d,version.wBuild:%d,version.wRevision:%d,eState:%d(0:故障1:正常)",
- devCategory.szType,devCategory.szModel,devCategory.szVendor,devCategory.version.wMajor,devCategory.version.wMinor,devCategory.version.wBuild,devCategory.version.wRevision,devCategory.eState);
- LOG4VTM(INFO, szRet);
- return Error_Succeed;
- }
- ErrorCodeEnum ContactlessCardImpl::Reset()
- {
- LOG4VTM_FUNCTION();
- if (!m_pConnect->IsLoadSucceed())
- return GetErrorInfo(PCSC_NOT_OPEN, "Reset");
- m_pConnect->CloseConnect();
- int iCount = 0;
- int iRt = m_pConnect->OpenConnect(&iCount);
- if (iRt != 0)
- return GetErrorInfo(PCSC_HARDWARE_ERROR, "Reset OpenConnect %d", iRt);
- iRt = m_pConnect->SetReaderName(0);
- if (iRt != 0)
- return GetErrorInfo(PCSC_HARDWARE_ERROR, "Reset SetReaderName %d", iRt);
- return GetErrorInfo(0, "Reset %d", iRt);
- }
- ErrorCodeEnum ContactlessCardImpl::DevClose()
- {
- LOG4VTM_FUNCTION();
- if (!m_pConnect->IsLoadSucceed())
- return GetErrorInfo(PCSC_NOT_OPEN, "DevClose");
- m_pConnect->CloseConnect();
- ErrorCodeEnum err = Error_Succeed;
- return err;
- }
- // DEC_SUCCESS DEC_HARDWARE DEC_TIMEOUT DEC_INVALID_PARAMETER DEC_INVALID_MASTER_KEY
- const static CmbErrorDef RFICErrorDat[] = {
- {0, "成功", Error_Succeed, DEC_SUCCESS},
- {PCSC_NOT_OPEN, "设备没有打开", Error_Hardware, DEC_DEV_NOT_OPENED},
- {PCSC_HARDWARE_ERROR,"设备硬件故障", Error_Hardware, DEC_HARDWARE},
- {PCSC_TIMEOUT, "设备响应超时", Error_DevCommFailed, DEC_TIMEOUT},
- {PCSC_PARA_ERR, "传入参数错误", Error_Param, DEC_INVALID_PARAMETER},
- {PCSC_NOT_CONN, "未建立连接", Error_DevMedia, DEC_INVALID_PARAMETER},
- {PCSC_NO_CARD, "未检测到卡", Error_DevMedia, DEC_INVALID_PARAMETER},
- {-105, "卡已经移除", Error_DevMedia, DEC_INVALID_PARAMETER},
- };
- ErrorCodeEnum ContactlessCardImpl::GetErrorInfo(int iCode, char* sErr, ...)
- {
- size_t iLenOne = sizeof(CmbErrorDef);
- size_t iLenAll = sizeof(RFICErrorDat);
- int iCount = iLenAll / iLenOne;
- char sErrInfo[256]="";
- DWORD dSta = 0;
- int iErr = -1;
- for (int ia = 0; ia < iCount; ia++)
- {
- if (RFICErrorDat[ia].iCode == iCode)
- {
- dSta = RFICErrorDat[ia].iInf;
- strcpy(sErrInfo, RFICErrorDat[ia].sInf);
- iErr = RFICErrorDat[ia].iRet;
- break;
- }
- }
- char sErrAll[300];
- va_list arglist;
- va_start(arglist, sErr);
- _vsnprintf(sErrAll, 128, sErr, arglist);
- va_end(arglist);
- if (sErrInfo[0])
- {
- strcat(sErrAll, " ");
- strcat(sErrAll, sErrInfo);
- }
- sErrAll[200] = 0;
- iLenOne = strlen(sErrAll);
- sprintf(m_DevErrInfo.szErrMsg, "{\"ErrCode\":\"%04x\",\"Description\":\"%s\"}", iErr, sErrAll);
- // strcpy(m_DevErrInfo.szErrMsg, sErrAll);
- m_DevErrInfo.dwErrMsgLen = ((dSta << 16) & 0xffff0000) + iLenOne;
- if (iErr != Error_Succeed)
- LOG4VTM(WARN, m_DevErrInfo.szErrMsg);
- else
- LOG4VTM(INFO, m_DevErrInfo.szErrMsg);
- return (ErrorCodeEnum)iErr;
- }
- ErrorCodeEnum ContactlessCardImpl::GetLastErr(DevErrorInfo &devErrInfo)
- {
- memcpy(&devErrInfo, &m_DevErrInfo, sizeof(DevErrorInfo));
- return Error_Succeed;
- }
- //
- ErrorCodeEnum ContactlessCardImpl::GetDevStatus(RFICReaderStatus& devStatus)
- {
- LOG4VTM_FUNCTION();
- if (!m_pConnect->IsLoadSucceed())
- return GetErrorInfo(PCSC_NOT_OPEN, "GetDevStatus");
- int ia = m_pConnect->GetCardStatus();
- switch(ia){
- case 1:
- devStatus.eMediaPos = CI_MEDIA_RF;
- break;
- case 2:
- devStatus.eMediaPos = CI_MEDIA_NOTPRESENT;
- m_bCardConn = false;
- break;
- default:
- devStatus.eMediaPos = CI_MEDIA_NOTPRESENT;
- m_bCardConn = false;
- }
- return Error_Succeed;
- }
- //
- // Abort current operation.
- //
- ErrorCodeEnum ContactlessCardImpl::AbortRead()
- {
- return Error_Succeed;
- }
- //
- // Active contactless card(Type A,B,Mifare)
- // The first,second,third activation order decided by fstType,scdType,thdType respectively
- // fstType,scdType,thdType can be one of 'A','B','M','0'(30H,no type)
- // outType indicates the type of activation result
- //
- ErrorCodeEnum ContactlessCardImpl::ActiveContactlessICCard(char fstType, char scdType, char thdType, char& outType)
- {
- LOG4VTM_FUNCTION();
- if (!m_pConnect->IsLoadSucceed())
- return GetErrorInfo(PCSC_NOT_OPEN, "ActiveContactlessICCard");
- BYTE byAtrData[256] = {0};
- int iAtrLen = 0;
- m_bCardConn = false;
- int iRet = m_pConnect->ReaderConnect(byAtrData, &iAtrLen);
- if (iRet != 0 || iAtrLen < 1)
- {
- outType = '0';
- return GetErrorInfo(PCSC_NO_CARD, "ActiveContactlessICCard ReaderConnect %d %s", iRet, m_pConnect->GetLastError());
- }
- char sHexData[512];
- ::ANSIToHexStr(byAtrData, iAtrLen, sHexData);
- printf("ATR %d %s\n", iAtrLen, sHexData);
- outType = 'A';
- if (strcmp(sHexData, "3B8F8001804F0CA000000306030001E00000018B") == 0)
- outType = '0';
- if (strcmp(sHexData, "3B8F8001804F0CA000000306030001000000006A") == 0) // 公交卡、房卡
- outType = 'M';
- if (strcmp(sHexData, "3B8F8001804F0CA0000003060300020000000069") == 0)
- outType = 'M';
- if (strcmp(sHexData, "3B8F8001804F0CA000000306030001E00000018B") == 0)
- outType = '0';
- // if (strcmp(sHexData, "3B8E800180318066B1C5240100ED83009000F7") == 0) //
- // outType = '2';
- if (iAtrLen == 13 && strstr(sHexData, "3B888001D103")) //身份证
- outType = 'B';
- m_bCardConn = true;
- return GetErrorInfo(iRet, "ActiveContactlessICCard");
- }
- //
- // Deactivate contactless IC card
- //
- ErrorCodeEnum ContactlessCardImpl::DeactContactlessICCard()
- {
- LOG4VTM_FUNCTION();
- if (!m_pConnect->IsLoadSucceed())
- return GetErrorInfo(PCSC_NOT_OPEN, "DeactContactlessICCard");
- m_bCardConn = false;
- int iRet = m_pConnect->EjectCard();
- if (iRet == 0)
- return GetErrorInfo(0, "DeactContactlessICCard");
- return GetErrorInfo(PCSC_HARDWARE_ERROR, "ActiveCDeactContactlessICCard %d", iRet);;
- }
- //
- // Warm reset card(IC)
- //
- ErrorCodeEnum ContactlessCardImpl::WarmReset()
- {
- LOG4VTM_FUNCTION();
- if (!m_pConnect->IsLoadSucceed())
- return GetErrorInfo(PCSC_NOT_OPEN, "WarmReset");
- m_bCardConn = false;
- if (m_pConnect->GetCardStatus() != 1)
- return GetErrorInfo(PCSC_NO_CARD, "WarmReset");
- int iRet = m_pConnect->EjectCard();
- if (iRet != 0)
- return GetErrorInfo(iRet, "WarmReset");
- BYTE byAtrData[256] = {0};
- int iAtrLen = 0;
- iRet = m_pConnect->ReaderConnect(byAtrData, &iAtrLen);
- if (iRet == 0)
- {
- m_bCardConn = true;
- return GetErrorInfo(0, "WarmReset");
- }
- return GetErrorInfo(PCSC_HARDWARE_ERROR, "WarmReset %d", iRet);;
- }
- //
- // Mifare operation
- // Arguments:
- // - eFunType:function type as load key,authentication and so on
- // - return/data(hex) byte order like BIG EDIAN. ex:0x12345678 --> data[i] = 0x12,data[i+1] = 0x34,data[i+2] = 0x56,data[i+3] = 0x78
- // - sendBuf:[parameter(hex)][data(hex)]
- // - recvBuf:[status(1byte)][return data(hex)]
- // -- [eFunType],[parameter,data],[status(1byte),return data]
- // -- [CI_MIFARE_LOAD_KEY],[key select(1byte),sector num(1byte),uncoded keys(6bytes)],[status(1byte)]
- // -- [CI_MIFARE_AUTH],[key select(1byte),sector num(1byte)],[status(1byte)]
- // -- [CI_MIFARE_READ],[block num(1byte)],[status(1byte),data(16bytes)]
- // -- [CI_MIFARE_WRITE],[block num(1byte),data(16bytes)],[status(1byte)]
- // -- [CI_MIFARE_INC],[source block num(1byte),destination block num(1byte),inc value(4bytes)],[status(1byte)]
- // -- [CI_MIFARE_DEC],[source block num(1byte),destination block num(1byte),dec value(4bytes)],[status(1byte)]
- // -- key select(1byte):AKey(00h),BKey(01h)
- // -- status(1byte):OK(00h),other error code(!00h)
- ErrorCodeEnum ContactlessCardImpl::MifareCommand(MifareFuctionEnum eFunType, CmdInfo sendBuf, CmdInfo& recvBuf)
- {
- LOG4VTM_FUNCTION();
- return Error_NotImpl;
- }
- //
- // RF Type A,B command.
- // APDU:Application Protocol Data Unit
- // Arguments:
- // - CmdSend.lpCmd:Command-APDU
- // - CmdRecv.lpData:Response-APDU
- //
- ErrorCodeEnum ContactlessCardImpl::RFTypeABCommand(CmdInfo sendBuf, CmdInfo& recvBuf)
- {
- LOG4VTM_FUNCTION();
- if (m_bCardConn == false)
- return GetErrorInfo(PCSC_NOT_CONN, "RFTypeABCommand");
- unsigned char sAnsi[1024];
- int iRetCount = 0;
- ::HexStrToANSI((char*)sendBuf.data, sAnsi, sendBuf.dwSize);
- int iRet = m_pConnect->SendApdu(sAnsi, sendBuf.dwSize << 1, sAnsi, &iRetCount);
- if (iRet != 0)
- return GetErrorInfo(iRet, "RFTypeABCommand SendApdu %d %s", iRet, m_pConnect->GetLastError());
- ::ANSIToHexStr(sAnsi, iRetCount, (char*)recvBuf.data);
- recvBuf.dwSize = iRetCount << 1;
- return Error_Succeed;
- }
- //halt card
- //card have been halted must move from induction zone then can be found again
- ErrorCodeEnum ContactlessCardImpl::HaltCard()
- {
- LOG4VTM_FUNCTION();
- if (!m_pConnect->IsLoadSucceed())
- return GetErrorInfo(PCSC_NOT_OPEN, "HaltCard");
- int iRet = m_pConnect->EjectCard();
- if (iRet == 0)
- {
- m_bCardConn = false;
- return GetErrorInfo(0, "HaltCard");
- }
- return GetErrorInfo(PCSC_HARDWARE_ERROR, "HaltCard %d", iRet);;
- }
|