FlexitimeTracker/DataCenter_Windows/WindowsDataCenter/CardReaderService/CardReaderService.cs
chris.watts90@outlook.com 9dc4832471 Added Ninject, configuration and default logger.
Made DefaultLogger use the eventlog rather than debug.writeline(..)
renamed service1 to CardReaderService
#22
2017-02-18 09:09:19 +00:00

174 lines
5.6 KiB
C#

using PCSC;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Threading;
using Interfaces;
namespace CardReaderService
{
public partial class CardReaderService : ServiceBase
{
private Thread _mainWorkThread;
private bool _stopMainWorkerThread;
private string _readerName = "";
private SCardMonitor _cardMonitor;
private ILogger _logger;
public CardReaderService()
{
InitializeComponent();
}
public void Start()
{
OnStart(new string[] {});
}
protected override void OnStart(string[] args)
{
_logger = NinjectHelper.GetInstance().Get<ILogger>();
_logger.Trace("Starting Service.. Getting available readers");
var ctxFactory = ContextFactory.Instance;
using(var context = ctxFactory.Establish(SCardScope.System))
{
var readerNames = context.GetReaders();
if (NoReaderAvailable(readerNames))
{
_logger.Trace("No Card Reader is available, Exiting..");
throw new ApplicationException("A card reader must be provided in order to operate.");
}
foreach (var reader in readerNames)
{
_logger.Trace("Found reader: {0}", reader);
}
var readerNameConfig = ConfigurationManager.AppSettings["ReaderName"];
if (string.IsNullOrEmpty(readerNameConfig))
{
if (!readerNames.Contains(readerNameConfig))
{
_logger.Warn("No reader found with the name: {0}, defaulting to first available reader {1}",
readerNameConfig, readerNames.First());
readerNameConfig=readerNames.First();
}
}
_logger.Trace("Choosing reader: {0}", readerNameConfig);
_readerName = readerNameConfig;
_cardMonitor = new SCardMonitor(ctxFactory, SCardScope.System);
_cardMonitor.CardInserted += _cardMonitor_CardInserted;
_cardMonitor.Start(_readerName);
StartWorkerThread();
}
}
public void StopService()
{
OnStop();
}
protected override void OnStop()
{
_stopMainWorkerThread = true;
if (_mainWorkThread!= null && _mainWorkThread.IsAlive)
{
_mainWorkThread.Join(3000);
if (_mainWorkThread.IsAlive)
{
_mainWorkThread.Interrupt();
}
}
if (_cardMonitor == null) return;
_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();
var rcvBuffer = new byte[256];
if (_readerName == string.Empty)
{
_logger.Fatal("Reader name is somehow empty...exiting");
_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) return;
var uid = ConvertByteUIDToString(rcvBuffer);
var atrString = ConvertByteUIDToString(e.Atr);
_logger.Trace("Card Inserted, ATR: " + atrString + ", and UID is: " + uid);
var postObj = new CardDataPost {CardUId = uid};
DataCenterHelper.PostAsync(postObj, "/api/swipedata");
_logger.Trace("Posted to Server");
}
else
{
_logger.Trace("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)
{
var 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;
}
}
}