/// <summary> /// Issue a read-record command for all records included in the GPO Responce, Tag AFL(Application file locator) /// </summary> public void ReadRecords() { byte[] afl; if (GpoTemplateFormat == EmvConstants.GpoTemplateFormat.Format1) { List <byte> gpores = TLV_GPO.TagList.Single(t => t.TagStringName == "80").TagValue; afl = gpores.Skip(2).ToArray(); } else { afl = TLV_GPO.TagList.SingleOrDefault(t => t.TagStringName == "94")?.TagValue.ToArray(); if (afl == null) { return; } } AflResult aflpos = TlvTools.AflParser(afl); EmvRecords = new List <SmartEmvRecord>(); foreach (var entry in aflpos.AflEntries) { for (int irecord = entry.StartRecord; irecord <= entry.EndRecord; irecord++) //foreach (int irecord in Enumerable.Range(entry.StartRecord, entry.EndRecord)) { CommandApdu apdu = new CommandApdu(IsoCase.Case2Short, _reader.ActiveProtocol); apdu.CLA = 0x00; apdu.INS = 0xB2; //GPO apdu.P1 = (byte)irecord; //select by name apdu.P2 = (byte)((entry.Sfi << 3) | 4); // First or only occurrence var res = _reader.TransmitWithLog(apdu); // data buffer if (res.SW1 == 0x6C) { apdu.Le = res.SW2; res = _reader.TransmitWithLog(apdu); // data buffer } if (res.SW1 != (byte)SW1Code.Normal) { throw new PCSCException(SCardError.CardUnsupported, "GPO not fully supported"); } var record = new SmartEmvRecord(entry.Sfi, irecord, (irecord <= entry.OfflineRecords), res.GetData()); EmvRecords.Add(record); } } }
public static AflResult AflParser(byte[] afl) { AflResult res = new AflResult(); int i = 0; while (i < afl.Length) { AflEntry entry = new AflEntry(); entry.Sfi = afl[i++] >> 3; entry.StartRecord = afl[i++]; entry.EndRecord = afl[i++]; entry.OfflineRecords = afl[i++]; res.AflEntries.Add(entry); } return(res); }