ISO 15693: OMNIKEY Contactless reader, occasional read failure

741 views Asked by At

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;
    }
0

There are 0 answers