internal ContactlessCard(Card card) { Id = BitConverter.ToString(card.IdBytes); Card = card; CardreaderName = card.CardreaderName; }
public void GetCardId() { // arrange _card = _reader.Connect(GetCardreaderName()).ConnectedCard; // act var getCardIdResult = _reader.GetCardId(_card); Assert.That(getCardIdResult.Bytes.Length, Is.GreaterThan(0)); }
public void GetCardState() { // arrange _card = _reader.Connect(GetCardreaderName()).ConnectedCard; // act var stateResult = _reader.GetCardState(_card); Assert.That(stateResult, Is.True); Assert.That(_card.State.CardStateType, Is.EqualTo(CardStateType.CardSpecific)); }
public void DisableDefaultBuzzer() { // arrange if (_card == null) _card = _reader.Connect(GetCardreaderName()).ConnectedCard; // act var operationResult = _reader.SetBuzzerOutputForCardDetection(_card, false); Assert.IsTrue(operationResult.IsCompletelySuccessful); }
public OperationResult DisconnectCard(Card cardForDisconnect) { if (cardForDisconnect == null) throw new ArgumentNullException("cardForDisconnect"); if (cardForDisconnect.ConnectionHandle != IntPtr.Zero) { var result = DisconnectCardMultiHandlesAware(cardForDisconnect); return result; } return OperationResult.Successful; }
/// <summary> /// Establishing a connection to smart card contained by a specific reader. /// <param name="cardreaderName">Card reader name to connection.</param> /// </summary> public ConnectResult Connect(string cardreaderName, Guid? idOverride = null) { var resourceManagerContext = EstablishContextIfNotEstablished(); IntPtr cardConnectionHandle; int connectionProtocolType; int returnCode = WinscardWrapper.SCardConnect( resourceManagerContext, cardreaderName, WinscardWrapper.SCARD_SHARE_SHARED, WinscardWrapper.SCARD_PROTOCOL_T0 | WinscardWrapper.SCARD_PROTOCOL_T1, out cardConnectionHandle, out connectionProtocolType); var operationResult = ReturnCodeManager.GetErrorMessage(returnCode); var connectResult = new ConnectResult(operationResult); if (operationResult.IsSuccessful) { var newCard = new Card( Thread.CurrentThread.ManagedThreadId, cardConnectionHandle, cardreaderName, connectionProtocolType); _cardConnectionManager.AddConnection( idOverride ?? newCard.InternalUid, Thread.CurrentThread.ManagedThreadId, cardConnectionHandle); connectResult.ConnectedCard = newCard; } return connectResult; }
private ApduResponse SendAPDU(Card card, byte[] bytesToSend, int expectedRequestLength) { Logger.TraceEvent(TraceEventType.Verbose, 0, "SendAPDU started"); Logger.TraceEvent(TraceEventType.Verbose, 0, "bytesToSend: {0}", BitConverter.ToString(bytesToSend)); Logger.TraceEvent(TraceEventType.Verbose, 0, "card connection handle: {0}", card.ConnectionHandle); Logger.Flush(); IntPtr cardConnectionHandle = card.ConnectionHandle; // establish a new temporary connection in case of context mismatch if (card.ThreadId != Thread.CurrentThread.ManagedThreadId) { Logger.TraceEvent(TraceEventType.Verbose, 0, string.Format("Card context mismatch. Original thread: {0}. Current thread: {1}", card.ThreadId, Thread.CurrentThread.ManagedThreadId)); Logger.Flush(); if (!_cardConnectionManager.IsConnectionExist(card.InternalUid, Thread.CurrentThread.ManagedThreadId)) { // establish a new connection var connectionResult = Connect(card.CardreaderName, card.InternalUid); if (!connectionResult.IsSuccessful) { return new ApduResponse { ReturnCode = connectionResult.StatusCode, RecvBuff = new byte[0], ResponseLength = 0 }; } // use a handle of a new connection cardConnectionHandle = connectionResult.ConnectedCard.ConnectionHandle; Logger.TraceEvent(TraceEventType.Verbose, 0, "SendAPDU: new connection established. Handle: " + cardConnectionHandle); } else { cardConnectionHandle = _cardConnectionManager .GetConnection(card.InternalUid, Thread.CurrentThread.ManagedThreadId); Logger.TraceEvent(TraceEventType.Verbose, 0, "SendAPDU: existed card context found. Handle: " + cardConnectionHandle); } } var recvBuff = new byte[500]; WinscardWrapper.SCARD_IO_REQUEST pioSendRequest; pioSendRequest.dwProtocol = card.Protocol; pioSendRequest.cbPciLength = PciLength; int returnCode = WinscardWrapper.SCardTransmit( cardConnectionHandle, ref pioSendRequest, ref bytesToSend[0], bytesToSend.Length, ref pioSendRequest, ref recvBuff[0], ref expectedRequestLength); Logger.TraceEvent(TraceEventType.Verbose, 0, "SendAPDU ended. Return code: " + returnCode); Logger.Flush(); //http://msdn.microsoft.com/en-us/library/windows/desktop/aa379804(v=vs.85).aspx //The pcbRecvLength should be at least n+2 and will be set to n+2 upon return. var result = new ApduResponse { RecvBuff = recvBuff, ResponseLength = expectedRequestLength, ReturnCode = returnCode }; return result; }
/// <summary> /// Terminates all connections for given card. /// </summary> /// <remarks> /// The card very likely is not attached to the cardreader at the moment of execution, /// so SCARD_LEAVE_CARD is used here to avoid error log messages from underlying winscard api. /// </remarks> private OperationResult DisconnectCardMultiHandlesAware(Card cardForDisconnect) { var currentHandle = cardForDisconnect.ConnectionHandle; // disconnect first (current) handle var mainReturnCode = WinscardWrapper.SCardDisconnect(cardForDisconnect.ConnectionHandle, WinscardWrapper.SCARD_LEAVE_CARD); var mainDisconnectResult = ReturnCodeManager.GetErrorMessage(mainReturnCode); Logger.TraceEvent(TraceEventType.Verbose, 0, "First handler disconnect result: {0}", mainDisconnectResult.StatusDescription); // disconnect the rest handles if (mainDisconnectResult.IsSuccessful) { var restHandlers = _cardConnectionManager.GetConnections(cardForDisconnect.InternalUid); Logger.TraceEvent(TraceEventType.Verbose, 0, "Card has {0} handlers", restHandlers.Length); foreach (var handleToDisconnect in restHandlers.Where(x => x != currentHandle)) { var returnCode = WinscardWrapper.SCardDisconnect(handleToDisconnect, WinscardWrapper.SCARD_LEAVE_CARD); var result = ReturnCodeManager.GetErrorMessage(returnCode); Logger.TraceEvent(TraceEventType.Verbose, 0, "Card handler disconnect result: {0}", result.StatusDescription); } _cardConnectionManager.CardDisconnected(cardForDisconnect.InternalUid); } cardForDisconnect.ConnectionHandle = IntPtr.Zero; return mainDisconnectResult; }
public ApduOperationResult UpdateLedAndBuzzer(Card card, byte ledState, byte t1, byte t2, byte repetitionNumber, byte buzzer) { var bytesToSend = new byte[9]; bytesToSend[0] = 0xFF; bytesToSend[1] = 0x00; bytesToSend[2] = 0x40; bytesToSend[3] = ledState; bytesToSend[4] = 0x04; bytesToSend[5] = t1; bytesToSend[6] = t2; bytesToSend[7] = repetitionNumber; bytesToSend[8] = buzzer; const int responseCodeLength = 2; ApduResponse response = SendAPDU(card, bytesToSend, responseCodeLength); return ReturnCodeManager.IsApduSuccessful(response); }
public ApduOperationResult SetBuzzerOutputForCardDetection(Card card, bool shouldBuzzWhenCardDetected) { var bytesToSend = new byte[5]; bytesToSend[0] = 0xFF; bytesToSend[1] = 0x00; bytesToSend[2] = 0x52; bytesToSend[3] = shouldBuzzWhenCardDetected ? (byte)0xFF : (byte)0x00; bytesToSend[4] = 0x00; const int responseCodeLength = 2; ApduResponse response = SendAPDU(card, bytesToSend, responseCodeLength); return ReturnCodeManager.IsApduSuccessful(response); }
/// <summary> /// The function provides the current status of a smart card in a reader. /// </summary> public OperationResult GetCardState(Card cardToRead) { if (cardToRead == null) throw new ArgumentNullException("cardToRead"); var sizeOfReadersListStructure = 0; var cardStateStatus = 0; var dwActProtocol = 0; var tmpAtrBytes = new byte[257]; var tmpAtrLen = 32; var returnCode = WinscardWrapper.SCardStatus(cardToRead.ConnectionHandle, cardToRead.CardreaderName, ref sizeOfReadersListStructure, ref cardStateStatus, ref dwActProtocol, ref tmpAtrBytes[0], ref tmpAtrLen); OperationResult result = ReturnCodeManager.GetErrorMessage(returnCode); if (result.IsSuccessful) { cardToRead.State = new CardState(cardStateStatus); cardToRead.Atr = tmpAtrBytes.Take(tmpAtrLen).ToArray(); cardToRead.Protocol = dwActProtocol; } return result; }
/// <summary> /// Returns a card's UID. /// </summary> public ReceiveCardIdResult GetCardId(Card cardToRead) { if (cardToRead == null) throw new ArgumentNullException("cardToRead"); var bytesToSend = new byte[5]; bytesToSend[0] = 0xFF; // Class bytesToSend[1] = 0xCA; // INS bytesToSend[2] = 0x00; // P1 bytesToSend[3] = 0x00; // P2 bytesToSend[4] = 0x00; // LE:Full Length ApduResponse response = SendAPDU(cardToRead, bytesToSend, 10); const int responseCodeLength = 2; var responseLengthWithoutResponseCodes = response.ResponseLength - responseCodeLength; var receiveCardIdResult = new ReceiveCardIdResult(ReturnCodeManager.IsApduSuccessful(response)); if (receiveCardIdResult.IsCompletelySuccessful) { //read UID bytes from apdu response receiveCardIdResult.Bytes = response.RecvBuff.Take(responseLengthWithoutResponseCodes).ToArray(); } return receiveCardIdResult; }
private void RememberCardreaderHadCard(string readerName, Card connectedCard) { Logger.TraceEvent(TraceEventType.Verbose, 0, "Marking that cardreader ({0}) had a card", readerName); Logger.Flush(); _attachedCardStatuses.AddOrUpdate(readerName, connectedCard, (key, newValue) => connectedCard); }
private void RaiseCardConnectedEvent(Card connectedLowlevelCard) { Logger.TraceEvent(TraceEventType.Verbose, 0, "Raising CardConnected event"); Logger.Flush(); SendOrPostCallback cb = state => CardConnected(null, new WatcherCardEventArgs(connectedLowlevelCard)); AsyncOperation.Post(cb, null); }
public void Led() { // arrange if (_card == null) _card = _reader.Connect(GetCardreaderName()).ConnectedCard; // act var getCardIdResult = _reader.GetCardId(_card); _reader.UpdateLedAndBuzzer(_card, 0x00, 0x00, 0x00, 0x00, 0x00); Assert.That(getCardIdResult.Bytes.Length, Is.GreaterThan(0)); }
public WatcherCardEventArgs(Card card) { Card = card; }