using System; using System.Collections.Generic; using System.Text; using System.Threading; using System.Xml.Serialization; using System.IO; using System.Net; using System.Net.Sockets; //using DWItaly.Sinp.Utility; using Wayne.Lib; using Wayne.FDCPOSLibrary; using Wayne.FDCPOSLibrary.Configuration; namespace Wayne.ForecourtControl.Fusion { public class TCPListenerThread { public bool bRunning = false; public bool bTerminate = false; TcpListener tcpListener = null; IFSFManager ifsfManager = null; string name = ""; public TCPListenerThread(TcpListener _listener, IFSFManager _ifsfManager, string _name) { tcpListener = _listener; ifsfManager = _ifsfManager; name = _name; } public void TCPListenerThreadProc() { Trace.WriteLine(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) { Trace.WriteLine("tcpListener starting"); tcpListener.Start(); Trace.WriteLine("tcpListener started"); } } catch (Exception ex) { Trace.WriteLine("TCPListenerThreadProc: Exception tcpListener.Start! " + ex.Message + " - " + ex.StackTrace); bRunning = false; return; } bTerminate = false; string sbuffer = ""; OverallResult result = OverallResult.Success; NetworkStream networkStream = null; System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding(); while (!bTerminate) { try { result = OverallResult.Success; if (tcpclient == null && tcpListener != null) //-- || !tcpclient.Connected) { Trace.WriteLine("TCPListenerThreadProc: TcpClient Accepting"); tcpclient = tcpListener.AcceptTcpClient(); Trace.WriteLine("TcpClient Accepted"); } else { //Trace.WriteLine(string.Format("{0} getting stream ...", this.name)); if (tcpListener != null) networkStream = tcpclient.GetStream(); else if (ifsfManager.clientSocket.socketReqChannelA != null) // Disconnet() makes _socketRequChannelA to null!!! networkStream = ifsfManager.clientSocket.socketReqChannelA.GetStream(); else { Trace.WriteLine("Both tcpListener and socketReqChannelA are null!!! break out - Id=" + this.ifsfManager.clientSocket.Id); break; } Trace.WriteLineIf(Trace.CheckTraceLevel(3), 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 byte[] 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; } header = new byte[headerLength]; Trace.WriteLineIf(Trace.CheckTraceLevel(3), string.Format("TCPListenerThreadProc: header length={0}", header.GetLength(0))); int nread = 0, nreadtot = 0; do { Trace.WriteLineIf(Trace.CheckTraceLevel(4), string.Format("TCPListenerThreadProc: reading ...")); nread = networkStream.Read(header, nreadtot, (headerLength) - nreadtot); Trace.WriteLineIf(Trace.CheckTraceLevel(4), 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); // There're some cases that msglenght was huge > 120mb if (msglength > 40000) throw new System.OutOfMemoryException("Wayne's exception: Out of memory"); // read message byte[] buffer; buffer = new byte[msglength]; Trace.WriteLineIf(Trace.CheckTraceLevel(3), string.Format("TCPListenerThreadProc: buffer msg length={0}", buffer.GetLength(0))); nreadtot = 0; do { Trace.WriteLineIf(Trace.CheckTraceLevel(4), string.Format("TCPListenerThreadProc: reading ...")); nread = networkStream.Read(buffer, nreadtot, msglength - nreadtot); Trace.WriteLineIf(Trace.CheckTraceLevel(4), 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 (!bTerminate && (nreadtot < msglength)); sb.Remove(0, sb.Length); sb.Append(Encoding.UTF8.GetString(buffer, 0, nreadtot)); Trace.WriteLineIf(Trace.CheckTraceLevel(3), string.Format("TCPListenerThreadProc Id={0}, WId={1}: read '{2}' bytes: {3}", this.ifsfManager.clientSocket.Id, this.ifsfManager.clientSocket.workstationID, msglength, Encoding.ASCII.GetString(buffer, 0, msglength))); sbuffer += sb.ToString(); bool bEnd = false; string sEndmsg = "", smsg = ""; int indexEndMsgSR = -1, indexEndFDCMsg = -1, indexEnd = -1; indexEnd = sbuffer.IndexOf("/>"); //Trace.WriteLineIf(Trace.CheckTraceLevel(3), string.Format("indexend={0}, buffer={1}", indexEnd, sbuffer)); do { indexEndMsgSR = sbuffer.IndexOf(""); indexEndFDCMsg = sbuffer.IndexOf(""); 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 (indexEndFDCMsg > 0) { indexEnd = indexEndFDCMsg; sEndmsg = ""; } else { indexEnd = sbuffer.IndexOf("/>"); sEndmsg = "/>"; } if (indexEnd >= 0) { smsg = sbuffer.Substring(0, indexEnd + sEndmsg.Length); sbuffer = sbuffer.Substring(indexEnd + sEndmsg.Length); //Trace.WriteLine(string.Format("smsg={0}, sbuffer={1}", smsg, sbuffer)); //string sValue = IniFile.IniReadValue(ConfigurationParams.inifile, "FUSION-Connection", "CheckEncryption"); if (this.ifsfManager.clientSocket.headerEncryption != 0) { MD5Crypter crypter = new MD5Crypter(); if (!crypter.verifyMD5Hash(smsg + MD5Crypter.passphrase, System.Text.Encoding.ASCII.GetString(header, Define.HeaderLength, Define.MD5EncriptionLength))) result = OverallResult.ValidationError; } if (smsg.Length > 0) { if (indexEndMsgSR >= 0) ifsfManager.ReadResponse(smsg, msglength, ref result); else if (indexEndFDCMsg > 0) ifsfManager.ReadMessage(smsg, msglength, ref result); } } else bEnd = true; } while (!bEnd); } } catch (SocketException sex) { Trace.WriteLine("Exception TCPListenerThreadProc: " + sex.Message); tcpclient = null; if (sex.ErrorCode == 10049) ifsfManager.Disconnect(); Thread.Sleep(1000); } catch (Exception ex) { tcpclient = null; ifsfManager.isForcedToDisconnect = true; Trace.WriteLine(string.Format("Exception TCPListenerThreadProc! {0}, Id={1}", ex.Message + " - " + ex.StackTrace, this.ifsfManager.clientSocket.Id)); ifsfManager.Disconnect(); bTerminate = true; // WJU - get out of the loop since Disconnect was called already. This is a quicker way out. } } if (tcpListener != null) tcpListener.Stop(); bRunning = false; Trace.WriteLine(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)); byte[] inputhash; 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]) { Trace.WriteLine(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)))); Trace.WriteLine(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 |= ((int)(header[pos - 1] << (Define.HeaderLength - pos) * 8)); } return length; } } public class IFSFSockets : IIdentifiableEntity, IDisposable//, IConnectable { private TcpClient _socketReqChannelA = null; public TcpClient socketReqChannelA { get { return _socketReqChannelA; } } private TcpListener _socketRespChannelB = null; public TcpListener socketRespChannelB { get { return _socketRespChannelB; } } private TcpListener _socketUnsolicitedChannelC = null; public TcpListener socketUnsolicitedChannelC { get { return _socketUnsolicitedChannelC; } } private TcpClient _socketReqChannelConfig = null; 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 = null; IFSFMessages _ifsfMessages = null; 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 = 0; public int iIPPortA { get { return _iIPPortA; } } private int _iIPPortB = 0; public int iIPPortB { get { return _iIPPortB; } } private int _iIPPortC = 0; public int iIPPortC { get { return _iIPPortC; } } private long _heartbeatInterval = 20000; public long heartbeatInterval { get { return _heartbeatInterval; } } private long _heartbeatTimeout = 20000; public long heartbeatTimeout { get { return _heartbeatTimeout; } } private long _headerEncryption = 1; public long headerEncryption { get { return _headerEncryption; } set { _headerEncryption = value; } } public bool logOnSendCalled = false; private byte[][] _validationInfo = null; 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 object _socketLockObject = new object(); internal object SocketLockObject { get { return _socketLockObject; } } private DeviceConnectionState _mainConnectionState = DeviceConnectionState.Disconnected; public DeviceConnectionState mainConnectionState { get { return _mainConnectionState; } set { lock (SocketLockObject) { if (_mainConnectionState != value) { _mainConnectionState = value; if (OnConnectionStateChange != null) { OnConnectionStateChange.Invoke(this, new ConnectionChangedEventArgs(mainConnectionState)); } } } } } public event EventHandler OnConnectionStateChange; public event EventHandler OnResponseTimeout; public readonly ConfigurationParams configParam; public IFSFSockets(int id, IFSFManager _ifsfManager/*, IIdentifiableEntity parentEntity*/) { this.id = id; this.parentEntity = (IIdentifiableEntity)ifsfManager; ifsfManager = _ifsfManager; configParam = _ifsfManager.ConfigParam; 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); _ifsfMessages.OnIFSFSMessageEnqueued += new EventHandler(ifsfmessages_OnMessageEnqueued); _ifsfMessages.OnResponseTimeout += new EventHandler(ifsfmessages_OnResponseTimeout); } 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) { Trace.WriteLine(string.Format("Exception reading IdShift: {0}", ex.Message + " - " + ex.StackTrace)); } } 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) { Trace.WriteLine(string.Format("Exception reading IdPumpShift: {0}", ex.Message + " - " + ex.StackTrace)); } } 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) { Trace.WriteLine(string.Format("Exception reading IdNozzleShift: {0}", ex.Message + " - " + ex.StackTrace)); } } 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) { Trace.WriteLine(string.Format("Exception reading IdTankShift: {0}", ex.Message + " - " + ex.StackTrace)); } } 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) { Trace.WriteLine(string.Format("Exception reading IPPortA: {0}", ex.Message + " - " + ex.StackTrace)); } } key = "PortB"; if (connectionStringParamDict.ContainsKey(key) && connectionStringParamDict[key] != null && connectionStringParamDict[key] != "") { try { this._iIPPortB = Convert.ToInt32(connectionStringParamDict[key]); } catch (Exception ex) { Trace.WriteLine(string.Format("Exception reading IPPortB: {0}", ex.Message + " - " + ex.StackTrace)); } } key = "PortC"; if (connectionStringParamDict.ContainsKey(key) && connectionStringParamDict[key] != null && connectionStringParamDict[key] != "") { try { this._iIPPortC = Convert.ToInt32(connectionStringParamDict[key]); } catch (Exception ex) { Trace.WriteLine(string.Format("Exception reading IPPortC: {0}", ex.Message + " - " + ex.StackTrace)); } } //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.ToInt16(connectionStringParamDict[key]); } catch (Exception ex) { Trace.WriteLine(string.Format("Exception reading heartbeatInterval: {0}", ex.Message + " - " + ex.StackTrace)); } } key = "heartbeatTimeout"; if (connectionStringParamDict.ContainsKey(key) && connectionStringParamDict[key] != null && connectionStringParamDict[key] != "") { try { this._heartbeatTimeout = Convert.ToInt16(connectionStringParamDict[key]); } catch (Exception ex) { Trace.WriteLine(string.Format("Exception reading _heartbeatTimeout: {0}", ex.Message + " - " + ex.StackTrace)); } } key = "headerEncryption"; if (connectionStringParamDict.ContainsKey(key) && connectionStringParamDict[key] != null && connectionStringParamDict[key] != "") { try { this._headerEncryption = Convert.ToInt16(connectionStringParamDict[key]); } catch (Exception ex) { Trace.WriteLine(string.Format("Exception reading _headerEncryption: {0}", ex.Message + " - " + ex.StackTrace)); } } 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) { Trace.WriteLine(string.Format("Exception reading _validationInfo: {0}", ex.Message + " - " + ex.StackTrace)); } } 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; bool bIPAddress = false; 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); Trace.WriteLine(string.Format("socketTimeout={0}", socketTimeout)); sValue = IniFile.IniReadValue(ConfigurationParams.inifile, "FUSION-Connection", "NoDelay"); if (sValue.Length > 0 && sValue == "0") noDelay = false; Trace.WriteLine(string.Format("socketTimeout={0}", socketTimeout)); } catch (Exception ex) { Trace.WriteLine("EXCEPTION! " + ex.Message); } _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; Trace.WriteLine(error); } else if (retrycount == 10) { retrycount = 0; ipAddress = this._sIPAddress; Trace.WriteLine(error); Thread.Sleep(5000); } retrycount++; try { socketReqChannelConfig.Connect(ipAddress, iIPPortConfig); bConnected = true; } catch (SocketException sex) { Trace.WriteLine(sex.Message + " - " + sex.StackTrace); if (sex.ErrorCode == 10049) bIPAddress = false; 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) { Trace.WriteLine(string.Format("end: EXCEPTION! Stack chiamate: {0} Messaggio: {1}", ex.StackTrace, ex.Message)); } if (iIPPortConfig != this._iIPPortA) { if (_socketReqChannelConfig != null) this._socketReqChannelConfig.Close(); this._socketReqChannelConfig = null; } } else Trace.WriteLine("SendConfig ERROR: NOT Connected!"); } /// /// will setup the tcp connect and send LogOn request to Fdc server. /// /// /// public bool Connect(string connectionString) { Trace.WriteLine(string.Format("start Connect: status='{0}'", this.mainConnectionState)); lock (ifsfManager.SyncObject) { if ((this.mainConnectionState == DeviceConnectionState.Disconnected) || (this.mainConnectionState == DeviceConnectionState.Disconnecting)) { //this.mainConnectionState = DeviceConnectionState.Connecting; try { Trace.WriteLine(string.Format("id={0}, -connectionString:'{1}'", this.id, connectionString)); getConnectionParams(connectionString); FDCGlobal.ProtocolVersion = FDCVersion.V0007;// "00.07";// FDCGlobal.VersionFromString(IniFile.IniReadValue(ConfigurationParams.inifile, "FUSION-Connection", "FDCPOSInterfaceVersion")); Trace.WriteLine(string.Format("id={0}, version:'{1}'", this.id, FDCGlobal.ProtocolVersion)); 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); Trace.WriteLine(string.Format("socketTimeout={0}", socketTimeout)); sValue = IniFile.IniReadValue(ConfigurationParams.inifile, "FUSION-Connection", "NoDelay"); if (sValue.Length > 0 && sValue == "0") noDelay = false; Trace.WriteLine(string.Format("socketTimeout={0}", socketTimeout)); } catch (Exception ex) { Trace.WriteLine("EXCEPTION! " + ex.Message); } 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; Trace.WriteLine(error); } else if (retrycount == 10) { retrycount = 0; ipAddress = this._sIPAddress; Trace.WriteLine(error); Thread.Sleep(5000); } retrycount++; try { Trace.WriteLine(string.Format("connecting to ip={0}, port={1}", ipAddress, this.iIPPortA)); this.socketReqChannelA.Connect(ipAddress, this.iIPPortA); bConnected = true; } catch (SocketException sex) { error = sex.Message + " - " + sex.StackTrace; Console.WriteLine("IFSFSocket to " + ipAddress + ", " + this.iIPPortA + " exceptioned: " + sex); Thread.Sleep(3000); } } if (iIPPortB != iIPPortA /*&& _socketRespChannelB == null*/) _socketRespChannelB = new TcpListener(iIPPortB); else _socketRespChannelB = null; if (iIPPortC != iIPPortA /*&& _socketUnsolicitedChannelC == null*/) _socketUnsolicitedChannelC = new TcpListener(iIPPortC); else _socketUnsolicitedChannelC = null; Trace.WriteLine(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) { Trace.WriteLine(string.Format("end: EXCEPTION! Stack chiamate: {0} Messaggio: {1}", ex.StackTrace, ex.Message)); return false; } } } //if ((this.mainConnectionState != DeviceConnectionState.Disconnected) && (this.mainConnectionState != DeviceConnectionState.Disconnecting)) //{ // throw new SocketException(SocketExceptionType.ClientNotDisconnected); //} //TransportFrameClientSocket.ValidateConnectionString(connectionString); //if (this.debugLogger.IsActive(LogCategory.UserRequest, DebugLogLevel.Normal)) //{ // this.debugLogger.Add(string.Format("Connect({0})", connectionString), LogCategory.UserRequest, DebugLogLevel.Normal); //} //this.userWantConnection = true; //this.stateMachine.IncomingEvent(new ConnectionStringStateEngineEvent(connectionString, EventType.ConnectRequested)); Trace.WriteLine("end: ok"); return true; } public void Disconnect() { //if ((this.mainConnectionState == DeviceConnectionState.Connected) || (this.mainConnectionState == DeviceConnectionState.Connecting)) { Trace.WriteLine("terminating respThreadObjs"); if (respChannelBThreadObj != null) respChannelBThreadObj.bTerminate = true; Trace.WriteLine("terminating respChannelCThreadObj"); if (unsolicitedChannelCThreadObj != null) unsolicitedChannelCThreadObj.bTerminate = true; if (respChannelConfigThreadObj != null) respChannelConfigThreadObj.bTerminate = true; 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; //if (this.debugLogger.IsActive(LogCategory.UserRequest, DebugLogLevel.Normal)) //{ // this.debugLogger.Add(string.Format("Disconnect()", new object[0]), LogCategory.UserRequest, DebugLogLevel.Normal); //} //this.userWantConnection = false; //this.stateMachine.IncomingEvent(new StateEngineEvent(EventType.DisconnectRequested)); } } public virtual void Dispose() { this.Dispose(true); GC.SuppressFinalize(this); } private void Dispose(bool disposing) { if (!this.disposed) { this.disposed = true; if (disposing) { //this.transportFrameClientSocket.Dispose(); //this.stateMachine.Dispose(); //this.debugLogger.Dispose(); } } } // Properties //[CLSCompliant(false)] //public ushort ClientId //{ // get // { // return this.transportFrameClientSocket.ClientId; // } //} //public string ClientName //{ // get // { // return this.transportFrameClientSocket.Name; // } //} 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 implementing 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) { if (sr != null && socketReqChannelA != null) { XmlSerializer serializer = null; var netstream = socketReqChannelA.GetStream(); using (var memstream = new MemoryStream()) { serializer = new XmlSerializer(typeof(T)); serializer.Serialize(memstream, (T)sr); // writes header and encription string using (var memstream2 = new MemoryStream()) { byte[] bytes = new byte[Define.HeaderLength]; using (var writer = new BinaryWriter(memstream2)) { bytes[3] = (byte)(memstream.Length & 0x000000FF); bytes[2] = (byte)((memstream.Length & 0x0000FF00) / Math.Pow(2, 8)); bytes[1] = (byte)((memstream.Length & 0x00FF0000) / Math.Pow(2, 16)); bytes[0] = (byte)((memstream.Length & 0xFF000000) / Math.Pow(2, 24)); writer.Write(bytes); bytes = new byte[Define.EncriptionTypeLength]; //string sValue = IniFile.IniReadValue(ConfigurationParams.inifile, "FUSION-Connection", "CheckEncryption"); if (this.ifsfManager.clientSocket.headerEncryption != 0) { MD5Crypter crypter = new MD5Crypter(); byte[] hashingbytes = new byte[memstream.Length + crypter.getPassphrase().GetLength(0)]; Array.Copy(memstream.GetBuffer(), hashingbytes, (int)memstream.Length); Array.Copy(crypter.getPassphrase(), 0, hashingbytes, (int)memstream.Length, (int)crypter.getPassphrase().Length); bytes = crypter.ComputeHash(hashingbytes); } else { for (int i = 0; i < Define.EncriptionTypeLength; i++) bytes[i] = 0; } writer.Write(bytes); memstream2.WriteTo(netstream); } } memstream.WriteTo(netstream); } TraceXML(serializer, (T)sr); } } public void SendConfigMessage(string configmessage) { NetworkStream netstream = socketReqChannelConfig.GetStream(); // writes header and encription string using (MemoryStream memstream = new MemoryStream()) { byte[] bytes = new byte[Define.HeaderLength]; using (BinaryWriter writer = new BinaryWriter(memstream)) { bytes[3] = (byte)(configmessage.Length & 0x000000FF); bytes[2] = (byte)((configmessage.Length & 0x0000FF00) / Math.Pow(2, 8)); bytes[1] = (byte)((configmessage.Length & 0x00FF0000) / Math.Pow(2, 16)); bytes[0] = (byte)((configmessage.Length & 0xFF000000) / Math.Pow(2, 24)); writer.Write(bytes); if (FDCGlobal.ProtocolVersion >= FDCVersion.V0100) { bytes = new byte[Define.EncriptionTypeLength]; if (this.ifsfManager.clientSocket.headerEncryption != 0) bytes[1] = (byte)(1); else bytes[1] = (byte)(0); bytes[0] = (byte)(0); writer.Write(bytes); } // writes encryption if (FDCGlobal.ProtocolVersion <= FDCVersion.V0007 || (FDCGlobal.ProtocolVersion >= FDCVersion.V0100 && this.ifsfManager.clientSocket.headerEncryption != 0)) { bytes = new byte[Define.MD5EncriptionLength]; //string sValue = IniFile.IniReadValue(ConfigurationParams.inifile, "FUSION-Connection", "CheckEncryption"); if (this.ifsfManager.clientSocket.headerEncryption != 0) { var crypter = new MD5Crypter(); byte[] hashingbytes = new byte[memstream.Length + crypter.getPassphrase().GetLength(0)]; Array.Copy(memstream.GetBuffer(), hashingbytes, (int)memstream.Length); Array.Copy(crypter.getPassphrase(), 0, hashingbytes, (int)memstream.Length, (int)crypter.getPassphrase().Length); bytes = crypter.ComputeHash(hashingbytes); } else { for (int i = 0; i < Define.MD5EncriptionLength; i++) bytes[i] = 0; } writer.Write(bytes); } byte[] bytedata; System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding(); bytedata = encoding.GetBytes(configmessage); writer.Write(bytedata); memstream.WriteTo(netstream); TraceXML(memstream, configmessage); } } } private void ifsfmessages_OnResponseTimeout(object sender, EventArgs e) { if (OnResponseTimeout != null) OnResponseTimeout.Invoke(this, e); } private void ifsfmessages_OnMessageEnqueued(object sender, EventArgs e) { Trace.WriteLineIf(Trace.CheckTraceLevel(3), string.Format("ifsfmessages_OnMessageEnqueued init")); string requestType = ""; int requestId = 0; try { while (ifsfMessages.serviceRequestChannelA.Count > 0) { BasePOSRequest sr = ifsfMessages.serviceRequestChannelA.Dequeue(); Trace.WriteLine(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); } switch (requestType) { case "POSHeartBeat": Serialize((ServiceRequestHeartbeat)sr); break; case "LogOn": if (FDCGlobal.ProtocolVersion <= FDCVersion.V0007) Serialize((ServiceRequestLogOnV07)sr); else Serialize((ServiceRequestLogOn)sr); break; case "LogOff": Serialize((ServiceRequestLogOff)sr); break; case "VersionInfo": Serialize((ServiceRequestVersionInfo)sr); break; case "StartForecourt": Serialize((ServiceRequestStartForecourt)sr); break; case "StopForecourt": Serialize((ServiceRequestStopForecourt)sr); break; case "GetCurrentFuellingStatus": Serialize((ServiceRequestGetCurrentFuellingStatus)sr); break; case "GetFuelPointTotals": Serialize((ServiceRequestGetFuelPointTotals)sr); break; case "GetDeviceState": Serialize((ServiceRequestGetDeviceState)sr); break; case "TerminateFuelling": Serialize((ServiceRequestTerminateFuelling)sr); break; case "AuthoriseFuelPoint": Serialize((ServiceRequestAuthoriseFuelPoint)sr); break; case "ChangeFuelMode": Serialize((ServiceRequestChangeFuelMode)sr); break; case "ChangeFuelPrice": Serialize((ServiceRequestChangeFuelPrice)sr); break; case "LockFuelSaleTrx": Serialize((ServiceRequestLockFuelSaleTrx)sr); break; case "UnlockFuelSaleTrx": Serialize((ServiceRequestUnlockFuelSaleTrx)sr); break; case "ClearFuelSaleTrx": Serialize((ServiceRequestClearFuelSaleTrx)sr); break; case "GetAvailableFuelSaleTrxs": Serialize((ServiceRequestGetAvailableFuelSaleTrxs)sr); break; case "GetFuelSaleTrxDetails": Serialize((ServiceRequestGetFuelSaleTrxDetails)sr); break; case "GetProductTable": Serialize((ServiceRequestGetProductTable)sr); break; case "GetModeTable": Serialize((ServiceRequestGetModeTable)sr); break; case "GetFuelMode": Serialize((ServiceRequestGetFuelMode)sr); break; case "GetConfiguration": Serialize((ServiceRequestGetConfiguration)sr); break; case "GetDSPConfiguration": Serialize((ServiceRequestGetDSPConfiguration)sr); break; case "GetTLGConfiguration": Serialize((ServiceRequestGetTLGConfiguration)sr); break; case "GetPPConfiguration": Serialize((ServiceRequestGetPPConfiguration)sr); break; case "SetConfiguration": Serialize((ServiceRequestSetConfiguration)sr); break; case "LockNozzle": Serialize((ServiceRequestLockNozzle)sr); break; case "UnlockNozzle": Serialize((ServiceRequestUnlockNozzle)sr); break; case "OpenDevice": Serialize((ServiceRequestOpenDevice)sr); break; case "CloseDevice": Serialize((ServiceRequestCloseDevice)sr); break; case "GetCountrySettings": Serialize((ServiceRequestGetCountrySettings)sr); break; case "GetDSPLimits": Serialize((ServiceRequestGetDSPLimits)sr); break; case "ChangeDSPLimits": Serialize((ServiceRequestChangeDSPLimits)sr); break; case "SuspendFuelling": Serialize((ServiceRequestSuspendFuelling)sr); break; case "ResumeFuelling": Serialize((ServiceRequestResumeFuelling)sr); break; case "LockTank": Serialize((ServiceRequestLockTank)sr); break; case "UnlockTank": Serialize((ServiceRequestUnlockTank)sr); break; case "GetTankData": Serialize((ServiceRequestGetTankData)sr); break; case "ReserveFuelPoint": Serialize((ServiceRequestReserveFuelPoint)sr); break; case "FreeFuelPoint": Serialize((ServiceRequestFreeFuelPoint)sr); break; case "StartFuelPointTest": Serialize((ServiceRequestStartFuelPointTest)sr); break; case "EndFuelPointTest": Serialize((ServiceRequestEndFuelPointTest)sr); break; case "OpenFuelPoint": Serialize((ServiceRequestOpenFuelPoint)sr); break; case "CloseFuelPoint": Serialize((ServiceRequestCloseFuelPoint)sr); break; case "SetDeviceAlarm": Serialize((ServiceRequestSetDeviceAlarm)sr); break; case "OPTAdd": Serialize((ServiceRequestOPTAdd)sr); break; case "OPTRemove": Serialize((ServiceRequestOPTRemove)sr); break; case "OPTWrite": if (FDCGlobal.ProtocolVersion <= FDCVersion.V0007) Serialize((ServiceRequestOPTWriteV07)sr); else Serialize((ServiceRequestOPTWrite)sr); break; case "ConfigStart": Serialize((ServiceRequestConfigStart)sr); break; case "ConfigEnd": Serialize((ServiceRequestConfigEnd)sr); break; case "DefGrade": case "DefGrades": Serialize((ServiceRequestDefGrades)sr); break; case "AssignGradePars": Serialize((ServiceRequestAssignGradePars)sr); break; case "DefTanks": Serialize((ServiceRequestDefTanks)sr); break; case "DefFuelMode": Serialize((ServiceRequestDefFuelMode)sr); break; case "DefFuellingMode": Serialize((ServiceRequestDefFuellingMode)sr); break; case "DefFuelPoint": Serialize((ServiceRequestDefFuelPoint)sr); break; case "AssignGrades": Serialize((ServiceRequestAssignGrades)sr); break; case "AssignMeters": Serialize((ServiceRequestAssignMeters)sr); break; case "AssignTanks": Serialize((ServiceRequestAssignTanks)sr); break; case "DefPricePole": Serialize((ServiceRequestDefPricePole)sr); break; case "LoadPriceset": Serialize((ServiceRequestLoadPriceset)sr); break; case "GetTPState": Serialize((ServiceRequestGetTPState)sr); break; default: throw new ArgumentOutOfRangeException("probably a merge issue..."); } } } catch (SocketException sex) { Trace.WriteLine("ifsfmessages_OnMessageEnqueued RequestType:" + requestType + " RequestId:" + requestId + " Exception! " + sex.Message + " - " + sex.StackTrace); if (mainConnectionState != DeviceConnectionState.Disconnected) { this.ifsfManager.Disconnect(); mainConnectionState = DeviceConnectionState.Disconnected; } } catch (Exception ex) { Trace.WriteLine("ifsfmessages_OnMessageEnqueued RequestType:" + requestType + " RequestId:" + requestId + " Exception! " + ex.Message + " - " + ex.StackTrace); if (mainConnectionState != DeviceConnectionState.Disconnected) { this.ifsfManager.Disconnect(); mainConnectionState = DeviceConnectionState.Disconnected; } } Trace.WriteLineIf(Trace.CheckTraceLevel(3), string.Format("ifsfmessages_OnMessageEnqueued end RequestType:{0}", requestType)); } private void TraceXML(XmlSerializer serializer, T sr) { try { if (configParam.TraceXML) { DateTime now = DateTime.Now; using (var testwriter = new StreamWriter(string.Format("{0}{1:00}-{2:00}-xmlClientMsg.xml", ConfigurationParams.tracePath, now.Day, now.Month), true)) { serializer.Serialize(testwriter, (T)sr); } } } catch (Exception ex) { Trace.WriteLine("Exception! " + ex.Message + " - " + ex.StackTrace); } } private void TraceXML(MemoryStream ms, string msg) { try { if (configParam.TraceXML) { DateTime now = DateTime.Now; using (var testwriter = new StreamWriter(string.Format("{0}{1:00}-{2:00}-xmlClientMsg.xml", ConfigurationParams.tracePath, now.Day, now.Month), true)) { testwriter.Write(msg); } } } catch (Exception ex) { Trace.WriteLine("Exception! " + ex.Message + " - " + ex.StackTrace); } } } }