public class LowLevelCommunication extends java.lang.Object implements LowLevelCommunicationInterface
Klasse zur Verwaltung der unteren Ebene von Datenverteilerverbindungen.
Die Aufgabe dieser Klasse ist es Telegramme zu versenden, zu empfangen und KeepAlive-Mechanismus zu verwalten.
Jede dieser Aufgaben wird durch mindestens einen Thread übernommen:
Empfang von Daten: ReceivingChannel (nimmt die Daten entgegen und legt diese in _receivingTable ab. Bei Konfigurationsanfragen kann es zur Zerstücklung von Telegrammen kommen, diese Teiltelgramme werden in _splittedTelegramsTable abgelegt und dort mit jedem empfang eines Teiltelegramms langsam zusammen gebaut und nach Vollendung an ClientHighLevelCommunication durchgereicht (nicht über den Worker-Thread). Beim empfang von Daten wird der KeepAlive-Thread benachrichtigt.), WorkerThread (bearbeitet die _receivingTable und reicht empfangene Telegramme an ClientHighLevelCommunication weiter).
Versand von Daten: SendingChannel (verschickt Telegramme aus der _sendingTable und benachrichtigt den KeepAlive Thread, sobald Daten verschickt wurden. Prüft die Laufzeit der einzelnen Telegramme und unterbricht die Verbindung sobald diese einen kritischen Wert unterschreitet).
KeepAlive-Mechanismus: KeepAliveThread (Verwaltet ob ein “KeepAlive” Telegramm verschickt werden muss. Dies ist abhängig davon, ob eine Telegramm versendet/empfangen wurde. Wurde eine bestimmte Anzahl Keepalive Telegramme versendet, so wird die Verbindung abgebaut. Wird nach dem versand eines KeepAlive Telegramms ein normales Telegramm empfangen/gesendet, so wird der KeepAlive-Telegrammzähler wieder auf 0 gesetzt. Anmerkung: Das KeepAlive Paket wird nicht über den SendingChannel-Thread verschickt, sondern direkt über den Outputstream.)
Alle vollständigen Telegramme werden in zwei TelegramQueue-Objekten gespeichert (eine für den Empfang, eine für den Versand). Die oben beschriebenen Threads (ausser der KeepAlive-Thread) arbeiten und synchronisieren sich auf den jeweiligen “PriorityTables”.
Begriffsdefinitionen: Protokollsteuerung DaV-DAF (Klasse ClientHighLevelCommunication), Datenrepräsentation (Klassen DataInputStream und DataOutputStream), TCP-Kommunikationskanal (Klasse TCP_IP_Communication)
Modifier and Type | Class and Description |
---|---|
(package private) class |
LowLevelCommunication.KeepAliveThread
Dieser Thread verschickt Keepalive Telegramme und baut die Verbindung ab, wenn dreimal nacheinander eine bestimmte Zeit lang keine Daten mehr empfangen wurden.
|
(package private) class |
LowLevelCommunication.ReceivingChannel |
(package private) class |
LowLevelCommunication.SendingChannel
Dieser Thread verschickt Telegramme mittels einer Datenverteilerverbindung (Outputstream der Verbindung).
|
private class |
LowLevelCommunication.ThroughputChecker |
private static class |
LowLevelCommunication.ThroughputCheckerState |
(package private) class |
LowLevelCommunication.WorkerThread |
Modifier and Type | Field and Description |
---|---|
private ConnectionInterface |
_connection
Die Kommunikationskomponente (TCP-IP…)
|
private static Debug |
_debug |
private boolean |
_disconnected
Verbindungsstatusinformation
|
private SrpTelegramEncryption |
_encryption |
private HighLevelCommunicationCallbackInterface |
_highLevelComponent
Der Komponente die benachrichtigt werden soll, wenn eine neues Telegramm ankommt.
|
private java.io.DataInputStream |
_inStream
Der Inputstream dieser Verbindung
|
private long |
_keepAliveReceiveTimeOut
Die Zeit in Millisekunden in der spätestens ein Telegramm empfangen werden muss.
|
private long |
_keepAliveSendTimeOut
Die Zeit in Millisekunden nach der spätestens ein KeepAlive-Telegramm gesendet werden muss, wenn in dieser Zeit kein sonstiges Telegramm gesendet wurde.
|
private LowLevelCommunication.KeepAliveThread |
_keepAliveThread
Der KeepAlivethread
|
private int |
_mode
Der Modus dieser Verbindung
|
private java.io.DataOutputStream |
_outStream
Der Outputstream dieser Verbindung
|
private TelegramQueue<DataTelegram> |
_receiveQueue
Queue, in der empfangene Telegramme zwischengespeichert werden.
|
private LowLevelCommunication.ReceivingChannel |
_receivingChannel
Der Empfangsthread dieser Kommunikation
|
private java.lang.String |
_remoteAddress |
private java.lang.String |
_remoteName |
private java.lang.String |
_remotePrefix |
private LowLevelCommunication.SendingChannel |
_sendingChannel
Der Sendethread dieser Kommunikation
|
private TelegramQueue<DataTelegram> |
_sendQueue
Queue, in der zu versendende Telegramme zwischengespeichert werden.
|
private boolean |
_sendTerminationTelegramWhenClosing
Kennung, die
true ist, wenn ein Verbindungsterminierungstelegramm beim Schließen der Verbindung versendet werden soll. |
private SplittedApplicationTelegramsTable |
_splittedTelegramsTable
Temporäre Liste der zerstückelten Telegramme
|
private DataTelegram |
_terminationTelegram |
private LowLevelCommunication.ThroughputChecker |
_throughputChecker |
private LowLevelCommunication.WorkerThread |
_updater
Der Aktuallisierungsthread
|
private boolean |
_waitingForSendingChannel |
static byte |
HANDLE_CONFIG_RESPONCES_MODE
Wert für den
mode -Parameter des Konstruktors, der bewirkt, dass Konfigurationsantworten ausgewertet und entsprechend an die höhere Kommunikationsebene weitergegeben werden. |
static byte |
NORMAL_MODE
Wert für den
mode -Parameter des Konstruktors, der bewirkt, dass Konfigurationsantworten wie normale Datentelegramme verarbeitet werden. |
Constructor and Description |
---|
LowLevelCommunication(ConnectionInterface connection,
int sendBufferSize,
int receiveBufferSize,
long keepAliveSendTimeOut,
long keepAliveReceiveTimeOut,
byte mode,
boolean connected) |
Modifier and Type | Method and Description |
---|---|
void |
connect(java.lang.String mainAddress,
int subAddress)
Diese Methode baut eine Kommunikationsverbindung zu den angegebenen Adressen auf.
|
void |
disableEncryption()
Deaktiviert die Verschlüsselung
|
void |
disconnect(boolean error,
java.lang.String message,
DataTelegram terminationTelegram)
Diese Methode wird von der Protokollschicht DaV-DAF aufgerufen, wenn die Kommunikationskanäle geschlossen werden sollen.
|
void |
enableEncryption(SrpTelegramEncryption encryption)
Aktiviert die Verschlüsselung
|
ConnectionInterface |
getConnectionInterface()
Gibt den Repräsentant der Verbindung zurück
|
EncryptionStatus |
getEncryptionStatus()
Gibt den Verschlüsselungsstatus zurück
|
HighLevelCommunicationCallbackInterface |
getHighLevelComponent() |
(package private) LowLevelCommunication.KeepAliveThread |
getKeepAliveThread()
Diese Methode dient nur für automatisierte Tests und ist nicht für den realen Einsatz gedacht.
|
(package private) LowLevelCommunication.ReceivingChannel |
getReceivingChannel()
Diese Methode dient nur für automatisierte Tests und ist nicht für den realen Einsatz gedacht.
|
private java.lang.String |
getRemotePrefix() |
java.lang.String |
getSendBufferState()
Liefert einen beschreibenden Text mit dem Zustand des Sendepuffers
|
(package private) LowLevelCommunication.SendingChannel |
getSendingChannel()
Diese Methode dient nur für automatisierte Tests und ist nicht für den realen Einsatz gedacht.
|
(package private) LowLevelCommunication.WorkerThread |
getUpdaterThread()
Diese Methode dient nur für automatisierte Tests und ist nicht für den realen Einsatz gedacht.
|
private void |
handleAbnormalBehaviour(boolean sendTermination,
java.lang.String message) |
boolean |
isNotConnected()
Gibt als Information zurück, ob die Kommunikationsverbindung unterbrochen ist.
|
void |
send(DataTelegram telegram)
Diese Methode wird von der Protokollschicht DaV-DAF aufgerufen, wenn ein Telegramm gesendet werden soll.
|
void |
send(DataTelegram[] telegrams)
Fügt mehrere Telegramme in die Sendetabelle ein.
|
void |
sendDirect(java.util.Collection<DataTelegram> telegrams)
Sendet Telegramme direkt, wobei die SendeQueue umgangen wird.
|
void |
sendDirect(DataTelegram telegram)
Sendet ein Telegramm direkt, wobei die SendeQueue umgangen wird.
|
void |
setHighLevelComponent(HighLevelCommunicationCallbackInterface highLevelComponent)
Setzt die Interpretationsschicht dieser Komponente für den internen Datenaustausch.
|
void |
setRemoteAddress(java.lang.String remoteAddress,
int remotePort) |
void |
setRemoteName(java.lang.String name)
Diese Methode setzt den Namen des Kommunikationspartners, der für Fehlermeldungen etc. verwendet wird.
|
private void |
setRemotePrefix() |
java.lang.String |
toString() |
void |
updateKeepAliveParameters(long keepAliveSendTimeOut,
long keepAliveReceiveTimeOut)
Diese Methode wird von der Protokollschicht DaV-DAF aufgerufen, wenn die Keepalive-Parameter-Verhandlung erfolgreich abgeschlossen ist und setzt somit die Timeouts des Keepaliveprozesses.
|
void |
updateThroughputParameters(float throughputControlSendBufferFactor,
long throughputControlInterval,
int minimumThroughput)
Diese Methode setzt die Parameter für die Durchsatzprüfung.
|
private void |
waitForEncryption() |
private void |
waitForNoEncryption() |
public static final byte NORMAL_MODE
Wert für den mode
-Parameter des Konstruktors, der bewirkt, dass Konfigurationsantworten wie normale Datentelegramme verarbeitet werden.
public static final byte HANDLE_CONFIG_RESPONCES_MODE
Wert für den mode
-Parameter des Konstruktors, der bewirkt, dass Konfigurationsantworten ausgewertet und entsprechend an die höhere Kommunikationsebene weitergegeben werden.
private static final Debug _debug
private ConnectionInterface _connection
Die Kommunikationskomponente (TCP-IP…)
private java.io.DataInputStream _inStream
Der Inputstream dieser Verbindung
private java.io.DataOutputStream _outStream
Der Outputstream dieser Verbindung
private LowLevelCommunication.ReceivingChannel _receivingChannel
Der Empfangsthread dieser Kommunikation
private LowLevelCommunication.SendingChannel _sendingChannel
Der Sendethread dieser Kommunikation
private LowLevelCommunication.WorkerThread _updater
Der Aktuallisierungsthread
private TelegramQueue<DataTelegram> _sendQueue
Queue, in der zu versendende Telegramme zwischengespeichert werden.
private TelegramQueue<DataTelegram> _receiveQueue
Queue, in der empfangene Telegramme zwischengespeichert werden.
private HighLevelCommunicationCallbackInterface _highLevelComponent
Der Komponente die benachrichtigt werden soll, wenn eine neues Telegramm ankommt.
private LowLevelCommunication.KeepAliveThread _keepAliveThread
Der KeepAlivethread
private long _keepAliveSendTimeOut
Die Zeit in Millisekunden nach der spätestens ein KeepAlive-Telegramm gesendet werden muss, wenn in dieser Zeit kein sonstiges Telegramm gesendet wurde.
private long _keepAliveReceiveTimeOut
Die Zeit in Millisekunden in der spätestens ein Telegramm empfangen werden muss. Wenn diese Zeit dreimal hintereinander abgelaufen ist, wird die Verbindung terminiert.
private volatile boolean _disconnected
Verbindungsstatusinformation
private int _mode
Der Modus dieser Verbindung
HANDLE_CONFIG_RESPONCES_MODE
,
NORMAL_MODE
private SplittedApplicationTelegramsTable _splittedTelegramsTable
Temporäre Liste der zerstückelten Telegramme
private boolean _sendTerminationTelegramWhenClosing
Kennung, die true
ist, wenn ein Verbindungsterminierungstelegramm beim Schließen der Verbindung versendet werden soll.
private DataTelegram _terminationTelegram
private LowLevelCommunication.ThroughputChecker _throughputChecker
private volatile boolean _waitingForSendingChannel
private java.lang.String _remotePrefix
private java.lang.String _remoteName
private java.lang.String _remoteAddress
private volatile SrpTelegramEncryption _encryption
public LowLevelCommunication(ConnectionInterface connection, int sendBufferSize, int receiveBufferSize, long keepAliveSendTimeOut, long keepAliveReceiveTimeOut, byte mode, boolean connected) throws ConnectionException
connection
- Verbindungsobjekt über dass die Kommunikation mit dem Kommunikationspartner realisiert wird.sendBufferSize
- Sendetabellenkapazität (in Byte)receiveBufferSize
- Empfangstabellenkapazität (in Byte)keepAliveSendTimeOut
- Zeitspanne in ms. Wird solange kein Telegramm verschickt, wird ein KeepAlive-Telegramm verschickt.keepAliveReceiveTimeOut
- Zeitspanne in ms. Wird solange keine Telegramm empfangen, wird ein Zähler herabgesetzt. Erreicht der Zähler 0 wird die Verbindung terminiert. Wird zwischendurch ein Telegramm empfangen, wird der Zähler auf das maximum gesetzt.mode
- Modus für das Konfigurationsdatenverhalten. Falls hier der Wert HANDLE_CONFIG_RESPONCES_MODE
übergeben wird, dann werden Konfigurationsantworten ausgewertet und entsprechend an die höhere Kommunikationsebene weitergegeben. Falls hier der Wert NORMAL_MODE
übergeben wird, dann werden Konfigurationsantworten wie normale Datentelegramme verarbeitet.connected
- Information, ob die Verbindung bereits erfolgt ist oder nicht (connected)ConnectionException
- Wenn das Verbindungsobjekt sich nicht im erwarteten Zustand befindet.LowLevelCommunication.KeepAliveThread getKeepAliveThread()
Diese Methode dient nur für automatisierte Tests und ist nicht für den realen Einsatz gedacht.
null
wenn dieser noch nicht aktiviert wurde.LowLevelCommunication.ReceivingChannel getReceivingChannel()
Diese Methode dient nur für automatisierte Tests und ist nicht für den realen Einsatz gedacht.
null
wenn dieser noch nicht aktiviert wurde.LowLevelCommunication.SendingChannel getSendingChannel()
Diese Methode dient nur für automatisierte Tests und ist nicht für den realen Einsatz gedacht.
null
wenn dieser noch nicht aktiviert wurde.LowLevelCommunication.WorkerThread getUpdaterThread()
Diese Methode dient nur für automatisierte Tests und ist nicht für den realen Einsatz gedacht.
null
wenn dieser noch nicht aktiviert wurde.public final ConnectionInterface getConnectionInterface()
LowLevelCommunicationInterface
Gibt den Repräsentant der Verbindung zurück
getConnectionInterface
in interface LowLevelCommunicationInterface
public final void setHighLevelComponent(HighLevelCommunicationCallbackInterface highLevelComponent)
LowLevelCommunicationInterface
Setzt die Interpretationsschicht dieser Komponente für den internen Datenaustausch. Erst nach Aufruf dieser Methode von der Protokollschicht DaV-DAF werden die Kommunikations-Threads gestartet, weil sonst keine Telegramme interpretiert oder weitergeleitet werden können.
setHighLevelComponent
in interface LowLevelCommunicationInterface
highLevelComponent
- Komponente, die benachrichtigt werden muss, wenn neue Nachrichten empfangen werden.public HighLevelCommunicationCallbackInterface getHighLevelComponent()
public final void updateKeepAliveParameters(long keepAliveSendTimeOut, long keepAliveReceiveTimeOut)
LowLevelCommunicationInterface
Diese Methode wird von der Protokollschicht DaV-DAF aufgerufen, wenn die Keepalive-Parameter-Verhandlung erfolgreich abgeschlossen ist und setzt somit die Timeouts des Keepaliveprozesses.
updateKeepAliveParameters
in interface LowLevelCommunicationInterface
keepAliveSendTimeOut
- SendekeepalivetimeoutkeepAliveReceiveTimeOut
- Empfangekeepalivetimeoutpublic final void updateThroughputParameters(float throughputControlSendBufferFactor, long throughputControlInterval, int minimumThroughput)
LowLevelCommunicationInterface
Diese Methode setzt die Parameter für die Durchsatzprüfung. Sie wird von der Protokollschicht DaV-DAF aufgerufen, wenn die Parameter für die Durchsatzprüfung erfolgreich verhandelt wurden.
updateThroughputParameters
in interface LowLevelCommunicationInterface
throughputControlSendBufferFactor
- Füllungsgrad des Sendepuffers als Faktor zwischen 0 und 1, ab dem die Durchsatzprüfung anfängt zu arbeiten.throughputControlInterval
- Zeit zwischen zwei Durchsatzprüfungen in MillisekundenminimumThroughput
- Minimal zulässiger Verbindungsdurchsatz in Bytes pro Sekundepublic final void connect(java.lang.String mainAddress, int subAddress) throws ConnectionException
Diese Methode baut eine Kommunikationsverbindung zu den angegebenen Adressen auf. Sie wird von der Protokollschicht DaV-DAF während der Verbindungsinitialisierung aufgerufen.
Nach dem Verbindungsaufbau werden die Referenzen auf den Sende- und den Empfangskanal festgehalten. Diese werden von den Threads benutzt um Daten zu senden oder empfangen.
connect
in interface LowLevelCommunicationInterface
mainAddress
- Adresse des Kommunikationspartners dieser Verbindung.subAddress
- Subadresse der Adresse.ConnectionException
- Falls die Verbindung nicht hergestellt werden kann.public final boolean isNotConnected()
LowLevelCommunicationInterface
Gibt als Information zurück, ob die Kommunikationsverbindung unterbrochen ist.
isNotConnected
in interface LowLevelCommunicationInterface
true
= Es besteht keine Verbindung; false
= sonstpublic final void send(DataTelegram telegram)
Diese Methode wird von der Protokollschicht DaV-DAF aufgerufen, wenn ein Telegramm gesendet werden soll.
Fügt ein Telegramm in die Sendetabelle ein.
send
in interface LowLevelCommunicationInterface
telegram
- Das zu versendende Telegramm.public final void send(DataTelegram[] telegrams)
LowLevelCommunicationInterface
Fügt mehrere Telegramme in die Sendetabelle ein.
send
in interface LowLevelCommunicationInterface
telegrams
- Die zu versendenden Telegramme.LowLevelCommunicationInterface.send(de.bsvrz.dav.daf.communication.lowLevel.telegrams.DataTelegram)
public final void disconnect(boolean error, java.lang.String message, DataTelegram terminationTelegram)
Diese Methode wird von der Protokollschicht DaV-DAF aufgerufen, wenn die Kommunikationskanäle geschlossen werden sollen.
Zunächst wird der Empfangsthread geschlossen; dadurch werden keine Daten mehr empfangen. Danach wird der Keep-alive-Thread geschlossen. Daraufhin wird gewartet, bis der Sendethread alle Telegramme aus der Sendetabelle gesendet hat, damit keine Daten verloren gehen. Anschließend wird der Sendethread beendet. Zuletzt werden die Kommunikationskanäle geschlossen.
disconnect
in interface LowLevelCommunicationInterface
error
- Besagt, ob es sich um eine Terminierung mit Fehler handelt. Falls true
werden sämtliche noch zum Versand gepufferten Telegramme verworfen; falls false
wird versucht, sämtliche zum Versand gepufferten Telegramme zu versenden.message
- Ursache der Terminierung im Fehlerfall.terminationTelegram
- Das Telegramm, dass als letztes Telegramm vor dem Schließen der Verbindung versendet werden soll oder null
, falls kein abschließendes Telegramm versendet werden soll.private void handleAbnormalBehaviour(boolean sendTermination, java.lang.String message)
public java.lang.String getSendBufferState()
LowLevelCommunicationInterface
Liefert einen beschreibenden Text mit dem Zustand des Sendepuffers
getSendBufferState
in interface LowLevelCommunicationInterface
public void setRemoteName(java.lang.String name)
LowLevelCommunicationInterface
Diese Methode setzt den Namen des Kommunikationspartners, der für Fehlermeldungen etc. verwendet wird.
setRemoteName
in interface LowLevelCommunicationInterface
name
- Name oder Identifikation des Kommunikationspartnerspublic final void setRemoteAddress(java.lang.String remoteAddress, int remotePort)
private void setRemotePrefix()
private java.lang.String getRemotePrefix()
public void enableEncryption(SrpTelegramEncryption encryption)
LowLevelCommunicationInterface
Aktiviert die Verschlüsselung
enableEncryption
in interface LowLevelCommunicationInterface
encryption
- Verschlüsselungpublic void disableEncryption()
LowLevelCommunicationInterface
Deaktiviert die Verschlüsselung
disableEncryption
in interface LowLevelCommunicationInterface
public EncryptionStatus getEncryptionStatus()
LowLevelCommunicationInterface
Gibt den Verschlüsselungsstatus zurück
getEncryptionStatus
in interface LowLevelCommunicationInterface
public void sendDirect(DataTelegram telegram)
LowLevelCommunicationInterface
Sendet ein Telegramm direkt, wobei die SendeQueue umgangen wird. Das Telegramm muss versendet wurden sein, wenn die Methode verlassen wird
sendDirect
in interface LowLevelCommunicationInterface
telegram
- Telegrammpublic void sendDirect(java.util.Collection<DataTelegram> telegrams)
LowLevelCommunicationInterface
Sendet Telegramme direkt, wobei die SendeQueue umgangen wird. Das Telegramm muss versendet wurden sein, wenn die Methode verlassen wird
sendDirect
in interface LowLevelCommunicationInterface
telegrams
- Telegrammeprivate void waitForEncryption() throws java.io.IOException
java.io.IOException
private void waitForNoEncryption() throws java.io.IOException
java.io.IOException
public java.lang.String toString()
toString
in class java.lang.Object