using System; using System.Collections.Generic; using System.Text; using System.Threading; using System.Xml; using System.Xml.Serialization; using System.IO; using System.Diagnostics; using System.Reflection; using System.Runtime.InteropServices; using System.Net; using System.Net.Sockets; using Wayne.FDCPOSLibrary; using Wayne.FDCPOSLibrary.Configuration; using Wayne.OptInterface; using Wayne.FDCPOSInterface.Configuration; namespace Wayne.FDCPOSInterface { using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using System.Linq; using System.Xml.Schema; public sealed class SchemasSG { private static readonly object instLock = new object(); private static Dictionary schemasSG; private static SchemasSG _instance; public static SchemasSG Instance { get { if (_instance == null) { lock (instLock) // make it multithread safe { if (_instance == null) { _instance = new SchemasSG(); } } } return _instance; } } public Dictionary GetSchemas { get { return schemasSG; } } private SchemasSG() { schemasSG = new Dictionary(); // read schemas from resource files Assembly a = Assembly.GetExecutingAssembly(); string name = a.GetName().Name; string sBasicTypeName = "SchemasSG.FDC_Basic_Types.xsd"; Stream sBasicTypes = a.GetManifestResourceStream(name + "." + sBasicTypeName); XmlSchema sBasicTypesSchema = XmlSchema.Read(sBasicTypes, ValidationCallback); //FDCPOSManager.tracer.WriteLine("BasicTypes Name: " + name + "." + sBasicTypeName); foreach (string resource in a.GetManifestResourceNames()) { if (resource.EndsWith(".xsd")) { try { //FDCPOSManager.tracer.WriteLine("Schema Name: " + resource); string shortName = resource.Substring(name.Length + 1); // get rid of Assembly name if (!sBasicTypeName.Equals(shortName)) { shortName = shortName.Substring(shortName.IndexOf(".") + 1); // get rid of the folder name SchemasSG shortName = shortName.Substring(0, shortName.Length - 4); // get rid of ".xsd" //FDCPOSManager.tracer.WriteLine("schema name: " + shortName); Stream s = Assembly.GetExecutingAssembly().GetManifestResourceStream(resource); { schemasSG[shortName] = new XmlSchemaSet(); schemasSG[shortName].Add(XmlSchema.Read(s, ValidationCallback)); schemasSG[shortName].Add(sBasicTypesSchema); // add this basic type to every node } } } catch (Exception ex) { //FDCPOSManager.tracer.WriteLine("Exception in Schemas! " + ex.Message); } } } } static void ValidationCallback(object sender, ValidationEventArgs args) { //if (args.Severity == XmlSeverityType.Warning) // FDCPOSManager.tracer.Write("WARNING: "); //else if (args.Severity == XmlSeverityType.Error) // FDCPOSManager.tracer.Write("ERROR: "); //FDCPOSManager.tracer.WriteLine(args.Message); } } public class FdcClientTcpHandler : IDisposable { private bool disposed = false; //static NLog.Logger fdcSocketLogger = NLog.LogManager.LoadConfiguration("nlog.config").GetLogger("FdcServerSocket"); private ILogger fdcSocketLogger; //= ServiceBuilder.Provider //.GetRequiredService().CreateLogger("FdcServerSocket"); private MD5Crypter crypter = new MD5Crypter(); /// /// ip:port, used for logging /// public string TcpClientEndPointString { get; private set; } private TcpClient tcpClient; public TcpClient TcpClient { get { return this.tcpClient; } } private FDCPOSManager fdcposManager; private FdcServerTcpHandler fdcServerTcpHandler; public string workstationID = ""; public string applicationSender = ""; /// /// fired on get tcp level error, mostly likely the tcp is broken /// public event EventHandler OnCommunicatingError; public FdcClientTcpHandler(FDCPOSManager _fdcposManager, FdcServerTcpHandler _fdcServerTcpHandler, TcpClient tcpClient, ILogger logger) { this.fdcposManager = _fdcposManager; this.fdcServerTcpHandler = _fdcServerTcpHandler; this.tcpClient = tcpClient; this.fdcSocketLogger = logger; } private void OnTcpClientDataRead(IAsyncResult ar) { NetworkStream networkStream; byte[] buffer = null; int readCount = 0; int previousReadCount = 0; Action callback = null; int expectingMsgLength = 0; try { //tuple is: ns, readBuffer, offset, readFullMsgCallback, expectingLengthToRead var parameter = (ar.AsyncState as Tuple, int>); networkStream = parameter.Item1; buffer = parameter.Item2; previousReadCount = parameter.Item3; callback = parameter.Item4; expectingMsgLength = parameter.Item5; readCount = networkStream.EndRead(ar); if (readCount == 0) throw new Exception("tcp client received 0 count data which indicates the connection is broken, trigger disconnection"); } catch (Exception eee) { fdcSocketLogger.LogError("EndRead Fdc client tcpClient NetworkStream exceptioned: " + eee + "\r\n will treat as OnCommunicatingError, this client with its Ip and port: " + this.TcpClientEndPointString); this.OnCommunicatingError?.Invoke(this, null); return; } if ((readCount + previousReadCount) < expectingMsgLength) { try { var _ = networkStream.BeginRead(buffer, (readCount + previousReadCount), (expectingMsgLength - (readCount + previousReadCount)), this.OnTcpClientDataRead, new Tuple, int>( networkStream, buffer, readCount + previousReadCount, callback, expectingMsgLength)); } catch (Exception eee) { fdcSocketLogger.LogError("Continue BeginRead Fdc client tcpClient NetworkStream exceptioned: " + eee + "\r\n will treat as OnCommunicatingError, this client with its Ip and port: " + this.TcpClientEndPointString); this.OnCommunicatingError?.Invoke(this, null); return; } } else { try { callback(buffer, networkStream); } catch (Exception xxx) { fdcSocketLogger.LogError("Callback in OnTcpClientDataRead exceptioned: " + xxx + "\r\n will ignore the error"); } } } private void ProcessMessageHeader(byte[] headerBuffer, NetworkStream networkStream) { try { int msgBodyLength = FdcClientTcpHandler.getMsgLength(headerBuffer); if (this.fdcSocketLogger.IsEnabled(LogLevel.Debug)) this.fdcSocketLogger.LogDebug($"Received a msg with BodyLength: {msgBodyLength}, will further parsing..."); if (msgBodyLength >= 19999) throw new ArgumentOutOfRangeException("MsgBodyLength: " + msgBodyLength + " is too big and unlikely a valid message"); byte[] bodyBuffer = new byte[msgBodyLength]; var r = networkStream.BeginRead(bodyBuffer, 0, msgBodyLength, this.OnTcpClientDataRead, //ns, readBuffer, offset, readFullMsgCallback, expectingLengthToRead new Tuple, int>( networkStream, bodyBuffer, 0, (bodyBuffer, __) => { this.ParseServiceRequestOrFdcMessageFromRaw(bodyBuffer, __, msgBodyLength, headerBuffer); this.StartReadingDataFromClient(); }, msgBodyLength)); } catch (Exception exxx) { fdcSocketLogger.LogError("BeginRead Fdc client tcpClient NetworkStream(ProcessMessageHeader) exceptioned: " + exxx + "\r\n will treat as OnCommunicatingError, this client with its Ip and port: " + this.TcpClientEndPointString); this.OnCommunicatingError?.Invoke(this, null); return; } } private void ParseServiceRequestOrFdcMessageFromRaw(byte[] bodyBuffer, NetworkStream networkStream, int msgLength, byte[] headerBytes) { var message = Encoding.UTF8.GetString(bodyBuffer); if (fdcSocketLogger.IsEnabled(LogLevel.Trace)) { // set a trace since the heartbeat msg is so frenquency and causing too much logging fdcSocketLogger.LogTrace($"Parsing ServiceRequest Or FdcMessage from raw incoming message: {message ?? ""}"); } var result = OverallResult.Success; string sEndmsg = ""; //no trailing spaces xml message string exactXmlMsgStr = ""; int indexEndMsgSR = -1, indexEndFDCMsg = -1, indexEnd = -1; indexEndMsgSR = message.IndexOf(""); indexEndFDCMsg = message.IndexOf(""); #region parse if (indexEndMsgSR >= 0 && indexEndFDCMsg >= 0) { indexEnd = System.Math.Min(indexEndMsgSR, indexEndFDCMsg); if (indexEndMsgSR < indexEndFDCMsg) { sEndmsg = ""; indexEndFDCMsg = -1; } else { sEndmsg = ""; indexEndMsgSR = -1; } } else if (indexEndMsgSR >= 0 && indexEndFDCMsg < 0) { indexEnd = indexEndMsgSR; sEndmsg = ""; } else if (indexEndMsgSR < 0 && indexEndFDCMsg >= 0) { indexEnd = indexEndFDCMsg; sEndmsg = ""; } else this.fdcSocketLogger.LogError("how a full MessageBody neither contains nor , not a valid Fdc msg, will ignore it"); #endregion if (indexEnd >= 0) { exactXmlMsgStr = message.Substring(0, indexEnd + sEndmsg.Length); message = message.Substring(indexEnd + sEndmsg.Length); if (fdcposManager.encryptedHeader) { var hashingTarget = exactXmlMsgStr + MD5Crypter.passphrase; if (!crypter.verifyMD5Hash(hashingTarget, headerBytes.Skip(Define.HeaderLength).Take(Define.EncriptionLength).Select(h => h.ToString("x2")).Aggregate((acc, n) => acc + n))) { if (fdcSocketLogger.IsEnabled(LogLevel.Information)) fdcSocketLogger.LogInformation("verifyMD5Hash failed for msg from " + this.TcpClientEndPointString + ", the computed&expecting hash string: " + crypter.getMD5Hash(hashingTarget) + ", the hashing target(incomingMsg+passcode): \r\n" + hashingTarget); result = OverallResult.ValidationError; } } if (exactXmlMsgStr.Length > 0) { this.fdcServerTcpHandler.ReadRequest(this, exactXmlMsgStr, msgLength, (indexEndMsgSR > 0) ? true : false, ref result); } } } public void StartReadingDataFromClient() { if (this.tcpClient == null || !this.tcpClient.Connected) return; try { this.TcpClientEndPointString = ((IPEndPoint)(tcpClient.Client.RemoteEndPoint)).ToString(); } catch { } try { NetworkStream networkStream = this.tcpClient.GetStream(); var headerBuffer = new byte[Define.HeaderLength + Define.EncriptionLength]; var _ = networkStream.BeginRead(headerBuffer, 0, (Define.HeaderLength + Define.EncriptionLength), this.OnTcpClientDataRead, //ns, readBuffer, offset, readFullMsgCallback, expectingLengthToRead new Tuple, int>( networkStream, headerBuffer, 0, this.ProcessMessageHeader, (Define.HeaderLength + Define.EncriptionLength))); } catch (Exception exxx) { fdcSocketLogger.LogError("Get or BeginRead Fdc client tcpClient NetworkStream exceptioned: " + exxx + "\r\n will ignore this client"); this.OnCommunicatingError?.Invoke(this, null); return; } } static public int getMsgLength(byte[] header) { int length = 0; for (int pos = 1; pos <= Define.HeaderLength; pos++) { length |= ((int)(header[pos - 1] << (Define.HeaderLength - pos) * 8)); } return length; } public void Dispose() { try { this.disposed = true; this.tcpClient.Close(); } catch { } finally { } } } public class FdcServerTcpHandler : IDisposable { private List fdcClientTcpHandlers = new List(); //protected static NLog.Logger fdcSocketLogger = NLog.LogManager.LoadConfiguration("nlog.config").GetLogger("FdcServerSocket"); protected ILogger fdcSocketLogger;// = ServiceBuilder.Provider.GetRequiredService().CreateLogger("FdcServerSocket"); private bool disposed = false; protected FDCPOSManager fdcPosManager; protected TcpListener tcpListener; protected int iIPPort; private bool traceXML = false; public FDCPOSInterfaceServer FdcPosInterface { get; set; } public int IPPort { get { return iIPPort; } set { iIPPort = value; } } public FdcServerTcpHandler(FDCPOSManager _fdcPosManager, int _iIPPort, ILogger logger) { this.fdcSocketLogger = logger; fdcPosManager = _fdcPosManager; iIPPort = _iIPPort; } public bool StartListening() { try { this.tcpListener = new TcpListener(IPAddress.Any, iIPPort); this.tcpListener.Start(); var _ = this.tcpListener.BeginAcceptTcpClient(this.OnTcpClientAccepted, null); this.fdcSocketLogger.LogInformation("FdcServerTcpHandler is listening on port: " + iIPPort); return true; } catch (Exception exxx) { fdcSocketLogger.LogError("Listening port: " + iIPPort + " exceptioned: " + exxx + "\r\n will QUIT listening"); throw; } } private void OnTcpClientAccepted(IAsyncResult ar) { TcpClient tcpClient = null; try { tcpClient = this.tcpListener.EndAcceptTcpClient(ar); this.fdcSocketLogger.LogDebug("A Tcp client: " + ((IPEndPoint)(tcpClient.Client.RemoteEndPoint)).ToString() + " has connected in..."); } catch (Exception exxx) { fdcSocketLogger.LogError($"TcpListener EndAcceptTcpClient exceptioned: {exxx.ToString() + Environment.NewLine}will continue listening(depends on is app shuting down)"); return; } finally { if (!this.disposed) tcpListener.BeginAcceptTcpClient(this.OnTcpClientAccepted, null); } var fdcClientTcpHandler = new FdcClientTcpHandler(fdcPosManager, this, tcpClient, this.fdcSocketLogger); fdcClientTcpHandler.OnCommunicatingError += (s, e) => { #region clean up fdcClientTcpHandler.Dispose(); string fdcClientId = FDCPOSClient.getClientID(fdcClientTcpHandler.workstationID, fdcClientTcpHandler.applicationSender); try { if (this.fdcPosManager.fdcClientList.ContainsKey(fdcClientId)) { fdcSocketLogger.LogInformation(string.Format("Cleaning up existed FdcClient '{0}' which from remote: {1}", fdcClientId, fdcClientTcpHandler.TcpClientEndPointString)); this.fdcPosManager.DisconnectClient(this.fdcPosManager.fdcClientList[fdcClientId]); } } catch (Exception eeee) { fdcSocketLogger.LogInformation(string.Format("Cleaning up existed FdcClient '{0}', from remote: {1} exceptioned: \r\n {2}", fdcClientId, fdcClientTcpHandler.TcpClientEndPointString, eeee)); } #endregion }; fdcClientTcpHandler.StartReadingDataFromClient(); this.fdcClientTcpHandlers.Add(fdcClientTcpHandler); } public string ReadRequest(FdcClientTcpHandler fdcClientTcpHandler, string message, int msglength, bool isServiceRequest, ref OverallResult result) { OverallResult extresult = result; ErrorCode iFDCStatus = (int)ErrorCode.ERRCD_OK; int requestId = -1; string requestType = (isServiceRequest) ? GetRequestType(message) : GetMessageType(message); string applicationSender = GetApplicationSender(message); string workstationId = GetWorkstationID(message); if (string.IsNullOrEmpty(requestType)) { fdcSocketLogger.LogInformation(string.Format("Client with applicationSender={0}, workstationId={1} is " + "sending in a message that Fcc resolved an empty or null requestType from it, unlikely an valid format message:{2}{3}", applicationSender, workstationId, Environment.NewLine, (message ?? ""))); result = OverallResult.NoData; iFDCStatus = ErrorCode.ERRCD_BADVAL; ((FDCPOSInterfaceServerManager)this.fdcPosManager).fdcPosInterface.messages.SendErrorResponse(requestType, workstationId, applicationSender, requestId, iFDCStatus, result.ToString()); return requestType; } try { //FDCPOSManager.tracer.WriteLine(string.Format("init requestType='{0}'", requestType)); if (fdcSocketLogger.IsEnabled(LogLevel.Trace)) fdcSocketLogger.LogTrace($"Parsed the incoming Request, requestType: {requestType ?? ""}, applicationSender: {applicationSender ?? ""}, workstationId: {workstationId ?? ""}, message: {Environment.NewLine} {message ?? ""}"); if (fdcSocketLogger.IsEnabled(LogLevel.Debug)) if (requestType != "POSHeartBeat") fdcSocketLogger.LogTrace($"Parsed the incoming Request, requestType: {requestType ?? ""}, applicationSender: {applicationSender ?? ""}, workstationId: {workstationId ?? ""}, message: {Environment.NewLine} {message ?? ""}"); if (requestType != "LogOn") { if (!this.fdcPosManager.fdcClientList.ContainsKey(FDCPOSClient.getClientID(workstationId, applicationSender))) { FDCPOSClient fdcposClient = new FDCPOSClient(fdcPosManager, null, this.fdcSocketLogger); fdcposClient.workstationID = workstationId; fdcposClient.applicationSender = applicationSender; IPEndPoint endpoint = (IPEndPoint)(fdcClientTcpHandler.TcpClient.Client.RemoteEndPoint); string sIPAddress = endpoint.Address.ToString(); fdcposClient.sIPAddress = sIPAddress; fdcposClient.FdcClientTcpHandler = fdcClientTcpHandler; fdcposClient.connected = true; fdcposClient.socketChannelResponse = fdcClientTcpHandler.TcpClient; fdcClientTcpHandler.workstationID = workstationId; fdcClientTcpHandler.applicationSender = applicationSender; fdcPosManager.fdcClientList.Add(FDCPOSClient.getClientID(workstationId, applicationSender), fdcposClient); if (this.fdcSocketLogger.IsEnabled(LogLevel.Debug)) this.fdcSocketLogger.LogDebug(string.Format("Unknown Client with appSender={0}, wId={1} is " + "sending Request(type={2}) in without log on, Will response: AuthentificationError", applicationSender, workstationId, requestType)); result = OverallResult.AuthentificationError; iFDCStatus = ErrorCode.ERRCD_COMMERR; ((FDCPOSInterfaceServerManager)this.fdcPosManager).fdcPosInterface.messages.SendErrorResponse(requestType, workstationId, applicationSender, requestId, iFDCStatus, result.ToString()); fdcPosManager.fdcClientList.Remove(FDCPOSClient.getClientID(workstationId, applicationSender)); return requestType; } if (result == OverallResult.Success && extresult == OverallResult.Success) { fdcPosManager.fdcClientList[FDCPOSClient.getClientID(workstationId, applicationSender)].heartbeat.StopClientDisconnectionTimer(); } } if (requestType == "POSHeartBeat") { if (fdcSocketLogger.IsEnabled(LogLevel.Debug)) this.fdcSocketLogger.LogDebug(string.Format("Received a POSHeartBeat from applicationSender: {0}, workstationId: {1}", (applicationSender ?? ""), (workstationId ?? ""))); // if (isServiceRequest) // { // ServiceRequestHeartbeat sr = Deserialize(myString, ref result); // if (!this.fdcposManager.tcpClientList.ContainsKey(FDCPOSClient.getClientID(sr.WorkstationID, sr.ApplicationSender))) // result = OverallResult.AuthentificationError; // if (sr != null && result == OverallResult.Success && extresult == OverallResult.Success) // { // fdcposManager.tcpClientList[FDCPOSClient.getClientID(sr.WorkstationID, sr.ApplicationSender)].heartbeat.ResetDisconnectionTimeout(); // } // } // else // { // FDCMessageFDCHeartbeat sr = Deserialize(myString, ref result); // if (!this.fdcposManager.tcpClientList.ContainsKey(FDCPOSClient.getClientID(sr.WorkstationID, sr.ApplicationSender))) // result = OverallResult.AuthentificationError; // if (sr != null && result == OverallResult.Success && extresult == OverallResult.Success) // { // fdcposManager.tcpClientList[FDCPOSClient.getClientID(sr.WorkstationID, sr.ApplicationSender)].heartbeat.ResetDisconnectionTimeout(); // } // } } else if (requestType == "LogOn") { ServiceRequestLogOn sr = Deserialize(message, ref result); if (sr != null) { requestId = sr.RequestIDNumber; if (sr.POSdata.GetLength(0) == 0) result = OverallResult.MissingMandatoryData; else { int iResponsePort = Convert.ToInt32(sr.POSdata[0].ResponsePort); if (iResponsePort == 0) iResponsePort = this.IPPort; int iUnsolicitedPort = Convert.ToInt32(sr.POSdata[0].UnsolicitedPort); if (iUnsolicitedPort == 0) iUnsolicitedPort = this.IPPort; fdcSocketLogger.LogInformation(string.Format("Client with WorkstationId: {0}, ApplicationSender: {1}, InterfaceVersion: {2} from {3} is logging on", sr.WorkstationID, sr.ApplicationSender, (sr.POSdata?.FirstOrDefault()?.interfaceVersion ?? ""), ((IPEndPoint)(fdcClientTcpHandler.TcpClient.Client.RemoteEndPoint)).ToString() )); if (sr.POSdata[0].interfaceVersion != null) { //FDCPOSManager.tracer.WriteLine(string.Format("sr.POSdata[0].interfaceVersion='{0}'", sr.POSdata[0].interfaceVersion)); if (sr.POSdata[0].interfaceVersion == "00.07") FDCGlobal.ProtocolVersion = FDCVersion.V0007; else if (sr.POSdata[0].interfaceVersion == "00.05") FDCGlobal.ProtocolVersion = FDCVersion.V0005; else if (sr.POSdata[0].interfaceVersion == "00.03") FDCGlobal.ProtocolVersion = FDCVersion.V0003; //FDCPOSManager.tracer.WriteLine(string.Format("interfaceVersion set")); } //FDCPOSManager.tracer.WriteLine(string.Format("this.fdcposManager.forecourtConfiguration={0}", this.fdcposManager.forecourtConfiguration)); //FDCPOSManager.tracer.WriteLine(string.Format("test={0}", sr.POSdata[0].ValidationInfo != null && (this.fdcposManager.forecourtConfiguration != "Q8-DENMARK" && this.fdcposManager.forecourtConfiguration != "WINCOR"))); if (sr.POSdata[0].ValidationInfo != null && (this.fdcPosManager.forecourtConfiguration != "Q8-DENMARK" && this.fdcPosManager.forecourtConfiguration != "WINCOR")) { string filename = "", version = "", ssigncheck = "", CRC = "", binaryCRC = "", versionCRC = "", addInfo = ""; string softsealfilename = "", softsealversion = "", binarysoftsealCRC = "", versionsoftsealCRC = ""; bool signaturecheck = false, softsealadded = false; DESCrypter crypter = new DESCrypter(); try { Monitor.Enter(fdcPosManager); foreach (byte[] validationInfoElem in sr.POSdata[0].ValidationInfo) { byte[] data = crypter.Decrypt(validationInfoElem); if (data != null && data.Length > 0) { signaturecheck = false; string s = System.Text.Encoding.UTF8.GetString(data, 0, data.GetLength(0)); //FDCPOSManager.tracer.WriteLine(string.Format("validation string='{0}'", s)); filename = s.Substring(0, s.IndexOf("###")); //FDCPOSManager.tracer.WriteLine(string.Format("filename='{0}'", filename)); s = s.Substring(s.IndexOf("###") + 3); version = s.Substring(0, s.IndexOf("###")); //FDCPOSManager.tracer.WriteLine(string.Format("version='{0}'", version)); s = s.Substring(s.IndexOf("###") + 3); ssigncheck = s.Substring(0, s.IndexOf("###")); //FDCPOSManager.tracer.WriteLine(string.Format("ssigncheck='{0}'", ssigncheck)); signaturecheck = (ssigncheck == "1") ? true : false; s = s.Substring(s.IndexOf("###") + 3); CRC = s.Substring(0, s.IndexOf("###")); if (CRC.IndexOf("-") >= 0) { binaryCRC = CRC.Substring(0, CRC.IndexOf("-")); versionCRC = CRC.Substring(CRC.IndexOf("-") + 1); } else versionCRC = CRC; //FDCPOSManager.tracer.WriteLine(string.Format("binaryCRC='{0}', versionCRC'{1}'", binaryCRC, versionCRC)); s = s.Substring(s.IndexOf("###") + 3); softsealfilename = s.Substring(0, s.IndexOf("###")); //FDCPOSManager.tracer.WriteLine(string.Format("softsealfilename='{0}'", softsealfilename)); s = s.Substring(s.IndexOf("###") + 3); softsealversion = s.Substring(0, s.IndexOf("###")); //FDCPOSManager.tracer.WriteLine(string.Format("softsealversion='{0}'", softsealversion)); s = s.Substring(s.IndexOf("###") + 3); if (s.IndexOf("###") == -1) CRC = s; else { CRC = s.Substring(0, s.IndexOf("###")); s = s.Substring(s.IndexOf("###") + 3); addInfo = s; } if (CRC.IndexOf("-") >= 0) { binarysoftsealCRC = CRC.Substring(0, CRC.IndexOf("-")); versionsoftsealCRC = CRC.Substring(CRC.IndexOf("-") + 1); } else versionsoftsealCRC = CRC; //FDCPOSManager.tracer.WriteLine(string.Format("binarysoftsealCRC='{0}', versionsoftsealCRC'{1}'", binarysoftsealCRC, versionsoftsealCRC)); if (softsealfilename != "" && !softsealadded) { //FDCPOSManager.tracer.WriteLine(string.Format("validate add file='{0}', version={1}", softsealfilename, softsealversion)); this.FdcPosInterface.ValidateSealAddReq(softsealfilename.Substring(softsealfilename.LastIndexOf('\\') + 1), softsealversion, (((FDCPOSInterfaceServerManager)this.fdcPosManager).certificate == certificateType.MID) ? binarysoftsealCRC : versionsoftsealCRC, ""); softsealadded = true; } if (signaturecheck) { //FDCPOSManager.tracer.WriteLine(string.Format("validate add file='{0}', version={1}", filename, version)); this.FdcPosInterface.ValidateSealAddReq(filename.Substring(filename.LastIndexOf('\\') + 1), version, (((FDCPOSInterfaceServerManager)this.fdcPosManager).certificate == certificateType.MID) ? binaryCRC : versionCRC, addInfo); } else { //FDCPOSManager.tracer.WriteLine(string.Format("signature failed file='{0}', version={1}", filename, version)); result = OverallResult.AuthentificationError; break; } } else { //FDCPOSManager.tracer.WriteLine(string.Format("error decrypting")); result = OverallResult.AuthentificationError; break; } } if (result == OverallResult.Success) { if (!this.FdcPosInterface.ValidateSealEndReq(true)) { //FDCPOSManager.tracer.WriteLine(string.Format("error on seal validation")); result = OverallResult.AuthentificationError; } } else { //FDCPOSManager.tracer.WriteLine(string.Format("reset seal validation info")); this.FdcPosInterface.ValidateSealEndReq(false); } } catch (Exception ex) { //FDCPOSManager.tracer.WriteLine(string.Format("LogOn Validation Info Exception! " + ex.Message)); result = OverallResult.AuthentificationError; } finally { Monitor.Exit(fdcPosManager); } } else { if (this.fdcPosManager.forecourtConfiguration != "Q8-DENMARK" && this.fdcPosManager.forecourtConfiguration != "WINCOR") { fdcSocketLogger.LogInformation("configuration is not Q8 and is not WINCOR - AuthorizationInfo must not be null - AuthentificationError !"); //FDCPOSManager.tracer.WriteLine(string.Format("configuration is not Q8 and is not WINCOR - AuthorizationInfo must not be null - AuthentificationError !")); result = OverallResult.AuthentificationError; } } IPEndPoint endpoint = (IPEndPoint)(fdcClientTcpHandler.TcpClient.Client.RemoteEndPoint); string sIPAddress = endpoint.Address.ToString(); if (result == OverallResult.Success && extresult == OverallResult.Success) { //FDCPOSManager.tracer.WriteLine(string.Format("PortA='{0}', PortB='{1}', PortC='{2}'", //this.IPPort, iResponsePort, iUnsolicitedPort)); //fdcSocketLogger.LogInformation(string.Format("PortA='{0}', PortB='{1}', PortC='{2}', in Logon", this.IPPort, iResponsePort, iUnsolicitedPort)); Messages.HeartbeatCallback heartbeatCallback = new Messages.HeartbeatCallback(this.FdcPosInterface.messages.Heartbeat); bool enteredmonitor = false; try { Monitor.Enter(fdcPosManager.fdcClientList); enteredmonitor = true; if (!fdcPosManager.fdcClientList.ContainsKey(FDCPOSClient.getClientID(sr.WorkstationID, sr.ApplicationSender))) { //FDCPOSManager.tracer.WriteLine(string.Format("Client not found - adding")); fdcSocketLogger.LogInformation("Client: " + FDCPOSClient.getClientID(sr.WorkstationID, sr.ApplicationSender) + " not found in TcpClientList(" + (fdcPosManager.fdcClientList.Keys.Any() ? fdcPosManager.fdcClientList.Keys.Select(k => k ?? "null").Aggregate((n, acc) => n + ", " + acc) : "Empty yet") + ") - will adding in, in LogOn"); FDCPOSClient fdcposClient = null; string posInfo; if (sr.POSdata[0].posInfo != null) // && sr.POSdata[0].posInfo != "") { posInfo = UTF8Encoding.UTF8.GetString(sr.POSdata[0].posInfo, 0, sr.POSdata[0].posInfo.GetLength(0)); POSType posType = FDCPOSClient.GetType(posInfo); if (posType == POSType.IXTerminal) { fdcposClient = new FDCPOSClientIX(fdcPosManager, heartbeatCallback, posInfo); } else if (posType == POSType.Generic) { fdcposClient = new FDCPOSClient(fdcPosManager, heartbeatCallback, this.fdcSocketLogger); } } else fdcposClient = new FDCPOSClient(fdcPosManager, heartbeatCallback, this.fdcSocketLogger); fdcposClient.workstationID = sr.WorkstationID; fdcposClient.applicationSender = sr.ApplicationSender; fdcposClient.sIPAddress = sIPAddress; fdcposClient.FdcClientTcpHandler = fdcClientTcpHandler; fdcClientTcpHandler.workstationID = sr.WorkstationID; fdcClientTcpHandler.applicationSender = sr.ApplicationSender; fdcPosManager.fdcClientList.Add(FDCPOSClient.getClientID(sr.WorkstationID, sr.ApplicationSender), fdcposClient); fdcSocketLogger.LogInformation(" Client: " + FDCPOSClient.getClientID(sr.WorkstationID, sr.ApplicationSender) + " is added in TcpClientList"); Monitor.Exit(fdcPosManager.fdcClientList); enteredmonitor = false; this.FdcPosInterface.LogOnReq(sr.WorkstationID, sr.ApplicationSender, sr.RequestIDNumber, iResponsePort, iUnsolicitedPort, (int)(FDCGlobal.ProtocolVersion)); } else if (!fdcPosManager.fdcClientList[FDCPOSClient.getClientID(sr.WorkstationID, sr.ApplicationSender)].logon && fdcPosManager.fdcClientList[FDCPOSClient.getClientID(sr.WorkstationID, sr.ApplicationSender)].sIPAddress == sIPAddress) { //FDCPOSManager.tracer.WriteLine(string.Format("Client found but not logged - logging")); fdcSocketLogger.LogInformation("Client: " + FDCPOSClient.getClientID(sr.WorkstationID, sr.ApplicationSender) + " is found in TcpClientList but not logged on - will set to LoggedOn, in LogOn"); FDCPOSClient fdcposClient = fdcPosManager.fdcClientList[FDCPOSClient.getClientID(sr.WorkstationID, sr.ApplicationSender)]; fdcposClient.logon = true; fdcposClient.FdcClientTcpHandler = fdcClientTcpHandler; Monitor.Exit(fdcPosManager.fdcClientList); enteredmonitor = false; this.FdcPosInterface.LogOnReq(sr.WorkstationID, sr.ApplicationSender, sr.RequestIDNumber, iResponsePort, iUnsolicitedPort, (int)(FDCGlobal.ProtocolVersion)); } else { //FDCPOSManager.tracer.WriteLine(string.Format("Client already logged (!?)")); fdcSocketLogger.LogInformation("Client: " + FDCPOSClient.getClientID(sr.WorkstationID, sr.ApplicationSender) + " already logged on, why log on again (!?), give it an Error, in LogOn"); Monitor.Exit(fdcPosManager.fdcClientList); enteredmonitor = false; FDCPOSClient tempTCPClient = new FDCPOSClient(fdcPosManager, heartbeatCallback, this.fdcSocketLogger); tempTCPClient.sIPAddress = sIPAddress; tempTCPClient.FdcClientTcpHandler = fdcClientTcpHandler; this.FdcPosInterface.messages.LogOn(sr.WorkstationID, sr.ApplicationSender, sr.RequestIDNumber, iResponsePort, iUnsolicitedPort, (int)(FDCPOSLibrary.ErrorCode.ERRCD_NOPERM), Convert.ToString(FDCPOSLibrary.OverallResult.AuthentificationError), tempTCPClient); } } catch (Exception ex) { fdcSocketLogger.LogError("LogOn Exceptioned: " + ex); if (enteredmonitor) { Monitor.Exit(fdcPosManager.fdcClientList); } //FDCPOSManager.tracer.WriteLine(string.Format("LogOn Exception! " + ex.Message)); FDCPOSClient tempTCPClient = new FDCPOSClient(fdcPosManager, heartbeatCallback, this.fdcSocketLogger); tempTCPClient.sIPAddress = sIPAddress; tempTCPClient.FdcClientTcpHandler = fdcClientTcpHandler; this.FdcPosInterface.messages.LogOn(sr.WorkstationID, sr.ApplicationSender, sr.RequestIDNumber, iResponsePort, iUnsolicitedPort, (int)FDCPOSLibrary.ErrorCode.ERRCD_NOPERM, Convert.ToString(FDCPOSLibrary.OverallResult.AuthentificationError), tempTCPClient); return requestType; } } else { //FDCPOSManager.tracer.WriteLine(string.Format("LogOn extresult={0}, result={1} ", extresult, result)); FDCPOSClient tempTCPClient = new FDCPOSClient(fdcPosManager, null, this.fdcSocketLogger); tempTCPClient.sIPAddress = sIPAddress; tempTCPClient.FdcClientTcpHandler = fdcClientTcpHandler; this.FdcPosInterface.messages.LogOn(sr.WorkstationID, sr.ApplicationSender, sr.RequestIDNumber, iResponsePort, iUnsolicitedPort, (int)FDCPOSLibrary.ErrorCode.ERRCD_COMMERR, (result != OverallResult.Success) ? Convert.ToString(result) : Convert.ToString(extresult), tempTCPClient); return requestType; } } } } else if (requestType == "LogOff") { ServiceRequestLogOff sr = Deserialize(message, ref result); if (sr != null) { requestId = sr.RequestIDNumber; if (result == OverallResult.Success && extresult == OverallResult.Success) { FdcPosInterface.LogOffReq(sr.WorkstationID, sr.ApplicationSender, sr.RequestIDNumber); } } } else if (requestType == "VersionInfo") { ServiceRequestVersionInfo sr = Deserialize(message, ref result); if (sr != null) { requestId = sr.RequestIDNumber; if (result == OverallResult.Success && extresult == OverallResult.Success) { this.FdcPosInterface.VersionInfoReq(sr.WorkstationID, sr.ApplicationSender, sr.RequestIDNumber); } } } else if (requestType == "StartForecourt") { ServiceRequestStartForecourt sr = Deserialize(message, ref result); if (sr != null) { requestId = sr.RequestIDNumber; if (result == OverallResult.Success && extresult == OverallResult.Success) { this.FdcPosInterface.StartForecourtReq(sr.WorkstationID, sr.ApplicationSender, sr.RequestIDNumber); } } } else if (requestType == "StopForecourt") { ServiceRequestStopForecourt sr = Deserialize(message, ref result); if (sr != null) { requestId = sr.RequestIDNumber; if (result == OverallResult.Success && extresult == OverallResult.Success) { bool emergencyStop = (sr.POSdata[0].EmergencyStop != null && sr.POSdata[0].EmergencyStop.ToUpper() == "NO") ? emergencyStop = false : emergencyStop = true; this.FdcPosInterface.StopForecourtReq(sr.WorkstationID, sr.ApplicationSender, sr.RequestIDNumber, emergencyStop); } } } else if (requestType == "GetCurrentFuellingStatus") { ServiceRequestGetCurrentFuellingStatus sr = Deserialize(message, ref result); if (sr != null) { requestId = sr.RequestIDNumber; if (sr.POSdata.GetLength(0) == 0 || sr.POSdata[0].DeviceClass == null || sr.POSdata[0].DeviceClass.DeviceID == "") result = OverallResult.MissingMandatoryData; if (result == OverallResult.Success && extresult == OverallResult.Success) { this.FdcPosInterface.GetCurrentFuellingStatusReq(sr.WorkstationID, sr.ApplicationSender, sr.RequestIDNumber, (sr.POSdata[0].DeviceClass.DeviceID == "*") ? -1 : Convert.ToInt32(sr.POSdata[0].DeviceClass.DeviceID)); } } } else if (requestType == "GetFuelPointTotals") { ServiceRequestGetFuelPointTotals sr = Deserialize(message, ref result); if (sr != null) { requestId = sr.RequestIDNumber; if (sr.POSdata.GetLength(0) == 0 || sr.POSdata[0].DeviceClass == null || sr.POSdata[0].DeviceClass.DeviceID == "" || sr.POSdata[0].DeviceClass.NozzleNo == "") result = OverallResult.MissingMandatoryData; if (result == OverallResult.Success && extresult == OverallResult.Success) { this.FdcPosInterface.GetFuelPointTotalsReq(sr.WorkstationID, sr.ApplicationSender, sr.RequestIDNumber, (sr.POSdata[0].DeviceClass.DeviceID == "*") ? -1 : Convert.ToInt32(sr.POSdata[0].DeviceClass.DeviceID), (sr.POSdata[0].DeviceClass.NozzleNo == "*") ? -1 : Convert.ToInt32(sr.POSdata[0].DeviceClass.NozzleNo)); } } } else if (requestType == "GetTotals") { ServiceRequestGetTotals sr = Deserialize(message, ref result); if (sr != null) { requestId = sr.RequestIDNumber; if (sr.POSdata.GetLength(0) == 0 || sr.POSdata[0].DeviceClass == null || sr.POSdata[0].DeviceClass.DeviceID == "" || sr.POSdata[0].DeviceClass.NozzleNo == "") result = OverallResult.MissingMandatoryData; if (result == OverallResult.Success && extresult == OverallResult.Success) { this.FdcPosInterface.GetFuelPointTotalsReq(sr.WorkstationID, sr.ApplicationSender, sr.RequestIDNumber, (sr.POSdata[0].DeviceClass.DeviceID == "*") ? -1 : Convert.ToInt32(sr.POSdata[0].DeviceClass.DeviceID), (sr.POSdata[0].DeviceClass.NozzleNo == "*") ? -1 : Convert.ToInt32(sr.POSdata[0].DeviceClass.NozzleNo)); } } } else if (requestType == "GetDeviceState") { ServiceRequestGetDeviceState sr = Deserialize(message, ref result); if (sr != null) { requestId = sr.RequestIDNumber; if (sr.POSdata.GetLength(0) == 0 || sr.POSdata[0].DeviceClass == null || sr.POSdata[0].DeviceClass.DeviceID == "") result = OverallResult.MissingMandatoryData; if (result == OverallResult.Success && extresult == OverallResult.Success) { this.FdcPosInterface.GetDeviceStateReq(sr.WorkstationID, sr.ApplicationSender, sr.RequestIDNumber, sr.POSdata[0].DeviceClass.Type, (sr.POSdata[0].DeviceClass.DeviceID == "*") ? -1 : Convert.ToInt32(sr.POSdata[0].DeviceClass.DeviceID)); } } } else if (requestType == "GetFPState") { ServiceRequestGetFPState sr = Deserialize(message, ref result); if (sr != null) { requestId = sr.RequestIDNumber; if (sr.POSdata.GetLength(0) == 0 || sr.POSdata[0].DeviceClass == null || sr.POSdata[0].DeviceClass.DeviceID == "") result = OverallResult.MissingMandatoryData; if (result == OverallResult.Success && extresult == OverallResult.Success) { this.FdcPosInterface.GetDeviceStateReq(sr.WorkstationID, sr.ApplicationSender, sr.RequestIDNumber, sr.POSdata[0].DeviceClass.Type, (sr.POSdata[0].DeviceClass.DeviceID == "*") ? -1 : Convert.ToInt32(sr.POSdata[0].DeviceClass.DeviceID)); } } } else if (requestType == "TerminateFuelling") { ServiceRequestTerminateFuelling sr = Deserialize(message, ref result); if (sr != null) { requestId = sr.RequestIDNumber; if (sr.POSdata.GetLength(0) == 0 || sr.POSdata[0].DeviceClass == null || sr.POSdata[0].DeviceClass.DeviceID == "") result = OverallResult.MissingMandatoryData; if (result == OverallResult.Success && extresult == OverallResult.Success) { this.FdcPosInterface.TerminateFuellingReq(sr.WorkstationID, sr.ApplicationSender, sr.RequestIDNumber, (sr.POSdata[0].DeviceClass.DeviceID == "*") ? -1 : Convert.ToInt32(sr.POSdata[0].DeviceClass.DeviceID)); } } } else if (requestType == "AuthoriseFuelPoint") { ServiceRequestAuthoriseFuelPoint sr = Deserialize(message, ref result); if (sr != null) { requestId = sr.RequestIDNumber; if (sr.POSdata.GetLength(0) == 0) result = OverallResult.MissingMandatoryData; if (result == OverallResult.Success && extresult == OverallResult.Success) { string products = ""; int mode = -1; if (sr.POSdata[0].DeviceClass == null || sr.POSdata[0].DeviceClass.DeviceID == "") { //FDCPOSManager.tracer.WriteLine("'device' missing"); result = OverallResult.MissingMandatoryData; } else { //Decimal MaxTrxVolume = 0, MaxTrxAmount = 0; ////FDCPOSManager.tracer.WriteLine(string.Format("products.GetLength={0}", sr.POSdata[0].DeviceClass.products.GetLength(0))); //FDCPOSManager.tracer.WriteLine(string.Format("fuelmode={0}, mode={1}", sr.POSdata[0].DeviceClass.FuelMode, (sr.POSdata[0].DeviceClass.FuelMode != null) ? sr.POSdata[0].DeviceClass.FuelMode.ModeNo : null)); if (sr.POSdata[0].DeviceClass.FuelMode != null && sr.POSdata[0].DeviceClass.FuelMode.ModeNo != null && sr.POSdata[0].DeviceClass.FuelMode.ModeNo != "") mode = Convert.ToInt32(sr.POSdata[0].DeviceClass.FuelMode.ModeNo); if (FDCGlobal.ProtocolVersion == FDCVersion.V0003) { if (sr.POSdata[0].DeviceClass.Products != null && sr.POSdata[0].DeviceClass.Products.ProductNo != null && sr.POSdata[0].DeviceClass.Products.ProductNo.GetLength(0) > 0) { foreach (string product in sr.POSdata[0].DeviceClass.Products.ProductNo) { //FDCPOSManager.tracer.WriteLine(string.Format("ProductNo='{0}', products='{0}'", product, products)); ////FDCPOSManager.tracer.WriteLine(string.Format("ProductNo='{0}', products='{0}'", product.ProductNo, products)); products += product + ";"; } } } else if (FDCGlobal.ProtocolVersion == FDCVersion.V0005) { if (sr.POSdata[0].DeviceClass.ReleasedProducts != null && sr.POSdata[0].DeviceClass.ReleasedProducts.ProductNo != null && sr.POSdata[0].DeviceClass.ReleasedProducts.ProductNo.GetLength(0) > 0) { foreach (string product in sr.POSdata[0].DeviceClass.ReleasedProducts.ProductNo) { //FDCPOSManager.tracer.WriteLine(string.Format("ProductNo='{0}'", product)); products += product + ";"; } } } else { if (sr.POSdata[0].DeviceClass.ReleasedProducts != null && sr.POSdata[0].DeviceClass.ReleasedProducts.Product != null && sr.POSdata[0].DeviceClass.ReleasedProducts.Product.GetLength(0) > 0) { foreach (ProductElementClass product in sr.POSdata[0].DeviceClass.ReleasedProducts.Product) { //FDCPOSManager.tracer.WriteLine(string.Format("ProductNo='{0}'", product.ProductNo, products)); products += product.ProductNo + ";"; } } } this.FdcPosInterface.AuthoriseFuelPointReq(sr.WorkstationID, sr.ApplicationSender, sr.RequestIDNumber, (sr.POSdata[0].DeviceClass.ReleaseToken != null) ? sr.POSdata[0].DeviceClass.ReleaseToken : "", (sr.POSdata[0].DeviceClass.FuellingType == "") ? 0 : Convert.ToInt32(sr.POSdata[0].DeviceClass.FuellingType), (sr.POSdata[0].DeviceClass.DeviceID == "*") ? -1 : Convert.ToInt32(sr.POSdata[0].DeviceClass.DeviceID), (sr.POSdata[0].DeviceClass.ReservingDeviceId == "") ? 0 : Convert.ToInt32(sr.POSdata[0].DeviceClass.ReservingDeviceId), FDCConvert.ToDecimal(sr.POSdata[0].DeviceClass.MaxTrxAmount), FDCConvert.ToDecimal(sr.POSdata[0].DeviceClass.MaxTrxVolume), products, mode, (sr.POSdata[0].DeviceClass.LockFuelSaleTrx != null && sr.POSdata[0].DeviceClass.LockFuelSaleTrx.ToUpper() == "TRUE") ? true : false, sr.POSdata[0].DeviceClass.PayType); } } } } else if (requestType == "ChangeFuelMode") { ServiceRequestChangeFuelMode sr = Deserialize(message, ref result); string mode = ""; if (sr != null) { requestId = sr.RequestIDNumber; if (sr.POSdata.GetLength(0) == 0 || sr.POSdata[0].DeviceClass == null) result = OverallResult.MissingMandatoryData; if (result == OverallResult.Success && extresult == OverallResult.Success) { if (sr.POSdata[0].DeviceClass.Length > 1) { foreach (ServiceRequestDeviceClassChangeFuelMode deviceClass in sr.POSdata[0].DeviceClass) { mode = ""; if (deviceClass != null) { if (FDCGlobal.ProtocolVersion == FDCVersion.V0003) { if (deviceClass.ModeNo != null) mode = deviceClass.ModeNo; } else { if (deviceClass.FuelMode != null && deviceClass.FuelMode.ModeNo != null) mode = deviceClass.FuelMode.ModeNo; } //FDCPOSManager.tracer.WriteLine(string.Format("DeviceID={0}, ModeNo={1}", deviceClass.DeviceID, mode)); if (mode != "") this.FdcPosInterface.ChangeFuelModeAddReq(sr.WorkstationID, sr.ApplicationSender, sr.RequestIDNumber, deviceClass.Type, (deviceClass.DeviceID == "*") ? -1 : Convert.ToInt32(deviceClass.DeviceID), Convert.ToInt32(mode)); } } this.FdcPosInterface.ChangeFuelModeEndReq(sr.WorkstationID, sr.ApplicationSender, sr.RequestIDNumber); } else { if (FDCGlobal.ProtocolVersion == FDCVersion.V0003) { if (sr.POSdata[0].DeviceClass[0].ModeNo != null) mode = sr.POSdata[0].DeviceClass[0].ModeNo; } else { if (sr.POSdata[0].DeviceClass[0].FuelMode != null && sr.POSdata[0].DeviceClass[0].FuelMode.ModeNo != null) mode = sr.POSdata[0].DeviceClass[0].FuelMode.ModeNo; } if (mode == "") result = OverallResult.MissingMandatoryData; this.FdcPosInterface.ChangeFuelModeReq(sr.WorkstationID, sr.ApplicationSender, sr.RequestIDNumber, sr.POSdata[0].DeviceClass[0].Type, (sr.POSdata[0].DeviceClass[0].DeviceID == "*") ? -1 : Convert.ToInt32(sr.POSdata[0].DeviceClass[0].DeviceID), Convert.ToInt32(mode)); } } } } else if (requestType == "ChangeFuelPrice") { ServiceRequestChangeFuelPrice sr = Deserialize(message, ref result); if (sr != null) { requestId = sr.RequestIDNumber; if (sr.POSdata.GetLength(0) == 0 || sr.POSdata[0].Product == null) result = OverallResult.MissingMandatoryData; //FDCPOSManager.tracer.WriteLineIf(FDCPOSManager.tracer.CheckTraceLevel(3), string.Format("result=" + result)); if (result == OverallResult.Success && extresult == OverallResult.Success) { string overallRes = OverallResult.Success.ToString(); if (sr.POSdata[0].Product != null) { string formattedString = ""; //double oldPrice; string sModeNo = "", sPriceNew = "", effectiveDateTime = ""; foreach (ServiceRequestProductChangeFuelPrice product in sr.POSdata[0].Product) { if (product == null) continue; sModeNo = ""; sPriceNew = ""; effectiveDateTime = ""; if (FDCGlobal.ProtocolVersion == FDCVersion.V0003) { sModeNo = (product.ModeNo != null) ? product.ModeNo : ""; sPriceNew = (product.PriceNew != null) ? product.PriceNew : ""; effectiveDateTime = (product.EffectiveDateTime != null) ? product.EffectiveDateTime : ""; string localresult = OverallResult.Success.ToString(); if (product.ProductNo != null && product.ProductNo != "" && sPriceNew != "" && sModeNo != "") { //localresult = this.FdcPosInterface.ChangeFuelPriceAddReq(sr.WorkstationID, sr.ApplicationSender, sr.RequestIDNumber, Convert.ToInt32(product.ProductNo), FDCConvert.ToDecimal(product.PriceNew), Convert.ToInt32(product.ModeNo), out oldPrice); formattedString = formattedString + product.ProductNo + ";" + sPriceNew + ";" + sModeNo + ";" + effectiveDateTime + "!"; } else { localresult = OverallResult.Failure.ToString(); } if (localresult != OverallResult.Success.ToString() && overallRes == OverallResult.Success.ToString()) overallRes = OverallResult.Failure.ToString(); else if (localresult == OverallResult.Success.ToString() && overallRes == OverallResult.Failure.ToString()) overallRes = OverallResult.PartialFailure.ToString(); //FDCPOSManager.tracer.WriteLine(string.Format("localresult={0}, overallRes={1}", localresult, overallRes)); //this.FdcPosInterface.messages.ChangeFuelPriceAdd(sr.WorkstationID, sr.ApplicationSender, sr.RequestIDNumber, Convert.ToInt32(product.ProductNo), FDCConvert.ToDecimal(product.PriceNew), Convert.ToInt32(product.ModeNo), Convert.ToDecimal(oldPrice)); } else { if (product.FuelMode != null) { /* the Schema said the FuleMode only can contain a single fule price change item!!!!!!!!!*/ foreach (ServiceRequestFuelModeChangeFuelPrice fuelMode in product.FuelMode) { if (fuelMode == null) continue; sModeNo = (fuelMode.ModeNo != null) ? fuelMode.ModeNo : ""; sPriceNew = (fuelMode.PriceNew != null) ? fuelMode.PriceNew : ""; effectiveDateTime = (fuelMode.EffectiveDateTime != null) ? fuelMode.EffectiveDateTime : ""; string localresult = OverallResult.Success.ToString(); if (product.ProductNo != null && product.ProductNo != "" && sPriceNew != "" && sModeNo != "") { //localresult = this.FdcPosInterface.ChangeFuelPriceAddReq(sr.WorkstationID, sr.ApplicationSender, sr.RequestIDNumber, Convert.ToInt32(product.ProductNo), FDCConvert.ToDecimal(product.PriceNew), Convert.ToInt32(product.ModeNo), out oldPrice); formattedString = formattedString + product.ProductNo + ";" + sPriceNew + ";" + sModeNo + ";" + effectiveDateTime + "!"; } else { localresult = OverallResult.Failure.ToString(); } if (localresult != OverallResult.Success.ToString() && overallRes == OverallResult.Success.ToString()) overallRes = OverallResult.Failure.ToString(); else if (localresult == OverallResult.Success.ToString() && overallRes == OverallResult.Failure.ToString()) overallRes = OverallResult.PartialFailure.ToString(); //FDCPOSManager.tracer.WriteLine(string.Format("localresult={0}, overallRes={1}, product.ProductNo={2}, fuelMode.PriceNew={3}, fuelMode.ModeNo={4}", localresult, overallRes, product.ProductNo, fuelMode.PriceNew, fuelMode.ModeNo)); //this.FdcPosInterface.messages.ChangeFuelPriceAdd(sr.WorkstationID, sr.ApplicationSender, sr.RequestIDNumber, Convert.ToInt32(product.ProductNo), FDCConvert.ToDecimal(product.PriceNew), Convert.ToInt32(product.ModeNo), Convert.ToDecimal(oldPrice)); } } } } //this.FdcPosInterface.ChangeFuelPriceEndReq(sr.WorkstationID, sr.ApplicationSender, sr.RequestIDNumber); string outresult = this.FdcPosInterface.ChangeFuelPriceInStringReq(sr.WorkstationID, sr.ApplicationSender, sr.RequestIDNumber, formattedString); if (string.IsNullOrEmpty(outresult)) overallRes = OverallResult.Failure.ToString(); string item, sProd, sPriceOld; while (outresult != "") { if (outresult.IndexOf('!') >= 0) { item = outresult.Substring(0, outresult.IndexOf('!')); sProd = item.Substring(0, item.IndexOf(';')); item = item.Substring(item.IndexOf(';') + 1); sPriceNew = item.Substring(0, item.IndexOf(';')); item = item.Substring(item.IndexOf(';') + 1); sModeNo = item.Substring(0, item.IndexOf(';')); item = item.Substring(item.IndexOf(';') + 1); sPriceOld = item.Substring(0, item.IndexOf(';')); effectiveDateTime = item.Substring(item.IndexOf(';') + 1); outresult = outresult.Substring(outresult.IndexOf('!') + 1); // pricenew and priceold always is formatted with '.' as decimal separator sPriceNew = sPriceNew.Replace(".", FDCConvert.DecimalSeparator); sPriceOld = sPriceOld.Replace(".", FDCConvert.DecimalSeparator); Decimal pricenew = FDCConvert.ToDecimal(sPriceNew), priceold = FDCConvert.ToDecimal(sPriceOld); //FDCPOSManager.tracer.WriteLine(string.Format("prod={0}, mode={1}, newprice={2}, effectiveDateTime={3}, oldprice={4}", sProd, sModeNo, sPriceNew, effectiveDateTime, sPriceOld)); this.FdcPosInterface.messages.ChangeFuelPriceAdd(sr.WorkstationID, sr.ApplicationSender, sr.RequestIDNumber, Convert.ToInt32(sProd), pricenew, Convert.ToInt32(sModeNo), effectiveDateTime, priceold); } } } else overallRes = OverallResult.MissingMandatoryData.ToString(); this.FdcPosInterface.messages.ChangeFuelPriceSend(sr.WorkstationID, sr.ApplicationSender, sr.RequestIDNumber, (int)ErrorCode.ERRCD_OK, overallRes); } } } else if (requestType == "LockFuelSaleTrx") { ServiceRequestLockFuelSaleTrx sr = Deserialize(message, ref result); if (sr != null) { string transactionNo = (sr.POSdata[0].DeviceClass.TransactionNo != null) ? sr.POSdata[0].DeviceClass.TransactionNo : ((sr.POSdata[0].DeviceClass.TransactionSeqNo != null) ? sr.POSdata[0].DeviceClass.TransactionSeqNo : ""); string releaseToken = (sr.POSdata[0].DeviceClass.ReleaseToken != null) ? sr.POSdata[0].DeviceClass.ReleaseToken : ""; requestId = sr.RequestIDNumber; if (sr.POSdata.GetLength(0) == 0 || sr.POSdata[0].DeviceClass == null || sr.POSdata[0].DeviceClass.DeviceID == "" || transactionNo == "") result = OverallResult.MissingMandatoryData; if (result == OverallResult.Success && extresult == OverallResult.Success) { this.FdcPosInterface.LockFuelSaleTrxReq(sr.WorkstationID, sr.ApplicationSender, sr.RequestIDNumber, (sr.POSdata[0].DeviceClass.DeviceID == "*") ? -1 : Convert.ToInt32(sr.POSdata[0].DeviceClass.DeviceID), Convert.ToInt32(transactionNo), releaseToken); } } } else if (requestType == "UnlockFuelSaleTrx") { ServiceRequestUnlockFuelSaleTrx sr = Deserialize(message, ref result); if (sr != null) { string transactionNo = (sr.POSdata[0].DeviceClass.TransactionNo != null) ? sr.POSdata[0].DeviceClass.TransactionNo : ((sr.POSdata[0].DeviceClass.TransactionSeqNo != null) ? sr.POSdata[0].DeviceClass.TransactionSeqNo : ""); string releaseToken = (sr.POSdata[0].DeviceClass.ReleaseToken != null) ? sr.POSdata[0].DeviceClass.ReleaseToken : ""; requestId = sr.RequestIDNumber; if (sr.POSdata.GetLength(0) == 0 || sr.POSdata[0].DeviceClass == null || sr.POSdata[0].DeviceClass.DeviceID == "" || transactionNo == "") result = OverallResult.MissingMandatoryData; if (result == OverallResult.Success && extresult == OverallResult.Success) { this.FdcPosInterface.UnlockFuelSaleTrxReq(sr.WorkstationID, sr.ApplicationSender, sr.RequestIDNumber, (sr.POSdata[0].DeviceClass.DeviceID == "*") ? -1 : Convert.ToInt32(sr.POSdata[0].DeviceClass.DeviceID), Convert.ToInt32(transactionNo), releaseToken); } } } else if (requestType == "ClearFuelSaleTrx") { ServiceRequestClearFuelSaleTrx sr = Deserialize(message, ref result); if (sr != null) { string transactionNo = (sr.POSdata[0].DeviceClass.TransactionNo != null) ? sr.POSdata[0].DeviceClass.TransactionNo : ((sr.POSdata[0].DeviceClass.TransactionSeqNo != null) ? sr.POSdata[0].DeviceClass.TransactionSeqNo : ""); string releaseToken = (sr.POSdata[0].DeviceClass.ReleaseToken != null) ? sr.POSdata[0].DeviceClass.ReleaseToken : ""; requestId = sr.RequestIDNumber; if (sr.POSdata.GetLength(0) == 0 || sr.POSdata[0].DeviceClass == null || sr.POSdata[0].DeviceClass.DeviceID == "" || transactionNo == "") result = OverallResult.MissingMandatoryData; if (result == OverallResult.Success && extresult == OverallResult.Success) { this.FdcPosInterface.ClearFuelSaleTrxReq(sr.WorkstationID, sr.ApplicationSender, sr.RequestIDNumber, (sr.POSdata[0].DeviceClass.DeviceID == "*") ? -1 : Convert.ToInt32(sr.POSdata[0].DeviceClass.DeviceID), Convert.ToInt32(transactionNo), releaseToken); } } } else if (requestType == "GetAvailableFuelSaleTrxs") { ServiceRequestGetAvailableFuelSaleTrxs sr = Deserialize(message, ref result); if (sr != null) { requestId = sr.RequestIDNumber; if (sr.POSdata.GetLength(0) == 0 || sr.POSdata[0].DeviceClass == null || sr.POSdata[0].DeviceClass.DeviceID == "") result = OverallResult.MissingMandatoryData; if (result == OverallResult.Success && extresult == OverallResult.Success) { this.FdcPosInterface.GetAvailableFuelSaleTrxsReq(sr.WorkstationID, sr.ApplicationSender, sr.RequestIDNumber, (sr.POSdata[0].DeviceClass.DeviceID == "*") ? -1 : Convert.ToInt32(sr.POSdata[0].DeviceClass.DeviceID)); } } } else if (requestType == "GetFuelSaleTrxDetails") { ServiceRequestGetFuelSaleTrxDetails sr = Deserialize(message, ref result); if (sr != null) { string transactionNo = (sr.POSdata[0].DeviceClass.TransactionNo != null) ? sr.POSdata[0].DeviceClass.TransactionNo : ((sr.POSdata[0].DeviceClass.TransactionSeqNo != null) ? sr.POSdata[0].DeviceClass.TransactionSeqNo : ""); string releaseToken = (sr.POSdata[0].DeviceClass.ReleaseToken != null) ? sr.POSdata[0].DeviceClass.ReleaseToken : ""; requestId = sr.RequestIDNumber; if (sr.POSdata.GetLength(0) == 0 || sr.POSdata[0].DeviceClass == null || sr.POSdata[0].DeviceClass.DeviceID == "" || (transactionNo == "" && releaseToken == "")) result = OverallResult.MissingMandatoryData; if (result == OverallResult.Success && extresult == OverallResult.Success) { this.FdcPosInterface.GetFuelSaleTrxDetailsReq(sr.WorkstationID, sr.ApplicationSender, sr.RequestIDNumber, (sr.POSdata[0].DeviceClass.DeviceID == "*") ? -1 : Convert.ToInt32(sr.POSdata[0].DeviceClass.DeviceID), (transactionNo == "*") ? -1 : Convert.ToInt32(transactionNo), releaseToken); } } } else if (requestType == "GetProductTable") { ServiceRequestGetProductTable sr = Deserialize(message, ref result); if (sr != null) { requestId = sr.RequestIDNumber; if (result == OverallResult.Success && extresult == OverallResult.Success) { this.FdcPosInterface.GetProductTableReq(sr.WorkstationID, sr.ApplicationSender, sr.RequestIDNumber); } } } else if (requestType == "GetModeTable") { ServiceRequestGetModeTable sr = Deserialize(message, ref result); if (sr != null) { requestId = sr.RequestIDNumber; if (result == OverallResult.Success && extresult == OverallResult.Success) { this.FdcPosInterface.GetModeTableReq(sr.WorkstationID, sr.ApplicationSender, sr.RequestIDNumber); } } } else if (requestType == "GetFuelMode") { ServiceRequestGetFuelMode sr = Deserialize(message, ref result); if (sr != null) { requestId = sr.RequestIDNumber; if (sr.POSdata.GetLength(0) == 0 || sr.POSdata[0].DeviceClass == null || sr.POSdata[0].DeviceClass.DeviceID == "") result = OverallResult.MissingMandatoryData; if (result == OverallResult.Success && extresult == OverallResult.Success) { this.FdcPosInterface.GetFuelModeReq(sr.WorkstationID, sr.ApplicationSender, sr.RequestIDNumber, sr.POSdata[0].DeviceClass.Type, (sr.POSdata[0].DeviceClass.DeviceID == "*") ? -1 : Convert.ToInt32(sr.POSdata[0].DeviceClass.DeviceID)); } } } else if (requestType == "GetConfiguration") { Messages.bWholeConfiguration = true; ServiceRequestGetConfiguration sr = Deserialize(message, ref result); if (sr != null) { requestId = sr.RequestIDNumber; if (result == OverallResult.Success && extresult == OverallResult.Success) { this.FdcPosInterface.GetConfigurationReq(sr.WorkstationID, sr.ApplicationSender, sr.RequestIDNumber, ""); } } } else if (requestType == "GetDSPConfiguration") { Messages.bWholeConfiguration = false; ServiceRequestGetDSPConfiguration sr = Deserialize(message, ref result); if (sr != null) { requestId = sr.RequestIDNumber; if (result == OverallResult.Success && extresult == OverallResult.Success) { this.FdcPosInterface.GetConfigurationReq(sr.WorkstationID, sr.ApplicationSender, sr.RequestIDNumber, DeviceType.DT_FuelDispenser); } } } else if (requestType == "GetTLGConfiguration") { Messages.bWholeConfiguration = false; ServiceRequestGetTLGConfiguration sr = Deserialize(message, ref result); if (sr != null) { requestId = sr.RequestIDNumber; if (result == OverallResult.Success && extresult == OverallResult.Success) { this.FdcPosInterface.GetConfigurationReq(sr.WorkstationID, sr.ApplicationSender, sr.RequestIDNumber, DeviceType.DT_TankLevelGauge); } } } else if (requestType == "GetPPConfiguration") { Messages.bWholeConfiguration = false; ServiceRequestGetPPConfiguration sr = Deserialize(message, ref result); if (sr != null) { requestId = sr.RequestIDNumber; if (result == OverallResult.Success && extresult == OverallResult.Success) { this.FdcPosInterface.GetConfigurationReq(sr.WorkstationID, sr.ApplicationSender, sr.RequestIDNumber, DeviceType.DT_PricePole); } } } else if (requestType == "SetConfiguration") { ServiceRequestSetConfiguration sr = Deserialize(message, ref result); if (sr != null) { requestId = sr.RequestIDNumber; if (result == OverallResult.Success && extresult == OverallResult.Success) { this.FdcPosInterface.SetConfigurationReq(sr); } } } else if (requestType == "LockNozzle") { ServiceRequestLockNozzle sr = Deserialize(message, ref result); if (sr != null) { requestId = sr.RequestIDNumber; if (sr.POSdata.GetLength(0) == 0 || sr.POSdata[0].DeviceClass == null || sr.POSdata[0].DeviceClass.DeviceID == "" || sr.POSdata[0].DeviceClass.NozzleNo == "") result = OverallResult.MissingMandatoryData; if (result == OverallResult.Success && extresult == OverallResult.Success) { this.FdcPosInterface.LockNozzleReq(sr.WorkstationID, sr.ApplicationSender, sr.RequestIDNumber, Convert.ToInt32(sr.POSdata[0].DeviceClass.DeviceID), (sr.POSdata[0].DeviceClass.NozzleNo == "*") ? -1 : Convert.ToInt32(sr.POSdata[0].DeviceClass.NozzleNo)); } } } else if (requestType == "UnlockNozzle") { ServiceRequestUnlockNozzle sr = Deserialize(message, ref result); if (sr != null) { requestId = sr.RequestIDNumber; if (sr.POSdata.GetLength(0) == 0 || sr.POSdata[0].DeviceClass == null || sr.POSdata[0].DeviceClass.DeviceID == "" || sr.POSdata[0].DeviceClass.NozzleNo == "") result = OverallResult.MissingMandatoryData; if (result == OverallResult.Success && extresult == OverallResult.Success) { this.FdcPosInterface.UnlockNozzleReq(sr.WorkstationID, sr.ApplicationSender, sr.RequestIDNumber, Convert.ToInt32(sr.POSdata[0].DeviceClass.DeviceID), (sr.POSdata[0].DeviceClass.NozzleNo == "*") ? -1 : Convert.ToInt32(sr.POSdata[0].DeviceClass.NozzleNo)); } } } else if (requestType == "GetCountrySettings") { ServiceRequestGetCountrySettings sr = Deserialize(message, ref result); if (sr != null) { requestId = sr.RequestIDNumber; if (result == OverallResult.Success && extresult == OverallResult.Success) { this.FdcPosInterface.GetCountrySettingsReq(sr.WorkstationID, sr.ApplicationSender, sr.RequestIDNumber); } } } else if (requestType == "GetDSPLimits") { ServiceRequestGetDSPLimits sr = Deserialize(message, ref result); if (sr != null) { requestId = sr.RequestIDNumber; if (sr.POSdata.GetLength(0) == 0 || sr.POSdata[0].DeviceClass == null || sr.POSdata[0].DeviceClass.DeviceID == "") result = OverallResult.MissingMandatoryData; if (result == OverallResult.Success && extresult == OverallResult.Success) { this.FdcPosInterface.GetDSPLimitsReq(sr.WorkstationID, sr.ApplicationSender, sr.RequestIDNumber, (sr.POSdata[0].DeviceClass.DeviceID == "*") ? -1 : Convert.ToInt32(sr.POSdata[0].DeviceClass.DeviceID)); } } } else if (requestType == "ChangeDSPLimits") { ServiceRequestChangeDSPLimits sr = Deserialize(message, ref result); if (sr != null) { requestId = sr.RequestIDNumber; if (sr.POSdata.GetLength(0) == 0 || sr.POSdata[0].DeviceClass == null || sr.POSdata[0].DeviceClass.DeviceID == "" || (FDCGlobal.ProtocolVersion > FDCVersion.V0003 && (sr.POSdata[0].DeviceClass.Product == null || sr.POSdata[0].DeviceClass.Product.FuelMode == null))) result = OverallResult.MissingMandatoryData; if (result == OverallResult.Success && extresult == OverallResult.Success) { int mode = 0, productNo = 0; Decimal maxTrxAmount = -1, maxTrxVolume = -1; if (FDCGlobal.ProtocolVersion == FDCVersion.V0003) { productNo = Convert.ToInt32(sr.POSdata[0].DeviceClass.ProductNo); mode = Convert.ToInt32(sr.POSdata[0].DeviceClass.ModeNo); maxTrxAmount = FDCConvert.ToDecimal(sr.POSdata[0].DeviceClass.MaxTrxAmount); maxTrxVolume = FDCConvert.ToDecimal(sr.POSdata[0].DeviceClass.MaxTrxVolume); } else { productNo = Convert.ToInt32(sr.POSdata[0].DeviceClass.Product.ProductNo); mode = Convert.ToInt32(sr.POSdata[0].DeviceClass.Product.FuelMode.ModeNo); maxTrxAmount = FDCConvert.ToDecimal(sr.POSdata[0].DeviceClass.Product.FuelMode.MaxTrxAmount); maxTrxVolume = FDCConvert.ToDecimal(sr.POSdata[0].DeviceClass.Product.FuelMode.MaxTrxVolume); } this.FdcPosInterface.ChangeDSPLimitsReq(sr.WorkstationID, sr.ApplicationSender, sr.RequestIDNumber, (sr.POSdata[0].DeviceClass.DeviceID == "*") ? -1 : Convert.ToInt32(sr.POSdata[0].DeviceClass.DeviceID), productNo, mode, maxTrxAmount, maxTrxVolume); } } } else if (requestType == "SuspendFuelling") { ServiceRequestSuspendFuelling sr = Deserialize(message, ref result); if (sr != null) { requestId = sr.RequestIDNumber; if (sr.POSdata.GetLength(0) == 0 || sr.POSdata[0].DeviceClass == null || sr.POSdata[0].DeviceClass.DeviceID == "") result = OverallResult.MissingMandatoryData; if (result == OverallResult.Success && extresult == OverallResult.Success) { this.FdcPosInterface.SuspendFuellingReq(sr.WorkstationID, sr.ApplicationSender, sr.RequestIDNumber, (sr.POSdata[0].DeviceClass.DeviceID == "*") ? -1 : Convert.ToInt32(sr.POSdata[0].DeviceClass.DeviceID)); } } } else if (requestType == "ResumeFuelling") { ServiceRequestResumeFuelling sr = Deserialize(message, ref result); if (sr != null) { requestId = sr.RequestIDNumber; if (sr.POSdata.GetLength(0) == 0 || sr.POSdata[0].DeviceClass == null || sr.POSdata[0].DeviceClass.DeviceID == "") result = OverallResult.MissingMandatoryData; if (result == OverallResult.Success && extresult == OverallResult.Success) { this.FdcPosInterface.ResumeFuellingReq(sr.WorkstationID, sr.ApplicationSender, sr.RequestIDNumber, (sr.POSdata[0].DeviceClass.DeviceID == "*") ? -1 : Convert.ToInt32(sr.POSdata[0].DeviceClass.DeviceID)); } } } else if (requestType == "LockTank") { ServiceRequestLockTank sr = Deserialize(message, ref result); if (sr != null) { requestId = sr.RequestIDNumber; if (sr.POSdata.GetLength(0) == 0 || sr.POSdata[0].DeviceClass == null || sr.POSdata[0].DeviceClass.DeviceID == "" || sr.POSdata[0].DeviceClass.TankNo == "") result = OverallResult.MissingMandatoryData; if (result == OverallResult.Success && extresult == OverallResult.Success) { this.FdcPosInterface.LockTankReq(sr.WorkstationID, sr.ApplicationSender, sr.RequestIDNumber, Convert.ToInt32(sr.POSdata[0].DeviceClass.DeviceID), Convert.ToInt32(sr.POSdata[0].DeviceClass.TankNo)); } } } else if (requestType == "UnlockTank") { ServiceRequestUnlockTank sr = Deserialize(message, ref result); if (sr != null) { requestId = sr.RequestIDNumber; if (sr.POSdata.GetLength(0) == 0 || sr.POSdata[0].DeviceClass == null || sr.POSdata[0].DeviceClass.DeviceID == "" || sr.POSdata[0].DeviceClass.TankNo == "") result = OverallResult.MissingMandatoryData; if (result == OverallResult.Success && extresult == OverallResult.Success) { this.FdcPosInterface.UnlockTankReq(sr.WorkstationID, sr.ApplicationSender, sr.RequestIDNumber, Convert.ToInt32(sr.POSdata[0].DeviceClass.DeviceID), Convert.ToInt32(sr.POSdata[0].DeviceClass.TankNo)); } } } else if (requestType == "GetTankData") { ServiceRequestGetTankData sr = Deserialize(message, ref result); if (sr != null) { requestId = sr.RequestIDNumber; if (sr.POSdata.GetLength(0) == 0 || sr.POSdata[0].DeviceClass == null || sr.POSdata[0].DeviceClass.DeviceID == "" || sr.POSdata[0].DeviceClass.TankNo == "") result = OverallResult.MissingMandatoryData; if (result == OverallResult.Success && extresult == OverallResult.Success) { this.FdcPosInterface.GetTankDataReq(sr.WorkstationID, sr.ApplicationSender, sr.RequestIDNumber, (sr.POSdata[0].DeviceClass.DeviceID == "*") ? -1 : Convert.ToInt32(sr.POSdata[0].DeviceClass.DeviceID), (sr.POSdata[0].DeviceClass.TankNo == "*") ? -1 : Convert.ToInt32(sr.POSdata[0].DeviceClass.TankNo)); } } } else if (requestType == "ReserveFuelPoint") { ServiceRequestReserveFuelPoint sr = Deserialize(message, ref result); if (sr != null) { requestId = sr.RequestIDNumber; if (sr.POSdata.GetLength(0) == 0 || sr.POSdata[0].DeviceClass == null || sr.POSdata[0].DeviceClass.DeviceID == "") result = OverallResult.MissingMandatoryData; if (result == OverallResult.Success && extresult == OverallResult.Success) { this.FdcPosInterface.ReserveFuelPointReq(sr.WorkstationID, sr.ApplicationSender, sr.RequestIDNumber, Convert.ToInt32(sr.POSdata[0].DeviceClass.DeviceID)); } } } else if (requestType == "FreeFuelPoint") { ServiceRequestFreeFuelPoint sr = Deserialize(message, ref result); if (sr != null) { requestId = sr.RequestIDNumber; if (sr.POSdata.GetLength(0) == 0 || sr.POSdata[0].DeviceClass == null || sr.POSdata[0].DeviceClass.DeviceID == "") result = OverallResult.MissingMandatoryData; if (result == OverallResult.Success && extresult == OverallResult.Success) { this.FdcPosInterface.FreeFuelPointReq(sr.WorkstationID, sr.ApplicationSender, sr.RequestIDNumber, Convert.ToInt32(sr.POSdata[0].DeviceClass.DeviceID)); } } } else if (requestType == "StartFuelPointTest") { ServiceRequestStartFuelPointTest sr = Deserialize(message, ref result); if (sr != null) { requestId = sr.RequestIDNumber; if (sr.POSdata.GetLength(0) == 0 || sr.POSdata[0].DeviceClass == null || sr.POSdata[0].DeviceClass.DeviceID == "") result = OverallResult.MissingMandatoryData; if (result == OverallResult.Success && extresult == OverallResult.Success) { this.FdcPosInterface.StartFuelPointTestReq(sr.WorkstationID, sr.ApplicationSender, sr.RequestIDNumber, Convert.ToInt32(sr.POSdata[0].DeviceClass.DeviceID)); } } } else if (requestType == "EndFuelPointTest") { ServiceRequestEndFuelPointTest sr = Deserialize(message, ref result); if (sr != null) { requestId = sr.RequestIDNumber; if (sr.POSdata.GetLength(0) == 0 || sr.POSdata[0].DeviceClass == null || sr.POSdata[0].DeviceClass.DeviceID == "") result = OverallResult.MissingMandatoryData; if (result == OverallResult.Success && extresult == OverallResult.Success) { this.FdcPosInterface.EndFuelPointTestReq(sr.WorkstationID, sr.ApplicationSender, sr.RequestIDNumber, Convert.ToInt32(sr.POSdata[0].DeviceClass.DeviceID)); } } } else if (requestType == "SetDeviceAlarm") { ServiceRequestSetDeviceAlarm sr = Deserialize(message, ref result); if (sr != null) { requestId = sr.RequestIDNumber; if (sr.POSdata.GetLength(0) == 0 || sr.POSdata[0].DeviceClass == null || sr.POSdata[0].DeviceClass.DeviceID == "") result = OverallResult.MissingMandatoryData; if (result == OverallResult.Success && extresult == OverallResult.Success) { this.FdcPosInterface.SetDeviceAlarmReq(sr.WorkstationID, sr.ApplicationSender, sr.RequestIDNumber, sr.POSdata[0].DeviceClass.Type, Convert.ToInt32(sr.POSdata[0].DeviceClass.DeviceID), Convert.ToInt32(sr.POSdata[0].DeviceClass.AlarmMsg[0].Number), sr.POSdata[0].DeviceClass.AlarmMsg[0].Text); } } } else if (requestType == "OpenFuelPoint") { ServiceRequestOpenFuelPoint sr = Deserialize(message, ref result); if (sr != null) { requestId = sr.RequestIDNumber; if (sr.POSdata.GetLength(0) == 0 || sr.POSdata[0].DeviceClass == null || sr.POSdata[0].DeviceClass.DeviceID == "") result = OverallResult.MissingMandatoryData; if (result == OverallResult.Success && extresult == OverallResult.Success) { this.FdcPosInterface.OpenFuelPointReq(sr.WorkstationID, sr.ApplicationSender, sr.RequestIDNumber, (sr.POSdata[0].DeviceClass.DeviceID == "*") ? -1 : Convert.ToInt32(sr.POSdata[0].DeviceClass.DeviceID)); } } } else if (requestType == "OpenDevice") { ServiceRequestOpenDevice sr = Deserialize(message, ref result); if (sr != null) { requestId = sr.RequestIDNumber; if (sr.POSdata.GetLength(0) == 0 || sr.POSdata[0].DeviceClass == null || sr.POSdata[0].DeviceClass.DeviceID == "") result = OverallResult.MissingMandatoryData; if (result == OverallResult.Success && extresult == OverallResult.Success) { this.FdcPosInterface.OpenFuelPointReq(sr.WorkstationID, sr.ApplicationSender, sr.RequestIDNumber, (sr.POSdata[0].DeviceClass.DeviceID == "*") ? -1 : Convert.ToInt32(sr.POSdata[0].DeviceClass.DeviceID)); } } } else if (requestType == "CloseFuelPoint") { ServiceRequestCloseFuelPoint sr = Deserialize(message, ref result); if (sr != null) { requestId = sr.RequestIDNumber; if (sr.POSdata.GetLength(0) == 0 || sr.POSdata[0].DeviceClass == null || sr.POSdata[0].DeviceClass.DeviceID == "") result = OverallResult.MissingMandatoryData; if (result == OverallResult.Success && extresult == OverallResult.Success) { this.FdcPosInterface.CloseFuelPointReq(sr.WorkstationID, sr.ApplicationSender, sr.RequestIDNumber, (sr.POSdata[0].DeviceClass.DeviceID == "*") ? -1 : Convert.ToInt32(sr.POSdata[0].DeviceClass.DeviceID)); } } } else if (requestType == "CloseDevice") { ServiceRequestCloseDevice sr = Deserialize(message, ref result); if (sr != null) { requestId = sr.RequestIDNumber; if (sr.POSdata.GetLength(0) == 0 || sr.POSdata[0].DeviceClass == null || sr.POSdata[0].DeviceClass.DeviceID == "") result = OverallResult.MissingMandatoryData; if (result == OverallResult.Success && extresult == OverallResult.Success) { this.FdcPosInterface.CloseFuelPointReq(sr.WorkstationID, sr.ApplicationSender, sr.RequestIDNumber, (sr.POSdata[0].DeviceClass.DeviceID == "*") ? -1 : Convert.ToInt32(sr.POSdata[0].DeviceClass.DeviceID)); } } } else if (requestType == "OPTAdd") { ServiceRequestOPTAdd sr = Deserialize(message, ref result); if (sr != null) { requestId = sr.RequestIDNumber; if (sr.POSdata.GetLength(0) == 0 || sr.POSdata[0].DeviceClass == null || sr.POSdata[0].DeviceClass.DeviceID == "") result = OverallResult.MissingMandatoryData; if (result == OverallResult.Success && extresult == OverallResult.Success) { if (sr.POSdata[0].DeviceClass.serialPort != null && sr.POSdata[0].DeviceClass.serialPort.Port.Length > 0) //OptInterfaceServer.optInterfaceServer. this.FdcPosInterface.AddSerialPortReq(sr.WorkstationID, sr.ApplicationSender, sr.RequestIDNumber, sr.POSdata[0].DeviceClass.Type, Convert.ToInt32(sr.POSdata[0].DeviceClass.DeviceID), Convert.ToInt32(sr.POSdata[0].DeviceClass.serialPort.Port), Convert.ToInt32(sr.POSdata[0].DeviceClass.serialPort.BaudRate), Convert.ToInt32(sr.POSdata[0].DeviceClass.serialPort.DataBit), Convert.ToInt32(sr.POSdata[0].DeviceClass.serialPort.StopBit), Convert.ToInt32(sr.POSdata[0].DeviceClass.serialPort.Parity)); else if (sr.POSdata[0].DeviceClass.tcp != null && sr.POSdata[0].DeviceClass.tcp.Port.Length > 0) //OptInterfaceServer.optInterfaceServer. this.FdcPosInterface.AddTCPReq(sr.WorkstationID, sr.ApplicationSender, sr.RequestIDNumber, sr.POSdata[0].DeviceClass.Type, Convert.ToInt32(sr.POSdata[0].DeviceClass.DeviceID), sr.POSdata[0].DeviceClass.tcp.Address, Convert.ToInt32(sr.POSdata[0].DeviceClass.tcp.Port)); } } } else if (requestType == "OPTRemove") { ServiceRequestOPTRemove sr = Deserialize(message, ref result); if (sr != null) { requestId = sr.RequestIDNumber; if (sr.POSdata.GetLength(0) == 0 || sr.POSdata[0].DeviceClass == null || sr.POSdata[0].DeviceClass.DeviceID == "") result = OverallResult.MissingMandatoryData; if (result == OverallResult.Success && extresult == OverallResult.Success) { this.FdcPosInterface.RemoveReq(sr.WorkstationID, sr.ApplicationSender, sr.RequestIDNumber, sr.POSdata[0].DeviceClass.Type, Convert.ToInt32(sr.POSdata[0].DeviceClass.DeviceID)); } } } else if (requestType == "OPTWrite") { ServiceRequestOPTWrite sr = Deserialize(message, ref result); if (sr != null) { requestId = sr.RequestIDNumber; if (sr.POSdata.GetLength(0) == 0 || sr.POSdata[0].DeviceClass == null || sr.POSdata[0].DeviceClass.DeviceID == "") result = OverallResult.MissingMandatoryData; if (result == OverallResult.Success && extresult == OverallResult.Success) { this.FdcPosInterface.WriteReq(sr.WorkstationID, sr.ApplicationSender, sr.RequestIDNumber, sr.POSdata[0].DeviceClass.Type, Convert.ToInt32(sr.POSdata[0].DeviceClass.DeviceID), sr.POSdata[0].DeviceClass.Message); } } } else if (requestType == "GenericTypelessMessage") { ServiceRequestGenericTypelessMessage sr = Deserialize(message, ref result); if (sr != null) { requestId = sr.RequestIDNumber; if (result == OverallResult.Success && extresult == OverallResult.Success) { this.FdcPosInterface.GenericTypelessMessageReq(sr.WorkstationID, sr.ApplicationSender, sr.RequestIDNumber, sr.POSdata[0].Message); } } } else { fdcSocketLogger.LogInformation(string.Format("Client with applicationSender={0}, workstationId={1} is " + "sending in an unknown requestType: {2} message, Will response: ParsingError", applicationSender, workstationId, requestType)); result = OverallResult.ParsingError; } } catch (Exception ex) { result = OverallResult.Failure; fdcSocketLogger.LogError("ReadRequest(requestType: " + (requestType ?? "") + ") from Fdc client(wId: " + (workstationId ?? "") + ",appSender: " + (applicationSender ?? "") + ") exceptioned: \r\n" + ex); //FDCPOSManager.tracer.WriteLine(string.Format("Exception! requestType='{0}': {1}", requestType, ex.Message)); } if (result != OverallResult.Success || extresult != OverallResult.Success) { ((FDCPOSInterfaceServerManager)this.fdcPosManager).fdcPosInterface.messages .SendErrorResponse(requestType, workstationId, applicationSender, requestId, (extresult != OverallResult.Success) ? ErrorCode.ERRCD_COMMERR : ErrorCode.ERRCD_BADVAL, result.ToString()); } else { if (fdcPosManager.fdcClientList.TryGetValue(FDCPOSClient.getClientID(workstationId, applicationSender), out FDCPOSClient cachedFdcPosClient)) cachedFdcPosClient.heartbeat.StartClientDisconnectionTimer(); } //FDCPOSManager.tracer.WriteLine(string.Format("end requestType='{0}'", requestType)); return requestType; } #region misc protected string GetRequestType(string myString) { return GetElemValue("RequestType", myString); } protected string GetMessageType(string myString) { return GetElemValue("MessageType", myString); } protected string GetApplicationSender(string myString) { return GetElemValue("ApplicationSender", myString); ; } protected string GetWorkstationID(string myString) { return GetElemValue("WorkstationID", myString); ; } protected string GetElemValue(string field, string myString) { // TODO string value = ""; try { if (myString.IndexOf(field) >= 0) { myString = myString.Substring(myString.IndexOf(field)); myString = myString.Substring(myString.IndexOf('\"') + 1); value = myString.Substring(0, myString.IndexOf('\"')); } } catch (Exception ex) { fdcSocketLogger.LogError("GetElemValue exceptioned: " + ex.ToString()); //FDCPOSManager.tracer.WriteLine("Exception!" + ex.Message); } return value; } #endregion #region Deserialize public T Deserialize(string xmlString, ref OverallResult result) { if (string.IsNullOrEmpty(xmlString)) throw new ArgumentNullException("Target string for Deserialize must not null or empty"); // Create an instance of the XmlSerializer class; // specify the type of object to be deserialized. result = OverallResult.Success; //=========================== Exception firstException = null; System.Xml.Schema.XmlSchemaSet smSet; SchemasSG sgmInst = SchemasSG.Instance; if (sgmInst.GetSchemas.ContainsKey((typeof(T).Name))) { smSet = sgmInst.GetSchemas[typeof(T).Name]; } else { smSet = null; } if (smSet != null) { var settings = new XmlReaderSettings { Schemas = smSet, CheckCharacters = true, IgnoreComments = true, IgnoreProcessingInstructions = true, IgnoreWhitespace = true, MaxCharactersInDocument = 999999, // most xml files have 450 characters, if this increases, we need to enlarge the number ValidationType = ValidationType.Schema, ValidationFlags = XmlSchemaValidationFlags.ProcessIdentityConstraints | XmlSchemaValidationFlags.ReportValidationWarnings }; settings.ValidationEventHandler += delegate (object sender, ValidationEventArgs args) { if (args.Severity == XmlSeverityType.Warning) { //Console.WriteLine("Warning: " + args.Message); fdcSocketLogger.LogInformation("XmlSchema Validation has a Warning : " + (args.Message ?? "") + Environment.NewLine + (args.Exception?.ToString() ?? "") + Environment.NewLine + xmlString); } else { if (firstException == null) { firstException = args.Exception; } fdcSocketLogger.LogError("XmlSchema Validation has an ERROR: " + (args.Message ?? "") + Environment.NewLine + (args.Exception?.ToString() ?? "") + Environment.NewLine + xmlString); //Console.WriteLine("Exception: " + args.Exception.ToString()); //FDCPOSManager.tracer.WriteLine("Exception: " + args.Exception.ToString()); } }; //====================================== T sr = default(T); try { using (var tempStream = new System.IO.StringReader(xmlString)) { using (var reader = XmlReader.Create(tempStream, settings)) { XmlSerializer serializer = new XmlSerializer(typeof(T)); serializer.UnknownNode += new XmlNodeEventHandler((_, n) => { //the target object may miss to defined a Property? fdcSocketLogger.LogInformation("XmlSerializer read an Unknown Node with Name: " + (n.Name ?? "") + ", text: " + (n.Text ?? "") + System.Environment.NewLine + xmlString); }); serializer.UnknownAttribute += new XmlAttributeEventHandler((_, e) => { //the target object may miss to defined a Property? System.Xml.XmlAttribute attr = e.Attr; fdcSocketLogger.LogInformation("XmlSerializer read an Unknown Attr with Name: " + (attr.Name ?? "") + ", value: " + (attr.Value ?? "") + System.Environment.NewLine + xmlString); }); sr = (T)serializer.Deserialize(reader); } } if (firstException != null) throw firstException; } catch (Exception ex) { result = OverallResult.ParsingError; //FDCPOSManager.tracer.WriteLine("Exception! " + ex.Message); fdcSocketLogger.LogError("Deserialize(string ,ref OverallResult) exceptioned for string: " + Environment.NewLine + xmlString + Environment.NewLine + "exception detail: " + ex); } return sr; } else { result = OverallResult.ParsingError; return default(T); } } // end of Deserialize #endregion /// /// 4 bytes Length(16 bytes hash excluded) + 16 bytes hash + UTF8 encoded xml content /// /// /// /// if false, will set 0 for all 16 bytes /// string is the serialized Message xml string public static Tuple SerializeFdcMessageToNetworkBytes(T sr, bool enableHashHeader) { var xmlMsgBodyMemStream = new MemoryStream(); XmlSerializer serializer = new XmlSerializer(typeof(T)); serializer.Serialize(xmlMsgBodyMemStream, (T)sr); xmlMsgBodyMemStream.Position = 0; string xmlBodyStr = ""; byte[] xmlBodyBytes = null; using (StreamReader _ = new StreamReader(xmlMsgBodyMemStream, Encoding.UTF8)) { xmlBodyStr = _.ReadToEnd(); xmlBodyBytes = Encoding.UTF8.GetBytes(xmlBodyStr); } #region msg header, 4 bytes of msg body length byte[] lengthBytes = new byte[Define.HeaderLength]; lengthBytes[3] = (byte)(xmlBodyBytes.Length & 0x000000FF); lengthBytes[2] = (byte)((xmlBodyBytes.Length & 0x0000FF00) / Math.Pow(2, 8)); lengthBytes[1] = (byte)((xmlBodyBytes.Length & 0x00FF0000) / Math.Pow(2, 16)); lengthBytes[0] = (byte)((xmlBodyBytes.Length & 0xFF000000) / Math.Pow(2, 24)); #endregion #region msg encription Bytes, 16 bytes var hashBytes = new byte[Define.EncriptionLength]; if (enableHashHeader) { MD5Crypter crypter = new MD5Crypter(); byte[] hashingbytes = new byte[xmlBodyBytes.Length + crypter.getPassphrase().Length]; Array.Copy(xmlBodyBytes, hashingbytes, xmlBodyBytes.Length); Array.Copy(crypter.getPassphrase(), 0, hashingbytes, xmlBodyBytes.Length, crypter.getPassphrase().Length); hashBytes = crypter.ComputeHash(hashingbytes); } else { for (int i = 0; i < Define.EncriptionLength; i++) hashBytes[i] = 0; } #endregion // 3 parts concat. var finalBytes = lengthBytes.Concat(hashBytes).Concat(xmlBodyBytes).ToArray(); return new Tuple(finalBytes, xmlBodyStr); } public bool SendResponse(FDCPOSClient fdcPosClient, T sr) { try { if (fdcPosClient == null) { fdcSocketLogger.LogInformation("SendResponse, client is NULL!"); //FDCPOSManager.tracer.WriteLine(string.Format("client is NULL!")); return false; } if (!fdcPosClient.connected) { fdcSocketLogger.LogInformation(string.Format("client '{0}' NOT connected, will skip send this response", fdcPosClient.sID)); //FDCPOSManager.tracer.WriteLine(string.Format("client '{0}' NOT connected", fdcposClient.sID)); return false; } Interlocked.Increment(ref FDCPOSManager.messageIdCounter); var result = SerializeFdcMessageToNetworkBytes(sr, this.fdcPosManager.encryptedHeader); if (result.Item1.Length >= 19999999) fdcSocketLogger.LogInformation("SendResponse " + typeof(T).Name + ", rawBytes Length: " + result.Item1.Length + " excceed normal value, will send anyway"); lock (fdcPosClient) { if (fdcSocketLogger.IsEnabled(LogLevel.Debug)) fdcSocketLogger.LogDebug("Will Send Fdc Response(full message include header bytes count: " + result.Item1.Length + "): " + sr.GetType().Name + ", content:\r\n" + result.Item2 + "\r\n to client(wId: " + (fdcPosClient.workstationID ?? "") + ", appSender: " + (fdcPosClient.applicationSender ?? "") + ")"); var networkStream = fdcPosClient.socketChannelResponse.GetStream(); networkStream.Write(result.Item1); if (fdcSocketLogger.IsEnabled(LogLevel.Debug)) { fdcSocketLogger.LogDebug(" done send Fdc Response: " + sr.GetType().Name); } } try { if (false && traceXML) { //DateTime now = DateTime.Now; //string sdate = now.Day.ToString() + "-" + now.Month.ToString() + "-"; //System.IO.StreamWriter testwriter = new StreamWriter(SINPConfigurazione.TracePath + sdate + "xmlServerResponse.xml", true); //serializer.Serialize(testwriter, sr); //testwriter.Close(); } } catch (Exception Ex) { fdcSocketLogger.LogError(string.Format("Exception tracing xml file: {0}", Ex.Message)); //FDCPOSManager.tracer.WriteLine(string.Format("Exception tracing xml file: {0}", Ex.Message)); } } catch (Exception ex) { fdcSocketLogger.LogError("SendResponse " + typeof(T).Name + " to client: " + fdcPosClient.sID + " Exceptioned: " + ex + System.Environment.NewLine + "Will disconect this client"); fdcPosClient.Dispose(); this.fdcPosManager.DisconnectClient(fdcPosClient); return false; } return true; } public void Dispose() { try { this.disposed = true; this.fdcSocketLogger.LogError($"FdcServerTcpHandler is on stopping, and will Dispose all fdcClientTcpHandlers(total: {this.fdcClientTcpHandlers.Count}) as well... "); this.tcpListener.Stop(); this.fdcClientTcpHandlers.ForEach(c => { try { c.Dispose(); } catch { } }); this.fdcClientTcpHandlers.Clear(); } finally { } } } }