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(); } }
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(); } }
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); }
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); }
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)); }
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); }
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); }
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])); }
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); }
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); }
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)); } }
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); }
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"); } }
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); } }
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); }
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); } }
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); } }
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; }
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(); } }
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); }
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(); } }
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); } }
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); }
public static int InitKeyboard(IntPtr sctp) { byte[] Response = ScpCommands.DoIO(sctp, 0xF8, new byte[] { 0x01, 0x00 }, 0xF0); return(Response[0]); }
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))); }
public static void ClearDisplay(IntPtr sctp) { ScpCommands.HideCursor(sctp); }
public static byte[] DoIO(IntPtr sctp, int command, byte data, int[] excpectedReturnCodes) { return(ScpCommands.DoIO(sctp, command, new[] { data }, excpectedReturnCodes)); }
public static byte[] DoIO(IntPtr sctp, int command, byte[] data, int excpectedReturnCode) { return(ScpCommands.DoIO(sctp, command, data, new[] { excpectedReturnCode })); }
private static void HideCursor(IntPtr sctp) { Size Size = ScpCommands.InitDisplay(sctp); ScpCommands.SetCursor(sctp, new Point(Size.Width, 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); }