416 lines
18 KiB
C#
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
|
|
}
|
|
}
|
|
}
|