/// <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); }
// 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(); } }