Files
imsInterface/interface/asm/dotnet/AdapterApplication3x/com.itac.oib/AdapterControl.cs
2025-06-06 09:15:13 +02:00

416 lines
18 KiB
C#

#region Namespace
using Asm.As.Oib.Client;
using com.itac.mes.domain;
using com.itac.mes.tools;
using com.itac.mes.proxy.sockets;
using Itac.Oib;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics;
using System.Net;
using System.Net.Sockets;
using System.Reflection;
#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<String, IhapEventChannel> openClientChannels = new Dictionary<String, IhapEventChannel>();
// pro Verbindung wird gez?hlt wie viele Connections es schon gab...
private Dictionary<String, Int32> channelNameCounter = new Dictionary<String, Int32>();
// 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<mes.tools.KeyValue> productVersions { 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
/// <summary>
/// subscriptions starten
/// </summary>
public void startMonitoringReceiver()
{
genericStart("Monitoring Receiver", MonitoringReceiver);
}
/// <summary>
/// subscriptions anhalten und austragen
/// </summary>
public void stopMonitoringReceiver()
{
genericStop("Monitoring Receiver", MonitoringReceiver);
}
public void startSetupCenterNotifyReceiver()
{
genericStart("SetupCenterReceiver", SetupCenterReceiver);
genericStart("SetupCenterExternalControlReceiver", SetupCenterExternalControlReceiver);
}
public void stopSetupCenterNotifyReceiver()
{
genericStop("SetupCenterReceiver", SetupCenterReceiver);
genericStop("SetupCenterExternalControlReceiver", SetupCenterExternalControlReceiver);
}
/// <summary>
/// subscriptions starten
/// </summary>
public void startTraceReceiver()
{
genericStart("TraceReceiver", TraceReceiver);
}
/// <summary>
/// subscriptions anhalten und austragen
/// </summary>
public void stopTraceReceiver()
{
genericStop("TraceReceiver", TraceReceiver);
}
/// <summary>
/// subscriptions starten
/// </summary>
public void startBoardGateKeeper()
{
genericStart("BoardGateKeeperReceiver", BoardGateKeeperReceiver);
}
/// <summary>
/// subscriptions anhalten und austragen
/// </summary>
public void stopBoardGateKeeper()
{
genericStop("BoardGateKeeperReceiver", BoardGateKeeperReceiver);
}
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<KeyValue>();
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();
}
public void startDekReceiver()
{
// not available in OIB 3
}
public void stopDekReceiver()
{
// not available in OIB 3
}
}
}