コード例 #1
0
        protected override byte[] Transmit(byte[] data)
        {
            this.BeginAtomic();
            try
            {
                if (this.connected)
                {
                    IntPtr Handle = this.AcquireHandle();

                    byte[] Response = ScpCommands.SendApdu(Handle, data);

                    this.ReleaseHandle();

                    return(Response);
                }
                else
                {
                    throw new SmartCardNotConnectedException(this.SmartCard);
                }
            }
            finally
            {
                this.EndAtomic();
            }
        }
コード例 #2
0
        private byte[] GetVariableValue(string message, Variable variable)
        {
            this.BeginAtomic();
            try
            {
                IntPtr Handle = this.AcquireHandle();
                try
                {
                    Size DisplaySize = ScpCommands.InitDisplay(Handle);
                    ScpCommands.Display(Handle, message);

                    ScpCommands.SetCursor(Handle, new Point(DisplaySize.Width - variable.Length, 1));
                    ScpCommands.WriteOnDisplay(Handle, new string('_', variable.Length));
                    ScpCommands.SetCursor(Handle, new Point(DisplaySize.Width - variable.Length, 1));

                    ScpCommands.StartInput(Handle, variable.MinLength, variable.Length);
                    while (ScpCommands.GetInputHasEnded(Handle) == false)
                    {
                        Thread.Sleep(250);
                    }
                    ScpCommands.ClearDisplay(Handle);
                    return(ScpCommands.EndInput(Handle));
                }
                finally
                {
                    this.ReleaseHandle();
                }
            }
            finally
            {
                this.EndAtomic();
            }
        }
コード例 #3
0
        private bool ProbeDevice()
        {
            this.BeginAtomic();
            try
            {
                IntPtr Handle = this.AcquireHandle();

                try
                {
                    // Handle could be acquired. try to read out version string
                    this.FriendlyName = $"{ScpCommands.GetVersionString(Handle)} on COM{this.port}";
                }
                catch
                {
                    //Do nothing in case of error
                    return(false);
                }
                finally
                {
                    this.ReleaseHandle();
                }
            }
            catch
            {
                //Do nothing in case of error
                return(false);
            }
            finally
            {
                this.EndAtomic();
            }
            return(true);
        }
コード例 #4
0
ファイル: SCPCommands.cs プロジェクト: whiletrue-eu/libraries
        public static void AbortInput(IntPtr sctp)
        {
            byte[] Command = new byte[3];

            Command[0] = 0x01; //keyboard commands
            Command[1] = 0x03; //stop input

            ScpCommands.DoIO(sctp, 0xF8, Command, 0xF0);
        }
コード例 #5
0
ファイル: SCPCommands.cs プロジェクト: whiletrue-eu/libraries
        public static byte[] EndInput(IntPtr sctp)
        {
            byte[] Command = new byte[3];

            Command[0] = 0x01; //keyboard commands
            Command[1] = 0x04; //read buffer
            Command[2] = 0x00; //buffer no

            return(ScpCommands.DoIO(sctp, 0xF8, Command, 0xF0));
        }
コード例 #6
0
ファイル: SCPCommands.cs プロジェクト: whiletrue-eu/libraries
        public static IntPtr Open(int port)
        {
            IntPtr Sctp = ScpCommands.sccp_open(0x31, 0, /*port*/ port, 0);

            if (Sctp == IntPtr.Zero)
            {
                throw new ScpException(LowLevelError.NoCardReader);
            }
            return(Sctp);
        }
コード例 #7
0
ファイル: SCPCommands.cs プロジェクト: whiletrue-eu/libraries
        public static void WriteOnDisplay(IntPtr sctp, string message)
        {
            byte[] Message = Encoding.ASCII.GetBytes(message);
            byte[] Command = new byte[Message.Length + 3];

            Command[0] = 0x00; //Display commands
            Command[1] = 0x03; //Display text at cursor
            Array.Copy(Message, 0, Command, 2, Message.Length);

            ScpCommands.DoIO(sctp, 0xF8, Command, 0xF0);
        }
コード例 #8
0
ファイル: SCPCommands.cs プロジェクト: whiletrue-eu/libraries
        public static Point GetCursor(IntPtr sctp)
        {
            byte[] Command = new byte[2];

            Command[0] = 0x00; //Display commands
            Command[1] = 0x04; //get cursor position

            byte[] Response = ScpCommands.DoIO(sctp, 0xF8, Command, 0xF0);

            return(new Point(Response[1], Response[0]));
        }
コード例 #9
0
ファイル: SCPCommands.cs プロジェクト: whiletrue-eu/libraries
        public static void SetCursor(IntPtr sctp, Point position)
        {
            byte[] Command = new byte[4];

            Command[0] = 0x00; //Display commands
            Command[1] = 0x02; //set cursor position
            Command[2] = (byte)position.Y;
            Command[3] = (byte)position.X;

            ScpCommands.DoIO(sctp, 0xF8, Command, 0xF0);
        }
コード例 #10
0
ファイル: SCPCommands.cs プロジェクト: whiletrue-eu/libraries
        public static bool GetInputHasEnded(IntPtr sctp)
        {
            byte[] Command = new byte[3];

            Command[0] = 0x01; //keyboard commands
            Command[1] = 0x02; //check keyboard status

            byte[] Response = ScpCommands.DoIO(sctp, 0xF8, Command, new[] { 0xF0, 0xFF });

            return(Response == null);
        }
コード例 #11
0
 public override byte[] PowerOn(IntPtr sctp, bool reset)
 {
     if (reset)
     {
         return(ScpCommands.DoIO(sctp, 0x01, new byte[] { 0x04 }, 0x82));
     }
     else
     {
         return(ScpCommands.DoIO(sctp, 0x01, 0x82));
     }
 }
コード例 #12
0
ファイル: SCPCommands.cs プロジェクト: whiletrue-eu/libraries
        private static void Display(IntPtr sctp, byte row, string message)
        {
            byte[] Message = Encoding.ASCII.GetBytes(message);
            byte[] Command = new byte[Message.Length + 4];

            Command[0] = 0x00; //Display commands
            Command[1] = 0x01; //Display text
            Command[2] = row;
            Array.Copy(Message, 0, Command, 3, Message.Length);

            ScpCommands.DoIO(sctp, 0xF8, Command, 0xF0);
        }
コード例 #13
0
ファイル: SCPCommands.cs プロジェクト: whiletrue-eu/libraries
        public static string GetVersionString(IntPtr sctp)
        {
            byte[] Response                = ScpCommands.DoIO(sctp, 0xF6, 0xF0);
            string VersionString           = new string(Encoding.ASCII.GetChars(Response));
            Regex  VersionStringExpression = new Regex(@"^(?<Version>[VX]\d\.\d\d) (?<Id>.*?) \((?<Text>.*?)\) (?<Copyright>.*?)$");

            if (VersionStringExpression.IsMatch(VersionString))
            {
                return(VersionStringExpression.Match(VersionString).Groups["Text"].Value);
            }
            else
            {
                return("unknown SCP device");
            }
        }
コード例 #14
0
ファイル: SCPCommands.cs プロジェクト: whiletrue-eu/libraries
        public static void Display(IntPtr sctp, string message)
        {
            Size Size = ScpCommands.InitDisplay(sctp);

            string[] Strings = (message + new string('\n', Size.Height)).Split('\n');
            ScpCommands.HideCursor(sctp);

            for (byte RowIndex = 0; RowIndex < Size.Height; RowIndex++)
            {
                string Message = Strings[RowIndex];
                Message.PadRight(Size.Width, ' ');

                ScpCommands.Display(sctp, RowIndex, Message);
            }
        }
コード例 #15
0
ファイル: SCPCommands.cs プロジェクト: whiletrue-eu/libraries
        public static void StartInput(IntPtr sctp, byte minLength, byte length)
        {
            ScpCommands.InitKeyboard(sctp);
            byte[] Command = new byte[9];

            Command[0] = 0x01; //keyboard commands
            Command[1] = 0x01; //init buffer
            Command[2] = 0x00; //buffer no
            Command[3] = 0x00; //no security lock
            Command[4] = minLength;
            Command[5] = length;
            Command[6] = 0x23; //# character as 'confirm'
            Command[7] = 0x2a; //* character as 'backspace'
            Command[8] = 0x2a; //* character as echo char

            ScpCommands.DoIO(sctp, 0xF8, Command, 0xF0);
        }
コード例 #16
0
        private void ReleaseHandle()
        {
            Monitor.Enter(this);
            try
            {
                this.handleCount--;

                if (this.handleCount == 0)
                {
                    ScpCommands.Close(this.handle);
                    this.handle = IntPtr.Zero;
                }
            }
            finally
            {
                Monitor.Exit(this);
            }
        }
コード例 #17
0
ファイル: SCPCommands.cs プロジェクト: whiletrue-eu/libraries
 public static CardStatus GetStatus(IntPtr sctp)
 {
     byte[] Response = ScpCommands.DoIO(sctp, 0xF8, new byte[] { 0x04, 0x00 }, 0xF0);
     if (Response[0] == 0x00)
     {
         return(CardStatus.NoCard);
     }
     else if (Response[0] == 0x01)
     {
         return(CardStatus.CardInsertedPowerOff);
     }
     else if (Response[0] == 0x02)
     {
         return(CardStatus.CardInsertedPowerOn);
     }
     else
     {
         return(CardStatus.Unknown);
     }
 }
コード例 #18
0
ファイル: SCPCommands.cs プロジェクト: whiletrue-eu/libraries
        public static void SelectApplicationProtocol(IntPtr sctp, Scap scap)
        {
            ScpCommands.DoIO(sctp, 0xF1, (byte)scap, new[] { 0x80, 0x81, 0x82 });

            ScapCommands Scap;

            switch (scap)
            {
            case SCP.Scap.T0:
                Scap = new Scap3Commands();
                break;

            /*case SCAP.T1:
             *                  Scap = new SCAPxCommands();
             *                  break;*/
            default:
                throw new ScpException(LowLevelError.CardNotSupported);
            }

            ScpCommands.scapsByHandle[sctp] = Scap;
        }
コード例 #19
0
        protected internal override void ConnectCard(Protocol protocol)
        {
            this.BeginAtomic();
            try
            {
                IntPtr Handle;
                try
                {
                    Handle = this.AcquireHandle();
                }
                catch
                {
                    throw new ScpException(LowLevelError.CardCommunicationError);
                }

                Scap ScpProtocol;
                switch (protocol)
                {
                case Protocol.T0:
                    ScpProtocol = Scap.T0;
                    break;

                case Protocol.T1:
                    ScpProtocol = Scap.T1;
                    break;

                default:
                    throw new Exception("Unknown Protocol");
                }

                ScpCommands.SelectApplicationProtocol(Handle, ScpProtocol);
                ScpCommands.PowerOn(Handle, true);

                this.connected = true;
            }
            finally
            {
                this.EndAtomic();
            }
        }
コード例 #20
0
        private IntPtr AcquireHandle()
        {
            IntPtr Handle;

            Monitor.Enter(this);
            try
            {
                if (this.handleCount == 0)
                {
                    int RetryConnectCount = 100;
                    while (this.handle == IntPtr.Zero)
                    {
                        try
                        {
                            this.handle = ScpCommands.Open(this.port);
                        }
                        catch
                        {
                            if (RetryConnectCount > 0)
                            {
                                Thread.Sleep(new Random().Next(1, 50));
                                RetryConnectCount--;
                            }
                            else
                            {
                                throw;
                            }
                        }
                    }
                }

                this.handleCount++;
                Handle = this.handle;
            }
            finally
            {
                Monitor.Exit(this);
            }
            return(Handle);
        }
コード例 #21
0
 private void DisplayMessage(string message, TimeSpan timeout)
 {
     this.BeginAtomic();
     try
     {
         IntPtr Handle = this.AcquireHandle();
         try
         {
             ScpCommands.Display(Handle, message);
             Thread.Sleep(timeout);
             ScpCommands.ClearDisplay(Handle);
         }
         finally
         {
             this.ReleaseHandle();
         }
     }
     finally
     {
         this.EndAtomic();
     }
 }
コード例 #22
0
ファイル: SCPCommands.cs プロジェクト: whiletrue-eu/libraries
        public static byte[] DoIO(IntPtr sctp, int command, byte[] data, int[] excpectedReturnCodes)
        {
            int ReturnCode = 0;

            byte[] ResponseBuffer = new byte[512];
            int    ResponseLength = ResponseBuffer.Length;

            LowLevelError Error = ScpCommands.sccp_io(sctp, command, data, data.Length, ref ReturnCode, ResponseBuffer, ref ResponseLength);

            ScpCommands.CheckError(Error);

            bool ExpectedReturnCodeFound = false;

            foreach (int ExceptedReturnCode in excpectedReturnCodes)
            {
                if (ReturnCode == ExceptedReturnCode)
                {
                    ExpectedReturnCodeFound = true;
                    break;
                }
            }
            if (ExpectedReturnCodeFound == false)
            {
                throw new ScpException((LowLevelError)ReturnCode);
            }

            if (ResponseLength > 0)
            {
                byte[] ResponseData = new byte[ResponseLength];
                Array.Copy(ResponseBuffer, 0, ResponseData, 0, ResponseLength);

                return(ResponseData);
            }
            else
            {
                return(null);
            }
        }
コード例 #23
0
        public override byte[] SendApdu(IntPtr sctp, byte[] data)
        {
            byte[] Command = new byte[data.Length + 2];
            Array.Copy(data, 0, Command, 0, 5); //Copy header
            if (data.Length > 5)
            {
                //Data to send
                Command[5] = data[4];                             //Set length of command data
                Array.Copy(data, 5, Command, 7, data.Length - 5); //Copy data
            }
            else
            {
                Command[6] = data[4]; //Set length of excpected data
            }

            byte[] Response = ScpCommands.DoIO(sctp, 0x04, Command, 0x82);

            byte[] ReturnData = new byte[Response.Length - 1];
            Array.Copy(Response, 3, ReturnData, 0, Response.Length - 3);   //Copy response data
            Array.Copy(Response, 0, ReturnData, ReturnData.Length - 2, 2); //Copy status word

            return(ReturnData);
        }
コード例 #24
0
ファイル: SCPCommands.cs プロジェクト: whiletrue-eu/libraries
 public static int InitKeyboard(IntPtr sctp)
 {
     byte[] Response = ScpCommands.DoIO(sctp, 0xF8, new byte[] { 0x01, 0x00 }, 0xF0);
     return(Response[0]);
 }
コード例 #25
0
ファイル: SCPCommands.cs プロジェクト: whiletrue-eu/libraries
 public static string GetVersionString(IntPtr sctp, Scap scap)
 {
     byte[] Response = ScpCommands.DoIO(sctp, 0xF6, new[] { (byte)scap }, 0xF0);
     return(new string(Encoding.ASCII.GetChars(Response)));
 }
コード例 #26
0
ファイル: SCPCommands.cs プロジェクト: whiletrue-eu/libraries
 public static void ClearDisplay(IntPtr sctp)
 {
     ScpCommands.HideCursor(sctp);
 }
コード例 #27
0
ファイル: SCPCommands.cs プロジェクト: whiletrue-eu/libraries
 public static byte[] DoIO(IntPtr sctp, int command, byte data, int[] excpectedReturnCodes)
 {
     return(ScpCommands.DoIO(sctp, command, new[] { data }, excpectedReturnCodes));
 }
コード例 #28
0
ファイル: SCPCommands.cs プロジェクト: whiletrue-eu/libraries
 public static byte[] DoIO(IntPtr sctp, int command, byte[] data, int excpectedReturnCode)
 {
     return(ScpCommands.DoIO(sctp, command, data, new[] { excpectedReturnCode }));
 }
コード例 #29
0
ファイル: SCPCommands.cs プロジェクト: whiletrue-eu/libraries
        private static void HideCursor(IntPtr sctp)
        {
            Size Size = ScpCommands.InitDisplay(sctp);

            ScpCommands.SetCursor(sctp, new Point(Size.Width, 0));
        }
コード例 #30
0
        private void PollCardReaderState()
        {
            CardReaderState NewState            = CardReaderState.Unknown;
            bool            SimulateCardRemoved = false;

            this.BeginAtomic();
            try
            {
                IntPtr Handle = this.AcquireHandle();

                try
                {
                    // Get Card status
                    ScpCommands.CardStatus Status = ScpCommands.GetStatus(Handle);
                    switch (Status)
                    {
                    case ScpCommands.CardStatus.NoCard:
                        NewState = CardReaderState.NoCard;
                        break;

                    case ScpCommands.CardStatus.CardInsertedPowerOff:
                        NewState = CardReaderState.CardPresent;
                        break;

                    case ScpCommands.CardStatus.CardInsertedPowerOn:
                        NewState = CardReaderState.CardExclusivelyInUse;
                        break;

                    default:
                        NewState = CardReaderState.Unknown;
                        break;
                    }
                    // Get ATR
                    if (Status == ScpCommands.CardStatus.CardInsertedPowerOff) //do NOT check power on cards, because the ATR cannot chnage when the card is powered!
                    {
                        ScpCommands.SelectApplicationProtocol(Handle, Scap.T0);
                        byte[] Atr = ScpCommands.PowerOn(Handle, false);
                        if (this.atr != null && !Atr.HasEqualValue(this.atr))
                        {
                            //Card was changed during polls -> simulate 'card removed' event
                            SimulateCardRemoved = true;
                        }
                        this.atr = Atr;
                        ScpCommands.PowerOff(Handle);
                    }
                    else if (Status == ScpCommands.CardStatus.CardInsertedPowerOn && this.handleCount == 0)
                    {
                        // the card is powered, but we didn't do it (is done at 'connect', but then the handle count must be greater)
                        NewState = CardReaderState.Unknown;
                    }
                }
// ReSharper disable EmptyGeneralCatchClause
                catch
                {
                    //Do nothing in case of error (next loop)
                }
                finally
                {
                    this.ReleaseHandle();
                }
            }
            catch
            {
                //Do nothing in case of error (next loop)
            }
            finally
            {
                this.EndAtomic();
            }
// ReSharper restore EmptyGeneralCatchClause


            if (SimulateCardRemoved)
            {
                this.state = CardReaderState.NoCard;
                this.InvokeStateChanged();
            }
            if (this.State != NewState)
            {
                this.state = NewState;
                this.InvokeStateChanged();
            }

            Thread.Sleep(1000);
        }