private void btnConnect_Click(object sender, EventArgs e)
        {
            Consult consult = new Consult();

            consult.ProtocolVer         = txtProtocolVer.Text;
            consult.ProtocolConformance = txtProtocolConformance.Text;
            consult.FunctionConformance = txtFunctionConformance.Text;
            int txMaxSize = int.Parse(txtTxMaxSize.Text);

            consult.TxMaxSize = (txMaxSize >> 8).ToString("X2") + (txMaxSize & 0x00ff).ToString("X2");
            int rxMaxSize = int.Parse(txtRxMaxSize.Text);

            consult.RxMaxSize = (rxMaxSize >> 8).ToString("X2") + (rxMaxSize & 0x00ff).ToString("X2");
            int maxSizeFrmNum = int.Parse(txtMaxSizeFrmNum.Text);

            consult.MaxSizeFrmNum = maxSizeFrmNum.ToString("X2");
            int maxApduSize = int.Parse(txtMaxApduSize.Text);

            consult.MaxApduSize = (maxApduSize >> 8).ToString("X2") + (maxApduSize & 0x00ff).ToString("X2");
            int overTime = int.Parse(txtOverTime.Text);

            consult.OverTime     = (overTime >> 24).ToString("X2") + (overTime >> 16).ToString("X2") + (overTime >> 8).ToString("X2") + (overTime & 0x00ff).ToString("X2");
            consult.SecurityRule = comboBoxSecurityRule.SelectedIndex.ToString("X2");
            Protocol698 p698 = new Protocol698();

            p698.Connect(txt698KeyVer.Text, consult);
        }
        private void btnCalcFCS_Click(object sender, EventArgs e)
        {
            tbFCS.Text = "";
            Functions.Delay(50);

            string frm = "";

            frm = (ckbAPDUDiv.Checked) ? (tbLen.Text + tbCtl.Text + tbAF.Text + tbSA.Text + tbCA.Text + tbHCS.Text + tbAPDU_1.Text + tbAPDU_2.Text
                                          + tbAPDU_3.Text + tbAPDU_4.Text + tbAPDU_5.Text + tbAPDU_6.Text) :
                  (tbLen.Text + tbCtl.Text + tbAF.Text + tbSA.Text + tbCA.Text + tbHCS.Text + tbAPDU.Text);
            frm = frm.Replace(" ", "").Replace("\n", "").Replace("\r", "");

            if (tbLen.Text.Replace(" ", "").Length != 4 ||
                tbCtl.Text.Replace(" ", "").Length != 2 ||
                tbAF.Text.Replace(" ", "").Length != 2 ||
                tbSA.Text.Replace(" ", "").Length < 2 ||
                tbCA.Text.Replace(" ", "").Length != 2 ||
                tbHCS.Text.Replace(" ", "").Length != 4
                //|| tbAPDU.Text.Replace(" ", "").Replace("\n", "").Replace("\r", "").Length < 2
                || frm.Length % 2 == 1)
            {
                MessageBox.Show("请输入正确帧!");
            }
            else
            {
                ushort fcs = Protocol698.pppfcs16(frm);
                tbFCS.Text = (fcs & 0x00ff).ToString("X2") + " " + ((fcs >> 8) & 0x00ff).ToString("X2");
            }
            tbFCS.Update();
        }
        private void btn698send_Click(object sender, EventArgs e)
        {
            btnClrData_Click(sender, e);
            if (ckbClearBefore.Enabled && ckbClearBefore.Checked)
            {
                tb698Explain.Clear();
            }
            if (ckbAutoCalcLen.Checked)
            {
                btnCalcLen_Click(sender, e);
            }
            if (ckbAutoCalcChk.Checked)
            {
                btnCalcHCS_Click(sender, e); btnCalcFCS_Click(sender, e);
            }

            string txString = "";

            txString = (ckbAPDUDiv.Checked) ? (tb68.Text + tbLen.Text + tbCtl.Text + tbAF.Text + tbSA.Text + tbCA.Text + tbHCS.Text + tbAPDU_1.Text + tbAPDU_2.Text
                                               + tbAPDU_3.Text + tbAPDU_4.Text + tbAPDU_5.Text + tbAPDU_6.Text + tbFCS.Text + tb16.Text) :
                       (tb68.Text + tbLen.Text + tbCtl.Text + tbAF.Text + tbSA.Text + tbCA.Text + tbHCS.Text + tbAPDU.Text + tbFCS.Text + tb16.Text);
            txString = txString.Replace(" ", "").Replace("\r", "").Replace("\n", "");

            if (tbLen.Text.Replace(" ", "").Length != 4 ||
                tbCtl.Text.Replace(" ", "").Length != 2 ||
                tbAF.Text.Replace(" ", "").Length != 2 ||
                tbSA.Text.Replace(" ", "").Length < 2 ||
                tbCA.Text.Replace(" ", "").Length != 2 ||
                tbHCS.Text.Replace(" ", "").Length != 4 ||
                tbFCS.Text.Replace(" ", "").Length != 4
                //|| tbAPDU.Text.Replace(" ", "").Replace("\r", "").Replace("\n", "").Length < 2
                || txString.Length % 2 == 1)
            {
                MessageBox.Show("请输入正确帧!");
                return;
            }

            Protocol698 p698 = new Protocol698();
            string      res  = p698.SendAndRecv(txString);

            if (res != null && res.Length > 0)
            {
                string[] frm = new string[res.Length / 2];
                for (int i = 0; i < res.Length / 2; i++)
                {
                    frm[i] = res.Substring(i * 2, 2);
                }
                int frmLen = Convert.ToInt16(frm[2] + frm[1], 16) + 2;
                if (frmLen != frm.Length)
                {
                    return;
                }

                OldVerDisp698(frm);//旧版报文接收
                if (!ckbOldVerDisp.Checked)
                {
                    NewVerDisp698(res);//新版报文接收
                }
            }
        }
        private void btnRead698Addr_Click(object sender, EventArgs e)
        {
            txt698Addr.Text = string.Empty;
            Functions.Delay(10);
            Protocol698 p698 = new Protocol698();

            txt698Addr.Text = p698.ReadAddr();
        }
        private void btnReadEsamInfo_Click(object sender, EventArgs e)
        {
            txt698EsamSerial.Text    = string.Empty;
            txt698KeyVer.Text        = string.Empty;
            txt698CommTimeLimit.Text = string.Empty;
            txt698CommRestTime.Text  = string.Empty;
            txt698Counter.Text       = string.Empty;
            txt698EsamVer.Text       = string.Empty;
            txt698MeterNo.Text       = string.Empty;
            txtApdu.Text             = string.Empty;
            Functions.Delay(10);

            Protocol698 p698 = new Protocol698();

            byte[] ret     = p698.ReadData("F1000200" + "F1000400" + "F1000500" + "F1000600" + "F1000700" + "40020200" + "F1000300");
            string strApdu = ret.ToHexString();

            txtApdu.Text = strApdu;

            int esamSerialNoStart = strApdu.IndexOf("F1000200") + 8 + 6;//序列号

            txt698EsamSerial.Text = strApdu.Substring(esamSerialNoStart, 16);
            Protocol698.SerialNo  = Transfer.StrToByte(txt698EsamSerial.Text);

            int keyVerStart = strApdu.IndexOf("F1000400") + 8 + 6;//对称密钥版本

            txt698KeyVer.Text = strApdu.Substring(keyVerStart, 32);

            int commLimitStart = strApdu.IndexOf("F1000500") + 8 + 4;//会话时效门限

            txt698CommTimeLimit.Text = strApdu.Substring(commLimitStart, 8);

            int commRestTimeStart = strApdu.IndexOf("F1000600") + 8 + 4;//会话时效剩余时间

            txt698CommRestTime.Text = strApdu.Substring(commRestTimeStart, 8);

            int counterStart = strApdu.IndexOf("F1000700") + 8 + 8;//当前计数器

            txt698Counter.Text = strApdu.Substring(counterStart, 8);

            int esamVerStart = strApdu.IndexOf("F1000300") + 8 + 6;//ESAM版本号

            txt698EsamVer.Text = strApdu.Substring(esamVerStart, 10);

            int meterNoStart = strApdu.IndexOf("40020200") + 8 + 6;//表号

            txt698MeterNo.Text  = strApdu.Substring(meterNoStart, 12);
            Protocol698.MeterNo = Transfer.StrToByte(txt698MeterNo.Text);

            txtCommState.Text          = "未协商或已失效";
            txtCommState.BackColor     = Color.Red;
            txtCommCertState.Text      = "未协商或已失效";
            txtCommCertState.BackColor = Color.Red;
            txtConnectState.Text       = "未连接或已失效";
            txtConnectState.BackColor  = Color.Red;
        }
        private void Comm698Test()
        {
            int oadCnt = Oads.Length / 8;

            string[] oad = new string[oadCnt];
            for (int i = 0; i < oadCnt; i++)
            {
                oad[i] = Oads.Substring(i * 8, 8);
            }

            int cnt = int.Parse(txtCnt.Text);

            if (cnt == 0)
            {
                cnt = 1000000;
            }

            Protocol698 p698 = new Protocol698();

            for (int i = 0; i < cnt; i++)
            {
                string txString = string.Empty;
                txString  = "681700" + "43" + (Addr.Length / 2 - 1).ToString("x2") + Addr.ReverseStr() + "10";
                txString += GetCs(txString.Substring(2));
                txString += "050101";
                Random ro   = new Random();
                int    rand = ro.Next(oadCnt);
                txString += oad[rand];
                txString += "00";
                txString += GetCs(txString.Substring(2));
                txString += "16";

                string res = string.Empty;
                SendCnt++;

                string ret = p698.SendAndRecv(txString);
                if (ret != null && ret.Length > 0)
                {
                    if (res.Length != 0)
                    {
                        SuccessCnt++;
                    }
                }
                double rate = SuccessCnt / SendCnt * 100;
                txtRate.Text = SuccessCnt + "/" + SendCnt + "*100% = " + rate.ToString() + "%";
            }
            btnTest.Text = "开始测试";
            if (TestThread.IsAlive) //判断SetTimeEventTestThread是否存在,不能撤消一个不存在的线程,否则会引发异常
            {
                TestThread.Abort(); //撤消SetTimeEventTestThread
            }
        }
        private void btnTest_Click(object sender, EventArgs e)
        {
            if (!Functions.IsNum(txtCnt.Text))
            {
                MessageBox.Show("测试次数请填入数字");
                return;
            }
            int cnt = int.Parse(txtCnt.Text);

            if (cnt < 0)
            {
                return;
            }

            if (btnTest.Text == "开始测试")
            {
                Oads = txtOad.Text.Replace(" ", "").Replace("\r", "").Replace("\n", "");;
                if (Oads.Length % 8 != 0)
                {
                    MessageBox.Show("OAD不正确!");
                    return;
                }
                SendCnt    = 0;
                SuccessCnt = 0;
                Protocol698 p698 = new Protocol698();
                Addr = p698.ReadAddr();
                if (Addr.Length == 0)
                {
                    MessageBox.Show("读表地址失败!");
                }

                ComTest698Flag = true;
                Control.CheckForIllegalCrossThreadCalls = false;//不检查跨线程的调用是否合法
                TestThread = new Thread(new ThreadStart(Comm698Test));
                TestThread.IsBackground = true;
                TestThread.Start();
            }
            if (btnTest.Text == "停止测试")
            {
                ComTest698Flag = false;
                if (TestThread.IsAlive) //判断SetTimeEventTestThread是否存在,不能撤消一个不存在的线程,否则会引发异常
                {
                    TestThread.Abort(); //撤消SetTimeEventTestThread
                }
            }

            btnTest.Text = (ComTest698Flag ? "停止测试" : "开始测试");
        }
        private void btnCalcHCS_Click(object sender, EventArgs e)
        {
            tbHCS.Text = "";
            Functions.Delay(50);

            string frm = tbLen.Text + tbCtl.Text + tbAF.Text + tbSA.Text + tbCA.Text;

            frm = frm.Replace(" ", "").Replace("\n", "").Replace("\r", "");

            if (tbLen.Text.Replace(" ", "").Length != 4 ||
                tbCtl.Text.Replace(" ", "").Length != 2 ||
                tbAF.Text.Replace(" ", "").Length != 2 ||
                tbSA.Text.Replace(" ", "").Length < 2 ||
                tbCA.Text.Replace(" ", "").Length != 2 ||
                frm.Length % 2 == 1)
            {
                MessageBox.Show("请输入正确帧!");
            }
            else
            {
                ushort hcs = Protocol698.pppfcs16(frm);
                tbHCS.Text = (hcs & 0x00ff).ToString("X2") + " " + ((hcs >> 8) & 0x00ff).ToString("X2");
            }
        }
        private string GetCs(string str)
        {
            ushort hcs = Protocol698.pppfcs16(str);

            return((hcs & 0x00ff).ToString("X2") + ((hcs >> 8) & 0x00ff).ToString("X2"));
        }
        private void NewVerDisp698(string[] frm)
        {
            //XDocument xd = XDocument.Load("xml698Data.xml");
            //XElement rt = xd.Element("Data");
            int frmLen = frm.Length;
            int posNum = 0;

            tb698Explain.AppendText(frm[posNum++] + "    ── 帧起始符\r\n");
            tb698Explain.AppendText(frm[posNum++] + " " + frm[posNum++] + " ── 长度域L=" + Convert.ToInt16(frm[posNum] + frm[posNum - 1], 16) + "字节\r\n");

            string ctrl = "";
            int    c    = Convert.ToInt16(frm[posNum], 16);

            switch (c & 0xc0)
            {
            case 0x00: ctrl += "[DIR=0,PRM=0,客户机对服务器上报的响应]"; break;

            case 0x40: ctrl += "[DIR=0,PRM=1,客户机发起的请求]"; break;

            case 0x80: ctrl += "[DIR=1,PRM=0,服务器发起的上报]"; break;

            case 0xc0: ctrl += "[DIR=1,PRM=1,服务器对客户机请求的响应]"; break;
            }
            switch (c & 0x20)
            {
            case 0x00: ctrl += "[不分帧]"; break;

            case 0x20: ctrl += "[分帧]"; break;
            }
            switch (c & 0x07)
            {
            case 0x01: ctrl += "[功能码(1):链路管理]"; break;

            case 0x03: ctrl += "[功能码(3):用户数据]"; break;

            default: ctrl += "[功能码(" + Convert.ToString(c & 0x07) + "):保留]"; break;
            }
            tb698Explain.AppendText(frm[posNum++] + "    ── 控制域C " + ctrl + "\r\n");
            int    af    = Convert.ToInt16(frm[posNum], 16);
            string strAf = "";

            switch (af & 0xc0)
            {
            case 0x00: strAf += "[单地址]"; break;

            case 0x01: strAf += "[通配地址]"; break;

            case 0x02: strAf += "[组地址]"; break;

            case 0x03: strAf += "[广播地址]"; break;
            }
            strAf += "[逻辑地址:" + (af & 0x30).ToString() + "]";
            strAf += "[地址长度:" + ((af & 0x0f) + 1).ToString() + "]";

            tb698Explain.AppendText(frm[posNum++]);
            for (int i = 0; i < (af & 0x0f) + 1; i++)
            {
                tb698Explain.AppendText(frm[posNum++]);
            }
            tb698Explain.AppendText(" ── SA " + strAf + "\r\n");
            tb698Explain.AppendText(frm[posNum++] + "    ── CA\r\n");
            tb698Explain.AppendText(frm[posNum++] + " " + frm[posNum++] + " ── HCS 帧头校验\r\n");
            tb698Explain.AppendText("──────────────────APDU──────────────────\r\n");
            switch (frm[posNum++])
            {
            case "01": tb698Explain.AppendText("01 ── APDU Tag [1] LINK-Response\r\n"); break;

            case "02": tb698Explain.AppendText("02 ── APDU Tag [2] CONNECT-Request\r\n"); break;

            case "03": tb698Explain.AppendText("03 ── APDU Tag [3] RELEASE-Request\r\n"); break;

            case "05": tb698Explain.AppendText("05 ── APDU Tag [5] GET-Request\r\n"); break;

            case "06": tb698Explain.AppendText("06 ── APDU Tag [6] SET-Request\r\n"); break;

            case "07": tb698Explain.AppendText("07 ── APDU Tag [7] ACTION-Request\r\n"); break;

            case "08": tb698Explain.AppendText("08 ── APDU Tag [8] REPORT-Response\r\n"); break;

            case "09": tb698Explain.AppendText("09 ── APDU Tag [9] PROXY-Request\r\n"); break;

            case "10": tb698Explain.AppendText("10 ── APDU Tag [16] SECURITY-Request\r\n"); break;

            case "81": tb698Explain.AppendText("81 ── APDU Tag [129] LINK-Request\r\n"); break;

            case "82": tb698Explain.AppendText("82 ── APDU Tag [130] CONNECT-Response\r\n"); break;

            case "83": tb698Explain.AppendText("83 ── APDU Tag [131] RELEASE-Response\r\n"); break;

            case "84": tb698Explain.AppendText("84 ── APDU Tag [132] RELEASE-Notification\r\n"); break;

            case "85":    //GET-Response
            {
                #region GET-Response
                tb698Explain.AppendText("85 ── APDU Tag [133] GET-Response\r\n");
                switch (frm[posNum++])
                {
                case "01":             //GetResponseNormal
                {
                    tb698Explain.AppendText("01 ── [1] GetResponseNormal\r\n");
                    tb698Explain.AppendText(frm[posNum++] + " ── PIID-ACD\r\n");
                    tb698Explain.AppendText(frm[posNum++] + frm[posNum++] + " " + frm[posNum++] + frm[posNum++] + " ── OAD\r\n");
                    switch (frm[posNum++])
                    {
                    case "00":
                    {
                        tb698Explain.AppendText("00 ── DAR\r\n");
                        int    tmp     = Convert.ToInt16(frm[posNum]);
                        string darType = Protocol698.GetDARType(tmp);
                        tb698Explain.AppendText(frm[posNum++] + " ── DAR [" + tmp + darType + "]\r\n");
                        break;
                    }

                    case "01":
                    {
                        tb698Explain.AppendText("01 ── Data\r\n");
                        int    tmp      = Convert.ToInt16(frm[posNum], 16);
                        string dataType = Protocol698.GetDataType(tmp);
                        tb698Explain.AppendText(frm[posNum++] + " ── 数据类型:[" + dataType + "]\r\n");
                        int size = Convert.ToInt16(frm[posNum], 16);
                        tb698Explain.AppendText(frm[posNum++] + " ── SIZE(" + size + ")\r\n");
                        string data = "";
                        for (int i = posNum; i < frmLen - 5; i++)
                        {
                            data += frm[posNum++];
                        }
                        tb698Explain.AppendText(data);
                        switch (dataType)
                        {
                        case "date_time":
                        {
                            int year         = Convert.ToInt16(data.Substring(0, 4), 16);
                            int month        = Convert.ToInt16(data.Substring(4, 2), 16);
                            int day_of_month = Convert.ToInt16(data.Substring(6, 2), 16);
                            int day_of_week  = Convert.ToInt16(data.Substring(8, 2), 16);
                            int hour         = Convert.ToInt16(data.Substring(10, 2), 16);
                            int minute       = Convert.ToInt16(data.Substring(12, 2), 16);
                            int second       = Convert.ToInt16(data.Substring(14, 2), 16);
                            int milliseconds = Convert.ToInt16(data.Substring(16), 16);
                            tb698Explain.AppendText(" ── " + year + "-" + month + "-" + day_of_month + "-"
                                                    + "周" + day_of_week + " " + hour + ":" + minute + ":" + second + ":" + milliseconds + "\r\n");
                            break;
                        }

                        case "date":
                        {
                            int year         = Convert.ToInt16(data.Substring(0, 4), 16);
                            int month        = Convert.ToInt16(data.Substring(4, 2), 16);
                            int day_of_month = Convert.ToInt16(data.Substring(6, 2), 16);
                            int day_of_week  = Convert.ToInt16(data.Substring(8, 2), 16);
                            tb698Explain.AppendText(" ── " + year + "-" + month + "-" + day_of_month + "-"
                                                    + "周" + day_of_week + "\r\n");
                            break;
                        }

                        case "time":
                        {
                            int hour   = Convert.ToInt16(data.Substring(0, 2), 16);
                            int minute = Convert.ToInt16(data.Substring(2, 2), 16);
                            int second = Convert.ToInt16(data.Substring(4, 2), 16);
                            tb698Explain.AppendText(" ── " + hour + ":" + minute + ":" + second + "\r\n");
                            break;
                        }

                        case "date_time_s":
                        {
                            int year   = Convert.ToInt16(data.Substring(0, 4), 16);
                            int month  = Convert.ToInt16(data.Substring(4, 2), 16);
                            int day    = Convert.ToInt16(data.Substring(6, 2), 16);
                            int hour   = Convert.ToInt16(data.Substring(8, 2), 16);
                            int minute = Convert.ToInt16(data.Substring(10, 2), 16);
                            int second = Convert.ToInt16(data.Substring(12), 16);
                            tb698Explain.AppendText(" ── " + year + "-" + month + "-" + day + " "
                                                    + hour + ":" + minute + ":" + second + "\r\n");
                            break;
                        }

                        default: tb698Explain.AppendText("\r\n"); break;
                        }
                        break;
                    }

                    default: tb698Explain.AppendText("返回错误\r\n"); break;
                    }
                    break;
                }

                case "02":            //GetResponseNormallist
                {
                    break;
                }

                case "03":            //GetResponseRecord
                {
                    break;
                }

                case "04":            //GetResponseRecordList
                {
                    break;
                }

                case "05":            //GetResponseNext
                {
                    break;
                }
                }
                break;
                #endregion
            }

            case "86":
            {
                #region SET-Response
                tb698Explain.AppendText("86 ── APDU Tag [134] SET-Response\r\n");
                switch (frm[posNum++])
                {
                case "01":             //SetResponseNormal
                {
                    tb698Explain.AppendText("01 ── [1] SetResponseNormal\r\n");
                    tb698Explain.AppendText(frm[posNum++] + " ── PIID-ACD\r\n");
                    tb698Explain.AppendText(frm[posNum++] + frm[posNum++] + " " + frm[posNum++] + frm[posNum++] + " ── OAD\r\n");
                    int    tmp     = Convert.ToInt16(frm[posNum]);
                    string darType = Protocol698.GetDARType(tmp);
                    tb698Explain.AppendText(frm[posNum++] + " ── DAR [" + tmp + darType + "]\r\n");
                    break;
                }

                case "02":             //SetResponseNormalList
                {
                    tb698Explain.AppendText("02 ── [2] SetResponseNormalList\r\n");
                    tb698Explain.AppendText(frm[posNum++] + " ── PIID-ACD\r\n");
                    int num = Convert.ToInt16(frm[posNum], 16);
                    tb698Explain.AppendText(frm[posNum++] + " ── SEQUENCE OF的个数=" + num + "\r\n");
                    for (int i = 0; i < num; i++)
                    {
                        tb698Explain.AppendText(frm[posNum++] + frm[posNum++] + " " + frm[posNum++] + frm[posNum++] + " ── OAD" + (i + 1) + "\r\n");
                        int    tmp     = Convert.ToInt16(frm[posNum]);
                        string darType = Protocol698.GetDARType(tmp);
                        tb698Explain.AppendText(frm[posNum++] + " ── DAR [" + tmp + darType + "]\r\n");
                    }
                    break;
                }

                case "03":             //SetThenGetResponseNormalList
                {
                    tb698Explain.AppendText("03 ── [3] SetResponseNormalList\r\n");
                    tb698Explain.AppendText(frm[posNum++] + " ── PIID-ACD\r\n");
                    int num = Convert.ToInt16(frm[posNum], 16);
                    tb698Explain.AppendText(frm[posNum++] + " ── SEQUENCE OF的个数=" + num + "\r\n");
                    for (int i = 0; i < num; i++)
                    {
                        tb698Explain.AppendText(frm[posNum++] + frm[posNum++] + " " + frm[posNum++] + frm[posNum++] + " ── set OAD" + (i + 1) + "\r\n");
                        int    tmp     = Convert.ToInt16(frm[posNum]);
                        string darType = Protocol698.GetDARType(tmp);
                        tb698Explain.AppendText(frm[posNum++] + " ── DAR [" + tmp + darType + "]\r\n");
                    }
                    tb698Explain.AppendText(frm[posNum++] + frm[posNum++] + " " + frm[posNum++] + frm[posNum++] + " ── read OAD" + "\r\n");
                    for (int i = posNum; i < frmLen - 5; i++)
                    {
                        tb698Explain.AppendText(frm[posNum++]);
                    }
                    tb698Explain.AppendText(" ── Data\r\n");
                    break;
                }

                default: tb698Explain.AppendText("返回错误\r\n"); break;
                }
                break;
                #endregion
            }

            case "87": tb698Explain.AppendText("87 ── APDU Tag [135] ACTION-Response\r\n"); break;

            case "88": tb698Explain.AppendText("88 ── APDU Tag [136] REPORT-Notification\r\n"); break;

            case "89": tb698Explain.AppendText("89 ── APDU Tag [137] PROXY-Response\r\n"); break;

            case "90": tb698Explain.AppendText("90 ── APDU Tag [144] SECURITY-Response\r\n"); break;

            default: tb698Explain.AppendText("返回错误\r\n"); break;
            }
            tb698Explain.AppendText(frm[frmLen - 5] + " ── FollowReport\r\n");
            tb698Explain.AppendText(frm[frmLen - 4] + " ── 时间标签\r\n");
            tb698Explain.AppendText("─────────────────End APDU─────────────────\r\n");
            tb698Explain.AppendText(frm[frmLen - 3] + " " + frm[frmLen - 2] + " ── FCS\r\n");
            tb698Explain.AppendText(frm[frmLen - 1] + "    ── 结束符\r\n");
            tb698Explain.AppendText("------------------------------------------------------------------------------------\r\n\r\n\r\n");
        }