Added: PCSC Implementation

This commit is contained in:
TheJoKlLa 2020-09-15 15:27:01 +02:00
parent 2034c08d33
commit 187dfc4f4a
16 changed files with 757 additions and 8 deletions

View File

@ -15,7 +15,9 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Borepin.GTK", "Borepin\Bore
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Borepin.macOS", "Borepin\Borepin.macOS\Borepin.macOS.csproj", "{3EC23FE7-395E-4BBC-B56B-9455354BDA34}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NFC", "NFC\NFC.csproj", "{72DAC306-D4B2-4DBF-9C32-317203FD5D61}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NFC", "NFC\NFC.csproj", "{72DAC306-D4B2-4DBF-9C32-317203FD5D61}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NFC_Test", "NFC_Test\NFC_Test.csproj", "{0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -249,6 +251,30 @@ Global
{72DAC306-D4B2-4DBF-9C32-317203FD5D61}.Release|x64.Build.0 = Release|Any CPU
{72DAC306-D4B2-4DBF-9C32-317203FD5D61}.Release|x86.ActiveCfg = Release|Any CPU
{72DAC306-D4B2-4DBF-9C32-317203FD5D61}.Release|x86.Build.0 = Release|Any CPU
{0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Debug|ARM.ActiveCfg = Debug|Any CPU
{0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Debug|ARM.Build.0 = Debug|Any CPU
{0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Debug|iPhone.Build.0 = Debug|Any CPU
{0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Debug|x64.ActiveCfg = Debug|Any CPU
{0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Debug|x64.Build.0 = Debug|Any CPU
{0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Debug|x86.ActiveCfg = Debug|Any CPU
{0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Debug|x86.Build.0 = Debug|Any CPU
{0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Release|Any CPU.Build.0 = Release|Any CPU
{0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Release|ARM.ActiveCfg = Release|Any CPU
{0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Release|ARM.Build.0 = Release|Any CPU
{0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Release|iPhone.ActiveCfg = Release|Any CPU
{0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Release|iPhone.Build.0 = Release|Any CPU
{0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Release|x64.ActiveCfg = Release|Any CPU
{0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Release|x64.Build.0 = Release|Any CPU
{0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Release|x86.ActiveCfg = Release|Any CPU
{0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

61
NFC/APDUCommand.cs Normal file
View File

@ -0,0 +1,61 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace NFC
{
public class APDUCommand
{
/// <summary>
/// ISO 7816 - CLA - Class
/// </summary>
public byte Class { get; set; }
/// <summary>
/// ISO 7816 - INS - Instruction
/// </summary>
public byte Instruction { get; set; }
/// <summary>
/// ISO 7816 - P1 - Parameter 1
/// </summary>
public byte Parameter1 { get; set; }
/// <summary>
/// ISO 7816 - P2 - Parameter 2
/// </summary>
public byte Parameter2 { get; set; }
/// <summary>
/// ISO 7816 - Lc - Length Command
/// </summary>
public byte LengthCommand
{
get
{
throw new NotImplementedException();
}
}
/// <summary>
/// ISO 7816 - Data - Data
/// </summary>
public byte[] Data { get; set; }
/// <summary>
/// ISO 7816 - Le - Length expected
/// </summary>
public byte LengthExpected
{
get
{
throw new NotImplementedException();
}
}
public byte[] APDUCommandMessage()
{
throw new NotImplementedException();
}
}
}

108
NFC/APDUResponse.cs Normal file
View File

@ -0,0 +1,108 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using NFC.Mifare_DESFire;
namespace NFC
{
public class APDUResponse
{
/// <summary>
/// ISO 7816 - Body - Body
/// </summary>
public byte[] Body { get; set; }
/// <summary>
/// ISO 7816 - SW1 - Status Word 1
/// </summary>
public byte SW1 { get; set; }
/// <summary>
/// ISO 7816 - SW2 - Status Word 2
/// </summary>
public byte SW2 { get; set; }
/// <summary>
/// Creates a new APDUResponse from the raw received data.
/// </summary>
public APDUResponse(byte[] raw) {
Body = raw.Take(raw.Length-1).ToArray();
SW1 = raw[raw.Length - 2];
SW2 = raw[raw.Length - 3];
}
public APDUResponse()
{
}
public APDUStatusWords StatusWord
{
get
{
// Some status words only require a specific first byte
// and in some cases SW2 contains additional information.
// This will filter out those errors. When there is more information separate methods for getting those are available.
switch(SW1) {
case 0x61:
// Kommando erfolgreich ausgeführt. xx Datenbytes können mit dem GET RESPONSE-Kommando abgeholt werden. Statuswort zur Steuerung des T=0-Protokolls
return APDUStatusWords.DATA_READY;
case 0x62:
// Warnung; Zustand des nichtflüchtigen Speichers nicht verändert
return APDUStatusWords.STORAGE_NOT_CHANGED;
case 0x63:
if((SW2 & 0xF0) == 0xC0) {
// Zähler hat den Wert x erreicht (die genaue Bedeutung ist vom Kommando abhängig)
return APDUStatusWords.COUNTER_REACHED;
}
// Warnung; Zustand des nichtflüchtigen Speichers verändert
return APDUStatusWords.STORAGE_CHANGED;
case 0x64:
// Ausführungsfehler; Zustand des nichtflüchtigen Speichers nicht verändert
return APDUStatusWords.EXECUTION_ERROR_WITHOUT_CHANGE;
case 0x65:
// Ausführungsfehler; Zustand des nichtflüchtigen Speichers verändert
return APDUStatusWords.EXECUTION_ERROR_WITH_CHANGE;
case 0x6C:
// Falsche Länge Le; xx gibt die korrekte Länge an Statuswort zur Steuerung des T=0-Protokolls
return APDUStatusWords.INVALID_LE;
}
return (APDUStatusWords) (((UInt16) SW1) << 8 | ((UInt16) SW2));
}
}
/// <summary>
/// If the reponse status is DATA_READY this method can be used to get the amount of data that can be read from the card.
/// </summary>
public byte DataLength
{
get
{
return SW2;
}
}
/// <summary>
/// If the reponse status is COUNTER_REACHED this method can be used to get the value that the counter reached.
/// </summary>
public byte Counter
{
get
{
return (byte)(SW2 & 0x0F);
}
}
/// <summary>
/// If the reponse status is INVALID_LE this method can be used to get the correct LE.
/// </summary>
public byte CorrectLE
{
get
{
return SW2;
}
}
}
}

209
NFC/APDUStatusWords.cs Normal file
View File

@ -0,0 +1,209 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace NFC.Mifare_DESFire
{
public enum APDUStatusWords : UInt16
{
/// <summary>
/// Kommando erfolgreich ausgeführt. xx Datenbytes können mit dem GET RESPONSE-Kommando abgeholt werden. Statuswort zur Steuerung des T=0-Protokolls
/// </summary>
DATA_READY = 0x6100,
/// <summary>
/// Die zurückgegebenen Daten können fehlerhaft sein.
/// </summary>
FAULTY_DATA = 0x6281,
/// <summary>
/// Da das Dateiende vorher erreicht wurde, konnten nur weniger als Le Bytes gelesen werden.
/// </summary>
UNEXPECTED_END_OF_FILE = 0x6282,
/// <summary>
/// Die ausgewählte Datei ist gesperrt (englisch invalidated, wörtlich „ungültig“).
/// </summary>
INVALIDATED_FILE = 0x6283,
/// <summary>
/// Die File Control Information (FCI) ist inkonform zu ISO 7816-4.
/// </summary>
FCI_NOT_CONFORM = 0x6284,
/// <summary>
/// Warnung; Zustand des nichtflüchtigen Speichers nicht verändert
/// </summary>
STORAGE_NOT_CHANGED = 0x6200,
/// <summary>
/// Zähler hat den Wert x erreicht (die genaue Bedeutung ist vom Kommando abhängig)
/// </summary>
COUNTER_REACHED = 0x63C0,
/// <summary>
/// Warnung; Zustand des nichtflüchtigen Speichers verändert
/// </summary>
STORAGE_CHANGED = 0x6300,
/// <summary>
/// Ausführungsfehler; Zustand des nichtflüchtigen Speichers nicht verändert
/// </summary>
EXECUTION_ERROR_WITHOUT_CHANGE = 0x6400,
/// <summary>
/// Speicherfehler
/// </summary>
MEMORY_ERROR = 0x6581,
/// <summary>
/// Ausführungsfehler; Zustand des nichtflüchtigen Speichers verändert
/// </summary>
EXECUTION_ERROR_WITH_CHANGE = 0x6500,
/// <summary>
/// Befehlslänge (Lc) oder erwartete Antwortlänge (Le) falsch
/// </summary>
INVALID_LC_LE = 0x6700,
/// <summary>
/// Funktionen im Class-Byte werden nicht unterstützt
/// </summary>
CLASS_FEATURE_NOT_SUPPORTED = 0x6800,
/// <summary>
/// Logische Kanäle werden nicht unterstützt
/// </summary>
LOGIC_CHANNEL_NOT_SUPPORTED = 0x6881,
/// <summary>
/// Secure Messaging wird nicht unterstützt
/// </summary>
SECURE_MESSAGING_NOT_SUPPORTED = 0x6882,
/// <summary>
/// Kommando nicht erlaubt
/// </summary>
COMMAND_NOT_ALLOWED = 0x6900,
/// <summary>
/// Kommando inkompatibel zur Dateistruktur
/// </summary>
COMMAND_INCOMPATIBLE = 0x6981,
/// <summary>
/// Sicherheitszustand nicht erfüllt
/// </summary>
SAFETY_STATUS_NOT_FULFILLED = 0x6982,
/// <summary>
/// Authentisierungsmethode ist gesperrt
/// </summary>
AUTHENTICATION_METHOD_LOCKED = 0x6983,
/// <summary>
/// Referenzierte Daten sind gesperrt
/// </summary>
REFERENCED_FILE_LOCKED = 0x6984,
/// <summary>
/// Nutzungsbedingungen sind nicht erfüllt
/// </summary>
TERMS_OF_SERVICE_NOT_FULFILLED = 0x6985,
/// <summary>
/// Kommando nicht erlaubt (kein EF selektiert)
/// </summary>
COMMAND_NOT_ALLOWED_NO_EF_SELECTED = 0x6986,
/// <summary>
/// Erwartete Secure-Messaging-Objekte nicht gefunden
/// </summary>
EXPECTED_SECURE_MESSAGING_OBJECTS_NOT_FOUND = 0x6987,
/// <summary>
/// Secure-Messaging-Datenobjekte sind inkorrekt
/// </summary>
INVALID_SECURE_MESSAGING_OBJECTS = 0x6988,
/// <summary>
/// Falsche Parameter P1/P2
/// </summary>
WRONG_PARAMETERS = 0x6A00,
/// <summary>
/// Falsche Daten
/// </summary>
WRONG_DATA = 0x6A80,
/// <summary>
/// Funktion wird nicht unterstützt
/// </summary>
FEATURE_NOT_SUPPORTED = 0x6A81,
/// <summary>
/// Datei wurde nicht gefunden
/// </summary>
FILE_NOT_FOUND = 0x6A82,
/// <summary>
/// Datensatz (engl. record) der Datei nicht gefunden
/// </summary>
RECORD_NOT_FOUND = 0x6A83,
/// <summary>
/// Nicht genügend Speicherplatz in der Datei
/// </summary>
INSUFFICIENT_SPACE = 0x6A84,
/// <summary>
/// Lc nicht konsistent mit der TLV-Struktur
/// </summary>
LC_TLV_INCONSISTENT = 0x6A85,
/// <summary>
/// Inkorrekte Parameter P1/P2
/// </summary>
INCORRECT_PARAMETERs = 0x6A86,
/// <summary>
/// Lc inkonsistent mit P1/P2
/// </summary>
LC_PARAMETERS_INCONSISTENT = 0x6A87,
/// <summary>
/// Referenzierte Daten nicht gefunden
/// </summary>
REFERENCED_FILE_NOT_FOUND = 0x6A88,
/// <summary>
/// Parameter P1/P2 falsch
/// </summary>
WRONG_PARAMETERS_2 = 0x6B00,
/// <summary>
/// Falsche Länge Le; xx gibt die korrekte Länge an Statuswort zur Steuerung des T=0-Protokolls
/// </summary>
INVALID_LE = 0x6C00,
/// <summary>
/// Das Kommando (INS) wird nicht unterstützt
/// </summary>
INSTRUCTION_NOT_SUPPORTED = 0x6D00,
/// <summary>
/// Die Kommandoklasse (CLA) wird nicht unterstützt
/// </summary>
CLASS_NOT_SUPPORTED = 0x6E00,
/// <summary>
/// Kommando wurde mit unbekanntem Fehler abgebrochen
/// </summary>
UNKNOWN_ERROR = 0x6F00,
/// <summary>
/// Kommando erfolgreich ausgeführt
/// </summary>
SUCCESS = 0x9000,
}
}

View File

@ -1,6 +1,4 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace NFC
{
@ -16,16 +14,18 @@ namespace NFC
bool IsAvailable();
/// <returns>Returns all available readers.</returns>
String[] GetReader();
string[] GetReaders();
/// <summary>
/// Create a new reader instance from the specified id.
/// </summary>
/// <returns>Returns the spatform specific reader that corresponds to the id.</returns>
/// <exception cref="ArgumentException">Invalid reader id.</exception>
IReader OpenReader(String readerID);
IReader OpenReader(string readerID);
}
public delegate void ReaderEventHandler(object sender, ICard card);
/// <summary>
/// Abstraction of a platform-specifc reader that can communicate with NFC cards.
/// </summary>
@ -34,12 +34,12 @@ namespace NFC
/// <summary>
/// Event that will be called when a new tag was discovered.
/// </summary>
event EventHandler CardDiscovered;
event ReaderEventHandler CardDiscovered;
/// <summary>
/// Event that will be called when a tag that is in use gets disconnected.
/// </summary>
event EventHandler CardLost;
event ReaderEventHandler CardLost;
void start();
@ -63,7 +63,7 @@ namespace NFC
/// </summary>
/// <param name="apdu_cmd">Application Protocol Data Unit Command - ISO 7816</param>
/// <returns>Application Protocol Data Unit Response - ISO 7816</returns>
byte[] Transmit(byte[] apdu_cmd);
APDUResponse Transmit(APDUCommand apdu_cmd);
}
public class ReaderUnavailableException : Exception { }

View File

@ -0,0 +1,44 @@
namespace NFC.Mifare_DESFire
{
enum APDUInstructions : byte
{
AUTHENTICATE_ISO = 0x1A,
AUTHENTICATE_AES = 0xAA,
CHANGE_KEY_SETTINGS = 0x54,
SET_CONFIGURATION = 0x5C,
CHANGE_KEY = 0xC4,
GET_KEY_VERSION = 0x64,
CREATE_APPLICATION = 0xCA,
DELETE_APPLICATION = 0xDA,
GET_APPLICATION_IDS = 0x6A,
FREE_MEMORY = 0x6E,
GET_DF_NAMES = 0x6D,
GET_KEY_SETTINGS = 0x45,
SELECT_APPLICATION = 0x5A,
FORMAT_PICC = 0xFC,
GET_VERSION = 0x60,
GET_CARD_UID = 0x51,
GET_FILE_IDS = 0x6F,
GET_FILE_SETTINGS = 0xF5,
CHANGE_FILE_SETTINGS = 0x5F,
CREATE_STDDATAFILE = 0xCD,
CREATE_BACKUPDATAFILE = 0xCB,
CREATE_VALUE_FILE = 0xCC,
CREATE_LINEAR_RECORD_FILE = 0xC1,
CREATE_CYCLIC_RECORD_FILE = 0xC0,
DELETE_FILE = 0xDF,
GET_ISO_FILE_IDS = 0x61,
READ_DATA = 0x8D,
WRITE_DATA = 0x3D,
GET_VALUE = 0x6C,
CREDIT = 0x0C,
DEBIT = 0xDC,
LIMITED_CREDIT = 0x1C,
WRITE_RECORD = 0x3B,
READ_RECORDS = 0xBB,
CLEAR_RECORD_FILE = 0xEB,
COMMIT_TRANSACTION = 0xC7,
ABORT_TRANSACTION = 0xA7,
CONTINUE = 0xAF,
}
}

View File

@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace NFC.Mifare_DESFire
{
public enum APDUStatusCodes : UInt16
{
OPERATION_OK = 0x9000, // = Successful operation
NO_CHANGES = 0x900C, // = No changes done to backup files, CommitTransaction / AbortTransaction not necessary
OUT_OF_EEPROM_ERROR = 0x900E, // = Insufficient NV-Memory to complete command
ILLEGAL_COMMAND_CODE = 0x901C, // = Command code not supported
INTEGRITY_ERROR = 0x901E, // = CRC or MAC does not match data Padding bytes not valid
NO_SUCH_KEY = 0x9040, // = Invalid key number specified
LENGTH_ERROR = 0x907E, // = Length of command string invalid
PERMISSION_DENIED = 0x909D, // = Current configuration / status does not allow the requested command
PARAMETER_ERROR = 0x909E, // = Value of the parameter(s) invalid
APPLICATION_NOT_FOUND = 0x90A0, // = Requested AID not present on PICC
APPL_INTEGRITY_ERROR = 0x90A1, // = Unrecoverable error within application, application will be disabled
AUTHENTICATION_ERROR = 0x90AE, // = Current authentication status does not allow the requested command
ADDITIONAL_FRAME = 0x90AF, // = Additional data frame is expected to be sent
BOUNDARY_ERROR = 0x90BE, // = Attempt to read/write data from/to beyond the file\'s/record\'s limits. Attempt to exceed the limits of a value file.
PICC_INTEGRITY_ERROR = 0x90C1, // = Unrecoverable error within PICC, PICC will be disabled
COMMAND_ABORTED = 0x90CA, // = Previous Command was not fully completed Not all Frames were requested or provided by the PCD
PICC_DISABLED_ERROR = 0x90CD, // = PICC was disabled by an unrecoverable error
COUNT_ERROR = 0x90CE, // = Number of Applications limited to 28, no additional CreateApplication possible
DUPLICATE_ERROR = 0x90DE, // = Creation of file/application failed because file/application with same number already exists
EEPROM_ERROR = 0x90EE, // = Could not complete NV-write operation due to loss of power, internal backup/rollback mechanism activated
FILE_NOT_FOUND = 0x90F0, // = Specified file number does not exist
FILE_INTEGRITY_ERROR = 0x90F1, // = Unrecoverable error within file, file will be disabled
}
}

View File

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace NFC.Mifare_DESFire
{
enum CryptoOperations : byte
{
TDES = 0x00,
TKTDES = 0x40,
AES = 0x80,
}
}

View File

@ -0,0 +1,20 @@
namespace NFC.Mifare_DESFire
{
enum FileCommunication : byte
{
/// <summary>
/// "Plain communication"
/// </summary>
PLAIN = 0x00,
/// <summary>
/// Plain communication secured by DES/3DES MACing
/// </summary>
MAC = 0x01,
/// <summary>
/// Fully DES/3DES enciphered communication
/// </summary>
ENCRYPT = 0x03
}
}

View File

@ -0,0 +1,30 @@
namespace NFC.Mifare_DESFire
{
enum FileTypes : byte
{
/// <summary>
/// Standard Data File
/// </summary>
STANDARD = 0x00,
/// <summary>
/// Backup Data Files
/// </summary>
BACKUP = 0x01,
/// <summary>
/// Value Files with Backup
/// </summary>
VALUE = 0x02,
/// <summary>
/// Linear Record Files with Backup
/// </summary>
LINEARRECORD = 0x03,
/// <summary>
/// Cyclic Record Files with Backup
/// </summary>
CYCLICRECORD = 0x04
}
}

View File

@ -4,4 +4,9 @@
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="PCSC" Version="5.0.0" />
<PackageReference Include="PCSC.Iso7816" Version="5.0.0" />
</ItemGroup>
</Project>

63
NFC/Readers/PCSC/Card.cs Normal file
View File

@ -0,0 +1,63 @@
using PCSC;
using PCSC.Iso7816;
namespace NFC.Readers.PCSC
{
public class Card : ICard
{
private IsoReader _ISOReader;
private string _ReaderID;
public Card(IsoReader isoreader, string readerID)
{
_ISOReader = isoreader;
_ReaderID = readerID;
}
public void Connect()
{
_ISOReader.Connect(_ReaderID, SCardShareMode.Shared, SCardProtocol.Any);
}
public void Disconnect()
{
_ISOReader.Disconnect(SCardReaderDisposition.Eject);
}
public APDUResponse Transmit(APDUCommand apdu_cmd)
{
Response response = _ISOReader.Transmit(Convert(apdu_cmd));
return Convert(response);
}
public CommandApdu Convert(APDUCommand apdu_cmd)
{
CommandApdu apdu = new CommandApdu(IsoCase.Case2Short, _ISOReader.ActiveProtocol)
{
CLA = apdu_cmd.Class,
INS = apdu_cmd.Instruction,
P1 = apdu_cmd.Parameter1,
P2 = apdu_cmd.Parameter2,
Data = apdu_cmd.Data,
Le = apdu_cmd.LengthExpected
};
return apdu;
}
public APDUResponse Convert(Response response)
{
ResponseApdu responseApdu = response.Get(0);
APDUResponse apduResponse = new APDUResponse()
{
SW1 = responseApdu.SW1,
SW2 = responseApdu.SW2,
Body = responseApdu.GetData()
};
return apduResponse;
}
}
}

View File

@ -0,0 +1,33 @@
using PCSC;
namespace NFC.Readers.PCSC
{
public class Hardware : IHardware
{
public string[] GetReaders()
{
var contextFactory = ContextFactory.Instance;
using (var context = contextFactory.Establish(SCardScope.System))
{
return context.GetReaders();
}
}
public bool IsAvailable()
{
if(GetReaders().Length == 0)
{
return false;
}
else
{
return true;
}
}
public IReader OpenReader(string readerID)
{
return new Reader(readerID);
}
}
}

View File

@ -0,0 +1,51 @@
using PCSC;
using PCSC.Iso7816;
using System;
using System.Collections.Generic;
using System.Text;
namespace NFC.Readers.PCSC
{
public class Reader : IReader, IDisposable
{
private string _ReaderID;
private IContextFactory _ContextFactory;
private ISCardContext _SCardContext;
private IsoReader _ISOReader;
private ICard _Card;
public Reader(string readerID)
{
_ReaderID = readerID;
}
public event ReaderEventHandler CardDiscovered;
public event ReaderEventHandler CardLost;
public void Dispose()
{
stop();
}
public void start()
{
_ContextFactory = ContextFactory.Instance;
_SCardContext = _ContextFactory.Establish(SCardScope.System);
_ISOReader = new IsoReader(_SCardContext);
_Card = new Card(_ISOReader, _ReaderID);
CardDiscovered?.Invoke(this, _Card);
}
public void stop()
{
CardLost?.Invoke(this, _Card);
_ISOReader.Dispose();
_SCardContext.Dispose();
}
}
}

17
NFC_Test/NFC_Test.csproj Normal file
View File

@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.7.1" />
<PackageReference Include="NUnit" Version="3.12.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\NFC\NFC.csproj" />
</ItemGroup>
</Project>

37
NFC_Test/REAL_Windows.cs Normal file
View File

@ -0,0 +1,37 @@
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.Text;
using NFC;
using NFC.Readers.PCSC;
namespace NFC_Test
{
[TestFixture, Explicit]
public class REAL_Windows
{
[Test]
public void GetReaders()
{
Hardware hardware = new Hardware();
string[] readers = hardware.GetReaders();
Console.WriteLine("Readers detected: {0}", readers.Length);
if(readers.Length > 0)
{
Console.WriteLine("List of ReaderIDs:");
foreach (string readerID in readers)
{
Console.WriteLine("{0}", readerID);
}
}
}
[TestCase("")]
public void Connect(string readerID)
{
}
}
}