private void ReadParsePSEClear_Click(object sender, EventArgs e)
        {
            uFCoder.s_block_deselect(100);


            ReadPSERtb.Clear();
            tCNR1.Clear();
            tCNR2.Clear();
            tCNR3.Clear();
            tCNR4.Clear();
        }
        private void ReadPSEButton_Click(object sender, EventArgs e)
        {
            unsafe
            {
                ReadPSERtb.Clear();

                if (rPSE2.Checked)
                {
                    TryEmvPseCardRead("2PAY.SYS.DDF01", "PSE2");
                }
                else if (rPSE1.Checked)
                {
                    TryEmvPseCardRead("1PAY.SYS.DDF01", "PSE1");
                }
                else
                {
                    MessageBox.Show("You must select Payment System Environment (PSE1/PSE2) first.");
                }
            }
        }
        unsafe int TryEmvPseCardRead(string df_name, string szTitlePse)
        {
            EMV_STATUS emv_status;


            tCNR1.Clear();
            tCNR2.Clear();
            tCNR3.Clear();
            tCNR4.Clear();

            uFCoder reader = new uFCoder();

            bool head_attached = false;

            emv_tree_node_t head = new emv_tree_node_t();
            emv_tree_node_t tail = new emv_tree_node_t();
            emv_tree_node_t temp = new emv_tree_node_t();

            afl_list_item_t afl_list      = new afl_list_item_t();
            afl_list_item_t afl_list_item = new afl_list_item_t();

            byte afl_list_count;

            byte[] r_apdu = new byte[258];
            int    Ne;

            byte[] aid     = new byte[16];
            char[] chr_aid = new char[16];
            byte[] sw      = new byte[2];

            byte sfi, record = 0, cnt = 1, aid_len = 0;

            byte[] gpo_data_field      = new byte[4];
            ushort gpo_data_field_size = 0;

            bool card_found = false;

            byte[] card_nr     = new byte[8];
            int    card_nr_len = 0;

            do
            {
                status = uFCoder.SetISO14443_4_Mode();

                if (status > 0)
                {
                    ReadPSERtb.AppendText("Error while switching into ISO 14443 - 4 mode, uFR status is: " + uFCoder.status2str(status));
                    break;
                }

                ReadPSERtb.AppendText(cnt++.ToString() + ". Issuing \"Select PSE\" command:  \n");
                ReadPSERtb.AppendText(" [C] 00 A4 04 00 " + BitConverter.ToString(Encoding.ASCII.GetBytes(df_name)).Replace("-", " ") + " 00");


                Ne = 256;

                status = uFCoder.APDUTransceive(0x00, 0xA4, 0x04, 0x00, df_name.ToCharArray(), df_name.Length, r_apdu, &Ne, 1, sw);

                if (status > 0)
                {
                    ReadPSERtb.AppendText("Error while executing APDU command, uFR status: " + uFCoder.status2str(status));
                    break;
                }
                else
                {
                    if (sw[0] != 0x90)
                    {
                        ReadPSERtb.AppendText("\n[SW]: " + sw[0].ToString("X2") + sw[1].ToString("X2") + "\n");
                        ReadPSERtb.AppendText("Could not continue execution due to an APDU error. \n");
                        break;
                    }

                    if (Ne > 0)
                    {
                        ReadPSERtb.AppendText("\n APDU command executed, response data length: " + Ne.ToString() + "\n");
                        ReadPSERtb.AppendText("[R] ");

                        for (int resp = 0; resp < Ne; resp++)
                        {
                            ReadPSERtb.AppendText(r_apdu[resp].ToString("X2") + ":");
                        }
                    }

                    ReadPSERtb.AppendText("\n[SW]: " + sw[0].ToString("X2") + sw[1].ToString("X2") + "\n");
                }


                emv_status = reader.newEmvTag(ref head, r_apdu, Ne, false);

                if (emv_status > 0)
                {
                    ReadPSERtb.AppendText("EMV parsing error code: " + emv_status.ToString());
                    break;
                }


                emv_status = reader.getSfi(ref head, &sfi);

                if (emv_status == 0)
                {
                    record = 1;

                    do
                    {
                        ReadPSERtb.AppendText("\n" + cnt.ToString() + ". Issuing \"Read Record\" command (record = " + record.ToString() + ", sfi = " + sfi.ToString() + ")\n");
                        ReadPSERtb.AppendText("[C] 00 B2 " + record.ToString("X2") + " " + ((sfi << 3) | 4).ToString("X2") + " 00\n");

                        emv_status = reader.emvReadRecord(r_apdu, &Ne, sfi, record, sw);
                        if (emv_status == 0)
                        {
                            emv_status = reader.newEmvTag(ref temp, r_apdu, Ne, false);

                            if (!head_attached)
                            {
                                head.next     = temp;
                                head_attached = true;
                            }
                            else
                            {
                                tail.next = temp;
                                tail      = tail.next;
                            }

                            if (Ne > 0)
                            {
                                ReadPSERtb.AppendText(" APDU command executed: response data length = " + Ne.ToString() + "\n");
                                ReadPSERtb.AppendText("[R] ");

                                for (int resp = 0; resp < Ne; resp++)
                                {
                                    ReadPSERtb.AppendText(r_apdu[resp].ToString("X2") + ":");
                                }
                            }
                            ReadPSERtb.AppendText("\n[SW] " + sw[0].ToString("X2") + sw[1].ToString("X2") + "\n");
                        }
                        else
                        {
                            if (sw[0] != 0x90)
                            {
                                ReadPSERtb.AppendText("\n[SW] " + sw[0].ToString("X2") + sw[1].ToString("X2") + "\n");
                                ReadPSERtb.AppendText("There is no records.\n");
                            }
                        }

                        record++;
                        cnt++;
                    } while (emv_status == 0);
                }

                emv_status = reader.getAid(ref head, ref aid, ref aid_len);
                if (emv_status == 0)
                {
                    Array.Copy(aid, chr_aid, aid.Length);
                }
                {
                    ReadPSERtb.AppendText("\n " + cnt++.ToString() + ". Issuing \"Select the appplication command\": \n");
                    ReadPSERtb.AppendText(" [C] 00 A4 00 00 " + aid_len.ToString("X2") + " ");
                    for (int print = 0; print < aid_len; print++)
                    {
                        ReadPSERtb.AppendText(aid[print].ToString("X2") + " ");
                    }
                    ReadPSERtb.AppendText(" 00");
                    Ne = 256;


                    status = uFCoder.APDUTransceive(0x00, 0xA4, 0x04, 0x00, chr_aid, aid_len, r_apdu, &Ne, 1, sw);

                    if (status != 0)
                    {
                        ReadPSERtb.AppendText(" Error while executing APDU command, uFR status is: " + uFCoder.status2str(status) + "\n");
                    }
                    else
                    {
                        if (sw[0] != 0x90)
                        {
                            ReadPSERtb.AppendText("\n[SW] " + sw[0].ToString("X2") + sw[1].ToString("X2") + "\n");
                            ReadPSERtb.AppendText("Could not continue execution due to an APDU error.\n");
                            break;
                        }

                        if (Ne > 0)
                        {
                            ReadPSERtb.AppendText("\n APDU command executed: response data length = " + Ne.ToString() + " bytes \n");
                            ReadPSERtb.AppendText("[R] ");
                            for (int resp = 0; resp < Ne; resp++)
                            {
                                ReadPSERtb.AppendText(r_apdu[resp].ToString("X2") + ":");
                            }
                        }
                        ReadPSERtb.AppendText("\n[SW] " + sw[0].ToString("X2") + sw[1].ToString("X2") + "\n");
                    }

                    emv_status = reader.newEmvTag(ref temp, r_apdu, Ne, false);
                    if (emv_status > 0)
                    {
                        ReadPSERtb.AppendText(" EMV parsing error code: " + emv_status.ToString());
                        break;
                    }

                    if (!head_attached)
                    {
                        head.next     = tail = temp;
                        head_attached = true;
                    }
                    else
                    {
                        tail.next = temp;
                        tail      = tail.next;
                    }

                    ReadPSERtb.AppendText("\n " + cnt++.ToString() + ". Formatting \"Get Processing Options\" instruction (checking PDOL).\n");
                    emv_status = reader.formatGetProcessingOptionsDataField(temp, ref gpo_data_field, &gpo_data_field_size);

                    if (emv_status > 0)
                    {
                        ReadPSERtb.AppendText("EMV parsing error code: " + emv_status.ToString());
                        break;
                    }

                    ReadPSERtb.AppendText("\n " + cnt++.ToString() + ". Issuing \"Get Processing options\" command:\n");
                    ReadPSERtb.AppendText(" [C] 80 A8 00 00 " + gpo_data_field_size.ToString("X2") + " ");
                    for (int comm = 0; comm < gpo_data_field_size; comm++)
                    {
                        ReadPSERtb.AppendText(gpo_data_field[comm].ToString("X2") + " ");
                    }
                    ReadPSERtb.AppendText("00\n");

                    Ne = 256;

                    char[] chr_gpo_array = new char[gpo_data_field_size];

                    Array.Copy(gpo_data_field, chr_gpo_array, gpo_data_field.Length);


                    status = uFCoder.APDUTransceive_Bytes(0x80, 0xA8, 0x00, 0x00, gpo_data_field, gpo_data_field_size, r_apdu, &Ne, 1, sw);

                    if (status != 0)
                    {
                        ReadPSERtb.AppendText(" Error while executing APDU command, uFR status: " + uFCoder.status2str(status) + "\n");

                        break;
                    }
                    else
                    {
                        if (sw[0] != 0x90)
                        {
                            ReadPSERtb.AppendText("\n[SW] " + sw[0].ToString("X2") + sw[1].ToString("X2"));
                            ReadPSERtb.AppendText("Could not continue execution due to an APDU error.");
                            break;
                        }
                        if (Ne > 0)
                        {
                            ReadPSERtb.AppendText("APDU command executed: response data length = " + Ne.ToString() + "\n");
                            ReadPSERtb.AppendText("[R] ");
                            for (int resp = 0; resp < Ne; resp++)
                            {
                                ReadPSERtb.AppendText(r_apdu[resp].ToString("X2") + ":");
                            }
                        }

                        ReadPSERtb.AppendText("\n[SW] " + sw[0].ToString("X2") + sw[1].ToString("X2"));
                    }

                    emv_status = reader.newEmvTag(ref temp, r_apdu, Ne, false);
                    if (emv_status > 0)
                    {
                        ReadPSERtb.AppendText(" EMV parsing error code: " + emv_status.ToString());
                        break;
                    }
                    tail.next = temp;
                    tail      = tail.next;

                    emv_status = reader.getAfl(temp, afl_list, &afl_list_count);

                    if (emv_status == EMV_STATUS.EMV_ERR_TAG_NOT_FOUND)
                    {
                        emv_status = reader.getAflFromResponseMessageTemplateFormat1(temp, afl_list, &afl_list_count);
                    }

                    if (emv_status > 0)
                    {
                        ReadPSERtb.AppendText(" EMV parsing error code: " + emv_status.ToString());
                        break;
                    }

                    afl_list_item = afl_list.next;

                    while (afl_list_item != null)
                    {
                        for (int r = afl_list_item.record_first; r <= afl_list_item.record_last; r++)
                        {
                            ReadPSERtb.AppendText("\n" + cnt.ToString() + ". Issuing \"Read Record\" command (record = " + r.ToString() + ", sfi = " + afl_list_item.sfi.ToString() + "):\n");

                            ReadPSERtb.AppendText(" [C] 00 B2 " + r.ToString("X2") + " " + ((afl_list_item.sfi << 3) | 4).ToString("X2") + " 00\n");

                            emv_status = reader.emvReadRecord(r_apdu, &Ne, afl_list_item.sfi, (byte)r, sw);

                            if (card_found == false)
                            {
                                card_found = reader.GetCardNumber(r_apdu, (int)Ne, ref card_nr, &card_nr_len);
                            }
                            if (emv_status == 0)
                            {
                                byte[] emv_apdu = new byte[r_apdu.Length];

                                Array.Copy(r_apdu, emv_apdu, r_apdu.Length);

                                emv_status = reader.newEmvTag(ref temp, emv_apdu, Ne, false);
                                if (emv_status == 0)
                                {
                                    tail.next = temp;
                                    tail      = tail.next;
                                }
                                if (Ne > 0)
                                {
                                    ReadPSERtb.AppendText("APDU command executed: response data length = " + Ne.ToString() + "\n");
                                    ReadPSERtb.AppendText("[R] ");
                                    for (int resp = 0; resp < Ne; resp++)
                                    {
                                        ReadPSERtb.AppendText(r_apdu[resp].ToString("X2") + ":");
                                    }
                                }

                                ReadPSERtb.AppendText("\n[SW] " + sw[0].ToString("X2") + sw[1].ToString("X2"));
                            }
                            else
                            {
                                if (sw[0] != 0x90)
                                {
                                    ReadPSERtb.AppendText("\n[SW] " + sw[0].ToString("X2") + sw[1].ToString("X2"));
                                }
                            }
                            cnt++;
                        }
                        afl_list_item = afl_list_item.next;
                    }
                }
            } while (false);
            tCNR1.AppendText(card_nr[0].ToString("X2") + " " + card_nr[1].ToString("X2"));
            tCNR2.AppendText(card_nr[2].ToString("X2") + " " + card_nr[3].ToString("X2"));
            tCNR3.AppendText(card_nr[4].ToString("X2") + " " + card_nr[5].ToString("X2"));
            tCNR4.AppendText(card_nr[6].ToString("X2") + " " + card_nr[7].ToString("X2"));

            uFCoder.s_block_deselect(100);

            return(0);
        }