public void GetCardId()
        {
            // arrange
            _card = _reader.Connect(GetCardreaderName()).ConnectedCard;

            // act
            var getCardIdResult = _reader.GetCardId(_card);

            Assert.That(getCardIdResult.Bytes.Length, Is.GreaterThan(0));
        }
Example #2
0
        private void Watch()
        {
            while (_started)
            {
                var statuses = new List <CardreaderStatus>(_statuses);

                if (statuses.All(x => x.Name != PnpNotification))
                {
                    statuses.Add(new CardreaderPnpStatus(_cardreadersNumber));
                }

                var statusesParam = statuses.ToArray();

                var operationResult = _cardreader.WaitForChanges(ref statusesParam);

                if (!operationResult.IsSuccessful)
                {
                    // when we call thread.abort the WaitForChanges returns Failed
                    // so check for that
                    if (_started)
                    {
                        Logger.TraceEvent(TraceEventType.Verbose, 0, "WaitForChanges operation result is " + operationResult.StatusName);
                        Logger.Flush();

                        throw new SmartCardException(operationResult);
                    }
                }

                Log(statusesParam);

                foreach (var cardreaderStatus in statusesParam)
                {
                    if (!cardreaderStatus.IsChanged)
                    {
                        continue;
                    }

                    var newStatuses = cardreaderStatus.Statuses;

                    if (newStatuses.Contains(CardreaderStatus.StatusType.Changed))
                    {
                        // first call after a card was putted on a cardreader will contain two statuses:
                        // Changed
                        // CardConnected

                        // and right after that there will be a second call with statuses:
                        // Changed
                        // CardConnected
                        // CardInUse

                        // so I filter out the second call

                        // CardUnresponsive status means that card was removed too fast

                        if (newStatuses.Contains(CardreaderStatus.StatusType.CardConnected) &&
                            !DidCardreaderHaveConnectedCard(cardreaderStatus.Name) &&
                            !newStatuses.Contains(CardreaderStatus.StatusType.CardUnresponsive))
                        {
                            var connectResult = _cardreader.Connect(cardreaderStatus.Name);

                            if (connectResult.IsSuccessful)
                            {
                                var connectedLowlevelCard = connectResult.ConnectedCard;

                                var result = _cardreader.GetCardId(connectedLowlevelCard);

                                if (result.IsCompletelySuccessful)
                                {
                                    if (!DidCardreaderHaveConnectedCard(cardreaderStatus.Name))
                                    {
                                        connectedLowlevelCard.IdBytes = result.Bytes;

                                        RememberCardreaderHadCard(cardreaderStatus.Name, connectedLowlevelCard);

                                        RaiseCardConnectedEvent(connectedLowlevelCard);
                                    }
                                }
                                else
                                {
                                    if (IsNoCardreaderResult(connectResult))
                                    {
                                        _cardreadersNumber--;

                                        RaiseCardreaderDisconnectedEvent(cardreaderStatus);

                                        RemoveCardreaderFromList(cardreaderStatus.Name);
                                    }
                                    else
                                    {
                                        // if card was detached before than id was received
                                        // reset updated status
                                        cardreaderStatus.NewStatusFlags = cardreaderStatus.CurrentStatusFlags;
                                    }
                                }
                            }
                            else if (IsNoCardreaderResult(connectResult))
                            {
                                _cardreadersNumber--;

                                RaiseCardreaderDisconnectedEvent(cardreaderStatus);

                                RemoveCardreaderFromList(cardreaderStatus.Name);
                            }
                            else if (connectResult.StatusCode == WinscardWrapper.SCARD_E_NO_SMARTCARD)
                            {
                                // card was detached too fast
                                // don't react to this
                            }
                            else
                            {
                                throw new SmartCardException(connectResult);
                            }
                        }
                        if (newStatuses.Contains(CardreaderStatus.StatusType.CardDisconnected) &&
                            !newStatuses.Contains(CardreaderStatus.StatusType.CardUnresponsive) &&
                            cardreaderStatus.CurrentStatusFlags != 0)
                        {
                            // don't want to raise disconnected event for unresponsive card
                            // because it means that card wasn't connected properly

                            // cardreaderStatus.CurrentStatusFlags != 0
                            // means that this is not a new cardreader status and it has some previous status
                            // cause otherways it doesn't make sense

                            if (DidCardreaderHaveConnectedCard(cardreaderStatus.Name))
                            {
                                var currentCard = LastConnectedCard(cardreaderStatus.Name);
                                if (currentCard != null)
                                {
                                    _cardreader.DisconnectCard(currentCard);
                                }

                                // reset previously connected card and raise the card connected event
                                ForgotAboutCardreaderHadCard(cardreaderStatus.Name);
                                RaiseCardDisconnectedEvent();
                            }
                        }
                        if (newStatuses.Contains(CardreaderStatus.StatusType.CardreaderDisconnected))
                        {
                            _cardreadersNumber--;

                            RaiseCardreaderDisconnectedEvent(cardreaderStatus);

                            RemoveCardreaderFromList(cardreaderStatus.Name);
                        }
                        if (cardreaderStatus.Name == PnpNotification)
                        {
                            DetectAvailableCardreaders();
                        }

                        cardreaderStatus.Swap();
                    }
                }
            }
        }