private void DisplayMessage(string message, TimeSpan duration)
        {
            int         Duration = (duration.TotalSeconds <= 60 ? (int)duration.TotalSeconds : 60);
            CardCommand Command  = new CardCommand();

            Command.Cla = 0x20;
            Command.Ins = 0x17;
            Command.P1  = 0x40;                                         // Display
            Command.P2  = 0x00;
            Command.AppendData(0x50, Encoding.ASCII.GetBytes(message)); //Display Message
            if (duration != TimeSpan.Zero)
            {
                Command.AppendData(0x80, 0x60); //timeout: take 60: the real timeout is performed by 'sleep'
            }

            this.SendCommandToReader(Command);
            Thread.Sleep(Duration * 1000);
        }
        private void ClearDisplay()
        {
            CardCommand Command = new CardCommand();

            Command.Cla = 0x20;
            Command.Ins = 0x17;
            Command.P1  = 0x40;             // Display
            Command.P2  = 0x00;
            Command.AppendData(0x50, 0x00); //Display empty message (->reset to default message)

            this.SendCommandToReader(Command);
        }
        private byte[] GetVariableValue(string message, Variable variable, IVariableResolver resolver)
        {
            byte[] Data = null;
            do
            {
                CardCommand Command = new CardCommand();
                Command.Cla = 0x20;
                Command.Ins = 0x16;
                Command.P1  = 0x50;                                         // Keyboard
                Command.P2  = 0x02;                                         // Display '*'
                Command.AppendData(0x50, Encoding.ASCII.GetBytes(message)); //Display Message
                Command.AppendData(0x80, 0x60);                             //Timeout
                //For variable timeout use: Command.Append(0x80, (byte) (timeout.TotalSeconds <= 60 ? timeout.TotalSeconds : 60)); //Timeout
                Command.Le = 0x00;

                CardResponse Response;
                try
                {
                    resolver.NotifyVariableEntryBegins(variable.Name);
                    Response = this.SendCommandToReader(Command);
                }
                finally
                {
                    resolver.NotifyVariableEntryEnded();
                }

                switch (Response.Status)
                {
                case 0x9000:
                    Data = Response.Data;
                    break;

                case 0x6401:
                    throw new UserCancelException();

                case 0x6410:
                    //TODO: auslagern in UIHandler
                    if (MessageBox.Show("The card readers pinpad is disabled.\n Please turn it on.", "Message", MessageBoxButtons.OKCancel) == DialogResult.OK)
                    {
                        continue;
                    }
                    else
                    {
                        throw new UserCancelException();
                    }

                case 0x6400:
                    //TODO: auslagern in UIHandler
                    if (MessageBox.Show("There was a timeout entering the PIN at the card reader.\nDo you want to retry?", "Question", MessageBoxButtons.YesNo) == DialogResult.Yes)
                    {
                        continue;
                    }
                    else
                    {
                        throw new UserCancelException();
                    }

                default:
                    throw new UnableToResolveVariableException(variable, $"Card reader returned unknown code 0x{Response.Status:4X}");
                }

                if (Data != null && (Data.Length < variable.MinLength || Data.Length > variable.Length))
                {
                    this.DisplayMessage(Orgamkt5CardReader.LayoutDisplayMessage("Pin entry error!\nPlease retry!", 0), TimeSpan.FromSeconds(2));
                    Data = null;
                }
            } while (Data == null);

            this.ClearDisplay();

            return(Data);
        }