private void CheckPseButton_Click(object sender, EventArgs e)
        {
            unsafe
            {
                CheckPSERtb.Clear();


                if (rPSE2.Checked)
                {
                    checkEmvPse("2PAY.SYS.DDF01", "PSE2");
                }
                else if (rPSE1.Checked)
                {
                    checkEmvPse("1PAY.SYS.DDF01", "PSE1");
                }
                else
                {
                    MessageBox.Show("You must select Payment System Environment (PSE1/PSE2) first.");
                }
            }
        }
        public unsafe void checkEmvPse(string df_name, string szTitlePse)
        {
            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();
            uFCoder         reader = new uFCoder();

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

            byte[]     sw = new byte[2];
            byte       sfi = 0, record = 0, cnt = 0;
            EMV_STATUS emv_status;

            do
            {
                status = uFCoder.SetISO14443_4_Mode();

                if (status != 0)
                {
                    CheckPSERtb.AppendText("Error while switching into ISO 14443-4 mode, uFR status is: " + uFCoder.status2str(status));
                    break;
                }
                CheckPSERtb.AppendText("1. Issuing \"Select PSE\" command (" + szTitlePse + "):\n");
                CheckPSERtb.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)
                {
                    CheckPSERtb.AppendText("Error while executing APDU command, uFR status is: " + uFCoder.status2str(status));
                    break;
                }
                else
                {
                    if (sw[0] != 0x90)
                    {
                        CheckPSERtb.AppendText("\n [SW] " + sw[0].ToString("X2") + " " + sw[1].ToString("X2"));

                        CheckPSERtb.AppendText("\nCould not continue execution due to an APDU error.\n");
                        break;
                    }
                    if (Ne > 0)
                    {
                        CheckPSERtb.AppendText("\n APDU command executed: response data length = " + Ne.ToString() + " bytes\n");
                        CheckPSERtb.AppendText(" [R] ");
                        for (int resp = 0; resp < Ne; resp++)
                        {
                            CheckPSERtb.AppendText(r_apdu[resp].ToString("X2") + ":");
                        }
                    }

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

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

                if (emv_status != 0)
                {
                    CheckPSERtb.AppendText("EMV parsing error code: " + emv_status.ToString());
                    break;
                }

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

                if (emv_status == 0)
                {
                    cnt    = 2;
                    record = 1;
                    do
                    {
                        CheckPSERtb.AppendText("\n" + cnt.ToString() + ". Issuing \"Read Record\" command (record = " + record.ToString() + ", sfi = " + sfi.ToString() + ")\n");
                        CheckPSERtb.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 (record == 1)
                            {
                                head.next = tail = temp;
                            }
                            else
                            {
                                tail.next = temp;
                                tail      = tail.next;
                            }

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

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

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

                CheckPSERtb.AppendText("\n--------------------------------------------------------------------------------------------------------------------------------------\n");
                CheckPSERtb.AppendText("          Card supports Payment System Environment: " + szTitlePse);
                CheckPSERtb.AppendText("\n===================================================================\n");
            } while (false);

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

            CheckPSERtb.Clear();
        }