/// <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); } } }
/// <summary> /// Issues a GPO command. /// </summary> /// <remarks>Pdol data , reponce parsing and storing are handled internaly</remarks> public void GetProcessingOptions() { List <byte> pdoldata = new List <byte> { 0x83 }; var pdol = TLV_SELECT.TagList.SingleOrDefault(t => t.TagStringName == "9F38"); if (pdol != null) { var tempdata = TlvTools.parseTagLengthData(pdol.TagValue.ToArray()); pdoldata.Add((byte)tempdata.Length); pdoldata.AddRange(tempdata); } else { pdoldata.Add(0x00); } CommandApdu apdu = new CommandApdu(IsoCase.Case4Short, _reader.ActiveProtocol) { CLA = new ClassByte(ClaHighPart.Iso8x, SecureMessagingFormat.None, 0), INS = 0xA8, P1 = 0x00, P2 = 00, Data = pdoldata.ToArray() }; var res = _reader.TransmitWithLog(apdu); // data buffer RES_GPO = res.GetData(); GpoTemplateFormat = (RES_GPO[0] == (byte)EmvConstants.GpoTemplateFormat.Format1) ? EmvConstants.GpoTemplateFormat.Format1 : EmvConstants.GpoTemplateFormat.Format2; TLV_GPO = new SmartTlv(RES_GPO); }