ISO 15693:OMNIKEY非接触式读卡器,偶尔读取失败

时间:2013-12-23 13:53:16

标签: smartcard rfid winscard iso-15693

我正在研究一个间歇性的问题,即从HID OMNIKEY非接触式读卡器的TI Tag HF-I RFID卡读取8块数据。下面的ReadEightBlocks例程从for循环中调用8次,每次循环startBlockNum增加8。读取卡上的所有64个数据块,8个读取8个块。 ReadEightBlocks调用SmartCardTransmit(),然后调用SCardTransmit()。但是,读取后8个块偶尔会失败,错误代码为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;
    }

0 个答案:

没有答案