public Personal readCitizenid()
        {
            Personal personal = new Personal();

            if (Open())
            {
                // Send SELECT/RESET command
                SendCommand(_apdu.CMD_SELECT());

                // CID
                personal.Citizenid = GetUTF8FromAsciiBytes(SendCommand(_apdu.CMD_CID()));

                Close();
                return(personal);
            }

            return(null);
        }
        public Boolean Open(string readerName = null)
        {
            try
            {
                // delay 1.5 second for ATR reading.
                Thread.Sleep(1500);

                _hContext = _contextFactory.Establish(SCardScope.System);
                _reader   = new SCardReader(_hContext);

                // Connect to the card
                if (String.IsNullOrEmpty(readerName))
                {
                    // Open first avaliable reader.
                    // Retrieve the list of Smartcard _readers
                    string[] szReaders = _hContext.GetReaders();
                    if (szReaders.Length <= 0)
                    {
                        throw new PCSCException(SCardError.NoReadersAvailable,
                                                "Could not find any Smartcard _reader.");
                    }

                    _err = _reader.Connect(szReaders[0],
                                           SCardShareMode.Exclusive,
                                           SCardProtocol.T0 | SCardProtocol.T1);
                    CheckErr(_err);
                }
                else
                {
                    _err = _reader.Connect(readerName,
                                           SCardShareMode.Shared,
                                           SCardProtocol.T0 | SCardProtocol.T1);
                    CheckErr(_err);
                }


                _pioSendPci = new IntPtr();
                switch (_reader.ActiveProtocol)
                {
                case SCardProtocol.T0:
                    _pioSendPci = SCardPCI.T0;
                    break;

                case SCardProtocol.T1:
                    _pioSendPci = SCardPCI.T1;
                    break;

                default:
                    throw new PCSCException(SCardError.ProtocolMismatch,
                                            "Protocol not supported: "
                                            + _reader.ActiveProtocol.ToString());
                }

                string[]      readerNames;
                SCardProtocol proto;
                SCardState    state;
                byte[]        atr;

                var sc = _reader.Status(
                    out readerNames,    // contains the reader name(s)
                    out state,          // contains the current state (flags)
                    out proto,          // contains the currently used communication protocol
                    out atr);           // contains the ATR

                if (atr == null || atr.Length < 2)
                {
                    return(false);
                }

                if (atr[0] == 0x3B && atr[1] == 0x68)       //Smart card tested with old type (Figure A.)
                {
                    _apdu = new APDU_THAILAND_IDCARD_TYPE_02();
                }
                else if (atr[0] == 0x3B && atr[1] == 0x78)   //Smart card tested with new type (figure B.)
                {
                    _apdu = new APDU_THAILAND_IDCARD_TYPE_02();
                }
                else if (atr[0] == 0x3B && atr[1] == 0x79)   // add 2016-07-10
                {
                    _apdu = new APDU_THAILAND_IDCARD_TYPE_02();
                }
                else if (atr[0] == 0x3B && atr[1] == 0x67)
                {
                    _apdu = new APDU_THAILAND_IDCARD_TYPE_01();
                }
                else
                {
                    // try unlisted card with TYPE 02
                    _apdu = new APDU_THAILAND_IDCARD_TYPE_02();

                    // Check ID checksum
                    SendCommand(_apdu.CMD_SELECT());
                    if (Checksum(GetUTF8FromAsciiBytes(SendCommand(_apdu.CMD_CID()))))
                    {
                        return(true);
                    }

                    _error_code    = ECODE_UNSUPPORT_CARD;
                    _error_message = "Card not support";
                    Debug.Print(_error_message);
                    return(false);
                }


                return(true);
            }
            catch (PCSCException ex)
            {
                _error_code    = ECODE_SCardError;
                _error_message = "Open Err: " + ex.Message + " (" + ex.SCardError.ToString() + ")";
                Debug.Print(_error_message);
                return(false);
            }
        }
        // Create new SCardContext then connect, and read data+photo from card
        public bool ReadCard()
        {
            try
            {
                _context = new SCardContext();
                _context.Establish(SCardScope.System);
                _cardReader = new SCardReader(_context);
                Console.WriteLine("Connection was establish");
                var readers = _context.GetReaders();

                if (readers == null)
                {
                    MonitorStop();
                    ReleaseContext();
                    return(false);
                }

                // this will invoke StatusChanged with NewState 'SCRState.Exclusive'. so, handle it carefully
                _err = _cardReader.Connect(readers.First(),
                                           SCardShareMode.Exclusive,
                                           SCardProtocol.T0 | SCardProtocol.T1);
                SetIntPtr(_cardReader.ActiveProtocol);
                Console.WriteLine("Card Reading.");
                Console.WriteLine("Check Card Error => " + _err);
                Console.WriteLine("Check Card Support => " + IsThailandSupportCard());
                //Console.WriteLine(IsThailandSupportCard());
                if (_err == SCardError.Success && IsThailandSupportCard())
                {
                    Personal personal = new Personal();
                    Console.WriteLine("inside if");
                    if (eventBeforeCardInserted != null)
                    {
                        eventBeforeCardInserted();
                    }

                    // Send SELECT/RESET command
                    SendCommand(_apdu.CMD_SELECT());

                    // CID
                    personal.Citizenid = GetUTF8FromAsciiBytes(SendCommand(_apdu.CMD_CID()));
                    id = personal.Citizenid;

                    // Fullname Thai + Eng + BirthDate + Sex
                    personal.Info = GetUTF8FromAsciiBytes(SendCommand(_apdu.CMD_PERSON_INFO()));

                    // Address
                    personal.Address = GetUTF8FromAsciiBytes(SendCommand(_apdu.CMD_ADDRESS()));

                    // issue/expire
                    personal.Issue_Expire = GetUTF8FromAsciiBytes(SendCommand(_apdu.CMD_CARD_ISSUE_EXPIRE()));

                    // get Photo
                    personal.PhotoRaw = SendPhotoCommand();
                    if (personal.PhotoRaw == null)
                    {
                        for (int i = 0; i < 3; i++)
                        {
                            Console.WriteLine("try to read photo attemp => " + (i + 1));
                            personal.PhotoRaw = SendPhotoCommand();
                            if (personal.PhotoRaw != null)
                            {
                                break;
                            }
                        }
                    }



                    Console.WriteLine("Read complete.");

                    if (eventCardInserted != null)
                    {
                        eventCardInserted(personal);
                    }

                    return(true);
                }
                return(false);
            }
            catch (PCSCException ex)
            {
                _error_code    = ECODE_SCardError;
                _error_message = "Err: " + ex.Message + " (" + ex.SCardError.ToString() + ")";
                Console.WriteLine(_error_message);
                Console.WriteLine("Cant Read");
                if (eventCardReadError != null)
                {
                    eventCardReadError(_error_message);
                }

                return(false);
            }
            finally
            {
                ReleaseContext();
            }
        }