我正在调查从 HID OMNIKEY 非接触式读卡器读取 TI Tag HF-I RFID 卡中的八个数据块的间歇性问题。下面的例程从一个循环中ReadEightBlocks
调用 8 次,每次增加 8 次。读取卡上的所有 64 个数据块,读取 8 个块。依次调用. 但是,读取第二个 8 块偶尔会失败,错误代码为. 谁能解释为什么即使发出了正确的命令,读取偶尔也会失败?for
startBlockNum
ReadEightBlocks
SmartCardTransmit()
SCardTransmit()
0x6A 0x82
protected bool ReadEightBlocks(ulong uid, int startBlockNum, out UInt32[] blocksData)
{
bool bFlag = false;
int numBlocks = 8;
int numBytePerBlock = 8;
int rxBufIndx = 0;
string rxBufData = string.Empty;
SmartCardData pack = new SmartCardData();
blocksData = new UInt32[numBlocks];
try
{
byte[] sendBuffer = { 0xFF, 0xB0, 0x00, Convert.ToByte(startBlockNum), 0x20 };
SCardTransmitReceived rxBuf = SmartCardTransmit(sendBuffer, sendBuffer.Length);
if (rxBuf.RcvFlag == SCardTransmitFlag.SUCCESS)
{
if ((rxBuf.RcvBuf[rxBuf.RcvBufLen - 2] == 0x90) && (rxBuf.RcvBuf[rxBuf.RcvBufLen - 1] == 0))
{
rxBufData = ParseRcvBuffer(rxBuf.RcvBuf, rxBuf.RcvBufLen);
pack.TransmitData = rxBufData;
numBlocks = rxBufData.Length / numBytePerBlock;
blocksData = new UInt32[numBlocks];
try
{
for (int i = 0; i < numBlocks; i++)
{
// Get a substring of the next 8 characters. This is the block data in hex, little-endian.
string blockDataString = rxBufData.Substring(rxBufIndx, numBytePerBlock);
blocksData[i] = System.UInt32.Parse(blockDataString, System.Globalization.NumberStyles.AllowHexSpecifier);
blocksData[i] = (uint)System.Net.IPAddress.HostToNetworkOrder((int)blocksData[i]);
// Next block
rxBufIndx += numBytePerBlock;
}
}
catch
{
return bFlag;
}
bFlag = true;
}
else if ((rxBuf.RcvBuf[rxBuf.RcvBufLen - 2] == 0x62) && (rxBuf.RcvBuf[rxBuf.RcvBufLen - 1] == 0x81))
{
// Warning
pack.TransmitData = string.Format("ReadEightBlocks(startBlockNum = {0}) --> Part of returned data may be corrupted.", startBlockNum.ToString());
}
else if ((rxBuf.RcvBuf[rxBuf.RcvBufLen - 2] == 0x62) && (rxBuf.RcvBuf[rxBuf.RcvBufLen - 1] == 0X82))
{
// Warning
pack.TransmitData = string.Format("ReadEightBlocks(startBlockNum = {0}) --> End of file reached before reading expected number of bytes.", startBlockNum.ToString());
}
else
{
// Error
pack.TransmitData = string.Format("ReadEightBlocks(startBlockNum = {0}) --> Error code.", startBlockNum.ToString());
}
pack.ReaderEvent = AvedroSmartCard.SmartCardReaderEvent.ReadEightBlocks;
OnRaisePacketReceivedEvent(new PacketReceivedEventArgs(pack));
_logger.Debug("Packet transmit data" + pack.TransmitData);
_logger.Debug("rxBuf.RcvBuf[rxBuf.RcvBufLen - 2] = " + (rxBuf.RcvBuf[rxBuf.RcvBufLen - 2]).ToString("X"));
_logger.Debug("rxBuf.RcvBuf[rxBuf.RcvBufLen - 1] = " + (rxBuf.RcvBuf[rxBuf.RcvBufLen - 1]).ToString("X"));
}
else
{
// Raise Error
_logger.Debug("rxBuf.RcvFlag != SUCCESS!");
}
}
catch (Exception ex)
{
string sMsg = String.Format("{0} - {1} {2}", MethodBase.GetCurrentMethod().Name, ex.GetType(), ex.Message);
_logger.DebugException(sMsg, ex);
}
return bFlag;
}
protected SCardTransmitReceived SmartCardTransmit(Byte[] sendBuffer, int sendbufferlen)
{
int iRetval;
SCardTransmitReceived rcvBufObj = new SCardTransmitReceived();
HiDWinscard.SCARD_IO_REQUEST sioreq;
sioreq.dwProtocol = 0x2;
sioreq.cbPciLength = 8;
HiDWinscard.SCARD_IO_REQUEST rioreq;
rioreq.cbPciLength = 8;
rioreq.dwProtocol = 0x2;
Byte[] receiveBuffer = new Byte[255]; //Receive Buffer in SCardTransmit
int receivebufferlen = 255;
try
{
iRetval = HID.SCardTransmit(m_hCard, ref sioreq, sendBuffer, sendbufferlen, ref rioreq, receiveBuffer, ref receivebufferlen);
if (iRetval == 0)
{
receiveBuffer.CopyTo(rcvBufObj.RcvBuf, 0);
rcvBufObj.RcvBufLen = receivebufferlen;
rcvBufObj.RcvFlag = SCardTransmitFlag.SUCCESS;
}
else
{
_logger.Debug(string.Format("SCardTransmit() Failed. Error Code: {0}.", iRetval.ToString()));
}
}
catch (Exception ex)
{
string sMsg = String.Format("{0} - {1} {2}", MethodBase.GetCurrentMethod().Name, ex.GetType(), ex.Message);
}
return rcvBufObj;
}