Exemplo n.º 1
0
        /// <summary>
        /// Will try to connect to _connectedReader and read the card.
        /// </summary>
        /// <returns>Either the data from the card or the error message. Or if 'uidOnly' is true, just the UID prefixed with 'UID^' and ending with '^'</returns>
        public string ReadCard(bool uidOnly = false)
        {
            SCardContext context = new SCardContext();

            context.Establish(SCardScope.System);
            SCardReader reader = new SCardReader(context);

            SCardError result = reader.Connect(_connectedReader, SCardShareMode.Shared, SCardProtocol.Any);

            if (result != SCardError.Success)
            {
                context.Dispose();
                reader.Dispose();
                return(string.Format("No card is detected (or reader reserved by another application){0}{1}",
                                     Environment.NewLine, SCardHelper.StringifyError(result)));
            }

            string[] readerNames; SCardProtocol protocol; SCardState state; byte[] atr;
            result = reader.Status(out readerNames, out state, out protocol, out atr);

            if (result != SCardError.Success)
            {
                context.Dispose();
                reader.Dispose();
                return(string.Format("Unable to read from card.{0}{1}", Environment.NewLine, SCardHelper.StringifyError(result)));
            }

            string message = string.Format("Card detected:{0}Protocol: {1}{0}State: {2}{0}ATR: {3}{0}",
                                           Environment.NewLine, protocol, state, BitConverter.ToString(atr ?? new byte[0]));

            CommandApdu apdu = new CommandApdu(IsoCase.Case2Short, reader.ActiveProtocol)
            {
                CLA         = 0xFF,
                Instruction = InstructionCode.GetData,
                P1          = 0x00,
                P2          = 0x00,
                Le          = 0
            };

            result = reader.BeginTransaction();

            if (result != SCardError.Success)
            {
                context.Dispose();
                reader.Dispose();
                return(string.Format("Cannot start transaction.{0} {1}", Environment.NewLine, SCardHelper.StringifyError(result)));
            }

            SCardPCI recievePci = new SCardPCI();
            IntPtr   sendPci    = SCardPCI.GetPci(reader.ActiveProtocol);

            byte[] recieveBuffer = new byte[256];

            result = reader.Transmit(sendPci, apdu.ToArray(), recievePci, ref recieveBuffer);

            if (result != SCardError.Success)
            {
                context.Dispose();
                reader.Dispose();
                return(string.Format("Cannot transmit data.{0} {1}", Environment.NewLine, SCardHelper.StringifyError(result)));
            }

            var responseApdu = new ResponseApdu(recieveBuffer, IsoCase.Case2Short, reader.ActiveProtocol);

            message += string.Format("SW1: {1}{0}SW2: {2}{0}", Environment.NewLine, responseApdu.SW1, responseApdu.SW2);

            string data = responseApdu.HasData ? BitConverter.ToString(responseApdu.GetData()) : "--";

            if (uidOnly)
            {
                context.Dispose();
                reader.Dispose();
                return(string.Format("UID^{0}^", data));
            }

            message += string.Format("UID: {0}", data);

            reader.EndTransaction(SCardReaderDisposition.Leave);
            reader.Disconnect(SCardReaderDisposition.Reset);

            context.Dispose();
            reader.Dispose();
            return(message);
        }
Exemplo n.º 2
0
        // thread to monitor nfc reader
        private void ScanForId()
        {
            Log("NFC Reading started");
            //Thread.Sleep(10000);
            List <string> currentTokens = new List <string>();
            SCardContext  sCardContext  = new SCardContext();
            SerialContext serialContext = new SerialContext();

            // basically keep running until we're told to stop
            while (state == ServiceState.Starting || state == ServiceState.Running)
            {
                // start dll and just call it
                //IntPtr idloc = Marshal.AllocHGlobal(100);
                //IntPtr errloc = Marshal.AllocHGlobal(100);
                //int len = PCSC_GetID(idloc, errloc);
                //string error = Marshal.PtrToStringAnsi(errloc);
                //string id = "";
                //if(len > 0)
                //    id = Marshal.PtrToStringAnsi(idloc, len);
                ////else
                ////    Log("Read error: " + error);

                //Marshal.FreeHGlobal(idloc);
                //Marshal.FreeHGlobal(errloc);
                List <string> ls = sCardContext.GetIds();
                ls = ls.Concat(serialContext.GetIds()).ToList();
                foreach (string id in ls)
                {
                    //string id = ls.FirstOrDefault() ?? "";
                    // check the id of the token
                    if (!currentTokens.Contains(id) && id != "")
                    {
                        Log("NFCTagDownEvent");
                        // we just got a new token (state change)

                        // load parameters from config
                        if (SystemStatus.AwaitingToken)
                        {
                            // this is where we capture it and show the next screen
                            if (SystemStatus.RegistrationClient != null)
                            {
                                TcpClient c = SystemStatus.RegistrationClient;
                                ServiceCommunication.SendNetworkMessage(ref c, JsonConvert.SerializeObject(new NetworkMessage()
                                {
                                    Type = MessageType.Token, Token = id
                                }));
                                SystemStatus.RegistrationClient = c;
                            }
                        }
                        else
                        {
                            // check config
                            foreach (User u in ApplicationConfiguration.Users)
                            {
                                string hashedToken = Crypto.Hash(Crypto.Hash(id) + u.Salt);
                                foreach (Event e in u.Events)
                                {
                                    if (hashedToken == e.Token)
                                    {
                                        foreach (Lazy <INFCRingServicePlugin> plugin in plugins)
                                        {
                                            if (plugin.Value.GetPluginName() == e.PluginName)
                                            {
                                                plugin.Value.NCFRingDown(id, e.Parameters, SystemStatus);

                                                Log("Plugin " + plugin.Value.GetPluginName() + " passed TagDown event");
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                    currentTokens.Remove(id);
                }
                foreach (string id in currentTokens)
                {
                    Log("NFCTagUpEvent");
                    // we just lost the token (state change)
                    if (SystemStatus.AwaitingToken)
                    {
                        // they just lifted it. reset this
                        SystemStatus.AwaitingToken = false;
                    }
                    else
                    {
                        // check config
                        foreach (User u in ApplicationConfiguration.Users)
                        {
                            string hashedToken = Crypto.Hash(Crypto.Hash(id) + u.Salt);
                            foreach (Event e in u.Events)
                            {
                                if (hashedToken == e.Token)
                                {
                                    foreach (Lazy <INFCRingServicePlugin> plugin in plugins)
                                    {
                                        if (plugin.Value.GetPluginName() == e.PluginName)
                                        {
                                            plugin.Value.NCFRingUp(id, e.Parameters, SystemStatus);
                                            Log("Plugin " + plugin.Value.GetPluginName() + " passed TagUp event");
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                currentTokens = ls;
                // sleep for configured delay?
                Thread.Sleep(100);
            }
            serialContext.Stop();
            Log("NFC Reading stopped");
        }
        // 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();
            }
        }