#region Namespace using System; using System.Collections.Generic; using System.Configuration; using System.Diagnostics; using System.Net; using System.Net.Sockets; using Asm.As.Oib.Client; using com.itac.mes.domain; using com.itac.mes.proxy.sockets; using com.itac.mes.tools; using Itac.Oib; #endregion namespace com.itac.oib { // remote-Methoden zum steuern der einzelnen Teile der Anwendung public class AdapterControl : IAdapterControl, IDisposable { #region Fields // Zugriff auf die folgenden Maps muss synchronisiert erfolgen static readonly object _locker = new object(); // In dieser Map sind alle offenen Verbindungen zum DataInterface enthalten private Dictionary openClientChannels = new Dictionary(); // pro Verbindung wird gez?hlt wie viele Connections es schon gab... private Dictionary channelNameCounter = new Dictionary(); // Verbindungsparameter zum DataInterface. Diese werden nach dem Start des DataInterface an den Adapter ?bertragen private int _port = 0; private string _ipAddress = ""; private string _hostName = ""; private string _canonicalHostName = ""; // die folgenden Werte werden beim Initialisieren des iTAC.OIB.Adapter gesetzt private int _own_itac_oib_adapter_port = 0; private string _own_ip_address = ""; private string _own_host_name = ""; private string _own_canonical_host_name = ""; #endregion // die eigentlichen OIB-Event-Receiver public SetupCenterReceiver SetupCenterReceiver { set; get; } public SetupCenterExternalControlReceiver SetupCenterExternalControlReceiver { set; get; } public MonitoringReceiver MonitoringReceiver { set; get; } public TraceabilityReceiver TraceReceiver { set; get; } public SpiReceiver SpiReceiver { get; set; } public ChangeoverReceiver ChangeoverReceiver { get; set; } public OibClient OibClient { get; set; } public BoardGateKeeperReceiver BoardGateKeeperReceiver { set; get; } public bool _isSetupStation; public List productVersions { get; set; } public DekPrinterExternalControlReceiver DekPrinterExternalControlReceiver { get; set; } public LineControlMesInterceptorReceiver MesLineControlMesInterceptorReceiver { get; set; } public AdapterControl() { var config = new AppSettingsReader(); try { // Der Port an dem der Adapter auf eingehende Verbindungen des iTAC DataInterface lauscht _own_itac_oib_adapter_port = (int)config.GetValue("ListenPort", typeof(int)); _own_host_name = Environment.MachineName; var hostInfo = Dns.GetHostEntry(_own_host_name); _own_canonical_host_name = hostInfo.HostName; var addresslist = Dns.GetHostAddresses(_own_host_name); // die eigene IP-Adresse raussuchen var theaddress = addresslist[0]; // jetzt versuchen eine gueltige V4 Adresse zu finden, diese bevorzugen foreach (var IPA in addresslist) { if (IPA.AddressFamily.ToString() == "InterNetwork") { theaddress = IPA; break; } } LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, theaddress.ToString()); _own_ip_address = theaddress.ToString(); } catch (Exception) { } } // eine neue socket zum DataInterface als Client aufmachen. ?ber diese Verbindung werden alle Events zum // Datainterface ?bertragen // Returned nie einen Null-Wert public IhapEventChannel GetDataInterfaceConnection(string channelName) { // sind die n?tigen Parameter gesetzt (_ipAddress, _hostname), damit eine Verbindung aufgebaut werden kann? if (_ipAddress.Equals("") || _hostName.Equals("") || _canonicalHostName.Equals("")) { //Fehlerausgabe LogHandler.log(Constants.LOGGER, TraceEventType.Critical, "ADAPTER: communication parameter unknown:\n" + "DataInterface IP Address = " + _ipAddress + "\n" + "DataInterface Host Name = " + _hostName + "\n" + "DataInterface Canonical Host Name = " + _canonicalHostName + "\n"); // Ende throw new Exception("iTAC.OIB.Adapter is not configured properly"); } // F?r jeden Kanal eine neue eigene Verbindung aufmachen. Pro Verbindung eine laufende Nummer z?hlen... var channelNameWithNumber = ""; // gab es f?r diesen channelName bereits eine Connection var counter = 0; lock (_locker) { if (channelNameCounter.ContainsKey(channelName)) { counter = channelNameCounter[channelName]; counter++; if (counter > 100000) { counter = 1; } channelNameCounter.Remove(channelName); channelNameCounter.Add(channelName, counter); } else { channelNameCounter.Add(channelName, counter); } channelNameWithNumber = channelName + "#" + counter; } // Neue Verbindung zum DataInterface aufmachen var tcpClient = new TcpClient(_canonicalHostName, _port); // eine neue TCp-Client-Verbindung var iHapEventChannel = new IhapEventChannel(tcpClient, channelNameWithNumber); if (iHapEventChannel == null) { LogHandler.log(Constants.LOGGER, TraceEventType.Error, "ADAPTER: iHapEventChannel not created"); throw new Exception("ADAPTER: iHapEventChannel not created"); } LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, "ADAPTER: before adding " + channelNameWithNumber); lock (_locker) { if (openClientChannels.ContainsKey(channelNameWithNumber)) { openClientChannels.Remove(channelNameWithNumber); } openClientChannels.Add(channelNameWithNumber, iHapEventChannel); } LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, "ADAPTER: " + channelNameWithNumber + " added"); iHapEventChannel.channelName = channelNameWithNumber; // Listener installieren, um zu reagieren, wenn das Data-Interface die Verbindung abgebrochen hat iHapEventChannel.connectionStateChangeListener += new PropertyChangeListener(iHapEventChannel_connectionStateChangeListener); var oibEvents = (OIBEvents)iHapEventChannel.GetTransparentProxy(); if (oibEvents == null) { LogHandler.log(Constants.LOGGER, TraceEventType.Error, "ADAPTER: iHapEventChannel.transparentProxy not created"); throw new Exception("ADAPTER: iHapEventChannel.transparentProxy not created"); } oibEvents.setChannelName(channelNameWithNumber); oibEvents.startup(); return iHapEventChannel; } #region IAdapterControl Member /// /// subscriptions starten /// public void startMonitoringReceiver() { genericStart("Monitoring Receiver", MonitoringReceiver); } /// /// subscriptions anhalten und austragen /// public void stopMonitoringReceiver() { genericStop("Monitoring Receiver", MonitoringReceiver); } public void startSetupCenterNotifyReceiver() { genericStart("SetupCenterReceiver", SetupCenterReceiver); genericStart("SetupCenterExternalControlReceiver", SetupCenterExternalControlReceiver); genericStart("DekPrinterExternalControlReceiver", DekPrinterExternalControlReceiver); genericStart("MesLineControlMesInterceptorReceiver", MesLineControlMesInterceptorReceiver); } public void stopSetupCenterNotifyReceiver() { genericStop("SetupCenterReceiver", SetupCenterReceiver); genericStop("SetupCenterExternalControlReceiver", SetupCenterExternalControlReceiver); genericStop("DekPrinterExternalControlReceiver", DekPrinterExternalControlReceiver); genericStop("MesLineControlMesInterceptorReceiver", MesLineControlMesInterceptorReceiver); } /// /// subscriptions starten /// public void startTraceReceiver() { genericStart("TraceReceiver", TraceReceiver); } /// /// subscriptions anhalten und austragen /// public void stopTraceReceiver() { genericStop("TraceReceiver", TraceReceiver); } /// /// subscriptions starten /// public void startBoardGateKeeper() { genericStart("BoardGateKeeperReceiver", BoardGateKeeperReceiver); } /// /// subscriptions anhalten und austragen /// public void stopBoardGateKeeper() { genericStop("BoardGateKeeperReceiver", BoardGateKeeperReceiver); } public void startDekReceiver() { genericStart("DekPrinterExternalControlReceiver", DekPrinterExternalControlReceiver); genericStart("MesLineControlMesInterceptorReceiver", MesLineControlMesInterceptorReceiver); } public void stopDekReceiver() { genericStop("DekPrinterExternalControlReceiver", DekPrinterExternalControlReceiver); genericStop("MesLineControlMesInterceptorReceiver", MesLineControlMesInterceptorReceiver); } public bool ping() { LogHandler.log(Constants.LOGGER, TraceEventType.Information, "ADAPTER: ping"); return true; } public bool isSetupStation() { LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, "ADAPTER: isSetupStation()"); return _isSetupStation; } public void setInterfaceHost(int port, string ipAddress, string canonicalHostName, string hostName) { LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, "ADAPTER: setInterfaceHost() called"); LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, "ADAPTER: set DataInterface port: " + port); LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, "ADAPTER: set DataInterface ipAddress: " + ipAddress); LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, "ADAPTER: set DataInterface canonical hostname : " + canonicalHostName); LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, "ADAPTER: set DataInterface hostname : " + hostName); // setzen der Parameter ist immer moeglich, wenn die Parameter noch nicht gesetzt wurden. if (_port != 0 && !_hostName.Equals("")) { // eine Änderung des Hostnamen ist nicht erlaubt, so lange der AdapterProzess besteht. if (!_hostName.Equals(hostName) || !_ipAddress.Equals(ipAddress) || !_canonicalHostName.Equals(canonicalHostName)) { LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, "ADAPTER: current port: " + _port + ": new port :" + port); LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, "ADAPTER: current ipAddress: " + _ipAddress + ": new ipAddress :" + ipAddress); LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, "ADAPTER: current canonical hostname : " + _canonicalHostName + ": new canonical hostname : " + canonicalHostName); LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, "ADAPTER: current hostname : " + _hostName + ": new hostname:" + hostName); LogHandler.log(Constants.LOGGER, TraceEventType.Warning, "ADAPTER: changing DataInterface communication parameter not allowed and not changed"); return; } } _port = port; _ipAddress = ipAddress; _hostName = hostName; _canonicalHostName = canonicalHostName; try { IhapEventChannel interfaceControlChannel = GetDataInterfaceConnection("interfaceControlChannel"); // die Methode "DataInterfaceShutdown" wird aufgerufen, wenn das Interface diese Clientverbindung abbricht // hierf?r wird ein zus?tzlicher Handler installiert // interfaceControlChannel.connectionStateChangeListener += new PropertyChangeListener(DataInterfaceShutdown); //interfaceControlChannel.connectionStateChangeListener += new PropertyChangeListener(iHapEventChannel_connectionStateChangeListener); var channel = (OIBEvents)interfaceControlChannel.GetTransparentProxy(); channel.RegisterAdapter(_own_itac_oib_adapter_port, _own_ip_address, _own_canonical_host_name, _own_host_name); var versions = OibClient.GetOibProxyVersions(); var versionList = new List(); foreach (var version in productVersions) { versionList.Add(version); } foreach (var version in versions) { if (version.Key.Equals("AsmApi")) { continue; } versionList.Add(new KeyValue() { key = version.Key, value = version.Value }); } channel.setVersionInfo(versionList.ToArray()); closeHandler(channel); } catch (Exception e) { LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, "ADAPTER: setInterfaceHost() call failed", e); } } public void setChannelName(string channelName) { LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, "ADAPTER: setting channel name(" + channelName + ")"); } #endregion // die Verbindung zum DataInterface aktiv abbauen internal void closeChannel(IhapEventChannel eventChannel) { lock (_locker) { openClientChannels.Remove(eventChannel.channelName); eventChannel.shutdown(); } } // die eingehende Verbindung aktiv schliessen internal void closeHandler(OIBEvents eventHandler) { eventHandler.shutdown(); } // Listener f?r ausgehende Verbindungen; wird aufgerufen, wenn f?r eine ausgehende Verbindung das schreiben fehlschl?gt (also durch das // DataInterface die Verbindung abgebrochen wurde internal void iHapEventChannel_connectionStateChangeListener(Object source, string channelName, string message) { LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, "ADAPTER: " + channelName + " " + message); closeChannel((IhapEventChannel)source); if (openClientChannels.Count > 0) { LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, "shutdown " + openClientChannels.Count + " remaining open connections from iTAC.OIB.Adpater to DataInterface"); } else { LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, "no remaining open connections from iTAC.OIB.Adpater to DataInterface"); } } // Wenn ein IHapHandler ein Disconnect feststellt wird eine Verbindung entfernt... public void DataInterfaceShutdown(object sender, string channelName, string message) { LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, channelName + " disconnected"); _port = 0; _ipAddress = ""; _canonicalHostName = ""; _hostName = ""; // alle client-Verbindungen muessen abgebaut werden... if (openClientChannels.Count > 0) { LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, "shutdown " + openClientChannels.Count + " remaining open connections from iTAC.OIB.Adpater to DataInterface"); } else { LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, "no remaining open connections from iTAC.OIB.Adpater to DataInterface"); } // ge?ffnete Eventing Queues stoppen stopMonitoringReceiver(); stopSetupCenterNotifyReceiver(); } protected void genericStop(String serviceName, IReceiver service) { if (service == null) { LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, "ADAPTER: " + serviceName + " will not be stopped because it was not initialized"); } else { LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, "ADAPTER: Stop " + serviceName + ""); service.Stop(); } } public void genericStart(String serviceName, IReceiver service) { if (service == null) { LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, "ADAPTER: " + serviceName + " will not be started because it was not initialized"); } else { LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, "ADAPTER: Start " + serviceName + ""); service.Start(); } } public void Dispose() { if (SetupCenterReceiver != null) SetupCenterReceiver.Dispose(); if (SetupCenterExternalControlReceiver != null) SetupCenterExternalControlReceiver.Dispose(); if (MonitoringReceiver != null) MonitoringReceiver.Dispose(); if (TraceReceiver != null) TraceReceiver.Dispose(); if (SpiReceiver != null) SpiReceiver.Dispose(); if (BoardGateKeeperReceiver != null) BoardGateKeeperReceiver.Dispose(); } } }