/// <summary>
        /// Reads the file pointed by the SFI found in the FCI of the application.
        /// </summary>
        /// <returns>Last status word.</returns>
        public UInt16 Read()
        {
            BeforeReadEvent.Raise(this, new EmvEventArgs());

            var tlvSfi = TlvFci.GetTag(0x88);

            if (tlvSfi == null)
            {
                throw new Exception(String.Format("PSE: no tag 88 (sfi) found in FCI [{0}]", TlvFci));
            }
            var sfi = new ShortFileIdentifier(tlvSfi);

            byte recordNumber = 0;

            do
            {
                recordNumber++;
                var crp = new CommandResponsePair {
                    CApdu = new EMVReadRecordCommand(recordNumber, sfi.Sfi, 0)
                };
                crp.Transmit(_cardChannel);
                _lastStatusWord = crp.RApdu.StatusWord;
                if (crp.RApdu.StatusWord == 0x9000)
                {
                    _tlvRecords.Add(new TlvData(crp.RApdu.Udr));
                }
            } while (_lastStatusWord == 0x9000);

            AfterReadEvent.Raise(this, new EmvEventArgs());

            return(_lastStatusWord);
        }
Example #2
0
        /// <summary>
        /// Process the GET PROCESSING OPTIONS phase of an EMV transaction.
        /// </summary>
        /// <returns>Last status word.</returns>
        public UInt16 GetProcessingOptions()
        {
            BeforeGetProcessingOptionsEvent.Raise(this, new EmvEventArgs());

            // If PDOL 9F38 is not supplied in FCI, then used 8300 as UDC; if supplied: build the PDOL in tag 83 L V
            byte[] pdolDataValue;
            if (TlvFci.HasTag(0x9F38))
            {
                // Use PDOL to build tag 83 value
                var pdol   = new DataObjectList(TlvFci.GetTag(0x9F38).Value);
                var tlvAll = new List <TlvData> {
                    TlvFci
                };
                tlvAll.AddRange(TlvTerminalData);
                pdolDataValue = pdol.BuildData(tlvAll);
            }
            else
            {
                pdolDataValue = new byte[0];
            }
            // Build tag 83 with computed value
            var tlvPdolData = new TlvData(0x83, (uint)pdolDataValue.Length, pdolDataValue);

            // Execute GET PROCESSING OPTIONS
            var cAPDU = new CommandAPDU(0x80, 0xA8, 0x00, 0x00, tlvPdolData.Length + 2, tlvPdolData.ToByteArray(), 0);
            var crp   = new CommandResponsePair(cAPDU);

            crp.Transmit(_cardChannel);

            _lastStatusWord = crp.RApdu.StatusWord;

            // If GET RESPONSE needed, do it
            if (crp.RApdu.Sw1 == 0x61)
            {
                _tlvProcessingOptions = new TlvData();

                crp = new CommandResponsePair(new GetResponseCommand(crp.RApdu.Sw2));
                crp.Transmit(_cardChannel);
                _lastStatusWord = crp.RApdu.StatusWord;
            }

            // Finally, store result
            if (crp.RApdu.StatusWord == 0x9000)
            {
                _tlvProcessingOptions = new TlvData(crp.RApdu.Udr);
            }

            AfterGetProcessingOptionsEvent.Raise(this, new EmvEventArgs());

            return(_lastStatusWord);
        }