|
@@ -114,7 +114,7 @@ ErrorCodeEnum IDCertImpl::GetDevCategory(DevCategoryInfo &devCategory)
|
|
|
// LOG4VTM(INFO, "GetDevCategory getFWVersion error");
|
|
|
// devCategory.eState = DEVICE_STATUS_CONNECTING;
|
|
|
}
|
|
|
- sprintf(devCategory.szModel , "FWID=%s#STYLE=IG#FUNCTION=ITF", sFile);
|
|
|
+ sprintf(devCategory.szModel , "FWID=%s#STYLE=IG#FUNCTION=ITF#CODE=UCS2", sFile);
|
|
|
return Error_Succeed;
|
|
|
}
|
|
|
|
|
@@ -511,6 +511,257 @@ ErrorCodeEnum IDCertImpl::IDCerGetDataEx(IDCerInfoEx &idCerInfoEx)
|
|
|
return Error_Succeed;
|
|
|
}
|
|
|
|
|
|
+ErrorCodeEnum IDCertImpl::IDCerGetDataEx2(IDCerInfoEx2 &idCerInfoEx2)
|
|
|
+{
|
|
|
+ LOG4VTM_FUNCTION();
|
|
|
+ if (!m_bOpen)
|
|
|
+ return HandleDevError(DEV_NOT_OPEN, __FUNCTION__);
|
|
|
+ memset(&idCerInfoEx2,0,sizeof(IDCerInfoEx2));
|
|
|
+ int iRt = Error_Succeed;
|
|
|
+ char strName[256]={0};
|
|
|
+ char strHeadPath[256] = {0};
|
|
|
+ sprintf(strHeadPath, "%s/zp.bmp", m_sLibPath);
|
|
|
+ char* pData = new char[4096];
|
|
|
+ memset(pData, 0, 4096);
|
|
|
+ int ppLen = 4096;
|
|
|
+ int iRetryCount = 0;
|
|
|
+ do
|
|
|
+ {
|
|
|
+ if (0 < iRetryCount)
|
|
|
+ LOG4VTM(WARN, "ReadIDInfoRawData need retry");
|
|
|
+ LOG4VTM(INFO, "ReadIDInfoRawData begin");
|
|
|
+ iRt = m_id81Dev->ReadIDInfoRawData(pData, ppLen);
|
|
|
+ LOG4VTM(INFO, "ReadIDInfoRawData end");
|
|
|
+ if (CWERR_IDCARD_SUCCESS == iRt)
|
|
|
+ break;
|
|
|
+ Sleep(100);
|
|
|
+ ++iRetryCount;
|
|
|
+ } while (iRetryCount < 2);
|
|
|
+
|
|
|
+ if (CWERR_IDCARD_SUCCESS == iRt)
|
|
|
+ {
|
|
|
+ char* pRawData = new char[2048];
|
|
|
+ memset(pRawData, 0, 2048);
|
|
|
+ size_t offset = 6;
|
|
|
+ WORD wRawLen = MAKEWORD(pData[1], pData[0]);
|
|
|
+ memcpy(pRawData, pData + offset, wRawLen);
|
|
|
+ offset += wRawLen;
|
|
|
+ m_iCardType = GetCardType(pRawData);
|
|
|
+ if (0 == m_iCardType || 2 == m_iCardType)
|
|
|
+ {
|
|
|
+ ExchangeNormalAndGAT(pRawData, idCerInfoEx2, 0 == m_iCardType);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ ExchangeForeign(pRawData, idCerInfoEx2);
|
|
|
+ }
|
|
|
+ delete[] pRawData; pRawData = nullptr;
|
|
|
+ }
|
|
|
+ iRt = m_id81Dev->GetID2InfoAllHead(strHeadPath,
|
|
|
+ m_iCardType);
|
|
|
+ memcmp(idCerInfoEx2.photoPath.data, strHeadPath, strlen(strHeadPath));
|
|
|
+ idCerInfoEx2.photoPath.dwSize = strlen(idCerInfoEx2.photoPath.data);
|
|
|
+
|
|
|
+ delete[] pData;
|
|
|
+ pData = nullptr;
|
|
|
+ LOG4VTM(INFO, "IDCerGetDataEx2<<<<<");
|
|
|
+ sprintf(strName, "IDCerGetData name=%d addr=%d", idCerInfoEx2.name.dwSize, idCerInfoEx2.address.dwSize);
|
|
|
+ LOG4VTM(INFO, strName);
|
|
|
+ return Error_Succeed;
|
|
|
+}
|
|
|
+
|
|
|
+void IDCertImpl::ExchangeNormalAndGAT(const char* lpSrcStr, IDCerInfoEx2& idCerInfoEx2, bool needTypeNull)
|
|
|
+{
|
|
|
+ int uDataOffset = 0;
|
|
|
+ // 姓名 30 bytes
|
|
|
+ memcpy(idCerInfoEx2.name.data, lpSrcStr + uDataOffset, 30);
|
|
|
+ idCerInfoEx2.name.dwSize = 30;
|
|
|
+ uDataOffset += 30;
|
|
|
+
|
|
|
+ // 性别 2 bytes
|
|
|
+ // 符合 GB/T 2261.1 的规定
|
|
|
+ // 第一字节:0--未知的性别; 1--男性; 2--女性; 9--未说明的性别。
|
|
|
+ // 5--女性改(变)为男性; 6--男性改(变)为女性
|
|
|
+ // 第二字节:00
|
|
|
+ memcpy(idCerInfoEx2.sex.data, lpSrcStr + uDataOffset, 2);
|
|
|
+ idCerInfoEx2.sex.dwSize = 2;
|
|
|
+ uDataOffset += 2;
|
|
|
+
|
|
|
+ // 民族 4 bytes
|
|
|
+ // 符合 GB/T 3304 的规定
|
|
|
+ memcpy(idCerInfoEx2.nation.data, lpSrcStr + uDataOffset, 4);
|
|
|
+ idCerInfoEx2.nation.dwSize = 4;
|
|
|
+ uDataOffset += 4;
|
|
|
+
|
|
|
+ // 出生日期 16 bytes 年月日:CCYYMMDD
|
|
|
+ memcpy(idCerInfoEx2.birthday.data, lpSrcStr + uDataOffset, 16);
|
|
|
+ idCerInfoEx2.birthday.dwSize = 16;
|
|
|
+ uDataOffset += 16;
|
|
|
+
|
|
|
+ // 住址 70 bytes
|
|
|
+ memcpy(idCerInfoEx2.address.data, lpSrcStr + uDataOffset, 70);
|
|
|
+ idCerInfoEx2.address.dwSize = 70;
|
|
|
+ uDataOffset += 70;
|
|
|
+
|
|
|
+ // 公民身份号码 36 bytes 符合 GB/T11643 的规定
|
|
|
+ memcpy(idCerInfoEx2.idno.data, lpSrcStr + uDataOffset, 36);
|
|
|
+ idCerInfoEx2.idno.dwSize = 36;
|
|
|
+ uDataOffset += 36;
|
|
|
+
|
|
|
+ // 签发机关 30 bytes
|
|
|
+ memcpy(idCerInfoEx2.department.data, lpSrcStr + uDataOffset, 30);
|
|
|
+ idCerInfoEx2.department.dwSize = 30;
|
|
|
+ uDataOffset += 30;
|
|
|
+
|
|
|
+ // 有效期起始日期 16 bytes 年月日:CCYYMMDD
|
|
|
+ memcpy(idCerInfoEx2.startDate.data, lpSrcStr + uDataOffset, 16);
|
|
|
+ idCerInfoEx2.startDate.dwSize = 16;
|
|
|
+ uDataOffset += 16;
|
|
|
+
|
|
|
+ // 有效期截止日期 16 bytes 年月日:CCYYMMDD
|
|
|
+ // 有效期为长期的存储表示为“长期”
|
|
|
+ memcpy(idCerInfoEx2.endDate.data, lpSrcStr + uDataOffset, 16);
|
|
|
+ idCerInfoEx2.endDate.dwSize = 16;
|
|
|
+ uDataOffset += 16;
|
|
|
+
|
|
|
+ // 通行证号码 18 bytes
|
|
|
+ // 台湾居民来往大陆通行证证件号码,如:“12345678”
|
|
|
+ // 港澳居民来往内地通行证证件号码,如:“H12345678”、“M12345678”
|
|
|
+ memcpy(idCerInfoEx2.txzCode.data, lpSrcStr + uDataOffset, 18);
|
|
|
+ idCerInfoEx2.txzCode.dwSize = 18;
|
|
|
+ uDataOffset += 18;
|
|
|
+
|
|
|
+ // 签发次数 4 bytes
|
|
|
+ // 港澳台居民居住证的签发次数,首次签发为“01”。
|
|
|
+ memcpy(idCerInfoEx2.issuedSN.data, lpSrcStr + uDataOffset, 4);
|
|
|
+ idCerInfoEx2.issuedSN.dwSize = 4;
|
|
|
+ uDataOffset += 4;
|
|
|
+
|
|
|
+ // 预留区 6 bytes
|
|
|
+ uDataOffset += 6;
|
|
|
+
|
|
|
+ // 证件类型标识 2 bytes
|
|
|
+ memcpy(idCerInfoEx2.idType.data, lpSrcStr + uDataOffset, 2);
|
|
|
+ idCerInfoEx2.idType.dwSize = 2;
|
|
|
+ if (needTypeNull)
|
|
|
+ {
|
|
|
+ memset(idCerInfoEx2.idType.data, 0x00, 2);
|
|
|
+ idCerInfoEx2.idType.dwSize = 0;
|
|
|
+ }
|
|
|
+ uDataOffset += 2;
|
|
|
+
|
|
|
+ // 预留区 6 bytes
|
|
|
+ uDataOffset += 6;
|
|
|
+}
|
|
|
+
|
|
|
+void IDCertImpl::ExchangeForeign(const char* lpSrcStr, IDCerInfoEx2& idCerInfoEx2)
|
|
|
+{
|
|
|
+ int uDataOffset = 0;
|
|
|
+ // 英文姓名 120 bytes
|
|
|
+ memcpy(idCerInfoEx2.englishName.data, lpSrcStr + uDataOffset, 120);
|
|
|
+ idCerInfoEx2.englishName.dwSize = 120;
|
|
|
+ uDataOffset += 120;
|
|
|
+
|
|
|
+ // 性别 2 bytes
|
|
|
+ // 符合 GB/T 2261.1 的规定
|
|
|
+ // 第一字节:0--未知的性别; 1--男性; 2--女性; 9--未说明的性别。
|
|
|
+ // 5--女性改(变)为男性; 6--男性改(变)为女性
|
|
|
+ // 第二字节:00
|
|
|
+ memcpy(idCerInfoEx2.sex.data, lpSrcStr + uDataOffset, 2);
|
|
|
+ idCerInfoEx2.sex.dwSize = 2;
|
|
|
+ uDataOffset += 2;
|
|
|
+
|
|
|
+ // 永久居留证号码 30 bytes
|
|
|
+ memcpy(idCerInfoEx2.idno.data, lpSrcStr + uDataOffset, 30);
|
|
|
+ idCerInfoEx2.idno.dwSize = 30;
|
|
|
+ uDataOffset += 30;
|
|
|
+
|
|
|
+ // 国籍或所在地区代码 6 bytes
|
|
|
+ // 符合 GB/T 2659-2000 的规定
|
|
|
+ memcpy(idCerInfoEx2.nationality.data, lpSrcStr + uDataOffset, 6);
|
|
|
+ idCerInfoEx2.nationality.dwSize = 6;
|
|
|
+ uDataOffset += 6;
|
|
|
+
|
|
|
+ // 中文姓名 30 bytes
|
|
|
+ memcpy(idCerInfoEx2.name.data, lpSrcStr + uDataOffset, 30);
|
|
|
+ idCerInfoEx2.name.dwSize = 30;
|
|
|
+ uDataOffset += 30;
|
|
|
+
|
|
|
+ // 证件签发日期 16 bytes
|
|
|
+ memcpy(idCerInfoEx2.startDate.data, lpSrcStr + uDataOffset, 16);
|
|
|
+ idCerInfoEx2.startDate.dwSize = 16;
|
|
|
+ uDataOffset += 16;
|
|
|
+
|
|
|
+ // 证件终止日期 16 bytes
|
|
|
+ memcpy(idCerInfoEx2.endDate.data, lpSrcStr + uDataOffset, 16);
|
|
|
+ idCerInfoEx2.endDate.dwSize = 16;
|
|
|
+ uDataOffset += 16;
|
|
|
+
|
|
|
+ // 出生日期 16 bytes
|
|
|
+ memcpy(idCerInfoEx2.birthday.data, lpSrcStr + uDataOffset, 16);
|
|
|
+ idCerInfoEx2.birthday.dwSize = 16;
|
|
|
+ uDataOffset += 16;
|
|
|
+
|
|
|
+ // 证件版本号 4 bytes
|
|
|
+ memcpy(idCerInfoEx2.idVersion.data, lpSrcStr + uDataOffset, 4);
|
|
|
+ idCerInfoEx2.idVersion.dwSize = 4;
|
|
|
+ uDataOffset += 4;
|
|
|
+
|
|
|
+ // 当次申请受理机关代码 8 bytes
|
|
|
+ memcpy(idCerInfoEx2.department.data, lpSrcStr + uDataOffset, 8);
|
|
|
+ idCerInfoEx2.department.dwSize = 8;
|
|
|
+ uDataOffset += 8;
|
|
|
+
|
|
|
+ // 证件类型标识 2 bytes
|
|
|
+ memcpy(idCerInfoEx2.idType.data, lpSrcStr + uDataOffset, 2);
|
|
|
+ idCerInfoEx2.idType.dwSize = 2;
|
|
|
+ uDataOffset += 2;
|
|
|
+
|
|
|
+ // 预留项 6 bytes
|
|
|
+ uDataOffset += 6;
|
|
|
+}
|
|
|
+
|
|
|
+int IDCertImpl::GetCardType(char* lpSrcStr)
|
|
|
+{
|
|
|
+ //0:二代身份证 1:外国人永久居留证 2:港澳台居民居住证
|
|
|
+ int iType = 0;
|
|
|
+ int uDataOffset = 0;
|
|
|
+ int uPartLen = 1;
|
|
|
+ char cDataTmp[128] = {0x00};
|
|
|
+ int cDataTmpLen = 0;
|
|
|
+
|
|
|
+ // 首先需要识别证件类型,返回的总数据为256字节
|
|
|
+ // 其中 249-250 这两个字节是证件类型标识
|
|
|
+ // 正常二代证这个字段可能为空
|
|
|
+ // "I" 表示 外国人永久居留证
|
|
|
+ // "J" 表示 港澳台居民居住证
|
|
|
+// memcpy(cDataTmp,lpSrcStr,sizeof(lpSrcStr));
|
|
|
+ cDataTmpLen = strlen(lpSrcStr);
|
|
|
+ if (0 < cDataTmpLen)
|
|
|
+ {
|
|
|
+ switch (lpSrcStr[248])
|
|
|
+ {
|
|
|
+ case 'I':
|
|
|
+ // 外国人永久居留身份证
|
|
|
+ iType = 1;
|
|
|
+ break;
|
|
|
+ case 'J':
|
|
|
+ // 港澳台居民居住证
|
|
|
+ iType = 2;
|
|
|
+ break;
|
|
|
+ case ' ':
|
|
|
+ iType = 0;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ LOG4VTM(INFO, iType);
|
|
|
+ }
|
|
|
+ sprintf(cDataTmp, "IDCerGetData 248=%c 249=%c 250=%c", lpSrcStr[248],lpSrcStr[249], lpSrcStr[250]);
|
|
|
+ LOG4VTM(INFO, cDataTmp);
|
|
|
+ return iType;
|
|
|
+}
|
|
|
+
|
|
|
// 强制弹出身份证等证件
|
|
|
// Force ID Card to eject。
|
|
|
//
|