using System; using System.Collections.Generic; using System.IO; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; using System.Xml.Linq; using System.Xml.Serialization; using Wayne.FDCPOSLibrary; using Wayne.FDCPOSLibrary.Configuration; using Wayne.Lib; using Wayne.Lib.Log; namespace Wayne.ForecourtControl.Fusion { public class TCPListenerThread : DisposableBase { public bool bRunning = false; private bool bTerminate = false; TcpListener tcpListener = null; IFSFManager ifsfManager = null; string name = ""; private readonly DebugLogger debugLogger; public TCPListenerThread(TcpListener _listener, IFSFManager _ifsfManager, string _name) { tcpListener = _listener; ifsfManager = _ifsfManager; name = _name; debugLogger = ifsfManager.DebugLogger; } private void DebugLog(string s) { if (debugLogger.IsActive()) debugLogger.Add(s); } public void TCPListenerThreadProc() { DebugLog(string.Format("TCPListenerThreadProc Id={0}, WId={1}: init", this.ifsfManager.clientSocket.Id, this.ifsfManager.clientSocket.workstationID)); TcpClient tcpclient = null; bRunning = true; try { if (tcpListener != null) { DebugLog("tcpListener starting"); tcpListener.Start(); DebugLog("tcpListener started"); } } catch (Exception ex) { DebugLog("TCPListenerThreadProc: Exception tcpListener.Start! " + ex.ToString()); bRunning = false; return; } bTerminate = false; string sbuffer = ""; while (!bTerminate) { try { if (tcpclient == null && tcpListener != null) { DebugLog("TCPListenerThreadProc: TcpClient Accepting"); tcpclient = tcpListener.AcceptTcpClient(); DebugLog("TcpClient Accepted"); } else { NetworkStream networkStream; if (tcpListener != null) networkStream = tcpclient.GetStream(); else networkStream = ifsfManager.clientSocket.socketReqChannelA.GetStream(); DebugLog(string.Format("TCPListenerThreadProc Id={0}, WId={1}: {2} got stream ...", this.ifsfManager.clientSocket.Id, this.ifsfManager.clientSocket.workstationID, this.name)); StringBuilder sb = new StringBuilder(); // read header int headerLength, encrStart; if (FDCGlobal.ProtocolVersion <= FDCVersion.V0007) { headerLength = Define.HeaderLength + Define.MD5EncriptionLength; encrStart = Define.HeaderLength; } else if (this.ifsfManager.clientSocket.headerEncryption != 0) { headerLength = Define.HeaderLength + Define.EncriptionTypeLength + Define.MD5EncriptionLength; encrStart = Define.HeaderLength + Define.EncriptionTypeLength; } else { headerLength = Define.HeaderLength + Define.EncriptionTypeLength; encrStart = Define.HeaderLength + Define.EncriptionTypeLength; } var header = new byte[headerLength]; DebugLog(string.Format("TCPListenerThreadProc: header length={0}", header.GetLength(0))); int nread, nreadtot = 0; do { DebugLog("TCPListenerThreadProc: reading ..."); nread = networkStream.Read(header, nreadtot, (headerLength) - nreadtot); DebugLog(string.Format("TCPListenerThreadProc Id={0}, WId={1}: read '{2}' bytes", this.ifsfManager.clientSocket.Id, this.ifsfManager.clientSocket.workstationID, nread)); nreadtot += nread; if (nread == 0) Thread.Sleep(500); } while (nreadtot < headerLength); int msglength = getMsgLength(header); // read message var buffer = new byte[msglength]; DebugLog(string.Format("TCPListenerThreadProc: buffer msg length={0}", buffer.GetLength(0))); nreadtot = 0; do { DebugLog("TCPListenerThreadProc: reading ..."); nread = networkStream.Read(buffer, nreadtot, msglength - nreadtot); DebugLog(string.Format("TCPListenerThreadProc Id={0}, WId={1}: read '{2}' bytes", this.ifsfManager.clientSocket.Id, this.ifsfManager.clientSocket.workstationID, nread)); nreadtot += nread; if (nread == 0) Thread.Sleep(500); } while (nreadtot < msglength); sb.Remove(0, sb.Length); sb.Append(Encoding.UTF8.GetString(buffer, 0, nreadtot)); string myString = Encoding.ASCII.GetString(buffer, 0, msglength); string logString; try { logString = XElement.Parse(myString).ToString(); } catch { logString = myString; } DebugLog(string.Format("TCPListenerThreadProc Id={0}, WId={1}: read '{2}' bytes:\r\n{3}", this.ifsfManager.clientSocket.Id, this.ifsfManager.clientSocket.workstationID, msglength, logString)); sbuffer += sb.ToString(); bool bEnd = false; do { var indexEndMsgSR = sbuffer.IndexOf(""); var indexEndFDCMsg = sbuffer.IndexOf(""); string sEndmsg; int indexEnd; if (indexEndMsgSR >= 0 && indexEndFDCMsg >= 0) { indexEnd = System.Math.Min(indexEndMsgSR, indexEndFDCMsg); if (indexEndMsgSR < indexEndFDCMsg) { sEndmsg = ""; } else { sEndmsg = ""; } } else if (indexEndMsgSR >= 0 && indexEndFDCMsg < 0) { indexEnd = indexEndMsgSR; sEndmsg = ""; } else if (indexEndFDCMsg > 0) { indexEnd = indexEndFDCMsg; sEndmsg = ""; } else { indexEnd = sbuffer.IndexOf("/>"); sEndmsg = "/>"; } if (indexEnd >= 0) { var smsg = sbuffer.Substring(0, indexEnd + sEndmsg.Length); sbuffer = sbuffer.Substring(indexEnd + sEndmsg.Length); var result = OverallResult.Success; if (this.ifsfManager.clientSocket.headerEncryption != 0) { bool error = checkHash(smsg, encrStart, header); if (error) { DebugLog(error ? "ValidationError" : "check OK"); int i = 0; while (i < sbuffer.Length && (sbuffer[i] == '\n' || sbuffer[i] == ' ' || sb[i] == '\t')) i++; if (i > 0) { DebugLog(string.Format("try to verify msg with '\\n' or ' ' ending chars ('{0}' found)", i)); smsg += sbuffer.Substring(0, i); sbuffer = sbuffer.Substring(0, sbuffer.Length - i); error = checkHash(smsg, encrStart, header); DebugLog(error ? "ValidationError" : "check OK"); if (error) result = OverallResult.ValidationError; } else result = OverallResult.ValidationError; } } if (smsg.Length > 0) { int i = 0; while (i < sbuffer.Length && (sbuffer[i] == '\n' || sbuffer[i] == ' ' || sb[i] == '\t')) i++; if (i > 0) { DebugLog(string.Format("try to verify msg with '\\n' or ' ' ending chars ('{0}' found)", i)); smsg += sbuffer.Substring(0, i); sbuffer = sbuffer.Substring(0, sbuffer.Length - i); DebugLog(string.Format("smsg={0}", smsg)); DebugLog(string.Format("sbuffer={0}", sbuffer)); } if (smsg.IndexOf("= 0) ifsfManager.ReadResponse(smsg, msglength, ref result); else ifsfManager.ReadMessage(smsg, msglength, ref result); } } else bEnd = true; } while (!bEnd); } } catch (SocketException sex) { DebugLog("Exception TCPListenerThreadProc: " + sex.ToString()); tcpclient = null; if (sex.ErrorCode == 10049) ifsfManager.Disconnect(); Thread.Sleep(1000); } catch (Exception ex) { DebugLog("Exception TCPListenerThreadProc! " + ex.ToString()); tcpclient = null; ifsfManager.Disconnect(); Thread.Sleep(1000); } } if (tcpListener != null) tcpListener.Stop(); bRunning = false; DebugLog(string.Format("TCPListenerThreadProc Id={0}, WId={1}: end", this.ifsfManager.clientSocket.Id, this.ifsfManager.clientSocket.workstationID)); } private bool checkHash(string smsg, int encrStart, byte[] header) { MD5Crypter crypter = new MD5Crypter(); byte[] datahash = crypter.ComputeHash(System.Text.Encoding.UTF8.GetBytes(smsg + MD5Crypter.passphrase)); var inputhash = new byte[Define.MD5EncriptionLength]; for (int i = encrStart; i < Define.MD5EncriptionLength + encrStart; i++) inputhash[i - encrStart] = header[i]; bool error = false; for (int i = 0; i < Define.MD5EncriptionLength; i++) if (inputhash[i] != datahash[i]) { DebugLog(string.Format("ValidationError: inputhash={0}, datahash={1}", System.Text.Encoding.UTF8.GetString(inputhash, 0, inputhash.GetLength(0)), System.Text.Encoding.UTF8.GetString(datahash, 0, datahash.GetLength(0)))); DebugLog(string.Format("ValidationError: inputhash[{0}]={1} != datahash[{2}]={3}", i, inputhash[i], i, datahash[i])); error = true; break; } return error; } private int getMsgLength(byte[] header) { int length = 0; for (int pos = 1; pos <= Define.HeaderLength; pos++) { length |= header[pos - 1] << (Define.HeaderLength - pos) * 8; } return length; } protected override void DoDispose() { bTerminate = true; } } public class IFSFSockets : IIdentifiableEntity, IDisposable//, IConnectable { private TcpClient _socketReqChannelA; public TcpClient socketReqChannelA { get { return _socketReqChannelA; } } private TcpListener _socketRespChannelB; public TcpListener socketRespChannelB { get { return _socketRespChannelB; } } private TcpListener _socketUnsolicitedChannelC; public TcpListener socketUnsolicitedChannelC { get { return _socketUnsolicitedChannelC; } } private TcpClient _socketReqChannelConfig; public TcpClient socketReqChannelConfig { get { return _socketReqChannelConfig; } } public TCPListenerThread respChannelBThreadObj; public Thread respChannelBThread; public TCPListenerThread unsolicitedChannelCThreadObj; public Thread unsolicitedChannelCThread; public TCPListenerThread respChannelConfigThreadObj; public Thread respChannelConfigThread; IFSFManager ifsfManager; IFSFMessages _ifsfMessages; public IFSFMessages ifsfMessages { get { return _ifsfMessages; } } private string _applicationSender; public string applicationSender { get { return _applicationSender; } } private string _workstationID; public string workstationID { get { return _workstationID; } } private string _sIPAddress; public string sIPAddress { get { return _sIPAddress; } } private string _sIPAddress2; public string sIPAddress2 { get { return _sIPAddress2; } } private int _iIPPortA; public int iIPPortA { get { return _iIPPortA; } } private int _iIPPortB; public int iIPPortB { get { return _iIPPortB; } } private int _iIPPortC; public int iIPPortC { get { return _iIPPortC; } } private long _heartbeatInterval; public long heartbeatInterval { get { return _heartbeatInterval; } } private long _heartbeatTimeout; public long heartbeatTimeout { get { return _heartbeatTimeout; } } private long _runningFuellingTimeout = 2000; public long runningFuellingTimeout { get { return _runningFuellingTimeout; } } private long _headerEncryption; public long headerEncryption { get { return _headerEncryption; } set { _headerEncryption = value; } } public bool logOnSendCalled = false; private byte[][] _validationInfo; public byte[][] validationInfo { get { return _validationInfo; } set { _validationInfo = value; } } private string _posInfo = ""; public string posInfo { get { return _posInfo; } set { _posInfo = value; } } private bool disposed; private int id; private IIdentifiableEntity parentEntity; private DeviceConnectionState _mainConnectionState = DeviceConnectionState.Disconnected; public DeviceConnectionState mainConnectionState { get { return _mainConnectionState; } set { if (_mainConnectionState != value) { _mainConnectionState = value; if (OnConnectionStateChange != null) { OnConnectionStateChange.Invoke(this, new ConnectionChangedEventArgs(mainConnectionState)); } } } } public event EventHandler OnConnectionStateChange; public event EventHandler OnResponseTimeout; private readonly DebugLogger debugLogger; public IFSFSockets(int id, IFSFManager _ifsfManager) { this.id = id; this.parentEntity = (IIdentifiableEntity)ifsfManager; ifsfManager = _ifsfManager; debugLogger = ifsfManager.DebugLogger; ConfigurationParams configParam = new ConfigurationParams(debugLogger); this._applicationSender = configParam.applicationSender; this._workstationID = configParam.workstationID; this._sIPAddress = configParam.sIPAddress; this._sIPAddress2 = configParam.sIPAddress2; this._iIPPortA = configParam.iIPPortA; this._iIPPortB = configParam.iIPPortB; this._iIPPortC = configParam.iIPPortC; this._heartbeatTimeout = configParam.heartbeatTimeout; this._heartbeatInterval = configParam.heartbeatInterval; this._headerEncryption = configParam.headerEncryption; _ifsfMessages = new IFSFMessages(this, debugLogger); _ifsfMessages.OnIFSFSMessageEnqueued += new EventHandler(ifsfmessages_OnMessageEnqueued); _ifsfMessages.OnResponseTimeout += new EventHandler(ifsfmessages_OnResponseTimeout); } private void DebugLog(string s) { if (debugLogger.IsActive()) debugLogger.Add(s); } private bool getConnectionParams(string connectionString) { Dictionary connectionStringParamDict; connectionStringParamDict = Strings.ParseConnectionString(connectionString); string key = ""; key = "IdShift"; if (connectionStringParamDict.ContainsKey(key) && connectionStringParamDict[key] != null && connectionStringParamDict[key] != "") { try { ((FUSIONForecourtControl)(FUSIONFactory.fusionForecourtControlList[this.Id])).manager.IdShift = Convert.ToInt32(connectionStringParamDict[key]); } catch (Exception ex) { DebugLog(string.Format("Exception reading IdShift: {0}", ex.ToString())); } } key = "IdPumpShift"; if (connectionStringParamDict.ContainsKey(key) && connectionStringParamDict[key] != null && connectionStringParamDict[key] != "") { try { ((FUSIONForecourtControl)(FUSIONFactory.fusionForecourtControlList[this.Id])).manager.IdPumpShift = Convert.ToInt32(connectionStringParamDict[key]); } catch (Exception ex) { DebugLog(string.Format("Exception reading IdPumpShift: {0}", ex.ToString())); } } key = "IdNozzleShift"; if (connectionStringParamDict.ContainsKey(key) && connectionStringParamDict[key] != null && connectionStringParamDict[key] != "") { try { ((FUSIONForecourtControl)(FUSIONFactory.fusionForecourtControlList[this.Id])).manager.IdNozzleShift = Convert.ToInt32(connectionStringParamDict[key]); } catch (Exception ex) { DebugLog(string.Format("Exception reading IdNozzleShift: {0}", ex.ToString())); } } key = "IdTankShift"; if (connectionStringParamDict.ContainsKey(key) && connectionStringParamDict[key] != null && connectionStringParamDict[key] != "") { try { ((FUSIONForecourtControl)(FUSIONFactory.fusionForecourtControlList[this.Id])).manager.IdTankShift = Convert.ToInt32(connectionStringParamDict[key]); } catch (Exception ex) { DebugLog(string.Format("Exception reading IdTankShift: {0}", ex.ToString())); } } key = "FuelGradeShift"; if (connectionStringParamDict.ContainsKey(key) && connectionStringParamDict[key] != null && connectionStringParamDict[key] != "") { try { ((FUSIONForecourtControl)(FUSIONFactory.fusionForecourtControlList[this.Id])).manager.FuelGradeShift = Convert.ToInt32(connectionStringParamDict[key]); } catch (Exception ex) { DebugLog(string.Format("Exception reading FuelGradeShift: {0}", ex.ToString())); } } key = "Host"; if (connectionStringParamDict.ContainsKey(key) && connectionStringParamDict[key] != null && connectionStringParamDict[key] != "") this._sIPAddress = connectionStringParamDict[key]; key = "Host2"; if (connectionStringParamDict.ContainsKey(key) && connectionStringParamDict[key] != null && connectionStringParamDict[key] != "") this._sIPAddress2 = connectionStringParamDict[key]; key = "Port"; if (connectionStringParamDict.ContainsKey(key) && connectionStringParamDict[key] != null && connectionStringParamDict[key] != "") { try { this._iIPPortA = Convert.ToInt32(connectionStringParamDict[key]); } catch (Exception ex) { DebugLog(string.Format("Exception reading IPPortA: {0}", ex.ToString())); } } key = "PortB"; if (connectionStringParamDict.ContainsKey(key) && connectionStringParamDict[key] != null && connectionStringParamDict[key] != "") { try { this._iIPPortB = Convert.ToInt32(connectionStringParamDict[key]); } catch (Exception ex) { DebugLog(string.Format("Exception reading IPPortB: {0}", ex.ToString())); } } key = "PortC"; if (connectionStringParamDict.ContainsKey(key) && connectionStringParamDict[key] != null && connectionStringParamDict[key] != "") { try { this._iIPPortC = Convert.ToInt32(connectionStringParamDict[key]); } catch (Exception ex) { DebugLog(string.Format("Exception reading IPPortC: {0}", ex.ToString())); } } //key = "workstationID"; //if (connectionStringParamDict.ContainsKey(key) && connectionStringParamDict[key] != null && connectionStringParamDict[key] != "") // this._applicationSender = connectionStringParamDict[key]; //else //{ // key = "ClientName"; // if (connectionStringParamDict.ContainsKey(key) && connectionStringParamDict[key] != null && connectionStringParamDict[key] != "") // this._applicationSender = connectionStringParamDict[key]; //} //key = "applicationSender"; //if (connectionStringParamDict.ContainsKey(key) && connectionStringParamDict[key] != null && connectionStringParamDict[key] != "") // this._workstationID = connectionStringParamDict[key]; //else //{ // key = "ClientId"; // if (connectionStringParamDict.ContainsKey(key) && connectionStringParamDict[key] != null && connectionStringParamDict[key] != "") // this._workstationID = connectionStringParamDict[key]; //} key = "ClientId"; if (connectionStringParamDict.ContainsKey(key) && connectionStringParamDict[key] != null && connectionStringParamDict[key] != "") { this._workstationID = connectionStringParamDict[key]; this._applicationSender = connectionStringParamDict[key]; } else { key = "applicationSender"; if (connectionStringParamDict.ContainsKey(key) && connectionStringParamDict[key] != null && connectionStringParamDict[key] != "") { this._workstationID = connectionStringParamDict[key]; this._applicationSender = connectionStringParamDict[key]; } } key = "heartbeatInterval"; if (connectionStringParamDict.ContainsKey(key) && connectionStringParamDict[key] != null && connectionStringParamDict[key] != "") { try { this._heartbeatInterval = Convert.ToInt64(connectionStringParamDict[key]); } catch (Exception ex) { DebugLog(string.Format("Exception reading heartbeatInterval: {0}", ex.ToString())); } } key = "heartbeatTimeout"; if (connectionStringParamDict.ContainsKey(key) && connectionStringParamDict[key] != null && connectionStringParamDict[key] != "") { try { this._heartbeatTimeout = Convert.ToInt64(connectionStringParamDict[key]); } catch (Exception ex) { DebugLog(string.Format("Exception reading _heartbeatTimeout: {0}", ex.ToString())); } } key = "runningFuellingTimeout"; if (connectionStringParamDict.ContainsKey(key) && connectionStringParamDict[key] != null && connectionStringParamDict[key] != "") { try { this._runningFuellingTimeout = Convert.ToInt64(connectionStringParamDict[key]); } catch (Exception ex) { DebugLog(string.Format("Exception reading _runningFuellingTimeout: {0}", ex.ToString())); } } key = "headerEncryption"; if (connectionStringParamDict.ContainsKey(key) && connectionStringParamDict[key] != null && connectionStringParamDict[key] != "") { try { this._headerEncryption = Convert.ToInt16(connectionStringParamDict[key]); } catch (Exception ex) { DebugLog(string.Format("Exception reading _headerEncryption: {0}", ex.ToString())); } } key = "posInfo"; if (connectionStringParamDict.ContainsKey(key) && connectionStringParamDict[key] != null && connectionStringParamDict[key] != "") this._posInfo = connectionStringParamDict[key]; key = "validationInfo"; if (connectionStringParamDict.ContainsKey(key) && connectionStringParamDict[key] != null && connectionStringParamDict[key] != "") { string[] validationInfoArray; try { //validationInfoArray = connectionStringParamDict[key].Split('@'); //this._validationInfo = new byte[validationInfoArray.Length][]; //int i = 0; //foreach(string s in validationInfoArray) //{ string s = connectionStringParamDict[key]; string elem; while (s.Length > 0) { if (s.IndexOf("@@@") >= 0) { elem = s.Substring(0, s.IndexOf("@@@")); s = s.Substring(s.IndexOf("@@@") + 3); } else { elem = s; s = ""; } //DESCrypter descrypter = new DESCrypter(); //byte[] dataencrypted = descrypter.Encrypt(elem); byte[] b = System.Text.Encoding.Unicode.GetBytes(elem); this.ifsfManager.LogOnAddValidationInfo(b); //IFSFManager.ArrayResize(ref _validationInfo, (_validationInfo != null) ? _validationInfo.Length + 1 : 1); //this._validationInfo[_validationInfo.Length-1] = new byte[dataencrypted.Length]; //this._validationInfo[_validationInfo.Length-1] = dataencrypted; } } catch (Exception ex) { DebugLog(string.Format("Exception reading _validationInfo: {0}", ex.ToString())); } } return true; } public void SendConfig(string commandFileName) { if (this.mainConnectionState == DeviceConnectionState.Connected) { int iIPPortConfig = Convert.ToInt32(IniFile.IniReadValue(ConfigurationParams.getSINPPath("ini\\") + @"ForecourtServer.ini", "FUSION-Connection", "IPPortConfig")); try { IPAddress serverIPAddress = null; IPEndPoint endPoint = null; if (iIPPortConfig != this._iIPPortA) { int socketTimeout = 3000; bool noDelay = true; try { string sValue = IniFile.IniReadValue(ConfigurationParams.inifile, "FUSION-Connection", "SocketTimeout"); if (sValue.Length > 0) socketTimeout = Convert.ToInt32(sValue); sValue = IniFile.IniReadValue(ConfigurationParams.inifile, "FUSION-Connection", "NoDelay"); if (sValue.Length > 0 && sValue == "0") noDelay = false; } catch (Exception ex) { DebugLog("EXCEPTION! " + ex.ToString()); } DebugLog(string.Format("socketTimeout={0}", socketTimeout)); _socketReqChannelConfig = new TcpClient(); _socketReqChannelConfig.SendTimeout = socketTimeout; _socketReqChannelConfig.NoDelay = noDelay; int retrycount = 0; bool bConnected = false; string ipAddress = this._sIPAddress; string error = ""; while (!bConnected) { if (retrycount == 5) { if (this._sIPAddress2 != "") ipAddress = this._sIPAddress2; DebugLog(error); } else if (retrycount == 10) { retrycount = 0; ipAddress = this._sIPAddress; DebugLog(error); Thread.Sleep(5000); } retrycount++; try { socketReqChannelConfig.Connect(ipAddress, iIPPortConfig); bConnected = true; } catch (SocketException sex) { error = sex.ToString(); Thread.Sleep(1000); } } respChannelConfigThreadObj = new TCPListenerThread(null, ifsfManager, "ChannelConfig"); respChannelConfigThread = new Thread(new ThreadStart(respChannelConfigThreadObj.TCPListenerThreadProc)); respChannelConfigThread.Start(); } else _socketReqChannelConfig = this._socketReqChannelA; Thread.Sleep(2000); // start reading file with config messages string line, xmlconfigfile = ConfigurationParams.getSINPPath("ini\\") + commandFileName; StringBuilder sb = new StringBuilder(); ; StreamReader sr = new StreamReader(xmlconfigfile); while (sr.Peek() != -1) { line = sr.ReadLine(); sb.Append(line); } sr.Close(); string allconfig = sb.ToString(); //string allconfig = sr.ReadToEnd(); string[] messages; string msg2; messages = allconfig.Split('#'); foreach (string msg in messages) { msg2 = msg; //msg2 = msg.Replace("\r", ""); //msg2 = msg2.Replace("\n", ""); //msg2 = msg2.Replace("\t", ""); this.SendConfigMessage(msg2); } } catch (Exception ex) { DebugLog(string.Format("SendConfig end: EXCEPTION! {0}", ex.ToString())); } if (iIPPortConfig != this._iIPPortA) { if (_socketReqChannelConfig != null) this._socketReqChannelConfig.Close(); this._socketReqChannelConfig = null; } } else DebugLog("SendConfig ERROR: NOT Connected!"); } public bool Connect(string connectionString) { DebugLog(string.Format("Connect init: status='{0}'", this.mainConnectionState)); if (this.mainConnectionState == DeviceConnectionState.Disconnected || this.mainConnectionState == DeviceConnectionState.Disconnecting) { //this.mainConnectionState = DeviceConnectionState.Connecting; try { getConnectionParams(connectionString); FDCGlobal.ProtocolVersion = FDCGlobal.VersionFromString(IniFile.IniReadValue(ConfigurationParams.inifile, "FUSION-Connection", "FDCPOSInterfaceVersion")); FDCGlobal.ConfigVersion = FDCGlobal.ConfigVersionFromString(IniFile.IniReadValue(ConfigurationParams.inifile, "FUSION-Connection", "FDCPOSConfigVersion")); DebugLog(string.Format("id={0}, -connectionString:'{1}', version:'{2}', configVersion:'{3}'", this.id, connectionString, FDCGlobal.ProtocolVersion, FDCGlobal.ConfigVersion)); this.ifsfManager.heartbeat.Stop(); this.ifsfManager.heartbeat.heartbeatInterval = this.heartbeatInterval; this.ifsfManager.heartbeat.heartbeatTimeout = this.heartbeatTimeout; int socketTimeout = 3000; bool noDelay = true; try { string sValue = IniFile.IniReadValue(ConfigurationParams.inifile, "FUSION-Connection", "SocketTimeout"); if (sValue.Length > 0) socketTimeout = Convert.ToInt32(sValue); sValue = IniFile.IniReadValue(ConfigurationParams.inifile, "FUSION-Connection", "NoDelay"); if (sValue.Length > 0 && sValue == "0") noDelay = false; } catch (Exception ex) { DebugLog("EXCEPTION! " + ex.ToString()); } DebugLog(string.Format("socketTimeout={0}", socketTimeout)); IPAddress serverIPAddress = null; IPEndPoint endPoint = null; _socketReqChannelA = new TcpClient(); _socketReqChannelA.SendTimeout = socketTimeout; _socketReqChannelA.NoDelay = noDelay; int retrycount = 0; bool bConnected = false; string ipAddress = this._sIPAddress; string error = ""; while (!bConnected) { if (retrycount == 5) { if (this._sIPAddress2 != "") ipAddress = this._sIPAddress2; DebugLog(error); } else if (retrycount == 10) { retrycount = 0; ipAddress = this._sIPAddress; DebugLog(error); Thread.Sleep(5000); } retrycount++; try { DebugLog(string.Format("connecting to ip={0}, port={1}", ipAddress, this.iIPPortA)); this.socketReqChannelA.Connect(ipAddress, this.iIPPortA); bConnected = true; } catch (SocketException sex) { error = sex.ToString(); Thread.Sleep(1000); } } if (iIPPortB != iIPPortA /*&& _socketRespChannelB == null*/) _socketRespChannelB = new TcpListener(iIPPortB); else _socketRespChannelB = null; if (iIPPortC != iIPPortA /*&& _socketUnsolicitedChannelC == null*/) _socketUnsolicitedChannelC = new TcpListener(iIPPortC); else _socketUnsolicitedChannelC = null; DebugLog(string.Format("Channel A Connected: Id={0}, WId={1}, AId={2}", this.id, this.workstationID, this.applicationSender)); ifsfManager.authentificationErrorRetry = true; if (this.validationInfo != null) ifsfManager.LogOn(validationInfo, posInfo, ""); else ifsfManager.LogOnSend(posInfo); ifsfManager.heartbeat.ResetDisconnectionTimeout(); if (iIPPortB != iIPPortA /*&& respChannelBThreadObj == null*/) { respChannelBThreadObj = new TCPListenerThread(socketRespChannelB, ifsfManager, "ChannelB"); respChannelBThread = new Thread(new ThreadStart(respChannelBThreadObj.TCPListenerThreadProc)); respChannelBThread.Start(); } else /*if (respChannelBThreadObj == null)*/ { respChannelBThreadObj = new TCPListenerThread(null, ifsfManager, "ChannelA"); respChannelBThread = new Thread(new ThreadStart(respChannelBThreadObj.TCPListenerThreadProc)); respChannelBThread.Start(); } if (iIPPortC != iIPPortA /*&& unsolicitedChannelCThreadObj == null*/) { unsolicitedChannelCThreadObj = new TCPListenerThread(socketUnsolicitedChannelC, ifsfManager, "ChannelC"); unsolicitedChannelCThread = new Thread(new ThreadStart(unsolicitedChannelCThreadObj.TCPListenerThreadProc)); unsolicitedChannelCThread.Start(); } } catch (Exception ex) { DebugLog(string.Format("Connect end: EXCEPTION! {0}", ex.ToString())); return false; } } DebugLog("Connect end: ok"); return true; } public void Disconnect() { DebugLog("terminating respThreadObjs"); if (respChannelBThreadObj != null) respChannelBThreadObj.Dispose(); DebugLog("terminating respChannelCThreadObj"); if (unsolicitedChannelCThreadObj != null) unsolicitedChannelCThreadObj.Dispose(); if (respChannelConfigThreadObj != null) respChannelConfigThreadObj.Dispose(); if (_socketReqChannelA != null) this._socketReqChannelA.Close(); this._socketReqChannelA = null; if (_socketReqChannelConfig != null) this._socketReqChannelConfig.Close(); this._socketReqChannelConfig = null; if (this._socketRespChannelB != null) this._socketRespChannelB.Stop(); _socketRespChannelB = null; if (this._socketUnsolicitedChannelC != null) this._socketUnsolicitedChannelC.Stop(); _socketUnsolicitedChannelC = null; } public virtual void Dispose() { this.Dispose(true); GC.SuppressFinalize(this); } private void Dispose(bool disposing) { if (!this.disposed) { this.disposed = true; if (disposing) { } } } public DeviceConnectionState ConnectionState { get { return this.mainConnectionState; } } public string EntitySubType { get { return "RPC"; } } public string EntityType { get { return "ClientSocket"; } } /// /// This is used by the logger and should never be set by inheriting classes /// public string FullEntityName { get; set; } public int Id { get { return this.id; } } public IIdentifiableEntity ParentEntity { get { return this.parentEntity; } } public void Serialize(T sr) { NetworkStream netstream = socketReqChannelA.GetStream(); byte[] payload; using (var memstream = new MemoryStream()) { XmlSerializer serializer = ifsfMessages.GetXmlSerializer(typeof(T)); serializer.Serialize(memstream, (T)sr); payload = memstream.ToArray(); } // writes header and encription string // writes message length using (var memstream = new MemoryStream()) { using (var writer = new BinaryWriter(memstream)) { writer.Write(new[] { (byte)(payload.Length >> 24), (byte)(payload.Length >> 16), (byte)(payload.Length >> 8), (byte)(payload.Length) }); // if V01 then writes algorithm type (0: no encription, 1: MD5 encryption if (FDCGlobal.ProtocolVersion >= FDCVersion.V0100) { writer.Write(new[] { (byte)(0), this.ifsfManager.clientSocket.headerEncryption != 0 ? (byte)(1) : (byte)(0) }); } // writes encryption if (FDCGlobal.ProtocolVersion <= FDCVersion.V0007 || (FDCGlobal.ProtocolVersion >= FDCVersion.V0100 && this.ifsfManager.clientSocket.headerEncryption != 0)) { byte[] bytes; if (this.ifsfManager.clientSocket.headerEncryption != 0) { var crypter = new MD5Crypter(); var passPhrase = crypter.getPassphrase(); var hashingbytes = new byte[payload.Length + passPhrase.Length]; Array.Copy(payload, hashingbytes, payload.Length); Array.Copy(passPhrase, 0, hashingbytes, payload.Length, passPhrase.Length); bytes = crypter.ComputeHash(hashingbytes); } else { bytes = new byte[Define.MD5EncriptionLength]; for (int i = 0; i < Define.MD5EncriptionLength; i++) bytes[i] = 0; } writer.Write(bytes); } writer.Write(payload); memstream.WriteTo(netstream); DebugLog(string.Format("Serialize: memstream={0}", Encoding.UTF8.GetString(payload))); } } } public void SendConfigMessage(string configmessage) { NetworkStream netstream = socketReqChannelConfig.GetStream(); byte[] payload = Encoding.UTF8.GetBytes(configmessage); // writes header and encription string using (MemoryStream memstream = new MemoryStream()) { using (BinaryWriter writer = new BinaryWriter(memstream)) { writer.Write(new[] { (byte)(payload.Length >> 24), (byte)(payload.Length >> 16), (byte)(payload.Length >> 8), (byte)(payload.Length) }); // if V01 then writes algorithm type (0: no encription, 1: MD5 encryption if (FDCGlobal.ProtocolVersion >= FDCVersion.V0100) { writer.Write(new[] { (byte)(0), this.ifsfManager.clientSocket.headerEncryption != 0 ? (byte)(1) : (byte)(0) }); } // writes encryption if (FDCGlobal.ProtocolVersion <= FDCVersion.V0007 || (FDCGlobal.ProtocolVersion >= FDCVersion.V0100 && this.ifsfManager.clientSocket.headerEncryption != 0)) { byte[] bytes; if (this.ifsfManager.clientSocket.headerEncryption != 0) { var crypter = new MD5Crypter(); var passPhrase = crypter.getPassphrase(); var hashingbytes = new byte[payload.Length + passPhrase.Length]; Array.Copy(payload, hashingbytes, payload.Length); Array.Copy(passPhrase, 0, hashingbytes, payload.Length, passPhrase.Length); bytes = crypter.ComputeHash(hashingbytes); } else { bytes = new byte[Define.MD5EncriptionLength]; for (int i = 0; i < Define.MD5EncriptionLength; i++) bytes[i] = 0; } writer.Write(bytes); } writer.Write(payload); memstream.WriteTo(netstream); DebugLog(string.Format("SendConfigMessage: memstream={0}", configmessage)); } } } private void ifsfmessages_OnResponseTimeout(object sender, EventArgs e) { if (OnResponseTimeout != null) OnResponseTimeout.Invoke(this, null); } private void ifsfmessages_OnMessageEnqueued(object sender, EventArgs e) { DebugLog("ifsfmessages_OnMessageEnqueued init:"); string requestType = ""; int requestId = 0; try { while (ifsfMessages.serviceRequestChannelA.Count > 0) { BasePOSRequest sr = ifsfMessages.serviceRequestChannelA.Dequeue(); //DebugLog(string.Format("sr.GetType: {0}", sr.GetType().FullName)); if (sr.GetType() == typeof(POSMessagePOSReady)) { requestType = ((FDCMessage)sr).MessageType; requestId = Convert.ToInt32(((FDCMessage)sr).MessageID); } else { requestType = ((ServiceRequest)sr).RequestType; requestId = Convert.ToInt32(((ServiceRequest)sr).RequestID); } DebugLog(string.Format("SendRequest RequestType: {0}, requestId={1}", requestType, requestId)); if (requestType == "POSHeartBeat") { Serialize((ServiceRequestHeartbeat)sr); } else if (requestType == "POS_Ready") { //Serialize((ServiceRequestPOSReady)sr); Serialize((POSMessagePOSReady)sr); } else if (requestType == "LogOn") { if (FDCGlobal.ProtocolVersion <= FDCVersion.V0007) Serialize((ServiceRequestLogOnV07)sr); else Serialize((ServiceRequestLogOn)sr); } else if (requestType == "LogOff") { Serialize((ServiceRequestLogOff)sr); } else if (requestType == "VersionInfo") { Serialize((ServiceRequestVersionInfo)sr); } else if (requestType == "StartForecourt") { Serialize((ServiceRequestStartForecourt)sr); } else if (requestType == "TwinOpenMaster") { Serialize((ServiceRequestTwinOpenMaster)sr); } else if (requestType == "StopForecourt") { Serialize((ServiceRequestStopForecourt)sr); } else if (requestType == "GetCurrentFuellingStatus") { Serialize((ServiceRequestGetCurrentFuellingStatus)sr); } else if (requestType == "GetTotals") { Serialize((ServiceRequestGetFuelPointTotals)sr); } else if (requestType == "GetDeviceState") { Serialize((ServiceRequestGetDeviceState)sr); } else if (requestType == "GetFPState") { Serialize((ServiceRequestGetFPState)sr); } else if (requestType == "GetTPState") { Serialize((ServiceRequestGetTPState)sr); } else if (requestType == "GetPPState") { Serialize((ServiceRequestGetPPState)sr); } else if (requestType == "GetVIRState") { Serialize((ServiceRequestGetVIRState)sr); } else if (requestType == "TerminateFuelling") { Serialize((ServiceRequestTerminateFuelling)sr); } else if (requestType == "AuthoriseFuelPoint") { Serialize((ServiceRequestAuthoriseFuelPoint)sr); } else if (requestType == "ChangeFuelMode") { Serialize((ServiceRequestChangeFuelMode)sr); } else if (requestType == "ChangeFPFuelMode") { Serialize((ServiceRequestChangeFuelMode)sr); } else if (requestType == "ChangeFuelPrice") { Serialize((ServiceRequestChangeFuelPrice)sr); } else if (requestType == "LockFuelSaleTrx") { Serialize((ServiceRequestLockFuelSaleTrx)sr); } else if (requestType == "UnlockFuelSaleTrx") { Serialize((ServiceRequestUnlockFuelSaleTrx)sr); } else if (requestType == "ClearFuelSaleTrx") { Serialize((ServiceRequestClearFuelSaleTrx)sr); } else if (requestType == "GetAvailableFuelSaleTrxs") { Serialize((ServiceRequestGetAvailableFuelSaleTrxs)sr); } else if (requestType == "GetFuelSaleTrxDetails") { Serialize((ServiceRequestGetFuelSaleTrxDetails)sr); } else if (requestType == "GetProductTable") { Serialize((ServiceRequestGetProductTable)sr); } else if (requestType == "GetModeTable") { Serialize((ServiceRequestGetModeTable)sr); } else if (requestType == "GetFuelMode") { Serialize((ServiceRequestGetFuelMode)sr); } else if (requestType == "GetFPFuelMode") { Serialize((ServiceRequestGetFPFuelMode)sr); } else if (requestType == "GetConfiguration") { Serialize((ServiceRequestGetConfiguration)sr); } else if (requestType == "GetDSPConfiguration") { Serialize((ServiceRequestGetDSPConfiguration)sr); } else if (requestType == "GetTLGConfiguration") { Serialize((ServiceRequestGetTLGConfiguration)sr); } else if (requestType == "GetPPConfiguration") { Serialize((ServiceRequestGetPPConfiguration)sr); } else if (requestType == "SetConfiguration") { Serialize((ServiceRequestSetConfiguration)sr); } else if (requestType == "LockNozzle") { Serialize((ServiceRequestLockNozzle)sr); } else if (requestType == "UnlockNozzle") { Serialize((ServiceRequestUnlockNozzle)sr); } else if (requestType == "OpenDevice") { Serialize((ServiceRequestOpenDevice)sr); } else if (requestType == "CloseDevice") { Serialize((ServiceRequestCloseDevice)sr); } else if (requestType == "GetCountrySettings") { Serialize((ServiceRequestGetCountrySettings)sr); } else if (requestType == "GetDSPLimits") { Serialize((ServiceRequestGetDSPLimits)sr); } else if (requestType == "ChangeDSPLimits") { Serialize((ServiceRequestChangeDSPLimits)sr); } else if (requestType == "SuspendFuelling") { Serialize((ServiceRequestSuspendFuelling)sr); } else if (requestType == "ResumeFuelling") { Serialize((ServiceRequestResumeFuelling)sr); } else if (requestType == "LockTank") { Serialize((ServiceRequestLockTank)sr); } else if (requestType == "UnlockTank") { Serialize((ServiceRequestUnlockTank)sr); } else if (requestType == "GetTankData") { Serialize((ServiceRequestGetTankData)sr); } else if (requestType == "ReserveFuelPoint") { Serialize((ServiceRequestReserveFuelPoint)sr); } else if (requestType == "FreeFuelPoint") { Serialize((ServiceRequestFreeFuelPoint)sr); } else if (requestType == "StartFuelPointTest") { Serialize((ServiceRequestStartFuelPointTest)sr); } else if (requestType == "EndFuelPointTest") { Serialize((ServiceRequestEndFuelPointTest)sr); } else if (requestType == "OpenFuelPoint") { Serialize((ServiceRequestOpenFuelPoint)sr); } else if (requestType == "CloseFuelPoint") { Serialize((ServiceRequestCloseFuelPoint)sr); } else if (requestType == "SetDeviceAlarm") { Serialize((ServiceRequestSetDeviceAlarm)sr); } else if (requestType == "OPTAdd") { Serialize((ServiceRequestOPTAdd)sr); } else if (requestType == "OPTRemove") { Serialize((ServiceRequestOPTRemove)sr); } else if (requestType == "OPTWrite") { if (FDCGlobal.ProtocolVersion <= FDCVersion.V0007) Serialize((ServiceRequestOPTWriteV07)sr); else Serialize((ServiceRequestOPTWrite)sr); } else if (requestType == "ConfigStart") { Serialize((ServiceRequestConfigStart)sr); } else if (requestType == "ConfigEnd") { Serialize((ServiceRequestConfigEnd)sr); } else if (requestType == "DefProducts") { Serialize((ServiceRequestDefProducts)sr); } else if (requestType == "DefGrades" || requestType == "DefGrade") { Serialize((ServiceRequestDefGrades)sr); } else if (requestType == "AssignGradePars") { Serialize((ServiceRequestAssignGradePars)sr); } else if (requestType == "DefTanks") { Serialize((ServiceRequestDefTanks)sr); } else if (requestType == "DefTankSuctions") { Serialize((ServiceRequestDefTankSuctions)sr); } else if (requestType == "DefFuelMode" || requestType == "DefFPFuelModes") { Serialize((ServiceRequestDefFuelMode)sr); } else if (requestType == "DefFuellingMode" || requestType == "DefFCFuelMode") { Serialize((ServiceRequestDefFuellingMode)sr); } else if (requestType == "DefFuelPoint") { Serialize((ServiceRequestDefFuelPoint)sr); } else if (requestType == "DefFuelPoints") { Serialize((ServiceRequestDefFuelPoints)sr); } else if (requestType == "AssignGrades") { Serialize((ServiceRequestAssignGrades)sr); } else if (requestType == "AssignMeters") { Serialize((ServiceRequestAssignMeters)sr); } else if (requestType == "AssignTanks") { Serialize((ServiceRequestAssignTanks)sr); } else if (requestType == "DefPricePole" | requestType == "DefPricePoles") { Serialize((ServiceRequestDefPricePole)sr); } else if (requestType == "LoadPriceset") { Serialize((ServiceRequestLoadPriceset)sr); } else if (requestType == "DefTankMonitor" || requestType == "DefTankMonitors") { Serialize((ServiceRequestDefTankMonitor)sr); } else if (requestType == "GetFuelPrice") { Serialize((ServiceRequestGetFuelPrices)sr); } else if (requestType == "DefFPOperationModes") { Serialize((ServiceRequestDefFPOperationModes)sr); } else if (requestType == "CloseReconciliationPeriod") { Serialize((ServiceRequestCloseReconciliationPeriod)sr); } else if (requestType == "GetTankReconciliation") { Serialize((ServiceRequestGetTankReconciliation)sr); } else if (requestType == "GetTankDelivery") { Serialize((ServiceRequestGetTankDelivery)sr); } else if (requestType == "StartFuelPoint") { Serialize((ServiceRequestStartFuelPoint)sr); } else if (requestType == "StopFuelPoint") { Serialize((ServiceRequestStopFuelPoint)sr); } else { DebugLog(string.Format("!!!!! Unhandled SendRequest RequestType: {0}, requestId={1}", requestType, requestId)); } } } catch (Exception ex) { DebugLog("ifsfmessages_OnMessageEnqueued RequestType:" + requestType + " RequestId:" + requestId + " Exception! " + ex.ToString()); if (mainConnectionState != DeviceConnectionState.Disconnected) { this.ifsfManager.Disconnect(); mainConnectionState = DeviceConnectionState.Disconnected; } } DebugLog(string.Format("ifsfmessages_OnMessageEnqueued end RequestType: {0}", requestType)); } } }