问题
I am investigating an intermittent issue where reading eight blocks of data from a TI Tag HF-I RFID card from an HID OMNIKEY contactless reader. The ReadEightBlocks
routine below is called 8 times from a for
loop that bumps startBlockNum
up by 8 each time. Reading all 64 data blocks on the card with 8 reads of 8 blocks. ReadEightBlocks
calls SmartCardTransmit()
that in turn calls SCardTransmit()
. However, reading the second 8 blocks occasionally fails with an error code of 0x6A 0x82
. Can anyone explain why the read occasionally fails even though the right command is issued?
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;
}
来源:https://stackoverflow.com/questions/20744981/iso-15693-omnikey-contactless-reader-occasional-read-failure