We can tap cards and print their UIDs
This commit is contained in:
parent
1829efd832
commit
f6d5b90e23
|
@ -7,4 +7,10 @@
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="PCSC" Version="6.1.3" />
|
||||||
|
<PackageReference Include="PCSC.Iso7816" Version="6.1.3" />
|
||||||
|
<PackageReference Include="System.CommandLine" Version="2.0.0-beta4.22272.1" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
@ -1,2 +1,79 @@
|
||||||
// See https://aka.ms/new-console-template for more information
|
using System.CommandLine;
|
||||||
Console.WriteLine("Hello, World!");
|
using PCSC;
|
||||||
|
using PCSC.Monitoring;
|
||||||
|
using PCSC.Iso7816;
|
||||||
|
|
||||||
|
var rootCommand = new RootCommand("Fancy Test Machine for AfRApay");
|
||||||
|
|
||||||
|
var listReadersOption = new Option<bool>("--list-readers", "List card readers and exit");
|
||||||
|
rootCommand.Add(listReadersOption);
|
||||||
|
|
||||||
|
rootCommand.SetHandler((listReaders) => {
|
||||||
|
using (var context = ContextFactory.Instance.Establish(SCardScope.System)) {
|
||||||
|
// We need a card reader or this won't work!
|
||||||
|
var readerNames = context.GetReaders();
|
||||||
|
if (readerNames.Length == 0) {
|
||||||
|
Console.Error.WriteLine("Error: no card reader detected");
|
||||||
|
Environment.Exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If --list-readers is passed, list readers and exit.
|
||||||
|
if (listReaders) {
|
||||||
|
Console.Error.WriteLine("---------- Connected Readers ----------");
|
||||||
|
foreach (var name in readerNames) {
|
||||||
|
Console.WriteLine(name);
|
||||||
|
}
|
||||||
|
Console.Error.WriteLine("---------------------------------------");
|
||||||
|
Environment.Exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Listen for events on all connected readers.
|
||||||
|
using (var monitor = MonitorFactory.Instance.Create(SCardScope.System)) {
|
||||||
|
monitor.Initialized += (_, args) => Console.WriteLine("[ Reader Initialized: {0} ]", args.ReaderName);
|
||||||
|
monitor.MonitorException += (_, args) => {
|
||||||
|
Console.Error.WriteLine("! ERROR: {0}", args);
|
||||||
|
Environment.Exit(1);
|
||||||
|
};
|
||||||
|
monitor.StatusChanged += (_, args) => Console.WriteLine("~ {0} -> {1}", args.LastState, args.NewState);
|
||||||
|
monitor.CardInserted += (_, args) => {
|
||||||
|
Console.WriteLine("> TAP: {0}", Convert.ToHexString(args.Atr));
|
||||||
|
var reader = new IsoReader(context, args.ReaderName, SCardShareMode.Shared, SCardProtocol.Any);
|
||||||
|
HandleTap(reader);
|
||||||
|
};
|
||||||
|
monitor.CardRemoved += (_, args) => {
|
||||||
|
Console.WriteLine("< OFF");
|
||||||
|
Console.WriteLine(); // Write a blank line between card taps for readability.
|
||||||
|
};
|
||||||
|
|
||||||
|
Console.WriteLine("[ Starting... ]");
|
||||||
|
monitor.Start(readerNames);
|
||||||
|
while (true) {
|
||||||
|
Console.Read();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, listReadersOption);
|
||||||
|
|
||||||
|
return await rootCommand.InvokeAsync(args);
|
||||||
|
|
||||||
|
// Queries a card for data when one is tapped.
|
||||||
|
static void HandleTap(IsoReader reader) {
|
||||||
|
// Send a PCSC pseudo-APDU to query the ISO 14443 UID.
|
||||||
|
var rsp = reader.Transmit(new CommandApdu(IsoCase.Case2Short, SCardProtocol.Any) {
|
||||||
|
CLA = 0xFF,
|
||||||
|
Instruction = InstructionCode.GetData,
|
||||||
|
P1 = 0x00,
|
||||||
|
P2 = 0x00,
|
||||||
|
});
|
||||||
|
if (!IsSucc(rsp)) {
|
||||||
|
Console.Error.WriteLine("--> Card Error: SW1={0} SW2={1}", (SW1Code)rsp.SW1, rsp.SW2);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var uid = rsp.GetData();
|
||||||
|
Console.WriteLine(" UID: {0}", Convert.ToHexString(uid));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Was the command successful?
|
||||||
|
static bool IsSucc(Response rsp) {
|
||||||
|
return rsp.SW1 == (byte)SW1Code.Normal && rsp.SW2 == 0x00;
|
||||||
|
}
|
||||||
|
|
|
@ -3,8 +3,12 @@ pkgs.mkShell {
|
||||||
name = "afrapay";
|
name = "afrapay";
|
||||||
packages = with pkgs; [
|
packages = with pkgs; [
|
||||||
dotnet-sdk_7
|
dotnet-sdk_7
|
||||||
|
pcsclite
|
||||||
|
|
||||||
# ESP32 tooling (for MateCard)
|
# ESP32 tooling (for MateCard)
|
||||||
platformio
|
platformio
|
||||||
];
|
];
|
||||||
|
|
||||||
|
# AfRApay.FTM tries to dlopen the pcsclite library at runtime.
|
||||||
|
LD_LIBRARY_PATH = [ "${pkgs.pcsclite.out}/lib" ];
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue