Beispiel #1
0
        void DisplayReaderState(uint ReaderState, CardBuffer CardAtr)
        {
            lbReaderStatus.Text = SCARD.ReaderStatusToString(ReaderState);

            if (CardAtr != null)
            {
                lbCardAtr.Text = CardAtr.AsString(" ");
            }
            else
            {
                lbCardAtr.Text = "";
            }

            bool runable = false;

            if ((ReaderState & SCARD.STATE_PRESENT) != 0)
            {
                if ((ReaderState & SCARD.STATE_UNAVAILABLE) == 0)
                {
                    if ((ReaderState & SCARD.STATE_MUTE) == 0)
                    {
                        runable = true;
                    }
                }
            }

            btnRun.Enabled = runable;
        }
Beispiel #2
0
        /// <summary>
        /// Callback used when the reader's status change
        /// As this method is called from a thread, you can't directly modify the user interface
        /// </summary>
        /// <param name="readerState"></param>
        /// <param name="cardAtr"></param>
        private void readerStatusChanged(uint readerState, CardBuffer cardAtr)
        {
            // When you are in a thread you can't directly modify the user interface
            if (InvokeRequired)
            {
                this.BeginInvoke(new readerStatusChangedInvoker(readerStatusChanged), readerState, cardAtr);
                return;
            }
            btnRead.Enabled      = false;
            txtAsciiContent.Text = "";
            txtFinalStatus.Text  = "";
            txtHexData.Text      = "";
            lblCardAtr.Text      = "";
            lblStatus.Text       = SCARD.ReaderStatusToString(readerState);

            if (cardAtr != null)
            {
                lblCardAtr.Text = cardAtr.AsString(" ");
                channel         = new SCardChannel(reader);
                if (!channel.Connect())
                {
                    lblStatus.Text = "Error, can't connect to the card";
                    return;
                }
                CAPDU capdu = new CAPDU(0xFF, 0xCA, 0x00, 0x00);    // Command sent to the reader
                RAPDU rapdu = channel.Transmit(capdu);              // Response sent from card
                if (rapdu.SW != 0x9000)                             // Something failed
                {
                    lblStatus.Text = "Get UID APDU failed!";
                    return;
                }
                btnRead.Enabled = true;
            }
        }
Beispiel #3
0
        void DisplayReaderState(uint ReaderState, CardBuffer CardAtr)
        {
            lbReaderStatus.Text = SCARD.ReaderStatusToString(ReaderState);

            if (CardAtr != null)
            {
                lbCardAtr.Text = CardAtr.AsString(" ");
            }
            else
            {
                lbCardAtr.Text = "";
            }
        }
Beispiel #4
0
        /// <summary>
        /// Callback used when the reader's status change
        /// As this method is called from a thread, you can't directly modify the user interface
        /// </summary>
        /// <param name="readerState"></param>
        /// <param name="cardAtr"></param>
        private void readerStatusChanged(uint readerState, CardBuffer cardAtr)
        {
            // When you are in a thread you can't directly modify the user interface
            if (InvokeRequired)
            {
                this.BeginInvoke(new readerStatusChangedInvoker(readerStatusChanged), readerState, cardAtr);
                return;
            }

            lblCardUid.Text  = "";
            lblCardAtr.Text  = "";
            lblCardType.Text = "";
            lblProtocol.Text = "";
            lblStatus.Text   = SCARD.ReaderStatusToString(readerState);

            if (cardAtr != null)
            {
                lblCardAtr.Text = cardAtr.AsString(" ");
                channel         = new SCardChannel(reader);
                if (!channel.Connect())
                {
                    lblCardUid.Text = "Error, can't connect to the card";
                    return;
                }
                CAPDU capdu = new CAPDU(0xFF, 0xCA, 0x00, 0x00);    // Command sent to the reader
                RAPDU rapdu = channel.Transmit(capdu);              // Response sent from card
                if (rapdu.SW != 0x9000)                             // Something failed
                {
                    lblCardUid.Text = "Get UID APDU failed!";
                    return;
                }
                // Display card's UID formated as an hexadecimal string
                byte[] rapduB            = rapdu.data.GetBytes();
                string hexadecimalResult = BitConverter.ToString(rapduB);
                lblCardUid.Text = hexadecimalResult.Replace("-", " ");

                // Card's type
                if (cardAtr.Length >= 19)
                {
                    // Card's protocol
                    int cardProdocol = cardAtr[12];
                    if (protocols.ContainsKey(cardProdocol))
                    {
                        lblProtocol.Text = protocols[cardProdocol];
                    }

                    if (cardAtr[4] == 0x80 && cardAtr[5] == 0x4F && cardAtr[6] == 0x0C && cardAtr[7] == 0xA0 && cardAtr[8] == 0x00 && cardAtr[9] == 0x00 && cardAtr[10] == 0x03 && cardAtr[11] == 0x06)
                    {
                        string pixSs = cardAtr[13].ToString("X2") + cardAtr[14].ToString("X2");
                        lblCardType.Text = "Wired-logic: ";
                        if (cardsNames.ContainsKey(pixSs))
                        {
                            lblCardType.Text += cardsNames[pixSs];
                        }
                    }
                    else
                    {
                        lblCardType.Text = "Unknow card type";
                    }
                }
                else
                {
                    lblCardType.Text = "Smartcard";
                }
            }
        }
Beispiel #5
0
        void UpdateReaderState(string ReaderName, uint ReaderState, CardBuffer CardAtr)
        {
            Console.WriteLine(DateTime.Now.ToString(NowFormat));
            Console.WriteLine("\tStatus changed for '" + ReaderName + "'");
            Console.WriteLine("\t\tState: " + SCARD.ReaderStatusToString(ReaderState));
            if (CardAtr != null)
            {
                Console.WriteLine("\t\tATR: " + CardAtr.AsString(" "));
            }

            for (int i = 0; i < lvReaders.Items.Count; i++)
            {
                EXImageListViewItem item = (EXImageListViewItem)lvReaders.Items[i];

                if (item.MyValue.Equals(ReaderName))
                {
                    /* Reader found in the list */
                    /* ------------------------ */

                    lvReaders.BeginUpdate();

                    /* Set status image */
                    int    statusImage;
                    string statusText;

                    if ((ReaderState & SCARD.STATE_PRESENT) != 0)
                    {
                        /* Card is present */
                        if ((ReaderState & SCARD.STATE_INUSE) != 0)
                        {
                            /* Card in use */
                            if ((ReaderState & SCARD.STATE_EXCLUSIVE) != 0)
                            {
                                /* Card in exclusive use */
                                statusText  = "In use (exclusive)";
                                statusImage = StatusImageExclusive;
                            }
                            else
                            {
                                statusText  = "In use (shared)";
                                statusImage = StatusImageInUse;
                            }
                        }
                        else
                        if ((ReaderState & SCARD.STATE_MUTE) != 0)
                        {
                            /* Card is mute */
                            statusText  = "Mute";
                            statusImage = StatusImageMute;
                        }
                        else
                        if ((ReaderState & SCARD.STATE_UNPOWERED) != 0)
                        {
                            /* Card is not powered */
                            statusText  = "Present, not powered";
                            statusImage = StatusImagePresent;
                        }
                        else
                        {
                            /* Card is powered */
                            statusText  = "Present, powered";
                            statusImage = StatusImagePresent;
                        }
                    }
                    else
                    if ((ReaderState & SCARD.STATE_UNAVAILABLE) != 0)
                    {
                        /* Problem */
                        statusText  = "Reserved (direct)";
                        statusImage = StatusImageUnavailable;
                    }
                    else
                    if ((ReaderState & SCARD.STATE_IGNORE) != 0)
                    {
                        /* Problem */
                        statusText  = "Error (ignore)";
                        statusImage = StatusImageError;
                    }
                    else
                    if ((ReaderState & SCARD.STATE_UNKNOWN) != 0)
                    {
                        /* Problem */
                        statusText  = "Error (status unknown)";
                        statusImage = StatusImageUnknown;
                    }
                    else
                    if ((ReaderState & SCARD.STATE_EMPTY) != 0)
                    {
                        /* No card */
                        statusText  = "Absent";
                        statusImage = StatusImageAbsent;
                    }
                    else
                    {
                        /* Problem */
                        statusText  = "Bad status";
                        statusImage = StatusImageError;
                    }

                    EXImageListViewSubItem subitem = (EXImageListViewSubItem)item.SubItems[2];
                    subitem.MyImage       = statusImages.Images[statusImage];
                    item.SubItems[3].Text = statusText;

                    if (CardAtr != null)
                    {
                        item.SubItems[4].Text = CardAtr.AsString("");
                    }
                    else
                    {
                        item.SubItems[4].Text = "";
                    }

                    lvReaders.EndUpdate();
                    break;
                }
                /* NB : we ignore the event in case the reader is not already listed */
            }
        }
Beispiel #6
0
        void ReaderStatusChanged(uint ReaderState, CardBuffer CardAtr)
        {
            /* The ReaderStatusChanged function is called as a delegate (callback) by the SCardReader object    */
            /* within its backgroung thread. Therefore we must use the BeginInvoke syntax to switch back from   */
            /* the context of the background thread to the context of the application's main thread. Overwise   */
            /* we'll get a security violation when trying to access the window's visual components (that belong */
            /* to the application's main thread and can't be safely manipulated by background threads).         */
            if (InvokeRequired)
            {
                this.BeginInvoke(new ReaderStatusChangedInvoker(ReaderStatusChanged), ReaderState, CardAtr);
                return;
            }

            eReaderStatus.Text = SCARD.ReaderStatusToString(ReaderState);

            if (CardAtr != null)
            {
                eCardAtr.Text = CardAtr.AsString(" ");
            }
            else
            {
                eCardAtr.Text = "";
            }

            if (ReaderState == SCARD.STATE_UNAWARE)
            {
//			  lbReaderStatus.Text = "";

                MessageBox.Show("The reader we were working on has disappeared from the system. This application will terminate now.",
                                "The reader has been removed",
                                MessageBoxButtons.OK,
                                MessageBoxIcon.Exclamation);

                Application.Exit();
            }
            else
            if ((ReaderState & SCARD.STATE_EMPTY) != 0)
            {
//			  lbReaderStatus.Text = "No card in the reader";
                card_available = false;
            }
            else
            if ((ReaderState & SCARD.STATE_UNAVAILABLE) != 0)
            {
//			  lbReaderStatus.Text = "Reader in use";
                card_available = false;
            }
            else
            if ((ReaderState & SCARD.STATE_MUTE) != 0)
            {
//			  lbReaderStatus.Text = "Card is mute";
                card_available = false;
            }
            else
            if ((ReaderState & SCARD.STATE_INUSE) != 0)
            {
//			  lbReaderStatus.Text = "Card in use";
                card_available = false;
            }
            else
            if ((ReaderState & SCARD.STATE_PRESENT) != 0)
            {
                //lbReaderStatus.Text = "Card ready";
                card_available = true;

                if (auto_write)
                {
                    BtnWriteClick(null, null);
                    auto_write = false;
                }
            }

            ShowStatus();
        }
        void ReaderStatusChanged(uint readerState, CardBuffer cardAtr)
        {
            try
            {
                string msg;

                if (InvokeRequired)
                {
                    this.BeginInvoke(new ReaderStatusChangedInvoker(ReaderStatusChanged), readerState, cardAtr);
                    return;
                }

                SCARD.ReaderStatusToString(readerState);

                if (cardAtr != null)
                {
                    _tagATR = RemoveSpaces(cardAtr.AsString(" "));
                }
                else
                {
                }

                if (readerState == SCARD.STATE_UNAWARE)
                {
                    if (_cardchannel != null)
                    {
                        _cardchannel.Disconnect();
                        _cardchannel = null;
                    }

                    if (!_inLoop)
                    {
                        msg = "The reader we were working with has gone AWOL from the system.";
                        WarnNotify("Warning|" + msg);
                        _inLoop = true;
                    }

                    tmrTagMonitor.Enabled = true;
                    msg = "Reader not Found. Please check Connection.";
                    WarnNotify("Warning|" + msg);
                }
                else if ((readerState & SCARD.STATE_EMPTY) != 0)
                {
                    _tag    = null;
                    _inLoop = false;

                    _studentData = null;
                    InfoNotify("Ready|Please insert another card for Tagging");

                    if (_cardchannel == null)
                    {
                        return;
                    }

                    _cardchannel.Disconnect();
                    _cardchannel = null;
                }
                else if ((readerState & SCARD.STATE_UNAVAILABLE) != 0)
                {
                }
                else if ((readerState & SCARD.STATE_MUTE) != 0)
                {
                }
                else if ((readerState & SCARD.STATE_INUSE) != 0)
                {
                    _inLoop = false;
                }
                else if ((readerState & SCARD.STATE_PRESENT) != 0)
                {
                    _inLoop = false;
                    if (_cardchannel != null)
                    {
                        return;
                    }

                    _cardchannel = new SCardChannel(DeviceManager.DeviceSpec.Nfc);

                    if (_cardchannel.Connect())
                    {
                        var mifare = new MiFareCardProg();
                        _tagUID = RemoveSpaces(mifare.GetUID(DeviceManager.DeviceSpec.Nfc).Trim());

                        _cardthread = new Thread(card_read_proc);
                        _cardthread.Start();
                    }
                    else
                    {
                        msg =
                            "NearField failed to connect to the card in the reader. Check that you don't have another application running in background that tries to work with the smartcards in the same time as NearField";
                        WarnNotify("Warning|" + msg);
                        _cardchannel = null;
                    }
                }
            }
            catch (Exception ex)
            {
                ErrorHandler.TreatError(ex);
            }
        }
Beispiel #8
0
        /// <summary>
        /// Callback used when the reader's status change
        /// As this method is called from a thread, you can't directly modify the user interface
        /// </summary>
        /// <param name="readerState"></param>
        /// <param name="cardAtr"></param>
        private void readerStatusChanged(uint readerState, CardBuffer cardAtr)
        {
            // When you are in a thread you can't directly modify the user interface
            if (InvokeRequired)
            {
                this.BeginInvoke(new readerStatusChangedInvoker(readerStatusChanged), readerState, cardAtr);

                return;
            }

            lblCardUid.Text  = "";
            lblCardAtr.Text  = "";
            lblCardType.Text = "";
            lblProtocol.Text = "";


            lblMonto.BackColor = Color.FromArgb(240, 240, 240);

            pctColor.BackColor = Color.FromArgb(255, 0, 0);


            //  pctFoto.Image = Properties.Resources.atleta;


            lblStatus.Text = SCARD.ReaderStatusToString(readerState);

            if (cardAtr != null)
            {
                lblCardAtr.Text = cardAtr.AsString(" ");
                channel         = new SCardChannel(reader);


                pctColor.BackColor = Color.FromArgb(121, 174, 235);

                //   pctFoto.Image = Properties.Resources.atleta;
                //    pctFoto.SizeMode = PictureBoxSizeMode.StretchImage;


                lblCedula.Text      = "Cédula: ";
                lblId.Text          = "Identificación: ";
                lblEstatus.Text     = "Cobrado: ";
                lblTotal.Text       = "Total: ";
                lblMonto.Text       = "Retraso: ";
                lblNombreNino.Text  = "";
                lblDeporteNino.Text = "";

                pctFoto.Image = Properties.Resources.atleta;
                pctCara.Image = Properties.Resources.blanco;

                if (!channel.Connect())
                {
                    lblCardUid.Text = "Error, no puede connectar la tarjeta";

                    return;
                }
                CAPDU capdu = new CAPDU(0xFF, 0xCA, 0x00, 0x00);    // Command sent to the reader
                RAPDU rapdu = channel.Transmit(capdu);              // Response sent from card

                if (connectCard())
                {
                    string cardUID = getcardUID();
                    lblCardUid.Text = cardUID;
                    lblUid2.Text    = cardUID;
                    lblST.Text      = "OK";
                    lblST.ForeColor = Color.FromArgb(34, 177, 76);



                    string aux = "Data Source=" + conexion.Fuente + ";Initial Catalog=" + conexion.Catalogo + ";User ID=" + conexion.User + ";Password="******"Select * from datos where brasalete =@zip";
                    try
                    {
                        SqlCommand cmd = new SqlCommand(consulta, conn);
                        cmd.Parameters.AddWithValue("@zip", cardUID);

                        conn.Open();
                        cmd.CommandType = CommandType.Text;
                        SqlDataReader dr = cmd.ExecuteReader();


                        while (dr.Read())
                        {
                            //   pctFoto.Image = Properties.Resources.lala;
                            pctFoto.Image    = new Bitmap(conexion.RutaImg + dr[1].ToString() + ".jpg");
                            pctFoto.SizeMode = PictureBoxSizeMode.StretchImage;

                            lblId.Text      = "Identificación: " + dr[0].ToString();
                            lblCedula.Text  = "Cédula: " + dr[1].ToString();
                            lblTotal.Text   = " Total: B/. " + dr[3].ToString();
                            lblEstatus.Text = "Cobrado:  B/. " + dr[4].ToString() + "  " + "Pendiente: B/. " + dr[5].ToString();

                            lblNombreNino.Text  = dr[0].ToString();
                            lblDeporteNino.Text = dr[2].ToString();

                            string monto = dr[10].ToString();
                            lblMonto.Text = "Retraso: " + monto + "  Meses";
                            switch (monto)
                            {
                            case "1":
                                // celeste
                                lblMonto.ForeColor = Color.FromArgb(121, 174, 235);
                                pctCara.Image      = Properties.Resources.caraFeliz;
                                break;

                            case "2":
                                // amarillo
                                lblMonto.BackColor = Color.FromArgb(255, 247, 0);
                                pctCara.Image      = Properties.Resources.caraTriste;
                                //  pctFoto.
                                break;

                            case "3":
                                // rojo
                                lblMonto.ForeColor = Color.FromArgb(255, 0, 0);
                                pctCara.Image      = Properties.Resources.llorando;
                                break;

                            // rojo
                            default:
                                lblMonto.ForeColor = Color.FromArgb(255, 0, 0);
                                pctCara.Image      = Properties.Resources.blanco;
                                break;
                            }


                            dr.GetString(1);
                            break;
                        }


                        dr.Close();
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message);
                    }
                    finally
                    {
                        if (conn.State == ConnectionState.Open)
                        {
                            conn.Close();
                        }
                    }
                }//fin de connect card()
                 //----------------------------------------------------------------



                /*
                 *
                 * if (rapdu.SW != 0x9000)                              // Something failed
                 * {
                 *  lblCardUid.Text = "Get UID APDU fallido!";
                 *  return;
                 * }
                 */
                // Display card's UID formated as an hexadecimal string

                /*
                 * byte[] rapduB = rapdu.data.GetBytes();
                 * string hexadecimalResult = BitConverter.ToString(rapduB);
                 *
                 * lblCardUid.Text = hexadecimalResult.Replace("-", " ");
                 */


                // Card's type
                if (cardAtr.Length >= 19)
                {
                    // Card's protocol
                    int cardProdocol = cardAtr[12];
                    if (protocols.ContainsKey(cardProdocol))
                    {
                        lblProtocol.Text = protocols[cardProdocol];
                    }

                    if (cardAtr[4] == 0x80 && cardAtr[5] == 0x4F && cardAtr[6] == 0x0C && cardAtr[7] == 0xA0 && cardAtr[8] == 0x00 && cardAtr[9] == 0x00 && cardAtr[10] == 0x03 && cardAtr[11] == 0x06)
                    {
                        string pixSs = cardAtr[13].ToString("X2") + cardAtr[14].ToString("X2");
                        lblCardType.Text = "Wired-logic: ";
                        if (cardsNames.ContainsKey(pixSs))
                        {
                            lblCardType.Text += cardsNames[pixSs];
                        }
                    }
                    else
                    {
                        lblCardType.Text = "Desconocido tipo de tarjeta";
                    }
                }
                else
                {
                    lblCardType.Text = "Smartcard";
                }
            }
        }
Beispiel #9
0
        void ReaderStatusChanged(uint ReaderState, CardBuffer CardAtr)
        {
            /* The ReaderStatusChanged function is called as a delegate (callback) by the SCardReader object    */
            /* within its backgroung thread. Therefore we must use the BeginInvoke syntax to switch back from   */
            /* the context of the background thread to the context of the application's main thread. Overwise   */
            /* we'll get a security violation when trying to access the window's visual components (that belong */
            /* to the application's main thread and can't be safely manipulated by background threads).         */
            if (InvokeRequired)
            {
                this.BeginInvoke(new ReaderStatusChangedInvoker(ReaderStatusChanged), ReaderState, CardAtr);
                return;
            }

            string s = SCARD.ReaderStatusToString(ReaderState);

            Trace.WriteLine("ReaderStatusChanged: " + s);
            eReaderStatus.Text = s;

            if (CardAtr != null)
            {
                s             = CardAtr.AsString(" ");
                eCardAtr.Text = s;
                Trace.WriteLine("\t" + s);
            }
            else
            {
                eCardAtr.Text = "";
            }

            if (ReaderState == SCARD.STATE_UNAWARE)
            {
                if (llcp != null)
                {
                    llcp.Stop();
                    llcp = null;
                }

                MessageBox.Show("The reader we were working on has disappeared from the system. This application will terminate now.",
                                "The reader has been removed",
                                MessageBoxButtons.OK,
                                MessageBoxIcon.Exclamation);

                Application.Exit();
            }
            else if ((ReaderState & SCARD.STATE_UNAVAILABLE) != 0)
            {
                Trace.WriteLine("Card unavailable");
            }
            else if ((ReaderState & SCARD.STATE_MUTE) != 0)
            {
                Trace.WriteLine("Card mute");
            }
            else if ((ReaderState & SCARD.STATE_INUSE) != 0)
            {
                Trace.WriteLine("Card in use");
            }
            else if ((ReaderState & SCARD.STATE_EMPTY) != 0)
            {
                Trace.WriteLine("Card absent");

                if (llcp != null)
                {
                    Trace.WriteLine("*** Target lost ***");

                    llcp.Stop();
                    llcp = null;

                    PerformStatusChange();
                }

                pControl.Enabled = true;
            }
            else if ((ReaderState & SCARD.STATE_PRESENT) != 0)
            {
                Trace.WriteLine("Card present");

                if ((llcp == null) && ((ReaderState & SCARD.STATE_INUSE) == 0))
                {
                    /* Try to work with this card, it may be a LLCP peer */
                    reader.StopMonitor();

                    pControl.Enabled = false;
                    Trace.WriteLine("*** Starting LLCP ***");

                    llcp = new LlcpInitiator(reader);

                    switch (status)
                    {
                    case Status.SendAndRecv_Ready:
                        /* We are both a receiver and a sender */
                        StartReceiver();
                        StartSender();
                        break;

                    case Status.RecvOnly_Ready:
                    case Status.RecvThenSend_RecvReady:
                    case Status.SendThenRecv_RecvReady:
                        /* We are a receiver */
                        StartReceiver();
                        break;

                    case Status.SendOnly_Ready:
                    case Status.RecvThenSend_SendReady:
                    case Status.SendThenRecv_SendReady:
                        /* We are a sender */
                        StartSender();
                        break;

                    default:
                        break;
                    }

                    if (!llcp.Start())
                    {
                        Trace.WriteLine("*** Failed to start LLCP ***");
                        MessageBox.Show("Failed to instantiate LLCP layer on the newly inserted card. This is likely to be caused by another application taking control of the card before us. Please close all other PC/SC-aware applications. It may also be required to instruct Windows to stop probing the card, see the paragraph pcsc_no_minidriver in the Readme of the PC/SC SDK for more informations.", "Communication error");
                        llcp             = null;
                        pControl.Enabled = true;
                    }

                    reader.StartMonitor(new SCardReader.StatusChangeCallback(ReaderStatusChanged));
                }
            }
        }
Beispiel #10
0
        void ReaderStatusChanged(uint ReaderState, CardBuffer CardAtr)
        {
            /* The ReaderStatusChanged function is called as a delegate (callback) by the SCardReader object    */
            /* within its backgroung thread. Therefore we must use the BeginInvoke syntax to switch back from   */
            /* the context of the background thread to the context of the application's main thread. Overwise   */
            /* we'll get a security violation when trying to access the window's visual components (that belong */
            /* to the application's main thread and can't be safely manipulated by background threads).         */
            if (InvokeRequired)
            {
                this.BeginInvoke(new ReaderStatusChangedInvoker(ReaderStatusChanged), ReaderState, CardAtr);
                return;
            }

            eReaderStatus.Text = SCARD.ReaderStatusToString(ReaderState);

            if (CardAtr != null)
            {
                eCardAtr.Text = CardAtr.AsString(" ");
            }
            else
            {
                eCardAtr.Text = "";
            }

            if (ReaderState == SCARD.STATE_UNAWARE)
            {
                if (cardchannel != null)
                {
                    cardchannel.Disconnect();
                    cardchannel = null;
                }

                MessageBox.Show("The reader we were working on has disappeared from the system. This application will terminate now.",
                                "The reader has been removed",
                                MessageBoxButtons.OK,
                                MessageBoxIcon.Exclamation);

                Application.Exit();
            }
            else
            if ((ReaderState & SCARD.STATE_EMPTY) != 0)
            {
                Trace.WriteLine("Reader: EMPTY");

                if (cardchannel != null)
                {
                    cardchannel.Disconnect();
                    cardchannel = null;
                }

                /* No card -> leave edit mode */
                setEditable(false);
            }
            else
            if ((ReaderState & SCARD.STATE_UNAVAILABLE) != 0)
            {
                Trace.WriteLine("Reader: UNAVAILABLE");
            }
            else
            if ((ReaderState & SCARD.STATE_MUTE) != 0)
            {
                Trace.WriteLine("Reader: MUTE");
            }
            else
            if ((ReaderState & SCARD.STATE_INUSE) != 0)
            {
                Trace.WriteLine("Reader: INUSE");
            }
            else
            if ((ReaderState & SCARD.STATE_PRESENT) != 0)
            {
                Trace.WriteLine("Reader: PRESENT");

                if (cardchannel == null)
                {
                    /* New card -> leave edit mode */
                    setEditable(false);

                    cardchannel = new SCardChannel(reader);

                    if (cardchannel.Connect())
                    {
                        Trace.WriteLine("Connected to the card");
                        cardthread = new Thread(card_read_proc);
                        cardthread.Start();
                    }
                    else
                    {
                        Trace.WriteLine("Connection to the card failed");

                        MessageBox.Show("NfcTool failed to connect to the card in the reader. Check that you don't have another application running in background that tries to work with the smartcards in the same time as NFCTool");

                        cardchannel = null;
                    }
                }


                //card_status = 1;
            }
        }