reference logger. add calls to logger to help trace the service on start/stop.
160 lines
5.1 KiB
C#
160 lines
5.1 KiB
C#
using PCSC;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.ServiceProcess;
|
|
using System.Text;
|
|
using System.Threading;
|
|
using Logger;
|
|
|
|
namespace CardReaderService
|
|
{
|
|
public partial class Service1 : ServiceBase
|
|
{
|
|
private Thread _mainWorkThread;
|
|
private bool _stopMainWorkerThread;
|
|
|
|
private string _readerName = "";
|
|
//private SCardReader _reader;
|
|
private SCardMonitor _cardMonitor;
|
|
|
|
public Service1()
|
|
{
|
|
InitializeComponent();
|
|
}
|
|
|
|
public void Start()
|
|
{
|
|
OnStart(new string[] {});
|
|
}
|
|
//
|
|
protected override void OnStart(string[] args)
|
|
{
|
|
Console.WriteLine("Starting.. Getting available readers");
|
|
MessageLogger.Log("Starting.. Getting available readers");
|
|
var ctxFactory = ContextFactory.Instance;
|
|
using(var context = ctxFactory.Establish(SCardScope.System))
|
|
{
|
|
var readerNames = context.GetReaders();
|
|
if (NoReaderAvailable(readerNames))
|
|
{
|
|
Console.WriteLine("No Card Reader is available, Exiting..");
|
|
MessageLogger.Log("No Card Reader is available, Exiting..");
|
|
return;
|
|
}
|
|
Console.WriteLine("Choosing first available reader: " + readerNames.First());
|
|
MessageLogger.Log("Choosing first available reader: " + readerNames.First());
|
|
_readerName = readerNames.First();
|
|
_cardMonitor = new SCardMonitor(ctxFactory, SCardScope.System);
|
|
_cardMonitor.CardInserted += _cardMonitor_CardInserted;
|
|
_cardMonitor.Start(_readerName);
|
|
|
|
StartWorkerThread();
|
|
}
|
|
}
|
|
|
|
public void Stop()
|
|
{
|
|
OnStop();
|
|
}
|
|
|
|
protected override void OnStop()
|
|
{
|
|
_stopMainWorkerThread = true;
|
|
if (_mainWorkThread!= null && _mainWorkThread.IsAlive)
|
|
{
|
|
_mainWorkThread.Join(3000);
|
|
if (_mainWorkThread.IsAlive)
|
|
{
|
|
_mainWorkThread.Interrupt();
|
|
}
|
|
}
|
|
if (_cardMonitor != null)
|
|
{
|
|
_cardMonitor.Cancel();
|
|
_cardMonitor.Dispose();
|
|
_cardMonitor = null;
|
|
}
|
|
}
|
|
|
|
private void StartWorkerThread()
|
|
{
|
|
_stopMainWorkerThread = false;
|
|
_mainWorkThread = new Thread(MainWorkerThread)
|
|
{
|
|
Name = "CardServiceMainThread",
|
|
IsBackground = false
|
|
};
|
|
_mainWorkThread.Start();
|
|
}
|
|
|
|
private void _cardMonitor_CardInserted(object sender, CardStatusEventArgs e)
|
|
{
|
|
var ctxFac = ContextFactory.Instance;
|
|
using (var ctx = ctxFac.Establish(SCardScope.System))
|
|
{
|
|
var reader = new SCardReader(ctx);
|
|
var pioSendPci = new IntPtr();
|
|
byte[] rcvBuffer = new byte[256];
|
|
|
|
if (_readerName == string.Empty)
|
|
{
|
|
Console.WriteLine("Reader name is somehow empty... WTF!");
|
|
_stopMainWorkerThread = true;
|
|
return;
|
|
}
|
|
|
|
var err = reader.Connect(_readerName, SCardShareMode.Shared, SCardProtocol.T0 | SCardProtocol.T1);
|
|
|
|
if (err == SCardError.Success)
|
|
{
|
|
var uIdcmd = new byte[] { 0xFF, 0xCA, 0x00, 0x00, 0x00 };
|
|
|
|
err = reader.Transmit(pioSendPci, uIdcmd, ref rcvBuffer);
|
|
if (err == SCardError.Success)
|
|
{
|
|
var uid = ConvertByteUIDToString(rcvBuffer);
|
|
var atrString = ConvertByteUIDToString(e.Atr);
|
|
Console.WriteLine("Card Inserted, ATR: " + atrString + ", and UID is: " + uid);
|
|
|
|
CardDataPost postObj = new CardDataPost {CardUId = uid};
|
|
DataCenterHelper.PostAsync(postObj, "/api/swipedata");
|
|
Console.WriteLine("Posted to Server");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Console.WriteLine("Reader failed to connect, error: " + Enum.GetName(typeof(SCardError), err));
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
private void MainWorkerThread()
|
|
{
|
|
while (!_stopMainWorkerThread)
|
|
{
|
|
//dont actually need to do anything.. but cannot exit right away?
|
|
Thread.Sleep(3000);
|
|
}
|
|
}
|
|
|
|
private string ConvertByteUIDToString(byte[] uid)
|
|
{
|
|
StringBuilder sb = new StringBuilder();
|
|
|
|
foreach(var b in uid)
|
|
{
|
|
sb.AppendFormat("{0:X2}", b);
|
|
}
|
|
|
|
return sb.ToString();
|
|
}
|
|
|
|
private bool NoReaderAvailable(ICollection<string> readerNames)
|
|
{
|
|
return readerNames == null || readerNames.Count < 1;
|
|
}
|
|
}
|
|
}
|