internal PCSCIso7816Protocol(byte[] atr, PCSCCard card) { // Reference the reader myCard = card; // Get the ATR value this.Atr = Atr.Parse(atr); // Map the PC/SC comms protocol to the appropriate CardFramework protocol switch (myCard.CommsProtocol) { case SCardProtocol.T0: CommsProtocol = Iso7816CommsProtocol.T0; break; case SCardProtocol.T1: CommsProtocol = Iso7816CommsProtocol.T1; break; case SCardProtocol.Raw: CommsProtocol = Iso7816CommsProtocol.Raw; break; default: throw PCSCException.ThrowUnsupportedProtocol(); } }
public override RApdu Transceive(CApdu command) { IntPtr requestPci; switch (myCard.CommsProtocol) { case SCardProtocol.T0: requestPci = PCSCApi.SCardPciT0; break; case SCardProtocol.T1: requestPci = PCSCApi.SCardPciT1; break; default: throw PCSCException.ThrowUnsupportedProtocol(); } int responseLength = 1024; byte[] responseBuffer = new byte[responseLength]; byte[] cmdBuffer = command.ToArray(); PCSCResult result = NativeMethods.SCardTransmit(myCard.Handle, requestPci, cmdBuffer, cmdBuffer.Length, IntPtr.Zero, responseBuffer, ref responseLength); if (PCSCResult.None == result) { byte[] response = new byte[responseLength]; Array.Copy(responseBuffer, response, responseLength); #if DEBUG RaiseOnTranscieve("CAPDU> " + Converters.ByteArrayToString(cmdBuffer)); RaiseOnTranscieve("RAPDU> " + Converters.ByteArrayToString(response)); #endif return(RApdu.Parse(response)); } else { #if DEBUG RaiseOnTranscieve("CAPDU> " + Converters.ByteArrayToString(cmdBuffer)); RaiseOnTranscieve("RAPDU> Error condition (HRESULT = " + EnumHelper.GetDescription(result) + ")"); #endif throw new PCSCException("Communications error."); } }
public void Connect(SCardShareMode shareMode = SCardShareMode.Shared) { PCSCResult result; // Are we already connected? if (myHandle != IntPtr.Zero) { return; } // Establish a new session context for this card result = NativeMethods.SCardEstablishContext(SCardScope.User, IntPtr.Zero, IntPtr.Zero, out myContext); if (PCSCResult.None != result) { throw PCSCException.ThrowByResult(result); } // Connect to the card result = NativeMethods.SCardConnect(myContext, myReaderName, shareMode, DefaultRequestedProtocols, ref myHandle, ref myCommsProtocol); if (PCSCResult.None != result) { // Disconnect (this will gracefully handle the context release) Disconnect(); throw PCSCException.ThrowByResult(result); } // Retrieve our ATR byte[] readerName = new byte[255]; uint readerLen = 255; SCardState state = 0; SCardProtocol cardProtocol = 0; uint atrLen = NativeMethods.SCARD_ATR_LENGTH; byte[] atr = new byte[atrLen]; result = NativeMethods.SCardStatus(myHandle, readerName, ref readerLen, out state, out cardProtocol, atr, ref atrLen); if (result != PCSCResult.None) { // Disconnect from the card Disconnect(); throw PCSCException.ThrowByResult(result); } // // Protocol Enumeration // try { // Add the default 7816 protocol Protocols.Add(new PCSCIso7816Protocol(atr, this)); // Determine whether this card is contactless or not if (SupportsIso14443) { // Replace the 7816 protocol with 14443 Protocols.Clear(); var protocol = new PCSCIso14443AProtocol(atr, this); Protocols.Add(protocol); // Create our OptionalCommands object OptionalCommands = new PCSCOptionalCommands(protocol); // // HACK: Adding a PCSCMifareProtocol to all ISO14443 cards, what // we should be doing is somehow determining if this card // supports Mifare or Mifare emulation // Protocols.Add(new PCSCMifareProtocol(this)); } } catch (Exception) { // Disconnect from the card Disconnect(); throw PCSCException.ThrowUnsupportedProtocol(); } }