diff --git a/CardReaderService/CardReaderService.conf b/CardReaderService/CardReaderService.conf index 27f379d..802a6f4 100644 --- a/CardReaderService/CardReaderService.conf +++ b/CardReaderService/CardReaderService.conf @@ -1,5 +1,5 @@ [program:CardReaderService] command=mono-service CardReaderService.exe --no-daemon -directory=/home/osboxes/CardReaderService -stdout_logfile=/home/osboxes/CardReaderService/out.log +directory=/DIRECTORYTOSET/CardReaderService +stdout_logfile=/DIRECTORYTOSET/CardReaderService/out.log redirect_stderr=true diff --git a/CardReaderService/CardReaderService.sln b/CardReaderService/CardReaderService.sln index a0006e0..79a69b4 100644 --- a/CardReaderService/CardReaderService.sln +++ b/CardReaderService/CardReaderService.sln @@ -9,6 +9,13 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CardReaderServiceHost", "Ca EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Logger", "Logger\Logger.csproj", "{42EFE386-DC2E-455A-BA81-5FC9CEE45D02}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Linux Conf", "Linux Conf", "{F9053F37-761D-45EE-9153-46776B083DBA}" + ProjectSection(SolutionItems) = preProject + CardReaderService.conf = CardReaderService.conf + install.sh = install.sh + uninstall.sh = uninstall.sh + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU diff --git a/CardReaderService/CardReaderService/CardDataPost.cs b/CardReaderService/CardReaderService/CardDataPost.cs new file mode 100644 index 0000000..6dfce4c --- /dev/null +++ b/CardReaderService/CardReaderService/CardDataPost.cs @@ -0,0 +1,10 @@ +using System; + +namespace CardReaderService +{ + public class CardDataPost + { + public DateTime UtcTimeStamp { get; set; } + public string CardUId { get; set; } + } +} \ No newline at end of file diff --git a/CardReaderService/CardReaderService/CardReaderService.csproj b/CardReaderService/CardReaderService/CardReaderService.csproj index 371c472..8621c3d 100644 --- a/CardReaderService/CardReaderService/CardReaderService.csproj +++ b/CardReaderService/CardReaderService/CardReaderService.csproj @@ -34,12 +34,12 @@ 4 - - ..\packages\Newtonsoft.Json.10.0.1\lib\net45\Newtonsoft.Json.dll + + ..\packages\Newtonsoft.Json.12.0.2\lib\net45\Newtonsoft.Json.dll True - ..\packages\PCSC.3.6.0\lib\net40\pcsc-sharp.dll + ..\packages\PCSC.4.2.0\lib\net40\PCSC.dll True @@ -54,6 +54,11 @@ + + + + + diff --git a/CardReaderService/CardReaderService/ConfigurationManager.cs b/CardReaderService/CardReaderService/ConfigurationManager.cs new file mode 100644 index 0000000..6ce4afa --- /dev/null +++ b/CardReaderService/CardReaderService/ConfigurationManager.cs @@ -0,0 +1,38 @@ +using System; +using System.Configuration; +using System.Linq; +using System.Reflection; + +namespace CardReaderService +{ + public class ConfigurationManager + { + public ConfigurationProperty GetConfiguration(string configName) + { + var cfgManager = GetConfigManager(); + if (cfgManager.AppSettings.Settings.AllKeys.Contains(configName)) + { + var cfg = cfgManager.AppSettings.Settings[configName]; + return new ConfigurationProperty + { + Group=string.Empty, + Id="NOTIMPLEMENTED", + Name = cfg.Key, + Value = cfg.Value, + ReadOnly = false, + Source = "CardReaderService", + Type = ConfigurationType.STRING + }; + } + + return null; + } + + private Configuration GetConfigManager() + { + return System.Configuration.ConfigurationManager.OpenExeConfiguration(ConfigFilePath); + } + + public string ConfigFilePath => new Uri(Assembly.GetEntryAssembly().CodeBase).LocalPath; + } +} \ No newline at end of file diff --git a/CardReaderService/CardReaderService/ConfigurationProperty.cs b/CardReaderService/CardReaderService/ConfigurationProperty.cs new file mode 100644 index 0000000..653f0ab --- /dev/null +++ b/CardReaderService/CardReaderService/ConfigurationProperty.cs @@ -0,0 +1,55 @@ +namespace CardReaderService +{ + /// + /// An object used to detail an element that can be configured in the system. + /// + public class ConfigurationProperty + { + /// + /// Unique Id for the configuration property. + /// + public string Id { get; set; } + /// + /// The display name of the configuration + /// + public string Name { get; set; } + + /// + /// The group under which this configuration falls (e.g.: TCP Settings - "TCP" or similar.) + /// + /// Application Specific grouping. + public string Group { get; set; } + + /// + /// The actual value of the Configuration property + /// + public string Value { get; set; } + + /// + /// The source of the configuration properties. + /// + /// + /// Using this property allows aggregation of configuration settings + /// by any configuration managers + /// + /// {TYPE}.getType().Name (or other suitably unique identifier) + public string Source { get; set; } + + /// + /// The type of the configuration + /// + /// + /// This can be used for UI proofing/validation to ensure a user + /// enters expected format (e.g.: enters a date time for a datetime type) + /// + public ConfigurationType Type { get; set; } + + /// + /// Specifies whether the configuration setting can be set by user or is readonly + /// + public bool ReadOnly { get; set; } + + //TODO: in future, add access level, could go read level/edit level + //public UserAccessLevel UserLevel {get;set;} + } +} \ No newline at end of file diff --git a/CardReaderService/CardReaderService/ConfigurationType.cs b/CardReaderService/CardReaderService/ConfigurationType.cs new file mode 100644 index 0000000..0f82c40 --- /dev/null +++ b/CardReaderService/CardReaderService/ConfigurationType.cs @@ -0,0 +1,33 @@ +namespace CardReaderService +{ + /// + /// The type of the configuration. + /// + public enum ConfigurationType + { + /// + /// No Type - shouldnt be used, but default for enum + /// + NONE, + /// + /// a string type configuration (could also be used for complex objects, e.g.: a json string/object). + /// + STRING, + /// + /// A whole number configuration + /// + INT, + /// + /// A number config with a decimal component + /// + DECIMAL, + /// + /// A Date Time Configuration + /// + DATETIME, + /// + /// A Boolean/TrueFalse configuration property (e.g.: On Off) + /// + BOOL + } +} \ No newline at end of file diff --git a/CardReaderService/CardReaderService/DataCenterHelper.cs b/CardReaderService/CardReaderService/DataCenterHelper.cs index 3cfe5a1..9c42926 100644 --- a/CardReaderService/CardReaderService/DataCenterHelper.cs +++ b/CardReaderService/CardReaderService/DataCenterHelper.cs @@ -1,36 +1,40 @@ using System; -using System.Collections.Generic; -using System.Configuration; -using System.Linq; using System.Net.Http; using System.Text; using System.Threading.Tasks; +using Logger; using Newtonsoft.Json; namespace CardReaderService { static class DataCenterHelper { + static DataCenterHelper() + { + } + public static void Post(CardDataPost postObject, string url) { - var endpointConfig = ConfigurationManager.AppSettings["DataCenterServiceEndpoint"] ?? - "http://localhost:8800"; + var cfgMgr = new ConfigurationManager(); + //using ConfigurationManager means we can change the value at runtime without having to restart the service. + var endpointConfig = cfgMgr.GetConfiguration("DataCenterServiceEndpoint")?.Value?? "http://localhost:8800"; + MessageLogger.Log("Targeting Endpoint: " + endpointConfig); using (var client = new HttpClient()) { var jsonObject = JsonConvert.SerializeObject(postObject); var content = new StringContent(jsonObject, Encoding.UTF8, "application/json"); try { - Console.WriteLine("Writing"); + MessageLogger.Log("Writing uid: "+ postObject.CardUId + " to the server."); var fullUrl = endpointConfig + url; + MessageLogger.Log("Writing to URL: " + fullUrl); var response = client.PostAsync(fullUrl, content).Result; - Console.WriteLine("Written"); + MessageLogger.Log("Successfully written to server"); } catch (Exception) { - Console.WriteLine("exceptioning"); - //ignore + MessageLogger.Log("Failed to send log to server."); } } } @@ -40,10 +44,4 @@ namespace CardReaderService return Task.Run(() => Post(postObject, url)); } } - - public class CardDataPost - { - public DateTime UtcTimeStamp { get; set; } - public string CardUId { get; set; } - } } diff --git a/CardReaderService/CardReaderService/Service1.cs b/CardReaderService/CardReaderService/Service1.cs index 1943312..c50d4dd 100644 --- a/CardReaderService/CardReaderService/Service1.cs +++ b/CardReaderService/CardReaderService/Service1.cs @@ -15,6 +15,7 @@ namespace CardReaderService { private Thread _mainWorkThread; private bool _stopMainWorkerThread; + private readonly ManualResetEvent _mre; private string _readerName = string.Empty; private SCardMonitor _cardMonitor; @@ -22,6 +23,7 @@ namespace CardReaderService public Service1() { InitializeComponent(); + _mre = new ManualResetEvent(false); } public void Start() @@ -64,6 +66,7 @@ namespace CardReaderService { MessageLogger.Log("Stopping.."); _stopMainWorkerThread = true; + _mre.Set(); if (_mainWorkThread != null && _mainWorkThread.IsAlive) { _mainWorkThread.Join(3000); @@ -95,46 +98,54 @@ namespace CardReaderService private void CardMonitor_CardInserted(object sender, CardStatusEventArgs e) { - var ctxFac = ContextFactory.Instance; - using (var ctx = ctxFac.Establish(SCardScope.System)) + try { - var reader = new SCardReader(ctx); - byte[] rcvBuffer = new byte[256]; - - if (_readerName == string.Empty) + var ctxFac = ContextFactory.Instance; + using (var ctx = ctxFac.Establish(SCardScope.System)) { - MessageLogger.Log("Reader name is somehow empty... WTF!"); - _stopMainWorkerThread = true; - return; - } + var reader = new SCardReader(ctx); + byte[] rcvBuffer = new byte[256]; - var err = reader.Connect(_readerName, SCardShareMode.Shared, SCardProtocol.Any); - if (err == SCardError.Success) - { - var pci = SCardPCI.GetPci(reader.ActiveProtocol); - - err = reader.Transmit(pci, CardCommands.GetUid, ref rcvBuffer); + if (_readerName == string.Empty) + { + MessageLogger.Log("Reader name is somehow empty... WTF!"); + _stopMainWorkerThread = true; + return; + } + var err = reader.Connect(_readerName, SCardShareMode.Shared, SCardProtocol.Any); if (err == SCardError.Success) { - var uid = ConvertByteUIDToString(rcvBuffer); - var atrString = ConvertByteUIDToString(e.Atr); + var pci = SCardPCI.GetPci(reader.ActiveProtocol); - MessageLogger.Log("Card Inserted, ATR: " + atrString + ", and UID is: " + uid); + err = reader.Transmit(pci, CardCommands.GetUid, ref rcvBuffer); - CardDataPost postObj = new CardDataPost { CardUId = uid, UtcTimeStamp = DateTime.UtcNow}; - DataCenterHelper.PostAsync(postObj, "/api/swipedata"); - MessageLogger.Log("Posted to Server"); + if (err == SCardError.Success) + { + var uid = ConvertByteUIDToString(rcvBuffer); + var atrString = ConvertByteUIDToString(e.Atr); + + MessageLogger.Log("Card Inserted, ATR: " + atrString + ", and UID is: " + uid); + + CardDataPost postObj = new CardDataPost { CardUId = uid, UtcTimeStamp = DateTime.UtcNow }; + DataCenterHelper.PostAsync(postObj, "/api/swipedata"); + MessageLogger.Log("Posted to Server"); + } + else + { + MessageLogger.Log("Failed to Read UID, Error: " + err); + } } else { - MessageLogger.Log("Failed to Read UID, Error: "+ err); + MessageLogger.Log("Reader failed to connect, error: " + Enum.GetName(typeof(SCardError), err)); } } - else - { - MessageLogger.Log("Reader failed to connect, error: " + Enum.GetName(typeof(SCardError), err)); - } + } + catch (Exception ex) + { + MessageLogger.Log("Exception has occurred in Card Inserted Event handler. Exception: "+ ex); + throw; } } @@ -166,6 +177,7 @@ namespace CardReaderService } } //dont actually need to do anything.. but cannot exit right away? + _mre.WaitOne(minimumLoopTimemS); } } diff --git a/CardReaderService/CardReaderServiceHost/CardReaderServiceHost.csproj b/CardReaderService/CardReaderServiceHost/CardReaderServiceHost.csproj index db0a5cd..61b73b5 100644 --- a/CardReaderService/CardReaderServiceHost/CardReaderServiceHost.csproj +++ b/CardReaderService/CardReaderServiceHost/CardReaderServiceHost.csproj @@ -34,8 +34,8 @@ 4 - - ..\packages\Newtonsoft.Json.10.0.1\lib\net45\Newtonsoft.Json.dll + + ..\packages\Newtonsoft.Json.12.0.2\lib\net45\Newtonsoft.Json.dll True @@ -53,6 +53,18 @@ + + CardReaderService.conf + PreserveNewest + + + install.sh + PreserveNewest + + + uninstall.sh + PreserveNewest + diff --git a/CardReaderService/Logger/MessageLogger.cs b/CardReaderService/Logger/MessageLogger.cs index e8aa791..a693525 100644 --- a/CardReaderService/Logger/MessageLogger.cs +++ b/CardReaderService/Logger/MessageLogger.cs @@ -14,7 +14,7 @@ namespace Logger public static void Log(string message) { Console.WriteLine(message); - System.IO.File.WriteAllText(_logPath, string.Format("{0} | {1}", DateTime.Now, message)); + File.AppendAllText(_logPath, string.Format("{0} | {1}{2}", DateTime.Now, message, Environment.NewLine)); } } } diff --git a/CardReaderService/install.sh b/CardReaderService/install.sh index 5a13335..a90cdb9 100644 --- a/CardReaderService/install.sh +++ b/CardReaderService/install.sh @@ -1,15 +1,24 @@ #!/bin/sh +if [ -z "$1" ] + then + echo "No arguments supplied, supply the base path" +fi echo "Installing dependencies" apt-get install mono-complete pcscd supervisor -y + +echo "Modifying supervisor conf file" +sed -i "s|/DIRECTORYTOSET|$1|g" CardReaderService.conf + echo "Installing service configuration file" cp CardReaderService.conf /etc/supervisor/conf.d/ + echo "Installing applicaton" -mkdir /home/osboxes/CardReaderService -cp CardReaderServiceHost/bin/Debug/*.* /home/osboxes/CardReaderService -cd /home/osboxes/CardReaderService +mkdir $1/CardReaderService +cp ./*.* $1/CardReaderService +cd $1/CardReaderService rm *.pdb rm *.vshost.exe rm *.vshost.exe.config rm *.vshost.exe.manifest echo "Starting application........." -service supervisor restart +service supervisor restart \ No newline at end of file diff --git a/CardReaderService/uninstall.sh b/CardReaderService/uninstall.sh index 5012336..5cb65ce 100644 --- a/CardReaderService/uninstall.sh +++ b/CardReaderService/uninstall.sh @@ -1,7 +1,12 @@ -echo "Stopping application...." +#!/bin/sh +if [ -z "$1" ] + then + echo "No arguments supplied, supply the base path" +fi +echo "Stopping service...." service supervisor stop rm -f /etc/supervisor/conf.d/CardReaderService.conf echo "Removing Application.." -rm -r -f /home/osboxes/CardReaderService +rm -r -f $1/CardReaderService echo "Removing application dependencies.." apt-get remove pcscd supervisor mono-complete -y