Merge branch 'CardReaderStartIssue-90' into Release0.2

This commit is contained in:
Chris.Watts90@outlook.com 2018-03-08 09:22:34 +00:00
commit 2601ea04f5
4 changed files with 82 additions and 44 deletions

View File

@ -18,6 +18,9 @@ namespace CardReaderService
private string _readerName = ""; private string _readerName = "";
private SCardMonitor _cardMonitor; private SCardMonitor _cardMonitor;
private bool _initialised = false;
private AutoResetEvent _mainWorkerTerminationSignal;
private ILogger _logger; private ILogger _logger;
public CardReaderService() public CardReaderService()
@ -32,43 +35,9 @@ namespace CardReaderService
protected override void OnStart(string[] args) protected override void OnStart(string[] args)
{ {
var configPath = string.Concat(System.Reflection.Assembly.GetEntryAssembly().Location, ".config");
_logger = NinjectHelper.GetInstance().Get<ILogger>(); _logger = NinjectHelper.GetInstance().Get<ILogger>();
_logger.Trace("Starting Service.. Getting available readers");
var ctxFactory = ContextFactory.Instance; StartWorkerThread();
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 = ConfigurationHandler.ConfigurationHandler.GetConfiguration("ReaderName");
if (string.IsNullOrEmpty(readerNameConfig) || (!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() public void StopService()
@ -79,6 +48,7 @@ namespace CardReaderService
protected override void OnStop() protected override void OnStop()
{ {
_stopMainWorkerThread = true; _stopMainWorkerThread = true;
_mainWorkerTerminationSignal.Set();
if (_mainWorkThread!= null && _mainWorkThread.IsAlive) if (_mainWorkThread!= null && _mainWorkThread.IsAlive)
{ {
_mainWorkThread.Join(3000); _mainWorkThread.Join(3000);
@ -102,6 +72,7 @@ namespace CardReaderService
Name = "CardServiceMainThread", Name = "CardServiceMainThread",
IsBackground = false IsBackground = false
}; };
_mainWorkerTerminationSignal = new AutoResetEvent(false);
_mainWorkThread.Start(); _mainWorkThread.Start();
} }
@ -135,7 +106,7 @@ namespace CardReaderService
_logger.Trace("Card Inserted, ATR: " + atrString + ", and UID is: " + uid); _logger.Trace("Card Inserted, ATR: " + atrString + ", and UID is: " + uid);
var postObj = new CardDataPost {CardUId = uid}; var postObj = new CardDataPost {CardUId = uid};
DataCenterHelper.PostAsync(postObj, "/api/swipedata"); DataCenterHelper.PostAsync(_logger, postObj, "/api/swipedata");
_logger.Trace("Posted to Server"); _logger.Trace("Posted to Server");
} }
else else
@ -151,7 +122,51 @@ namespace CardReaderService
while (!_stopMainWorkerThread) while (!_stopMainWorkerThread)
{ {
//dont actually need to do anything.. but cannot exit right away? //dont actually need to do anything.. but cannot exit right away?
Thread.Sleep(3000); if (!WeHaveValidCardReader())
{
if (_initialised)
{
//card reader no longer available, tidy up.
_cardMonitor.Cancel();
_cardMonitor.CardInserted -= _cardMonitor_CardInserted;
_cardMonitor.Dispose();
_cardMonitor = null;
_initialised = false;
}
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..");
}
else
{
foreach (var reader in readerNames)
{
_logger.Trace("Found reader: {0}", reader);
}
var readerNameConfig = ConfigurationHandler.ConfigurationHandler.GetConfiguration("ReaderName");
if (string.IsNullOrEmpty(readerNameConfig) || (!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);
_initialised = true;
}
}
}
_mainWorkerTerminationSignal.WaitOne(3000);
} }
} }
@ -169,5 +184,23 @@ namespace CardReaderService
{ {
return readerNames == null || readerNames.Count < 1; return readerNames == null || readerNames.Count < 1;
} }
private bool WeHaveValidCardReader()
{
if (_cardMonitor == null)
{
return false;
}
_logger.Trace(_cardMonitor.GetCurrentState(0).ToString());
if (_cardMonitor.GetCurrentState(0) == SCRState.Unknown
|| _cardMonitor.GetCurrentState(0) == SCRState.Unavailable
|| _cardMonitor.GetCurrentState(0) == (SCRState.Ignore | SCRState.Unavailable)
//|| _cardMonitor.GetCurrentState(0) == SCRState.Unaware //if we say this is an invalid state, we cause a memory leak where we create a duplicate card monitor, subscribe and overwrite.
)
{
return false;
}
return true;
}
} }
} }

View File

@ -5,13 +5,14 @@ using System.Linq;
using System.Net.Http; using System.Net.Http;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Interfaces;
using Newtonsoft.Json; using Newtonsoft.Json;
namespace CardReaderService namespace CardReaderService
{ {
static class DataCenterHelper static class DataCenterHelper
{ {
public static void Post(CardDataPost postObject, string url) public static void Post(ILogger logger, CardDataPost postObject, string url)
{ {
var endpointConfig = ConfigurationHandler.ConfigurationHandler.GetConfiguration("DataCenterServiceEndpoint") ?? var endpointConfig = ConfigurationHandler.ConfigurationHandler.GetConfiguration("DataCenterServiceEndpoint") ??
"http://localhost:8800"; "http://localhost:8800";
@ -22,10 +23,10 @@ namespace CardReaderService
var content = new StringContent(jsonObject, Encoding.UTF8, "application/json"); var content = new StringContent(jsonObject, Encoding.UTF8, "application/json");
try try
{ {
Console.WriteLine("Writing"); logger.Trace("Writing");
var fullUrl = endpointConfig + url; var fullUrl = endpointConfig + url;
var response = client.PostAsync(fullUrl, content).Result; var response = client.PostAsync(fullUrl, content).Result;
Console.WriteLine("Written"); logger.Trace("Written");
} }
catch (Exception) catch (Exception)
{ {
@ -35,9 +36,9 @@ namespace CardReaderService
} }
} }
public static Task PostAsync(CardDataPost postObject, string url) public static Task PostAsync(ILogger logger, CardDataPost postObject, string url)
{ {
return Task.Run(() => Post(postObject, url)); return Task.Run(() => Post(logger, postObject, url));
} }
} }

View File

@ -4,8 +4,12 @@
autoReload="true"> autoReload="true">
<targets> <targets>
<target name="viewer" xsi:type="Chainsaw" address="udp://127.0.0.1:4000" /> <target name="viewer" xsi:type="Chainsaw" address="udp://127.0.0.1:4000" />
<target xsi:type="Console" name="consoleViewer"
layout="${longdate}|${level:uppercase=true}|${message}"
detectConsoleAvailable="true" />
</targets> </targets>
<rules> <rules>
<logger name="*" minlevel="Trace" writeTo="viewer" /> <logger name="*" minlevel="Trace" writeTo="viewer" />
<logger name="*" minlevel="Trace" writeTo="consoleViewer" />
</rules> </rules>
</nlog> </nlog>

View File

@ -9,14 +9,14 @@ namespace NLogLogger
{ {
public class NLogger:ILogger public class NLogger:ILogger
{ {
private NLog.Logger _logger; private readonly Logger _logger;
public NLogger() public NLogger()
{ {
var nlogConfigPathOption = var nlogConfigPathOption =
ConfigurationHandler.ConfigurationHandler.GetConfiguration("NLogConfigFilePath"); ConfigurationHandler.ConfigurationHandler.GetConfiguration("NLogConfigFilePath");
if (nlogConfigPathOption == null) if (nlogConfigPathOption == null)
{ {
throw new ArgumentNullException("nlogConfigPath"); throw new ArgumentNullException("nlogConfigPath", "NLogConfigFilePath missing from application config file.");
} }
var nlogConfigPath = new Uri(Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().CodeBase), nlogConfigPathOption)).LocalPath; var nlogConfigPath = new Uri(Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().CodeBase), nlogConfigPathOption)).LocalPath;
LogManager.Configuration = new XmlLoggingConfiguration(nlogConfigPath); LogManager.Configuration = new XmlLoggingConfiguration(nlogConfigPath);