diff options
Diffstat (limited to 'system/net')
| -rw-r--r-- | system/net/1.7.5/doc/EUMEL Netz | 832 | ||||
| -rw-r--r-- | system/net/1.7.5/src/basic net | 840 | ||||
| -rw-r--r-- | system/net/1.7.5/src/callee | 14 | ||||
| -rw-r--r-- | system/net/1.7.5/src/net inserter | 50 | ||||
| -rw-r--r-- | system/net/1.7.5/src/net manager-M | 302 | ||||
| -rw-r--r-- | system/net/1.7.5/src/net report-M | 29 | ||||
| -rw-r--r-- | system/net/1.8.7/doc/netzhandbuch | 2045 | ||||
| -rw-r--r-- | system/net/1.8.7/doc/netzhandbuch.anhang | 58 | ||||
| -rw-r--r-- | system/net/1.8.7/doc/netzhandbuch.index | 259 | ||||
| -rw-r--r-- | system/net/1.8.7/source-disk | 1 | ||||
| -rw-r--r-- | system/net/1.8.7/src/basic net | 1148 | ||||
| -rw-r--r-- | system/net/1.8.7/src/net files-M | 5 | ||||
| -rw-r--r-- | system/net/1.8.7/src/net hardware interface | 389 | ||||
| -rw-r--r-- | system/net/1.8.7/src/net inserter | 145 | ||||
| -rw-r--r-- | system/net/1.8.7/src/net manager | 797 | ||||
| -rw-r--r-- | system/net/1.8.7/src/net report | 41 | ||||
| -rw-r--r-- | system/net/1.8.7/src/netz | 20 | ||||
| -rw-r--r-- | system/net/unknown/doc/EUMEL Netz | 829 | 
18 files changed, 7804 insertions, 0 deletions
| diff --git a/system/net/1.7.5/doc/EUMEL Netz b/system/net/1.7.5/doc/EUMEL Netz new file mode 100644 index 0000000..ad39db3 --- /dev/null +++ b/system/net/1.7.5/doc/EUMEL Netz @@ -0,0 +1,832 @@ +#type ("trium8")##limit (11.0)# 
 +#start(2.5,1.5)##pagelength (17.4)# 
 +#block# 
 +#headeven# 
 + 
 +%                        EUMEL-Netzbeschreibung 
 + 
 + 
 +#end# 
 +#headodd# 
 + 
 +#center#Inhalt#right#% 
 + 
 + 
 +#end# 
 + 
 +#type ("triumb12")# 
 +1. Einleitung 
 + 
 + 
 +Teil 1: Netz einrichten und benutzen 
 +#type ("trium8")# 
 + 
 +1. Benutzung des Netzes 
 + 
 +2. Hardwarevoraussetzungen 
 + 
 +3. Einrichten des Netzes 
 + 
 +4. Informationsmglichkeiten 
 + 
 +5. Eingriffsmglichkeiten 
 + 
 +6. Fehlerbehebung im Netz 
 + 
 +#type ("triumb12")# 
 + 
 +Teil 2: Arbeitsweise der Netzsoftware 
 +#type ("trium8")# 
 + 
 +1. Die Netztask 
 + 
 +2. Protokollebenen 
 + 
 +3. Stand der Netzsoftware 
 + 
 +#page# 
 +#headodd# 
 + 
 +#center#Einleitung#right#% 
 + 
 + 
 +#end# 
 + 
 +#type("triumb12")# 
 +1. Einleitung #type("trium8")# 
 + 
 + 
 +Das EUMEL-Netz dient dazu mehrere EUMEL-Rechner (sog. Stationen) mit-
 +einander zu koppeln. Diese Kopplung wird von Betriebsystem dazu benutzt, das
 +Sendungskonzept (siehe Systemhandbuch 1.7, Intertaskkommunikation) so auszu-
 +dehnen, da Tasks verschiedener Stationen einander Datenrume zusenden
 +knnen. Auf dem Sendungskonzept aufbauende Konzepte nutzen daher automa-
 +tisch das Netz aus: So ist es z.B. mglich 
 + 
 +- von einer Station aus auf einer anderen zu Drucken, 
 + 
 +- in PUBLIC einer anderen Station Dateien zu sichern (save), vorausgesetzt, da
 +  PUBLIC dort ein free global manager ist, 
 + 
 +- auf einer anderen Station zu archivieren (z.B. wenn das eigene Archivlaufwerk
 +  defekt ist oder ein anderes Format hat). 
 + 
 +Das Netz kann ab EUMEL-Version 1.7.3 eingesetzt werden. 
 + 
 + 
 +#type("triumb12")# 
 +Teil 1: Netz einrichten und benutzen 
 + 
 +1. Benutzung des Netzes #type("trium8")# 
 +#headodd# 
 + 
 +#center#Teil 1: Netz einrichten und benutzen#right#% 
 + 
 + 
 +#end# 
 + 
 +   Zur Benutzung des Netzes stehen folgende Operatoren und Prozeduren zur
 +   Verfgung: 
 + 
 + 
 +1.1 
 + 
 +   TASK OP / (INT CONST station, TEXT CONST taskname) 
 + 
 +   liefert die Task #on("bold")#taskname#off("bold")# von der Station #on("bold")#station#off("bold")#. 
 + 
 +   Wenn die Station #on("bold")#station#off("bold")# nicht am Netz ist oder nicht eingeschaltet ist, wird
 +   solange gewartet, bis das der Fall ist. 
 + 
 +   Fehlerflle: 
 + 
 +     - task "..." gibt es nicht 
 + 
 +       Die angeforderte Task gibt es in der Zielstation nicht. 
 + 
 +     - Collectortask fehlt 
 + 
 +       Das Kommando #on("bold")#define collector#off("bold")# wurde nicht gegeben (siehe 4.2). 
 + 
 +     - Station x antwortet nicht 
 + 
 +       Eine nicht vorhandene oder abgeschaltete Station wurde angesprochen. 
 +       Hinweis: Dieser Fehler wird angenommen, wenn eine berwachungszeit
 +                von ca. 30 Sekunden verschrichen ist, ohne da Station x die
 +                Taskidentifikation angeliefert hat. 
 + 
 +   Beispiel: 
 + 
 +     list (5/"PUBLIC") 
 + 
 +     Dateiliste von PUBLIC auf Station 5 wird angefordert. 
 + 
 +1.2 
 + 
 +   TASK OP / (INT CONST station, TASK CONST task) 
 + 
 +   liefert 
 + 
 +   station / name (task) . 
 + 
 + 
 +   Beispiel: 
 + 
 +     list (4/archive) 
 + 
 + 
 +1.3 
 + 
 +   INT PROC station (TASK CONST task) 
 + 
 +   liefert die Stationsnummer der Task #on("bold")#task#off("bold")#. 
 + 
 +   Beispiel: 
 + 
 +     put (station (myself)) 
 + 
 +     gibt die eigene Stationsnummer aus. 
 + 
 + 
 +1.4 
 + 
 +   PROC archive (TEXT CONST archivename, INT CONST station) 
 + 
 +   dient dazu das Archiv auf der Station #on("bold")#station#off("bold")# anzumelden. 
 + 
 +   Beispiel: 
 + 
 +   archive ("std", 4); list (4/archive) 
 + 
 +   gibt das Inhaltsverzeichnis der Archivfloppy im Laufwerk der Station 4 aus. 
 +   Hinweis: Vergessen Sie bei solchen Querarchivierungen nicht die Stations-
 +            angabe bei jedem einzelnen Archivkommando (z.B fetch ("xxx", #on("bold")#4/#off("bold")#
 +            archive). 
 +   Hinweis: Querarchivieren ist langsam. Verwenden Sie es nur, wenn Sie Flop-
 +            pyformate umsetzen wollen. 
 + 
 + 
 +1.5 
 + 
 +   PROC free global manager 
 + 
 +   dient dazu, die eigene Task ber das Netz ansprechbar zu machen. Jede
 +   andere Task im Netz kann dann die blichen Manageraufrufe ('save', 'fetch',
 +   u.s.w.) an die eigene Task machen, sofern diese nicht an ein Terminal gekop-
 +   pelt ist. 
 + 
 +   Die Task wird (wie bei 'break') abgekoppelt und meldet sich in Zukunft mit
 +   'maintenance' statt mit 'gib kommando'. 
 + 
 +   Beispiel: 
 + 
 +   An Station 4 ruft man in der Task 'hugo' das Kommando #on("bold")#free global manager#off("bold")#
 +   auf. Anschlieend kann man von jeder Station aus z.B. 'list (4/"hugo")' u.s.w.
 +   machen. 
 + 
 + 
 +1.6 
 + 
 +  TEXT PROC name (TASK CONST t) 
 + 
 +  Diese (schon immer vorhandene) Prozedur wurde dahingehend erweitert, da der
 +  Name einer Task einer anderen Station ber Netz angefordert wird. 
 + 
 +  Fehlerfall: 
 + 
 +  Station x antwortet nicht 
 + 
 + 
 + 
 + 
 +#type("triumb12")#2. Hardwarevoraussetzungen#type("trium8")# 
 + 
 +2.1 Zwei Stationen 
 + 
 +      Sie knnen zwei Stationen miteinander Vernetzen, wenn Sie dafr an jeder
 +      Station eine V24-Schnittstelle zur Verfgung stellen. 
 + 
 +      Diese beiden Schnittstellen verbinden Sie mit einem Kabel zur Rechner-
 +      kopplung (siehe Systemhandbuch 1.7 Teil 2). 
 + 
 +2.2 Mehrere Stationen 
 + 
 +      Wenn Sie mehr als zwei Stationen vernetzen wollen, brauchen neben je
 +      einer V24 an jeder Station noch je eine Netzanschlubox. 
 + 
 +      Jede Box besitzt eine V24-Schnittstelle zum Anschlu an die V24-
 +      Schnittstelle der zugeorneten Station und eine weitere Schnittstelle zur
 +      Verbindung der Boxen untereinander. 
 + 
 + 
 +#type("triumb12")#3. Einrichten des Netzes #type("trium8")# 
 + 
 +Hinweis: Dieses Kapitel ist nur fr Systembetreuer wichtig. 
 + 
 +3.1 Legen Sie Stationsnummern fr die am Netz beteiligten Rechner fest (von 1 an
 +    aufsteigend). 
 + 
 +    Die Boxen haben ebenfalls Stationsnummern. Die Stationsnummern der Box
 +    und des zugeordneten Rechners mssen bereinstimmen. 
 + 
 + 
 +3.2 Holen Sie an jeder Station die Task #on("bold")#configurator#off("bold")# an ein Terminal und geben Sie
 +    das Kommando #on("bold")#define collector ("net port")#off("bold")#. Geben Sie auerdem das
 +    Kommando #on("bold")#define station (x)#off("bold")#, wobei #on("bold")#x#off("bold")# die gewhlte Stationsnummer ist. 
 + 
 +    Hinweis: Taskkommunikationen, die zu dem Zeitpunkt laufen, fhren zu feh-
 +             lerhaften Verhalten. Dies liegt daran, da durch #on("bold")#define station#off("bold")# alle
 +             Task-Id's gendert werden mssen, weil eine Task-Id u.a. die
 +             Stationsnummer der eigenen Station enthlt (siehe 2.3). TASK-
 +             Variable, die noch Task-Id's mit keiner oder falscher Stationsnum-
 +             mer enthalten, knnen nicht mehr zum Ansprechen einer Task
 +             verwendet werden. 
 + 
 +    Beispiel: Der Spoolmanager (siehe Benutzerhandbuch 1.7 Teil 12) richtet
 +              beim Kommando #on("bold")#start#off("bold")# einen Worker ein und merkt sich dessen
 +              Task-Id in einer TASK-Variablen, um sicherzustellen, da nur der
 +              Worker Dateien zum Drucken abholt. Wird jetzt das Kommando #on("bold")#
 +              define station#off("bold")# gegeben, kann der Spoolmanager seinen Worker
 +              nicht mehr identifizieren, weil der Worker eine neue Task-Id er-
 +              halten hat. Man mu daher den Worker lschen und mit dem
 +              Kommando #on("bold")#start#off("bold")# im Spoolmanager wieder neu einrichten. 
 + 
 + 
 +             Sinnvollerweise gibt man #on("bold")#define station#off("bold")# sofort nach den Laden eines
 +             frischen Systems von Archiv. 
 + 
 +    Konfigurieren Sie mit dem Kommando #on("bold")#configurate#off("bold")# den fr das Netz vorgese-
 +    henen Kanal auf 
 + 
 +    - transparent 
 +    - 9600 Baud (Standardeinstellung der Boxen) 
 +    - RTS/CTS-Protokoll 
 +    - groen Puffer 
 +    - 8 bit 
 +    - even parity 
 +    - 1 stopbit. 
 + 
 +    Falls diese Einstellungen nicht alle angeboten werden, klren Sie mit Ihrem
 +    Rechnerlieferanten, ob und wie diese Einstellungen erreicht werden knnen. 
 +    Hinweis: Notfalls kann auf das RTS/CTS-Protokoll verzichtet werden, wenn
 +             der Eingabepuffer der Station gro genug ist. Die Anzahl simultan
 +             laufender Netzkommunikationen ist dann auf 
 + 
 +             puffergre DIV 150 
 + 
 +             begrenzt (bei Z80, 8086: 3; bei M20: 10). 
 +   Hinweis: Es knnen auch andere Baudraten (2400, 4800, 19200) an der Box
 +            eingestellt werden. 
 + 
 +3.3 Achten Sie bei der Verbindung von der Station zur Netzbox (bzw. zur Gegen-
 +    station bei einem Zweistationennetz ohne Boxen) darauf, da neben den
 +    Empfangs- und Sendeleitungen auch die Leitungen RTS und CTS verdrahtet
 +    werden, also ein 5 poliges Kabel verwendet wird (siehe Systemhandbuch 1.7
 +    Teil 2). Die Pin-Belegung der Boxen entspricht den dortigen Angaben. 
 + 
 +    Beispiel: 
 + 
 +    Verbindung eines CSK-Systems mit der Box: 
 + 
 +    Stecker                  Stecker 
 +    Pin                      Pin 
 + 
 +    2  <--------->           3 
 +    3  <--------->           2 
 +    4  <--------->           5 
 +    5  <--------->           4 
 +    7  <--------->           7 
 + 
 + 
 +3.4 Richten Sie eine Task #on("bold")#net#off("bold")# unter #on("bold")#SYSUR#off("bold")# ein und insertieren Sie dort die Datei-
 +en 
 + 
 +    net report/M 
 +    basic net 
 +    net manager/M. 
 + 
 +    Beantworten Sie die Frage nach dem Kanal fr das Netz und nach der Flu-
 +    kontrolle (RTS/CTS). 
 + 
 + 
 +#type("triumb12")#4. Informationsmglichkeiten #type("trium8")# 
 + 
 +   In der Task #on("bold")#net#off("bold")# wird eine Datei #on("bold")#report#off("bold")# gefhrt in der Fehlersituationen des
 +   Netzes verzeichnet werden. Diese Datei kann in jeder anderen Task mit #on("bold")#list
 +   (/"net")#off("bold")# angezeigt werden. 
 + 
 +   In jeder Task kann durch das Kommando #on("bold")#list (/"net port")#off("bold")# eine bersicht ber
 +   die momentan laufenden Netzbertragungen der eigenen Station erhalten
 +   werden. 
 + 
 + 
 +#type("triumb12")#5. Eingriffsmglichkeiten #type("trium8")# 
 +#headodd# 
 + 
 +#center#Eingriffsmglichkeiten#right#% 
 + 
 + 
 +#end# 
 + 
 +5.1 Jede Task kann Sende- und Empfangsstrme, die bei #on("bold")#list (/"net port")#off("bold")# gemel-
 +    det worden sind und die eigene Task betreffen, abbrechen. Hierzu ist das
 +    Kommando #on("bold")#erase ("x",/"net port")#off ("bold")# zu geben, wobei x die Stromnummer (aus
 +    dem 'list') ist. 
 + 
 +    Unberechtigte Lschversuche werden abgewiesen. 
 + 
 +    Von der Task 'net' aus knnen jedoch damit beliebige Strme abgebrochen
 +    werden. 
 + 
 +5.2 Durch das Kommando #on("bold")#start#off("bold")# kann von der Task 'net' aus das Netz neu gestartet
 +    werden. Dabei werden alle augenblicklichen Netzkommunikationen gelscht.
 +    Die Tasks 'net port' und 'net timer' werden dabei gelscht und neu eingerich-
 +    tet. 
 + 
 +    #on("bold")#start (kanal, quit)#off("bold")# wirkt wie #on("bold")#start#off("bold")#. Zustzlich wird als Netzkanal 'kanal' eingestellt
 +    und maximal 'quit' Empfangsstrme zugelassen. 'quit' ist auf 3 zu setzen,
 +    wenn der Kanal ohne RTS/CTS angeschlossen ist (siehe 3.2). 
 + 
 + 
 +#type("triumb12")#6. Fehlersuche im Netz #type("trium8")# 
 + 
 +   Fehler im Netz knnen sich verschiedenartig auswirken. Im Folgenden wird auf
 +   einige Beispiele eingegangen: 
 + 
 +   Beispiel: 
 + 
 +   Auf #on("bold")#list (4/public)#off("bold")# erfolgt die Meldung 'Station 4 antwortet nicht'. 
 + 
 +   Fehlermglichkeiten: 
 + 
 +   -  Station 4 gibt es nicht am Netz. 
 +      Abhilfe: Richtige Station angeben. 
 + 
 +   -  Station 4 ist nicht eingeschaltet. 
 +      Abhilfe: Station 4 einschalten. Kommando erneut geben. 
 + 
 +   -  Netztask an Station 4 ist nicht arbeitsfhig. 
 +      Abhilfe: Kommando 'start' in der Task 'net'. 
 + 
 +   -  Stationsnummern und Boxnummern stimmen nicht berein. 
 +      Abhilfe: Mit 'define station' Stationsnummern korrigieren (siehe 3.2). 
 + 
 +   -  Verbindung Rechner/Box am eigenen Rechner oder an Station 4 fehlt. 
 +      Abhilfe: Verbindungen berprfen. Durch Ansprechen einer dritten Station
 +               kann oft schnell geklrt werden, welche Rechner/Box-Verbindung
 +               defekt sein mu. 
 + 
 +   -  Verbindung der Boxen untereinander defekt. 
 +      Abhilfe: Fehlende Verbindung, Masseschlu und Dreher (keine 1:1 Ver-
 +               bindung) berprfen und beheben. 
 +      Hinweis: Liegt z.B. ein Masseschlu vor, so kann es durchaus sein, da
 +               Boxen, die nicht in der Nhe des Masseschlu stehen noch mitei-
 +               nander arbeiten knnen. Man kann aus der Tatsache, da zwei
 +               Boxen miteinander arbeiten knnen, also nicht schlieen, da man
 +               nicht nach diesem Fehler suchen mu. 
 + 
 + 
 +   Beispiel: 
 + 
 +   Auf #on("bold")#list (4/public)#off("bold")# erfolgt keine Reaktion. 
 + 
 + 
 +   -  Station 4 ist whrend dieser Sendung zusammengebrochen. 
 +      Abhilfe: Station 4 wieder starten. Die Bearbeitung des 'list'-Kommandos
 +               wird automatisch wieder aufgenommen. 
 + 
 +   -  PUBLIC auf Station 4 ist nicht im Managerzustand. 
 +      Abhilfe: PUBLIC in den Managerzustand versetzen. 
 + 
 + 
 +      Hinweis: Das Netz hat nocht nicht die volle Sendungslogik des EUMEL. So
 +               wird nur ca. 10 Minuten lang versucht, eine Sendung zuzustellen.
 +               Danach wird die Sendung gelscht. Ist dies eingetreten, so mu
 +               das list-Kommando erneut gegeben werden. 
 + 
 +   -  Fehler in der Netzhardware. 
 +      berprfen Sie, ob 
 + 
 +      - die Boxen eingeschaltet sind, 
 +      - die Bereitlampe blinkt (wenn nicht: RESET an der Box) 
 +      - die V24-Kabel richtig stecken, 
 +      - die Boxen untereinander verbunden sind (1 zu 1 Verbindungen der 5
 +        poligen Diodenbuchsen). 
 + 
 + 
 +   -  Die Netzsoftware ist auf einen nicht vorhergesehenen Fehler gelaufen. 
 +      Dieser wird im Report vermerkt. 
 +      Abhilfe: Geben Sie in der Task #on("bold")#net#off("bold")# das Kommando #on("bold")#start#off("bold")#. Dadurch wird die
 +               Netzsoftware neu gestartet. Alle Netzkommunikationen dieser
 +               Station gehen verloren. 
 + 
 + 
 +   Beispiel: 
 + 
 +   Auf #on("bold")#list (4/public)#off("bold")# erfolgt die Meldung 'Collectortask fehlt'. 
 + 
 +   -  In der Task 'configurator' wurde das Kommando 'define collector' (siehe 3.2)
 +      nicht gegeben. 
 + 
 +   -  Die Task 'net port' existiert nicht mehr. 
 +      Abhilfe: Kommando 'start' in der Task 'net'. 
 + 
 + 
 +   Beispiel: 
 + 
 +   Nach #on("bold")#fetch ("hugo",4/public)#off("bold")# sind Teile von der Datei "hugo" verflscht. 
 + 
 +   -  Die V24-Verbindung zur Box ist nicht in Ordnung. 
 +      Abhilfe: Abstand zwischen Rechner und Box verkrzen; Baudrate ernie-
 +               drigen; Durch Wechseln der V24-Schnittstelle feststellen, ob
 +               diese defekt ist. 
 +      Hinweis: Die Verbindung zwischen den Boxen ist durch Prfsummen abge-
 +               sichert (Hardware). 
 + 
 +#headodd# 
 + 
 +#center#Teil 2: Arbeitsweise der Netzsoftware#right#% 
 + 
 + 
 +#end# 
 +#page# 
 +#type("triumb12")# 
 + 
 +Teil 2: Arbeitsweise der Netzsoftware 
 + 
 + 
 +1. Die Netztask #type ("trium8")# 
 + 
 +In diesem Kapitel wird beschrieben, wie eine Netztask in das System
 +eingebettet ist und welche Aufgaben sie hat. Unter Einhaltung dieser
 +Konzepte kann die ausgelieferte Netztask so gendert werden, da sie
 +beliebige andere Netzhardware untersttzt. Z.Zt. ist die Netzsoftware noch
 +nicht so gegliedert, da nur eine hardwareabhngige Komponente ausgetauscht
 +werden mu. 
 + 
 +Die Kommunikation zwischen Tasks im EUMEL-Betriebssystem basiert auf einem
 +Rendevouskonzept: Die Zieltask einer Sendung mu empfangsbereit sein, wenn die
 +Quelltask sendet. 
 + 
 +Die Kommunikationsprozeduren auf der niedrigsten Ebene sind 'send' (Senden)
 +und 'wait' (Warten auf Empfang). Bei der Kommunikation werden eine Integer
 +'code' und ein Datenraum 'dr' bergeben. 'code' mu >= 0 sein, da negative
 +Codes systemintern verwandt werden. Ist die empfangende Task an einen Kanal
 +gekoppelt ('continue'), so fhrt eine Zeicheneingabe auf diesem Kanal dazu,
 +da eine
 +Sendung mit dem Code -4 ankommt. Die Eingabedaten mssen mit den blichen
 +Eingabeprozeduren ('inchar' u.s.w.) abgeholt werden. Der bermittelte Datenraum
 +und die Absendertask sind dabei ohne Bedeutung und drfen nicht interpretiert
 +werden. 
 + 
 +Die Prozedur 'send' hat einen Rckmeldeparameter, der besagt, ob die Sendung
 +bermittelt wurde. Gibt es die Zieltask nicht oder steht sie nicht im 'wait', so kann
 +die Sendung nicht bermittelt werden. 
 + 
 + 
 +Ein Entwicklungskriterium fr das EUMEL-Netz war es, mglichst wenig Unter-
 +sttzung von der virtuellen EUMEL-Maschine (EUMEL0) zu fordern, damit weit-
 +gehend in ELAN programmiert werden kann. Dadurch ist es mglich eine (privili-
 +gierte) Task mit der Netzabwicklung zu betrauen. 
 + 
 +Zunchst wird auf die EUMEL0-Untersttzung eingegangen: 
 + 
 +1.1. Es gibt die Prozedur 'define collector', mit der die fr das Netz verantwort-
 +     liche Task der EUMEL0-Maschine bekannt gemacht wird. Diese Task wird im
 +     folgenden Collector genannt. 
 + 
 +1.2. Es gibt die Prozedur 'define station', die fr den Rechner eine Stationsnum-
 +     mer einstellt. Anhand dieser Nummer werden die Rechner eines Netzes un-
 +     terschieden. Das Einstellen bewirkt, da fr alle Tasks die Stationsnummer in
 +     ihre Task-Id eingetragen wird (Task-Id's sind die Werte, die der Typ TASK
 +     annehmen kann). 
 + 
 +1.3. Der Befehl 'station (task)' liefert die Stationsnummer der 'task'. So liefert z.B.
 +     'station (myself)' die Stationsnummer des eigenen Rechners. 
 + 
 +1.4. Eine Sendung, deren Zieltask in einem anderen Rechner liegt (also station
 +     (ziel) <> station (myself)), wird auf die Collectortask geleitet. 
 + 
 +1.5. Es gibt eine Prozedur 'collected destination', die es dem Collector erlaubt, die
 +     eigentliche Zieltask einer auf ihn geleiteten Sendung zu erfahren. 
 + 
 +1.6. Es gibt eine Variante der Prozedur 'send', die es dem Collector gestattet, der
 +     Zieltask eine beliebige andere Task als Absender vorzumachen. 
 + 
 +1.7. Es gibt eine spezielle Task-Id 'collector', durch die der augenblicklich ein-
 +     gestellte Collector erreicht wird. Diese wird als Zieltask beim Aufruf der Ver-
 +     mittlungsdienste angegeben (siehe 2.5). Eine Sendung an 'collector' wird von
 +     EUMEL0 an den derzeitigen Collector geschickt. 
 + 
 +Ein Collector kann also auf drei Wegen von den brigen Tasks desselben Rechners
 +Sendungen erhalten: 
 + 
 +  1. ber ein normales Send (z.B. bei 'list (/"net port")', wenn "net port" der der-
 +     zeitige Collector ist), 
 + 
 +  2. ber ein Send an die Task 'collector' (s.u.) und 
 + 
 +  3. als umgeleitete Sendung (z.B. bei 'list' an eine Task auf einem anderen
 +     Rechner). 
 + 
 +Der Collector kann diese Flle anhand von 'collected destination' unterscheiden. 
 + 
 +Die Punkte 1.4...1.6 dienen dazu, den Collector fr ber Netz kommunizierende
 +Task unsichtbar zu machen: Der Collector taucht nicht als Ziel oder Quelle von
 +Sendungen auf. Das ist notwendig, damit normale Tasks sich nicht darum kmmern
 +mssen, ob eine Sendung bers Netz geht oder im eigenen Rechner bleibt. 
 + 
 +Wenn ein Datenraum an einen anderen Rechner geschickt wird, mu der gesamte
 +Inhalt (z. Zt. max. 1 MB) bertragen werden. Dies macht bei der blichen Netz-
 +hardware eine Zerlegung in Packete ntig (siehe Systemhandbuch 173, Teil 4,
 +Punkt 5). Fr Netze ber V24-Kanle stehen spezielle Blockbefehle zur verf-
 +gung: 
 + 
 +1.8. blockin / blockout (dr,seite,512+abstand,anzahl,rest) 
 + 
 +   Es werden maximal 'anzahl' Bytes transferiert. In 'rest' wird zurckgemeldet,
 +   wieviel Bytes nicht bearbeitet wurden (z.B. weil der Kanal nichts anliefert).
 +   Bearbeitet werden die Bytes 
 + 
 +      'seite' * 512 + 'abstand' 
 + 
 +   bis maximal 
 + 
 +      'seite' * 512 + 'abstand' + 'anzahl' - 1 
 + 
 +  Der Kanal, an den die Task gekoppelt ist, wird dabei ber Stream-IO (d.h.
 +  'incharety' bei 'blockin' bzw. 'out' bei 'blockout') angesprochen. 
 + 
 +  Hinweis: Die Anforderung darf nicht ber Seitengrenze gehen, d.h. 
 + 
 +  'abstand' + 'anzahl' <= 512 
 + 
 +  mu erfllt sein. 
 + 
 + 
 +Eine Netzsendung luft wie folgt ab: 
 + 
 +Die Task q auf Rechner rq mache ein 'send' an die Task z auf Rechner rz. 
 + 
 +1. Die Prozedur send ist ein EUMEL0-Befehl. Die EUMEL0-Ebene erkennt, da
 +   die Sendung an die Station rz geht, da die Stationsnummer in der Task-Id
 +   enthalten ist. Daher wird die Sendung zum Collector, den EUMEL0 wegen 'de-
 +   fine collector' kennt, umgeleitet. 
 + 
 +2. Die Task Collector empfngt ber 'wait' den Datenraum, den Sendecode und
 +   die Absendertask q. Die Zieltask z erfhrt sie durch 'collected destination'. 
 + 
 +3. Der Collector nimmt Kontakt mit dem Collector des Rechner rz, dessen Sta-
 +   tionsnummer ja 'station(z)' ist, auf und bermittelt diesem Sendecode, Quelltask
 +   (q), eigentliche Zieltask (z) und den Datenraum. Da die Collectoren in ELAN
 +   geschrieben sind, knnen sie an beliebige Netzhardware und Protokolle ange-
 +   pat werden. 
 + 
 +4. Der Collector auf Rechner rz verwendet das spezielle 'send', um der Zieltask die
 +   Sendung zuzustellen. Dadurch erscheint nicht der Collector sondern die Task q
 +   als Absender der Sendung. 
 + 
 +Zur Abwicklung der Vermittlungsebene (Teil 1: 2.4) mu der Collector noch
 +spezielle Funktionen beherrschen. Diese sind 
 + 
 +   der /-Operator (Taskname in Task-Id wandeln) und 
 +   die name-Prozedur (Task-Id in Namen wandeln). 
 + 
 +Der /-Operator macht eine Sendung an den 'collector', wobei im Datenraum der
 +Name der Task steht und der Sendecode gleich der Stationsnummer ist (siehe
 +Quellcode 173, Packet tasks). Der Collector setzt sich mit dem Collector dieser Sta-
 +tion in Verbindung, damit dieser die Task-Id ermittelt und zurckschickt. Der
 +eigene Collector schickt dann dem /-Operator als Antwort einen Datenraum, der
 +die Task-Id enthlt. 
 + 
 +Umgekehrt luft 'name' ab: Wenn die Task-Id von einer fremden Station ist,
 +schickt 'name' eine Sendung an den 'collector', wobei im Datenraum die Task-Id
 +steht und Sendecode = 256 ist. Der Collector entnimmt die Stationnummer der
 +Task aus der Task-Id und lt sich vom entsprechenden Collector den Tasknamen
 +geben. Dieser wird der 'name'-Prozedur im Antwortdatenraum bergeben. 
 + 
 +#type ("triumb12")#2. Ebenen #type("trium8")# 
 + 
 +In diesem Kapitel werden die Protokollebenen fr das Netz beschrieben, wie
 +sie die ausgelieferte Netzsoftware benutzt und erwartet. Bei anderer
 +Netzhardware mssen die Ebenen 1 bis 3 ausgetauscht werden. Unter Einhaltung
 +der im vorigen Kapitel beschriebenen Randbedingungen knnen auch die hheren
 +Ebenen gendert werden. 
 + 
 + 
 +2.1 Physikalische Ebene 
 + 
 +    2.1.1  Station <--> Box 
 + 
 +           V24-Schnittstelle mit RTS/CTS-Handshake. Vollduplex. 
 + 
 +    2.1.2  Box <--> Box 
 + 
 +           RS422 ber 2 verdrillte Leitungspaare (Takt und Daten). 
 + 
 +2.2 Verbindungsebene 
 + 
 +    2.2.1  Station <--> Box 
 + 
 +           Asynchron 
 +           8 Bit 
 +           Even Parity 
 +           2400/4800/9600/19200 Baud (einstellbar ber Ltbrcken) 
 + 
 +    2.2.2  Box <--> Box 
 + 
 +           SDLC 
 +           400 KBaud 
 + 
 +2.3 Netzebene 
 + 
 +    2.3.1  Station <--> Box 
 + 
 +           Telegrammformat:  STX, <n>, <ziel>, <quelle>, <(n-4) byte> 
 + 
 +           <n> ist Lngenangabe ( 8 <= n <= 160) 
 +           <ziel>, <quelle> sind Stationsnummern. Diese mssen an den je-
 +           weiligen Boxen ber Ltbrcken eingestellt sein. 
 + 
 +           Box --> Station: 
 + 
 +           Ein Telegramm kommt nur bei der Station an, bei deren Box die
 +           Nummer <ziel> eingestellt ist. Dadurch ist ein Mithren fremder
 +           bertragungen nicht mglich (Datenschutz). 
 + 
 +           Zwischen Telegrammen knnen Fehlermeldungen der Box (Klartext)
 +           bermittelt werden (z.B. 'skipped x', wenn ein STX von der Box er-
 +           wartet wurde, aber 'x' von der Station ankommt). 
 + 
 +           Station --> Box: 
 + 
 +           Ein Telegramm wird nur abgeschickt, wenn <quelle> mit der einge-
 +           stellten Nummer bereinstimmt (Datenschutz: Man kann nicht eine
 +           beliebige Station zu sein vorschwindeln, es sei denn man hat physi-
 +           schen Zugriff zur Box und stellt dort die Stationsnummer um). 
 + 
 +    2.3.2  Box <--> Box 
 + 
 +           Telegrammformat: FRAME, <ziel>, <quelle>, <daten> ,
 +           <CRC-Code> 
 + 
 +           Eine Lngenangabe ist nicht ntig, da SDLC eine Rekonstruktion der
 +           Lnge erlaubt. 
 + 
 +           Telegramme mit falschen CRC-Code werden vernichtet. Auf hheren
 +           Ebenen mu dies durch Zeitberwachung erkannt und behandelt
 +           werden. 
 + 
 + 
 +2.4 Transportebene 
 + 
 +    Diese Ebene wickelt das Rendevous zwischen einer Task, die 'send' macht,
 +    und einer Task, die im 'wait' steht, ab (siehe: EUMEL-Systemhandbuch). 
 + 
 +    Der im 'send' angegebene Datenraum wird als Folge von Seiten (im
 +    EUMEL-Sinne: Pagingeinheit und Allokiereinheit) bermittelt, wobei jede Seite
 +    noch in 64 Byte groe Stcke zerlegt wird. Es werden nur echt allokierte Seiten
 +    bermittelt. Um nicht jedes Telegramm voll qualifizieren zu mssen, wird
 +    zunchst eine Art virtuelle Verbindung durch ein OPEN-Telegramm erffnet.
 +    Danach folgen variable viele DATA-Telegramme. Beide Sorten werden durch
 +    QUIT-Telegramme quittiert, um folgende Funktionen zu ermglichen: 
 + 
 +    Flukontrolle (z.B. Zielrechner langsam) 
 +    Wiederaufsetzen (verlorene Telegramme) 
 +    Abbruch (z.B. weil Zieltask inzwischen beendet). 
 + 
 +    Ein CLOSE-Telegramm ist nicht ntig, da das letzte DATA-Telegramm als
 +    solches erkannt werden kann (siehe unten). 
 + 
 +    2.4.1 OPEN-Telegramm 
 + 
 +          STX, 20, <ziel>, <quelle>, <strom>, <sequenz>, <seite>, 
 +          <quelltask>, <zieltask>, <code> 
 + 
 +          <ziel>, <quelle> siehe 2.3.1 
 + 
 +          <strom>      Die Stromnummer identifiziert die virtuelle Verbindung.
 +                       Sie mu in den QUIT-Telegrammen angegeben wer-
 +                       den. 
 + 
 +          <sequenz>    -1 (Kennzeichen fr OPEN) 
 + 
 +          <seite>      Nummer der ersten echt allokierten Seite des Datenra-
 +                       ums (=-1, falls Nilspace) 
 + 
 +          <quelltask>  Taskid der sendenden Task 
 + 
 +          <zieltask>   Taskid der empfangenden Task 
 + 
 +          <code>       Wert des im 'send' angegebenen Codes. 
 + 
 +    2.4.2 DATA-Telegramm 
 + 
 +          STX, 74, <ziel>, <quelle>, <sequenz>, <seite>, <64 byte> 
 + 
 +          <sequenz>    wird von Telegramm zu Telegramm hochgezhlt. Dient
 +                       der berwachung gegen verlorengegangene Telegramme
 +                       bzw. durch Zeitberwachung verdoppelter Telegramme. 
 + 
 +          <seite>      Nummer der x.ten echt allokierten Seite des Datenra-
 +                       ums. (x = (<sequenz>+16) DIV 8). 
 + 
 +          <64 byte>    Nutzinformation. Diese gehrt zur Adresse a des Daten-
 +                       raums. 
 + 
 +                       a = N (<sequenz> DIV 8 + 1) * 512 
 +                           + (<sequenz> MOD 8) * 64 
 + 
 +                       wobei N (x) die Nummer der x.ten Seite ist. 
 + 
 +                       Aus den Formeln ergibt sich, da diese Nummer schon in
 +                       einem vorhergehenden DATA/OPEN-Telegramm ber-
 +                       mittelt wurde (im Feld <seite>). 
 + 
 +    2.4.3 QUIT-Telegramm 
 + 
 +          STX, 8, <ziel>, <quelle>, <strom>, <quit> 
 + 
 +          <strom>      mu die Stromnummer sein, die in dem OPEN/DATA-
 +                       Telegramm stand, das quittiert wird. 
 + 
 +          <quit>       0 :  ok. Nchstes Telegramm schicken. 
 + 
 +                       -1:  bertragung neu starten (mit OPEN), weil die
 +                            Empfangsstation das OPEN nicht erhalten hat. 
 + 
 +                       -2:  bertragung ca. 20 Telegramme zurcksetzen. 
 + 
 +                       -3:  bertragung abbrechen. 
 + 
 + 
 +2.5 Vermittlungsebene 
 + 
 +    Diese Ebene ist dafr zustndig, Tasknamen von Task auf anderen Stationen
 +    in Taskids (Werte des Typs TASK) zu wandeln und umgekehrt. Hierzu wird im
 +    entsprechenden OPEN-Telegramm der Code -6 (bzw. -7) als <code>
 +    eingetragen. Die Netzempfangstask erkennt diese Codes und wickelt die
 +    Aufgaben selbst ab, soda es dabei nicht ntig ist, irgendeine Taskid der
 +    Zielstation zu kennen. 
 + 
 +    Dieses Verfahren ist mglich, weil im 'send' nur positive Codes erlaubt sind. 
 + 
 +2.6 Hhere Ebenen 
 + 
 +    Hhere Ebenen sind nicht mehr netzspezifisch. Sie basieren alle auf dem
 +    Send/Wait-Konzept des EUMEL. So gibt es z.B. den 'global manager', der
 +    Aufbewahrung und Zugriff von Dateien in einer Task regelt. Dabei darf diese
 +    Task (bei der Variante 'free global manager') auf einer beliebigen Station im
 +    Netz liegen. Wegen des Rendevous-Konzepts knnen beliebige Sicherheit-
 +    strategien benutzt werden (z.B.: Keine Dateien an Station 11 ausliefern). Von
 +    groen Wert ist z.B., da man ohne weiteres das Archiv (Floppylaufwerk) einen
 +    anderen Station anmelden und benuzten kann, wodurch eine einfache Kon-
 +    vertierung von Floppyformaten mglich ist. Dies ist mglich, weil auch die Ar-
 +    chiv-Task der Stationen sich an das Globalmanagerprotokoll halten. 
 + 
 + 
 +#type("triumb12")# 
 +Bemerkungen#type("trium8")# 
 + 
 +Fehlerbehandlung besteht bis Ebene 3 darin, fehlerhafte Telegramme einfach zu
 +entfernen. Die Ebene 4 berwacht den Netzverkehr sowieso ber Timeouts, die
 +eine Wiederhohlung eines Telegrammes bewirken, wenn die Quittung ausbleibt. 
 + 
 +Da bei der sendenden Station der ganze Datenraum zur Verfgung steht, ist eine
 +Fenstertechnik (wie bei HDLC) nicht ntig. Es kann zu jedem Zeitpunkt um beliebig
 +viele Telegramme zurckgesetzt werden. 
 + 
 +Da im EUMEL eine Textdatei ein Datenraum mit sehr komplexer Struktur ist (wegen
 +der Insert/Delete-Mglichkeiten, ohne den Rest der Datei zu schieben), ist es ein
 +hoher Aufwand, von einem fremden Betriebssytem her Textdateien ins EUMEL-
 +Netz zu senden. Fr solche Zwecke mu noch eine einfachere Dateistruktur defi-
 +niert werden und entsprechende Dateikonverter erstellt werden. 
 + 
 + 
 + 
 +#type("triumb12")#3. Stand der Netzsoftware #type("trium8")# 
 + 
 +Das EUMEL-System wickelt die Prozedur #on("bold")#send#off("bold")# ber das Netz ab, wenn die
 +Stationsnummer der Zieltask ungleich der eigenen Stationsnummer ist. Umge-
 +kehrt kann man der von der Prozedur #on("bold")#wait#off("bold")# gelieferten Absendertask die Absen-
 +derstation entnehmen (siehe Prozedur #on("bold")#station#off("bold")# in Abschnitt 3). 
 + 
 +Nicht untersttzt wird z.Zt. die Logik der Prozeduren #on("bold")#call#off("bold")# und #on("bold")#pingpong#off("bold")#. Diese
 +funktionieren nur in der gewohnten Weise, wenn die Zieltask in #on("bold")#wait#off("bold")# steht. Ist
 +die Zieltask lnger als ca. 10 Minuten #on("bold")#busy#off("bold")# oder nicht mehr vorhanden, geht die
 +Sendung einfach verloren (Gefordert ist: bei #on("bold")#call#off("bold")#: immer wieder versuchen; bei #on("bold")#
 +pingpong#off("bold")#: Rckmeldung -2). 
 + 
 +Wegen dieser Einschrnkung kann man z.B. ein sicheres Drucken von Station a
 +auf einen Drucker der Station b nur durch einen eigenen Spoolmanager auf
 +Station a verwirklichen. Die Einrichtung eines solchen Managers ist allerdings
 +sowieso sinnvoll, damit man 
 + 
 +- das normale 'print'-Kommando verwenden kann (statt z.B. save ("xxx",
 +4/printer);) und 
 +- nicht zu warten braucht, bis die Datei bers Netz gesendet ist. 
 + 
 + 
 + 
 + 
 + 
 diff --git a/system/net/1.7.5/src/basic net b/system/net/1.7.5/src/basic net new file mode 100644 index 0000000..88b41e5 --- /dev/null +++ b/system/net/1.7.5/src/basic net @@ -0,0 +1,840 @@ +PACKET basic net DEFINES                          (* D. Heinrichs *)
 +                                                  (* 02.10.85     *)
 +  nam,
 +  max verbindungsnummer,
 +  neuer start,
 +  packet eingang,
 +  neue sendung,
 +  zeitueberwachung,
 +  verbindung,
 +  loesche verbindung:
 +
 +TEXT PROC nam (TASK CONST t):
 +  IF t = collector THEN name (t)
 +  ELIF station (t) <> station (myself) 
 +  THEN "** fremd **"
 +  ELSE name (t)
 +  FI
 +END PROC nam;
 +
 +INT PROC tasknr (TASK CONST t):
 +  IF t = collector THEN maxtasks
 +  ELSE index (t)
 +  FI
 +END PROC tasknr;
 +
 +LET
 +    maxtasks = 127,
 +    max strom = 20,
 +    max strom 1 = 21,
 +    stx = ""2"",
 +    code stx = 2, 
 +    ack = 0,
 +    nak = 1,
 +    error nak = 2,
 +    zeichen eingang = 4,
 +    list code = 15,
 +    fetch code = 11,
 +    inspect code = 30,
 +    continue code = 100,
 +    erase code = 14,
 +    report code = 99,
 +    seiten groesse = 512,
 +    dr verwaltungslaenge = 8,
 +    dr verwaltungslaenge2=10,
 +    nutzlaenge = 64,
 +    openlaenge = 20,
 +    vorspannlaenge = 10, 
 +    neue ack laenge = 10, 
 +    ack laenge = 8,
 +
 +    (* Typen von Kommunikationsströmen *)
 +
 +    send wait = 0,
 +    zustellung = 1,
 +    call pingpong = 2,
 +    call im wait = 3,
 +    call im abbruch = 4,
 +    call in zustellung = 5,
 +
 +    (*quittungscodes*)
 +
 +    ok = 0,
 +    von vorne = 1,
 +    wiederhole = 2,
 +    loesche = 3,
 +    beende = 4;
 +
 +LET STEUER =
 +      STRUCT ( 
 +      INT  head, 
 +           rechner nummern, 
 +           strom,
 +           sequenz,
 +           seitennummer,
 +      TASK quelle,ziel,
 +      INT  sende code);
 + 
 +BOUND STEUER VAR open block;
 +
 +BOUND STRUCT (STEUER steuer, INT typ) VAR info block; 
 + 
 +BOUND STRUCT (
 +      INT  head, 
 +           rechner nummern, 
 +           strom,
 +           sequenz,
 +           seitennummer) VAR vorspann ;
 + 
 +BOUND STRUCT ( 
 +      INT  head, 
 +           rechner nummern, 
 +           strom, 
 +           code) VAR ack packet ; 
 + 
 +INT CONST max verbindungsnummer := max strom;
 +
 +BOOL PROC blockin (DATASPACE VAR ds, INT CONST seite, abstand, laenge): 
 + INT VAR hilfslaenge:=laenge, code:= abstand+laenge+512;
 + REAL VAR time out := clock (1) + 10.0;
 + REP 
 +   blockin (ds,seite,code-hilfslaenge, hilfslaenge, hilfslaenge); 
 + UNTIL hilfslaenge = 0 OR clock (1) > time out PER  ;
 + hilfslaenge = 0
 +END PROC blockin; 
 +
 +PROC blockout (DATASPACE CONST ds, INT CONST seite, abstand, laenge): 
 + INT VAR hilfslaenge:=laenge, code:= abstand+laenge+512; 
 + REP 
 +   blockout (ds,seite,code-hilfslaenge, hilfslaenge, hilfslaenge); 
 + UNTIL hilfslaenge = 0 PER 
 +END PROC blockout; 
 + 
 + 
 + 
 + 
 +DATASPACE VAR work space;
 + 
 + 
 +INT CONST packete pro seite:= seitengroesse DIV nutzlaenge, 
 +          packete pro seite minus 1 := packete pro seite -1,
 +          datenpacketlaenge := vorspannlaenge + nutzlaenge;
 + 
 +INT VAR err,strom; 
 + 
 +INT VAR   own:=station (myself) ,
 +          quit max := 3,
 +          quit zaehler := 3,
 +          own256 := 256*own;
 +INT CONST stx open := code stx+256*openlaenge,
 +          stx quit := code stx+256*acklaenge;
 +
 +  ROW maxstrom1 STEUER VAR verbindungen; 
 +  ROW maxstrom1 DATASPACE VAR netz dr; 
 +  ROW maxstrom1 INT VAR zeit, typ;
 +  FOR strom FROM 1 UPTO maxstrom1 REP vdr := nilspace; forget (vdr) PER;
 +  ROW maxstrom INT VAR dr page ;
 +  ROW maxtasks INT VAR alter call;
 +  STEUER VAR opti;
 + 
 +.vx : verbindungen (strom). 
 + 
 +vdr: netz dr (strom). 
 + 
 +falsche stromnummer: strom < 1 OR strom > maxstrom.
 +
 +call aufruf: typ(strom) >= call pingpong.
 +
 +alles raus: vx.seitennummer = -1 AND letztes packet der seite . 
 +
 +letztes packet der seite :
 +(vx.sequenz AND packete pro seite minus 1) = packete pro seite minus 1.
 +
 +PROC neuer start (INT CONST empfangsstroeme):
 +  workspace := nilspace;
 +  open block := workspace; 
 +  info block := workspace;
 +  vorspann := workspace; 
 +  ack packet := workspace;
 +  FOR strom FROM 1 UPTO maxstrom1 REP 
 +  vx.strom := 0;  forget (vdr)
 +  PER; 
 +  INT VAR i;
 +  FOR i FROM 1 UPTO maxtasks REP alter call (i) := 0 PER;
 +  quitmax := empfangsstroeme;
 +  own:=station (myself);
 +  quit zaehler := quit max;
 +  own256 := 256*own; 
 +  reset box.
 +
 +reset box: 
 +  out (90*""4""); 
 +  REP UNTIL incharety (1) = "" PER. 
 + 
 +END PROC neuer start;
 +
 +DATASPACE PROC verbindung (INT CONST nr):
 +  infoblock.steuer := verbindungen (nr);
 +  infoblock.typ := typ (nr);
 +  workspace
 +END PROC verbindung;
 +
 +PROC neue sendung (TASK CONST q,z, INT CONST cod, DATASPACE CONST dr):
 +
 +  naechste verbindung vorbereiten;
 +  forget (vdr); vdr := dr;
 +  IF z = collector 
 +  THEN 
 +    verbindungsebene 
 +  ELSE 
 +    sendung starten (q,z,cod)
 +  FI.
 +
 +verbindungsebene: 
 +  IF cod = 256 THEN name von fremdstation
 +  ELIF cod > 256
 +  THEN
 +    taskinfo fremd 
 +  ELSE
 +    task id von fremd
 +  FI.
 +
 +taskinfo fremd: sendung starten (q, collector, cod-256, -8).
 +
 +task id von fremd: sendung starten (q,collector, zielstation,-6) .
 +
 +name von fremdstation:
 +  BOUND TASK VAR tsk := vdr;
 +  TASK VAR tsk1 := tsk;
 +  forget (vdr);
 +  vdr := nilspace;
 +  sendung starten (q, tsk1, -7).
 +
 +zielstation: cod.
 +
 +END PROC neue sendung; 
 +
 +PROC zeitueberwachung
 +     (INT VAR snr, TASK VAR  q, z, INT VAR ant,DATASPACE VAR  dr):
 +  snr INCR 1;
 +  FOR strom FROM snr UPTO maxstrom REP zeitkontrolle PER;
 +  snr := 0. 
 +
 +zeitkontrolle: 
 +  IF vx.strom <> 0 AND zeit(strom) > 0
 +  THEN 
 +    zeit(strom) DECR 1; 
 +    IF sendung noch nicht zugestellt
 +    THEN 
 +      IF zeit(strom) = 0 THEN 
 +         report ("Nicht zustellbar. """+nam (vx.ziel)+""". "+
 +         text (vx.rechnernummernDIV256)); 
 +         loesche verbindung (strom)
 +      ELSE
 +         snr := strom;
 +         q := vx.quelle;
 +         z := vx.ziel;
 +         ant := vx.sendecode;
 +         dr := vdr;
 +         LEAVE zeitueberwachung
 +      FI
 +    ELIF zeit(strom) = 0 THEN wiederholen FI 
 +  FI. 
 + 
 +sendung noch nicht zugestellt:
 +  typ (strom) = zustellung.
 +
 +wiederholen: 
 +  IF sendeeintrag 
 +  THEN 
 +    sendung wiederholen
 +  ELSE
 +    empfangseintrag freigeben
 +  FI. 
 + 
 +sendeeintrag : vx.rechnernummern DIV 256 = own . 
 + 
 +sendung wiederholen:
 +  IF wiederholung noch sinnvoll 
 +  THEN
 +    IF frisch 
 +    THEN 
 +      time out bei open
 +    ELSE 
 +      datenteil wiederholen 
 +    FI
 +  ELSE
 +    sendung loeschen
 +  FI.
 +
 +wiederholung noch sinnvoll:
 +  task noch da AND bei call noch im call.
 +
 +task noch da: vx.quelle = collector OR exists (vx.quelle).
 +
 +bei call noch im call: 
 +  IF call aufruf
 +  THEN
 +    callee (vx.quelle) = vx.ziel
 +  ELSE
 +    TRUE
 +  FI.
 +
 +frisch: vx.sequenz = -1. 
 + 
 +time out bei open:
 +  IF vx.sendecode > -4 THEN open wiederholen ELSE nak an quelle senden FI.
 +
 +nak an quelle senden:
 +  forget (vdr); vdr := nilspace;
 +  BOUND TEXT VAR erm := vdr;
 +  erm := "Station "+text(vx.rechnernummernMOD256)+" antwortet nicht";
 +  snr := strom;
 +  q := collector;
 +  z := vx.quelle;
 +  ant := error nak;
 +  dr := vdr;
 +  sendung loeschen;
 +  LEAVE zeitueberwachung .
 +
 +open wiederholen: 
 +  sendereport ("wdh open"); 
 +  zeit(strom) := 20;
 +  openblock := vx; 
 +  openblock.head := stx open; 
 +  ab die post. 
 + 
 +datenteil wiederholen: 
 +  sendereport ("wdh data. sqnr "+text (vx.sequenz));
 +  senden .
 +
 +empfangseintrag freigeben:
 +  IF antwort auf call 
 +  THEN
 +    weiter warten
 +  ELSE
 +    empfangsreport ("Empfangseintrag freigegeben");
 +    empfang loeschen
 +  FI.
 +antwort auf call: callee (vx.ziel) = vx.quelle.
 +
 +weiter warten: zeit (strom) := 200.
 +
 +END PROC zeitueberwachung;
 +
 +PROC sendereport (TEXT CONST txt):
 +  report (text (strom)+":"+txt+". Absender: """+nam (vx.quelle)+
 +          """. Ziel "+text(vx.rechnernummernMOD256)); 
 +END PROC sendereport;
 +
 +PROC empfangsreport  (TEXT CONST txt):
 +  report (text (strom)+":"+txt+". Empfänger: """
 +          +nam (vx.ziel)+""". Quelle "+text (vx.rechnernummernDIV256));
 +END PROC empfangsreport  ;
 +
 +PROC sendung loeschen:
 +    IF callaufruf CAND alter call (tasknr (vx.quelle)) = strom
 +    THEN
 +       alter call (tasknr (vx.quelle)) := 0
 +    FI;
 +    vx.strom := 0;
 +    forget (vdr)
 +END PROC sendung loeschen;
 +
 +PROC empfang loeschen:
 +    quit zaehler INCR 1;
 +    IF callaufruf AND alter call (tasknr (vx.ziel)) = strom
 +    THEN
 +       alter call (tasknr (vx.ziel)) := 0
 +    FI; 
 +    forget (vdr);
 +    vx.strom := 0
 +END PROC empfang loeschen;
 +
 +PROC loesche verbindung (INT CONST nr):
 +  strom := nr;
 +  IF sendeeintrag
 +  THEN
 +    sendung loeschen
 +  ELSE
 +    gegenstelle zum loeschen auffordern; 
 +    empfang loeschen
 +  FI.
 +
 +gegenstelle zum loeschen auffordern:
 +  IF verbindung aktiv THEN quittieren (-loesche) FI.
 +
 +verbindung aktiv: vx.strom > 0.
 +
 +sendeeintrag: vx.rechnernummern DIV 256 = own . 
 +
 +END PROC loesche verbindung;
 +
 +PROC weiter senden: 
 +  IF NOT alles raus
 +  THEN
 +    sequenz zaehlung; 
 +    IF neue seite THEN seitennummer eintragen FI;
 +    senden
 +  FI.
 +
 +sequenz zaehlung: 
 +  vx.sequenz INCR 1. 
 + 
 +neue seite: 
 +  (vx.sequenz AND packete pro seite minus 1) = 0. 
 +
 +seitennummer eintragen: 
 +  dr page (strom) :=  vx.seiten nummer;
 +  vx.seitennummer := next ds page (vdr, dr page (strom)). 
 + 
 + 
 +END PROC weiter senden;
 + 
 +PROC senden:
 +  zeit(strom) := 3;
 +  vorspann senden;
 +  daten senden.
 +
 +vorspann senden: 
 +  openblock := vx; 
 +  blockout (workspace, 1, dr verwaltungslaenge, vorspannlaenge). 
 + 
 +daten senden: 
 +  blockout (vdr,dr page (strom),distanz,nutzlaenge). 
 + 
 +distanz: nutzlaenge* (vx.sequenz AND (packete pro seite minus 1)). 
 +
 +END PROC senden;
 +
 +PROC naechste verbindung vorbereiten: 
 +  FOR strom FROM 1 UPTO maxstrom REP 
 +  UNTIL vx.strom = 0 PER; 
 +  IF vx.strom <> 0 THEN errorstop ("Verbindungsengpass") FI. 
 +END PROC naechste verbindung vorbereiten;
 +
 +PROC sendung starten (TASK CONST quelle, ziel, INT CONST code): 
 +  sendung starten (quelle,ziel, station(ziel), code) 
 +END PROC sendung starten;
 + 
 +PROC sendung starten (TASK CONST quelle, ziel, INT CONST ziel station,code):
 +  IF ziel station = own 
 +  THEN
 +    report ("Irrläufer: Sendung an eigene Station. Absender:"""+
 +            nam (quelle)+""".");
 +    vx.strom := 0;
 +    forget (vdr)
 +  ELSE
 +    openblock.ziel := ziel;
 +    openblock.quelle :=quelle; 
 +    openblock.sendecode := code;
 +    openblock.rechnernummern:= ziel station + own256; 
 +    alten call loeschen (quelle);
 +    IF call oder ping pong
 +    THEN typ (strom) := call pingpong; call merken
 +    ELSE typ (strom) := send wait FI;
 +    sendung neu starten
 +  FI.
 +
 +call oder pingpong: openblock.ziel = callee (openblock.quelle).
 +
 +call merken: alter call (tasknr (quelle)) := strom.
 +
 +END PROC sendung starten;
 +
 +PROC sendung neu starten:
 +  openblock.head:= stx open; 
 +  openblock.sequenz := -1; 
 +  openblock.seitennummer:= next ds page (vdr,-1); 
 +  openblock.strom := strom;
 +  vx := open block; 
 +  zeit(strom) := 3;
 +  ab die post;
 +  vx.head:=code stx+256*(vorspannlaenge+nutzlaenge). 
 + 
 +END PROC sendung neu starten; .
 +
 +ab die post: 
 +  block out (work space,1, dr verwaltungslaenge,open laenge).
 + 
 +PROC alten call loeschen (TASK CONST quelle):
 +  IF alter call aktiv
 +  THEN
 +    INT VAR lstrom := strom;
 +    vx:=openblock;
 +    strom := alter call (tasknr (quelle));
 +    IF in ausfuehrungsphase
 +    THEN
 +      sendereport ("Call-Löschung vorgemerkt");
 +      loeschung vormerken
 +    ELSE
 +      report ("Call gelöscht."""+nam(quelle)+""". Strom "+text(strom));
 +      loesche verbindung (strom)
 +    FI;
 +    strom := lstrom;
 +    openblock := vx
 +  FI.
 +
 +in ausfuehrungsphase:
 +  typ(strom) = call im wait OR typ (strom) = call in zustellung.
 +
 +loeschung vormerken:
 +  typ(strom) := call im abbruch;
 +  alter call (tasknr (quelle)) := 0.
 +
 + 
 +  alter call aktiv:
 +    alter call (tasknr (quelle)) > 0.
 +
 +END PROC alten call loeschen;
 +
 +PROC packet eingang
 +  (TEXT CONST ft, INT VAR snr, TASK VAR  q, z, INT VAR ant,DATASPACE VAR  dr):
 +    snr := 0;
 +    vorspann holen; 
 +    IF NOT ring logik THEN daten teil FI.
 +
 +ring logik: FALSE.
 +# IF selbst quelle THEN daten aus puffer entfernen ; TRUE
 +  ELIF NOT selbst ziel THEN weitergeben; TRUE 
 +  ELSE FALSE
 +  FI.
 +
 +selbst quelle: openblock.rechnernummern DIV 256 = station (myself).
 +
 +selbst ziel:   (openblock.rechnernummern AND 255) = own.
 +#
 +daten aus puffer entfernen:
 +  IF code (t) > nutzlaenge 
 +  THEN
 +    BOOL VAR dummy :=blockin (workspace, 1, drverwaltungslaenge, nutzlaenge) 
 +  FI.
 +#
 +weitergeben:
 +  IF code (t) > nutzlaenge
 +  THEN 
 +    IF NOT  blockin (workspace, 2, 0, nutzlaenge) 
 +    THEN LEAVE test auf packeteingang FI;
 +  FI;
 +  out (stx+t);
 +  blockout (workspace, 1, drverwaltungslaenge2, blocklaenge);
 +  IF code (t) > nutzlaenge
 +  THEN
 +    blockout (workspace, 2, 0, nutzlaenge)
 +  FI.
 +#
 +vorspann holen: 
 +  sync; 
 +  IF NOT blockin (workspace, 1, dr verwaltungslaenge2, block laenge)
 +  THEN LEAVE packeteingang 
 +  FI.
 +
 +
 +blocklaenge: IF code t  > nutzlaenge 
 +             THEN 
 +               vorspannlaenge-2 
 +             ELSE 
 +               code t -2 
 +             FI. 
 +
 +sync: 
 +  TEXT VAR skipped:=ft , t :="";
 +  REP 
 +    skipped CAT t;
 +    t := incharety (1); 
 +    IF t = "" THEN 
 +      report ("skipped",skipped); 
 +      LEAVE packet eingang
 +    FI ;
 +    INT VAR codet := code (t);
 +  UNTIL blockanfang PER; 
 +  IF skipped <> stx THEN report ("skipped bei sync:", skipped) FI. 
 + 
 +blockanfang: 
 +  (skipped SUB length(skipped)) = stx 
 +  AND
 +  (codet = datenpacketlaenge
 +  OR codet = ack laenge OR codet = neue ack laenge OR code t = openlaenge). 
 + 
 +daten teil: 
 +  IF neue verbindung 
 +  THEN
 +    verbindung bereitstellen
 +  ELIF quittung 
 +  THEN 
 +    strom := ack packet.strom; 
 +    IF falsche stromnummer THEN report ("Strom falsch in Quittung");
 +                                LEAVE datenteil FI;
 +    IF vx.strom = 0 THEN LEAVE datenteil FI;
 +    IF ackpacket.code >= ok   THEN weiter senden
 +    ELIF ackpacket.code = -von vorne THEN
 +        sendereport ("Neustart");
 +        openblock := vx; 
 +        sendung neu starten 
 +    ELIF ackpacket.code = -wiederhole THEN back 16
 +    ELIF ackpacket.code = -loesche    THEN fremdloeschung
 +    ELIF ackpacket.code = -beende AND alles raus THEN strom abschliessen
 +    FI
 +  ELIF verbindung festgestellt 
 +  THEN
 +    zeit(strom) := 200;
 +    opti := vx;
 +    datenpacket
 +  ELSE 
 +    strom := maxstrom1; 
 +    vx:=openblock;
 +    report ("Daten ohne Eroeffnung von " +text(vx.rechnernummernDIV256) 
 +    +"  Sequenznr "+text(openblock.sequenz)); 
 +    daten aus puffer entfernen;
 +    IF alles raus THEN quittieren (-beende) ELSE quittieren(-von vorne) FI
 +  FI. 
 +
 +verbindung bereitstellen:
 +  IF openblock.ziel = collector OR station (openblock.ziel) = own
 +  THEN
 +    freie verbindungsnummer; 
 +    vdr := nilspace;
 +    vx := open block; 
 +    zeit(strom) := 10;
 +    quittieren falls genug pufferplatz;
 +    vx.sequenz := 0 ; 
 +    IF loeschung vorgemerkt
 +    THEN 
 +      loesche verbindung (strom)
 +    ELSE
 +      opti := vx;
 +      abschluss testen
 +    FI;
 +  FI.
 +
 +loeschung vorgemerkt: typ(strom) = call im abbruch.
 +
 +strom abschliessen:
 +  IF call aufruf THEN zeit(strom) := 80; ausfuehrungsphase merken
 +  ELSE
 +    vx.strom := 0; 
 +    forget (vdr)
 +  FI.
 +
 +ausfuehrungsphase merken: typ(strom) := call in zustellung.
 + 
 +back16:
 +  datenraum etwas rueckspulen; 
 +  nicht sofort senden (* wegen vagabundierender Quittungen *).
 +
 +nicht sofort senden: zeit(strom) := 2.
 +
 +datenraum etwas rueckspulen:
 +  sendereport ("etwas rueckgespult");
 +  INT VAR sk , vs :=-1;
 +  dr page (strom) := -1;
 +  INT VAR i;
 +  FOR i FROM 1 UPTO vx.sequenz DIV packete pro seite - etwas REP
 +    vs INCR packete pro seite;
 +    dr page (strom) := next ds page (vdr, dr page (strom)) 
 +  PER;
 +  vx.seiten nummer := next ds page (vdr, dr page (strom)) ;
 +  vx.sequenz := vs.
 +
 +etwas: 3.
 +
 +fremdloeschung:
 +  IF fremdrechner ok und sendung 
 +  THEN
 +    IF typ (strom) = call in zustellung
 +    THEN
 +      typ (strom) := call im wait
 +    ELSE
 +      sendereport ("Sendung von Gegenstelle geloescht");
 +      sendung loeschen
 +    FI
 +  FI.
 +
 +fremdrechner ok und sendung:
 + (ackpacket.rechnernummern DIV 256) = (vx.rechnernummern AND 255).
 +
 +
 +quittieren falls genug pufferplatz:
 +  IF quit zaehler > 0 THEN
 +    quit zaehler DECR 1;
 +    open quittieren;
 +    block vorab quittieren
 +  FI.
 +
 +open quittieren: quittieren (ok).
 +block vorab quittieren: quittieren (ok).
 +
 +quittung:  code t <= neue ack laenge. 
 + 
 +neue verbindung: code t = open laenge.
 + 
 +verbindung festgestellt: 
 +  FOR strom FROM maxstrom DOWNTO 1 REP 
 +    IF bekannter strom
 +    THEN LEAVE verbindung festgestellt WITH TRUE FI 
 +  PER; 
 +  FALSE. 
 + 
 +bekannter strom: 
 +  vx.strom = vorspann.strom AND vom selben rechner. 
 + 
 +vom selben rechner: 
 +  vx.rechnernummern = vorspann.rechnernummern. 
 + 
 +daten: 
 +  IF NOT blockin (vdr, opti.seiten nummer, distanz, nutzlaenge)
 +  THEN quittieren (-wiederhole); LEAVE packeteingang 
 +  FI; 
 +  sequenz zaehlung;
 +  IF neue seite kommt 
 +  THEN 
 +    vx.seiten nummer := vorspann.seiten nummer 
 +  FI. 
 + 
 +datenpacket:
 +  IF sendung wartet auf zustellung THEN auffrischen ELSE daten holen FI.
 +
 +sendung wartet auf zustellung: typ (strom) = zustellung.
 +
 +auffrischen: zeit (strom) := 100; daten aus puffer entfernen.
 +
 +daten holen:
 +  IF opti.sequenz >= vorspann.sequenz AND opti.sequenz < vorspann.sequenz+100
 +  THEN 
 +    IF opti.sequenz <> vorspann.sequenz
 +    THEN empfangsreport ("Sequenzreset von "+text(opti.sequenz)+" auf "+
 +                  text (vorspann.sequenz));
 +         vx.sequenz := vorspann.sequenz;
 +         vorabquittung regenerieren 
 +    FI;
 +    quittieren(ok); 
 +    daten  ; 
 +    abschluss testen
 +  ELSE 
 +    empfangsreport ("Sequenzfehler: soll "+text(vx.sequenz)+" ist "+ 
 +            text(vorspann.sequenz));
 +    quittieren (-wiederhole);
 +    daten aus puffer entfernen
 +  FI. 
 + 
 +vorabquittung regenerieren: quittieren (ok).
 + 
 +distanz: (opti.sequenz AND  packete pro seite minus 1 ) * nutzlaenge. 
 + 
 +sequenz zaehlung: 
 +  vx.sequenz INCR 1. 
 + 
 +neue seite kommt: 
 +(vx.sequenz AND packete pro seite minus1) = 0. 
 + 
 +freie verbindungsnummer: 
 +  INT VAR h strom :=0;
 +  FOR strom FROM 1 UPTO maxstrom REP 
 +    IF vx.strom = 0 THEN h strom := strom 
 +    ELIF bekannter strom
 +    THEN empfangsreport ("Reopen"); 
 +         quit zaehler INCR 1;
 +         forget (vdr);
 +         LEAVE freie verbindungsnummer 
 +    ELIF antwort auf call
 +    THEN
 +      typ (strom) := call pingpong;
 +      forget (vdr);
 +      LEAVE freie verbindungsnummer 
 +    FI
 +  PER; 
 +  strom := h strom; 
 +  IF strom = 0 THEN
 +    error stop ("Zuviele simulatane Verbindungen") 
 +  FI; 
 +  typ(strom) := send wait.
 +
 +antwort auf call:
 +  openblock.sendecode >= 0 AND
 +  call aufruf AND vx.quelle = openblock.ziel AND vx.ziel = openblock.quelle. 
 +
 +abschluss testen: 
 +  IF neue seite kommt AND vx.seiten nummer = -1 
 +  THEN 
 +    quittieren (-beende);
 +    an ziel weitergeben 
 +  FI. 
 + 
 +an ziel weitergeben: 
 +  IF tasknummerfrage  THEN taskfrage beantworten ;pufferplatz freigeben;
 +  ELIF tasknamenfrage THEN name senden ;pufferplatz freigeben;
 +  ELIF taskinfofrage  THEN task info senden;pufferplatz freigeben;
 +  ELSE                     senden
 +  FI. 
 +
 +pufferplatz freigeben: quitzaehler INCR 1.
 +
 +senden:
 +  max 100 versuche; 
 +  snr := strom;
 +  IF NOT callaufruf THEN typ (strom) := zustellung FI;
 +  q := vx.quelle;
 +  z := vx.ziel;
 +  ant := vx.sendecode;
 +  dr := vdr;
 +  LEAVE packet eingang.
 +
 +tasknummerfrage:opti.sendecode = -6.
 + 
 +tasknamenfrage: opti.sendecode = -7.
 + 
 +taskinfofrage: opti.sendecode = -8.
 +
 +max 100 versuche: zeit(strom) := 100.
 +
 +taskfrage beantworten:
 +  BOUND TEXT VAR tsk := vdr; 
 +  TEXT VAR save tsk := tsk;
 +  forget (vdr); vdr := nilspace; 
 +  BOUND TASK VAR task id := vdr;
 +  disable stop;
 +  task id := task(save tsk);
 +  IF is error THEN 
 +    clear error; enable stop;
 +    forget (vdr); vdr := nilspace; 
 +    BOUND TEXT VAR errtxt := vdr;
 +    errtxt := text(station(myself))+"/"""+save tsk+""" gibt es nicht";
 +    sendung starten (collector, opti.quelle, 2)
 +  ELSE
 +    enable stop;
 +    sendung starten (collector, opti.quelle, 0)
 +  FI.
 + 
 +name senden: 
 +  forget (vdr); vdr := nilspace;
 +  tsk := vdr; 
 +  disable stop;
 +  tsk := nam (opti.ziel);
 +  clear error; enable stop;
 +  sendung starten (collector, opti.quelle, 0). 
 + 
 +task info senden:
 +  BOUND INT VAR ti code := vdr;
 +  INT VAR ti cd := ti code;
 +  forget (vdr); vdr := nilspace;
 +  FILE VAR task inf := sequential file (output,vdr);
 +  head line (task inf,"Station "+text(own)); 
 +  task info (ti cd, task inf);
 +  sendung starten (collector,opti.quelle,0).
 + 
 +END PROC packet eingang;
 +
 +PROC quittieren(INT CONST code) : 
 +  quellrechner wird zielrechner; 
 +  ackpacket.code := code; 
 +  ackpacket.head := stx quit;
 +  ackpacket.strom := vx.strom;
 +  blockout (workspace,1,dr verwaltungslaenge, ack laenge). 
 + 
 +quellrechner wird zielrechner: 
 +  ack packet.rechnernummern := vx.rechnernummern DIV 256 
 +                               + own256. 
 + 
 +END PROC quittieren; 
 + 
 +END PACKET basic net;
 diff --git a/system/net/1.7.5/src/callee b/system/net/1.7.5/src/callee new file mode 100644 index 0000000..42d80da --- /dev/null +++ b/system/net/1.7.5/src/callee @@ -0,0 +1,14 @@ +PACKET callee DEFINES callee:
 +
 +TASK PROC callee (TASK CONST t): 
 +  IF im wait THEN trick 1 (t); trick 2 ELSE niltask FI.
 +im wait: (status(t) AND 3) = 2. 
 +END PROC callee; 
 + 
 +PROC trick 1 (TASK CONST t): 
 +  INT VAR x := pcb(t,11), y:=pcb(t,12); 
 +END PROC trick1; 
 + 
 +TASK PROC trick 2: TASK VAR calle; calle END PROC trick2; 
 + 
 +END PACKET callee;
 diff --git a/system/net/1.7.5/src/net inserter b/system/net/1.7.5/src/net inserter new file mode 100644 index 0000000..d8c0856 --- /dev/null +++ b/system/net/1.7.5/src/net inserter @@ -0,0 +1,50 @@ +
 +{ Inserter für EUMEL - Netz - Software;                         04.12.83
 +  berücksichtigt EUMEL - Versionen 1.7.3 und 1.7.5, sowie Multi / Single } 
 + 
 + 
 +INT VAR version :: id (0), cy :: 4;
 +IF online THEN head FI;
 +
 +IF ich bin multi THEN insert multi net
 +                 ELSE meldung an single
 +FI.
 +
 +ich bin multi : (pcb (9) AND 255) > 1.
 +
 +insert multi net :
 +   IF version >= 173 THEN IF version < 175 THEN insert and say ("callee") FI; 
 +                          insert and say ("net report/M"); 
 +                          insert and say ("basic net"); 
 +                          insert and say ("net manager/M") 
 +                     ELSE versionsnummer zu klein
 +   FI.
 +
 +meldung an single : 
 +   cursor (1, cy);
 +   putline
 +   ("Das EUMEL - Netz ist zur Zeit nur auf Multi - User - Versionen");
 +   putline ("installierbar !").
 +
 +head :
 +   page;
 +   putline (" E U M E L  -  Netz  -  Inserter");
 +   put     ("---------------------------------").
 + 
 +versionsnummer zu klein : 
 +   cursor (1, cy);
 +   putline ("Netzsoftware erst ab Version 1.7.3 insertierbar !").
 + 
 +PROC insert and say (TEXT CONST name of packet): 
 +   IF online THEN cl eop (1, cy); 
 +                  put ("Paket '" + name of packet + "' wird insertiert"); 
 +                  line (2);
 +                  cy INCR 1
 +   FI;
 +   insert (name of packet); 
 +END PROC insert and say;
 +
 +PROC cl eop (INT CONST cx, cy) :
 +   cursor (cx, cy);
 +   out    (""4"")
 +END PROC cl eop;
 diff --git a/system/net/1.7.5/src/net manager-M b/system/net/1.7.5/src/net manager-M new file mode 100644 index 0000000..bf64a68 --- /dev/null +++ b/system/net/1.7.5/src/net manager-M @@ -0,0 +1,302 @@ +PACKET net manager DEFINES start,stop,net manager,frei:
 +TEXT VAR stand := "Netzsoftware vom  02.09.85";
 +                 (*Heinrichs     *)
 + 
 +LET
 +    ack = 0,
 +    nak = 1,
 +    error nak = 2,
 +    zeichen eingang = 4,
 +    list code = 15,
 +    fetch code = 11,
 +    freigabecode = 29,
 +    continue code = 100,
 +    erase code = 14,
 +    report code = 99, 
 +
 +    (* Typen von Kommunikationsströmen *)
 +
 +    send wait = 0,
 +    zustellung = 1,
 +    call pingpong = 2,
 +    call im wait = 3,
 +    call im abbruch = 4,
 +    call in zustellung = 5;
 + 
 +LET STEUER =
 +      STRUCT ( 
 +      INT  head, 
 +           rechner nummern, 
 +           strom,
 +      INT  sequenz,
 +           seiten nummer,
 +      TASK quelle,ziel,
 +      INT  sende code); 
 + 
 +LET INFO = STRUCT (STEUER steuer, INT typ); 
 + 
 +TASK VAR sohn;
 +INT VAR strom,c.
 + 
 +vx: v.steuer.
 + 
 +PROC frei (INT CONST stat,lvl): 
 +  DATASPACE VAR ds := nilspace;
 +  BOUND STRUCT (INT x,y) VAR msg := ds;
 +  msg.x := stat; msg.y := lvl;
 +  INT VAR return;
 +  call (/"net port", freigabecode, ds, return) ;
 +  forget (ds)
 +END PROC frei; 
 + 
 +PROC net manager (DATASPACE VAR ds, INT CONST order, phase, TASK CONST
 +                  ordertask):
 + 
 +    IF order = report code
 +    THEN 
 +      forget ("report",quiet); 
 +      copy (ds,"report"); 
 +      forget (ds) 
 +    ELSE 
 +      IF ordertask < myself
 +      OR order = list code
 +      OR order > continue code
 +      THEN
 +        IF order = list code 
 +        THEN
 +          enable stop;
 +          forget (ds); ds := old ("report");
 +          FILE VAR ff := sequential file (output,ds);
 +          putline (ff,stand);
 +          putline (ff,"Rechner "+text(station(myself))+"  um "+time of day);
 +          send (ordertask, ack, ds)
 +        ELSE
 +        free manager (ds,order,phase,order task) 
 +        FI
 +      ELSE
 +      errorstop ("nur 'list' ist erlaubt")
 +      FI
 +    FI 
 +END PROC net manager; 
 +
 +TASK VAR cd,stask;
 +ROW 255 INT VAR erlaubt; 
 +INT VAR i;
 +FOR i FROM 1 UPTO 255 REP erlaubt (i) := 0 PER;
 +
 +PROC communicate: 
 +  enable stop;
 +  INT VAR scode;
 +  DATASPACE VAR dr := nilspace;
 +  neuer start (quit max);
 +REP 
 +  forget (dr); 
 +  wait (dr, scode, stask); 
 +  cd := collected destination;
 +  IF zeichen da OR zeit abgelaufen 
 +  THEN 
 +    packet
 +  ELIF cd = myself 
 +  THEN 
 +    netz info und steuerung 
 +  ELSE
 +    neue sendung (stask, cd, scode, dr)
 +  FI 
 +PER. 
 + 
 +zeichen da: scode < 0 . 
 + 
 +zeit abgelaufen: scode = ack AND cd = myself. 
 +
 +packet: 
 +    TEXT VAR t := incharety; 
 +    INT VAR snr, ant,err;
 +    TASK VAR quelle, ziel;
 +    snr := 0;
 +    REP 
 +      IF t = "" 
 +      THEN 
 +        zeitueberwachung (snr, quelle, ziel, ant, dr); 
 +      ELSE
 +        packet eingang (t, snr, quelle, ziel, ant, dr); 
 +      FI;
 +      IF snr > 0 
 +      THEN 
 +        IF ant > 5 AND erlaubt(station (quelle)) < 0 
 +        THEN unerlaubt
 +        ELSE 
 +          send (quelle,ziel,ant,dr,err); 
 +          fehlerbehandlung ;
 +        FI
 +      FI 
 +    UNTIL snr = 0 OR zeichen da PER.
 +
 +fehlerbehandlung: 
 +  IF ok oder ziel nicht da THEN loesche verbindung (snr) FI. 
 + 
 +ok oder ziel nicht da: err=0 OR err=-1. 
 + 
 +netz info und steuerung: 
 +    IF scode = list code THEN   list status 
 +  ELIF scode = erase code THEN strom beenden
 +  ELIF scode = freigabe code AND stask = father THEN freigabelevel 
 +  ELSE forget (dr); ablehnen ("nicht möglich") 
 +  FI. 
 + 
 +freigabelevel: 
 +  BOUND STRUCT (INT stat,lvl) VAR lv := dr; 
 +  IF lv.stat > 0 AND lv.stat < 256 THEN erlaubt (lv.stat) := lv.lvl FI; 
 +  send (stask,ack,dr).
 + 
 +unerlaubt: 
 +  report ("Fremdzugriff von "+text(station (quelle))+" auf "+nam(ziel)
 +          +" code "+text(ant)); 
 +  loesche verbindung (snr). 
 + 
 +strom beenden:
 +  BOUND TEXT VAR stromtext := dr;
 +  INT VAR erase strom := int (stromtext);
 +  forget (dr);
 +  strom := erase strom;
 +  IF falsche stromnummer THEN ablehnen ("Strom gibt es nicht")
 +  ELSE 
 +    BOUND INFO VAR v := verbindung (strom); 
 +  IF
 +    stask = father OR stask = vx.quelle OR stask = vx.ziel
 +  THEN
 +    loeschen
 +  ELSE ablehnen ("Nur Empfänger/Absender darf löschen")
 +  FI
 +  FI. 
 + 
 +loeschen:
 +  IF sendeeintrag  THEN
 +    IF callee (vx.quelle) = vx.ziel THEN absender warnen FI;
 +    loesche verbindung (strom)
 +  ELSE
 +    IF callee (vx.ziel) = vx.quelle THEN warnen FI; 
 +    loesche verbindung (strom)
 +  FI; 
 +  dr := nilspace;
 +  send (stask,ack,dr).
 +
 +absender warnen:
 + dr := nilspace;
 + send(vx.ziel,vx.quelle,1,dr,err) .
 +
 +warnen:
 + dr := nilspace;
 +BOUND TEXT VAR errtxt := dr; errtxt:= "Station antwortet nicht"; 
 +send (vx.quelle,vx.ziel,error nak, dr, err). 
 + 
 +falsche stromnummer: strom < 1 OR strom > max verbindungsnummer.
 +sendeeintrag: vx.rechnernummern DIV256 = station (myself).
 +END PROC communicate;
 +
 +PROC ablehnen (TEXT CONST t):
 +  DATASPACE VAR vdr := nilspace;
 +  BOUND TEXT VAR errtxt := vdr; 
 +  errtxt := t;
 +  send (stask, error nak, vdr).
 +END PROC ablehnen;
 +
 +PROC stop: 
 +  disable stop; 
 +  end (task ("net port"));
 +  end (task ("net timer")); 
 +  clear error;
 +END PROC stop; 
 + 
 +PROC list status: 
 + 
 +  DATASPACE VAR ds := nilspace; 
 +  FILE VAR f:=sequential file (output, ds);
 +  FOR strom FROM 1 UPTO max verbindungsnummer REP 
 +    BOUND INFO VAR v := verbindung (strom);
 +    IF vx.strom <> 0 THEN info FI 
 +  PER; 
 +  send (stask, ack, ds). 
 + 
 +info: 
 +  put (f,"Strom "+text(strom)+" (sqnr"+text(vx.sequenz)+")"); 
 +  IF sendeeintrag THEN sendeinfo ELSE empfangsinfo FI; 
 +  line (f). 
 + 
 +sendeeintrag: vx.rechnernummern DIV 256 = station(myself) . 
 + 
 +sendeinfo: 
 +  IF v.typ = call im wait THEN put (f,"erwartet Antwort von")
 +  ELIF v.typ = call in zustellung THEN put (f,"Ziel busy. Zielstation:") 
 +  ELIF v.typ = call im abbruch THEN put (f,"wird gelöscht bei Antwort von") 
 +  ELSE put (f,"sendet an") 
 +  FI; 
 +  put (f,vx.rechnernummernMOD256); 
 +  put (f,". Absender ist """+nam (vx.quelle)+"""."). 
 + 
 +empfangsinfo: 
 +  IF v.typ = zustellung THEN 
 +  put (f,"Sendung noch nicht zustellbar")
 +  ELSE
 +  put (f,"empfängt von");
 +  put (f,vx.rechnernummernDIV256); 
 +  FI;
 +  put (f,". Empfaenger ist """+nam (vx.ziel)+""".").
 +END PROC list status; 
 +
 +
 +PROC start (INT CONST chan):
 +  c:=chan;
 +  start
 +END PROC start;
 +INT VAR quitmax := 3;
 +PROC start (INT CONST chan,quit):
 +  quitmax := quit;
 +  c:=chan;
 +  start
 +END PROC start;
 +
 +PROC start: 
 +stop;
 +IF exists ("report") THEN forget ("report") FI;
 +FILE VAR s := sequential file (output,"report"); 
 +putline (s," N e u e r   S t a r t "+time of day); 
 +begin ("net port",PROC net io, sohn); 
 +TASK VAR dummy;
 +begin ("net timer",PROC timer,dummy);
 +define collector (sohn) 
 +END PROC start; 
 + 
 +PROC timer: 
 +  disable stop;
 +  REP 
 +    clear error;
 +    DATASPACE VAR ds := nilspace;
 +    pause (100); 
 +    send (sohn, ack, ds) 
 +  PER; 
 +END PROC timer; 
 +
 +PROC net io:
 +  disable stop; 
 +  fetch ("report");
 +  commanddialogue (FALSE); 
 +  continue (c);
 +  communicate;
 +  TEXT VAR emsg := "++++++ "+error message +" Zeile "+text(errorline);
 +  clear error; 
 +  report (emsg);
 +  save ("report");
 +  end (myself) 
 +END PROC net io; 
 +
 +put ("Netzkanalnummer:"); get (c);line;
 +IF yes ("Ist der Netzkanal mit Flußkontrolle verdrahtet") THEN
 +   quit max := 10
 +ELSE
 +   quit max := 3
 +FI; 
 +END PACKET net manager;
 + 
 + 
 +start; global manager (PROC (DATASPACE VAR,INT CONST,INT CONST, TASK
 +CONST) net manager ) 
 diff --git a/system/net/1.7.5/src/net report-M b/system/net/1.7.5/src/net report-M new file mode 100644 index 0000000..3ce67ff --- /dev/null +++ b/system/net/1.7.5/src/net report-M @@ -0,0 +1,29 @@ +PACKET net report DEFINES report: 
 +
 +LET reportcode = 99;
 +
 +PROC report (TEXT CONST x):
 +  report(x,"") 
 +END PROC report;
 +
 +PROC report (TEXT CONST txt, info): 
 +  IF storage (old("report")) > 20 THEN forget ("report",quiet) FI;
 +  reportfile := sequential file (output, "report");
 +  put (reportfile, date);
 +  put (reportfile, time of day);
 +  put (reportfile, txt); 
 +  INT VAR i; 
 +  FOR i FROM 1 UPTO length (info) REP 
 +    INT VAR z :=  code (infoSUBi)  ;
 +    IF z < 32 OR z > 126 
 +      THEN put (reportfile,"%"+text(z)) 
 +      ELSE put (reportfile,infoSUBi)
 +    FI
 +  PER; 
 +  line (reportfile); 
 +  DATASPACE VAR net report := old ("report"); 
 +  send (father, report code , net report)
 +END PROC report; 
 +FILE VAR reportfile; 
 + 
 +END PACKET net report;
 diff --git a/system/net/1.8.7/doc/netzhandbuch b/system/net/1.8.7/doc/netzhandbuch new file mode 100644 index 0000000..7083462 --- /dev/null +++ b/system/net/1.8.7/doc/netzhandbuch @@ -0,0 +1,2045 @@ +____________________________________________________________________________  +  +  +#on("b")##on ("u")#  +#center#Betriebssystem E U M E L  +#off ("u")#  +  +  +#center#Netzsoftware  +  +  +  +  +#off("b")#  +#center#Lizenzfreie Software der  +#on ("b")#  +  +#center#Gesellschaft für Mathematik und Datenverarbeitung mbH,  +#center#5205 Sankt Augustin  +  +  +#off("b")#  +#center#Die Nutzung der Software ist nur im Schul- und Hochschulbereich für  +#center#nichtkommerzielle Zwecke gestattet.  +  +#center#Gewährleistung und Haftung werden ausgeschlossen  +  +  +____________________________________________________________________________  +#page#  +#pagenr ("%",1)##setcount(1)##block##pageblock##count per page#  +#headeven#  +#center#EUMEL Netzbeschreibung  +#center#____________________________________________________________  +  +#end#  +#headodd#  +#center#Inhalt  +#center#____________________________________________________________  +  +#end#  +#bottomeven#  +#center#____________________________________________________________  +Netz - % #right# GMD  +#end#  +#bottomodd#  +#center#____________________________________________________________  +GMD #right#Netz - %  +#end#  +  +#center#Inhalt  +  +#clear pos##lpos(1.0)##rpos(9.5)#  +#table#  +  +1. Einleitung  #topage("0")#  +  +Teil 1: Netz einrichten und benutzen  #topage("1")#  +  +  +1.1. Hardwarevoraussetzungen  #topage("1.1")#  +1.2. Einrichten des Netzes    #topage("1.2")#  +1.3. Benutzung des Netzes   #topage("1.3")#  +1.4. Informationsmöglichkeiten   #topage("1.4")#  +1.5. Eingriffsmöglichkeiten   #topage("1.5")#  +1.6. Fehlerbehebung im Netz   #topage("1.6")#  +1.7. Sicherheit im Netz       #topage("1.7")#  +  +  +  +Teil 2: Arbeitsweise der Netzsoftware   #topage("2")#  +  +  +2.1. Die Netztask    #topage("2.1")#  +2.2. Protokollebenen   #topage("2.2")#  +2.3. Stand der Netzsoftware  #topage("2.3")#  +  +  +  +Teil 3: Netz-Hardware-Interface   #topage("3")#  +  +  +3.1. Einführung   #topage("3.1")#  +3.2. Arbeitsweise des Netz-Hardware-Interfaces   #topage("3.2")#  +3.3. Netztreiber  #topage("3.3")#  +3.4. Prozedurschnittstelle des EUMEL-Netzes  #topage("3.4")#  +  +  +  +Anhang      #topage("A")#  +  +  +1. Fehlermeldungen  #topage("A.1")#  +2. Literaturhinweise    #topage("A.2")#  +3. Index  #topage("A.3")#  +  +#table end#  +#clear pos#  +  +#page#  +#pagenr ("%", 2)##setcount (1)##block##pageblock##count per page#  +#headeven#  +#center#EUMEL Netzbeschreibung  +#center#____________________________________________________________  +  +#end#  +#headodd#  +#center#Einleitung  +#center#____________________________________________________________  +  +#end#  +#bottomeven#  +#center#____________________________________________________________  +Netz - % #right#GMD  +#end#  +#bottomodd#  +#center#____________________________________________________________  +GMD #right#Netz - %  +#end#  + +1. Einleitung  +  +#goalpage("0")#  +Das EUMEL-Netz dient dazu, mehrere EUMEL-Rechner (sog. #ib#Station#ie#en) miteinan +der zu koppeln. Diese Kopplung wird vom Betriebssystem dazu benutzt, das Sen +dungskonzept [1] so auszudehnen, daß Tasks verschiedener Stationen einander +Datenräume zusenden können. Auf dem #ib#Sendungskonzept#ie# aufbauende Konzepte +nutzen daher automatisch das Netz aus: So ist es z.B. möglich  +  +-  von einer Station aus auf einer anderen zu drucken,  +  +-  in die Task PUBLIC einer anderen Station #ib#Datei#ie#en zu sichern (save), vorausge +   setzt, daß PUBLIC dort ein #on("b")#free global manager#off("b")# ist,  +  +-  auf einer anderen Station zu archivieren (z.B. wenn das eigene Archivlaufwerk +   defekt ist oder ein anderes Format hat).  +  +Diese #ib#Netzversion#ie# kann ab EUMEL-Version 1.8.1 eingesetzt werden.  +  +Diese Netzbeschreibung besteht aus drei Teilen. In Teil 1 wird beschrieben, wie das +EUMEL-Netz benutzt und eingerichtet wird. Als Benutzer eines EUMEL- +Rechners, der vernetzt ist, ist nur dieser Teil der Netzbeschreibung für Sie wichtig. +Teil 2 erklärt die Funktionsweise der #ib#Netzsoftware#ie#, im dritten Teil wird die Schnitt +stelle für die Anpassung anderer #ib#Netzhardware#ie# definiert.  +  +Hinweis:  +  +Zur erstmaligen #ib#Installation#ie# des EUMEL-Netzes ist außer dieser Beschreibung noch +die Netzsoftware (auf Floppy) und die EUMEL-Netz-#ib#Installationsanleitung#ie#, die mit +der Software geliefert wird, notwendig.  +  +In der vorliegenden Netzbeschreibung wird das EUMEL-Netz möglichst "hardware +unabhängig" beschrieben. Wenn hardwareabhängige Beispiele gegeben werden, so +ist die dort beschriebene Hardware stets die #ib#Datenbox#ie#.  +#pagenr ("%", 3)##setcount (1)##block##pageblock##count per page#  +#headeven#  +#center#EUMEL Netzbeschreibung  +#cneter#____________________________________________________________  +  +#end#  +#headodd#  +#center#Teil 1 :  Netz einrichten und benutzen  +#center#____________________________________________________________  +  +#end#  +#bottomeven#  +#center#____________________________________________________________  +Netz - % #right#GMD  +#end#  +#bottomodd#  +#center#____________________________________________________________  +GMD #right#Netz - %  +#end#  +#page#  +  +Teil 1: Netz einrichten und benutzen  +#goalpage("1")#  +  +  +  +1.1. Hardwarevoraussetzungen  +#goalpage("1.1")#  +  +  +Zwei Stationen  +  +Sie können zwei #ib#Station#ie# miteinander vernetzen, wenn Sie dafür an jeder Station eine +#ib#V.24#ie#-#ib#Schnittstelle#ie# zur Verfügung stellen.  +  +Diese beiden Schnittstellen verbinden Sie mit einem Kabel zur #ib#Rechnerkopplung#ie# [2].  +  +  +Mehrere Stationen  +  +Wenn Sie mehr als zwei Stationen vernetzen wollen, stehen Ihnen zwei Konzepte zur +Verfügung: das Anlegen von #ib#Netzknoten#ie# bzw. das Verwenden eines #ib#Strang#ie#es. Die +Konzepte können gemischt eingesetzt werden.  +  +Ein Strang besteht aus einer Anzahl von #ib#Netzbox#ie#en (z.B. KHW-Box oder Ethernet +anschluß).  +  +Jede Box besitzt eine #ib#Schnittstelle#ie# (z.B. #ib#V.24#ie#) zum Anschluß an einen der Kanäle +1...15 der zugeordneten #ib#Station#ie# und eine weitere Schnittstelle zur #ib#Verbindung#ie# der +Boxen untereinander.  +  +Ein #ib#Knoten#ie# ist eine Station, bei der der Netzbetrieb über mehrere Kanäle läuft.  +  +Da die #ib#Netzsoftware#ie# pro #ib#Kanal#ie# eines Knotens eine Task generiert, ist das Knoten +konzept dem Strangkonzept hinsichtlich des #ib#Durchsatz#ie#es unterlegen. Preisgünstiger +ist jedoch das #ib#Knotenkonzept#ie#, weil dabei #ib#Netzbox#ie#en überflüssig werden.  +  +Beim Knotenkonzept wird eine #ib#Vermaschung#ie# nicht zur Optimierung benutzt (Ver +maschung heißt, daß eine #ib#Zielstation#ie# über verschiedene Knoten erreichbar ist). Daher +sollte man keine Vermaschung vorsehen.  +  +#ib#Nachbarn#ie# sind Stationen, die an denselben #ib#Netzstrang#ie# angeschlossen oder direkt +über ein #ib#V.24#ie#-Kabel verbunden sind.  +  +Bei der Entscheidung, welche Stationen man zu #ib#Knoten#ie# macht, sollte beachtet wer +den, daß (a) Stationen, zwischen denen hoher Verkehr besteht, Nachbarn werden und +daß (b) besonders leistungsfähige Rechner #ib#Knoten#ie#stationen sein sollten.  +#page#  +  +1.2. Einrichten des Netzes  +#goalpage("1.2")#  +  +  +Hinweis: Dieses Kapitel ist nur für Systembetreuer wichtig.  +  +a) Legen Sie für die am Netz beteiligten Rechner #ib#Stationsnummer#ie#n fest (von 1 an +   aufsteigend).  +  +   Die Boxen haben ebenfalls Stationsnummern. Die Stationsnummern der Box und +   des zugeordneten Rechners müssen übereinstimmen.  +  +  +b) Holen Sie an jeder #ib#Station#ie# die Task #on("bold")#configurator#off("bold")# an ein Terminal und geben Sie +   das Kommando #on("bold")##ib#define station#ie# (x)#off("bold")#, wobei #on("bold")#x#off("bold")# die gewählte Stationsnummer ist.  +  +   Hinweis:  Taskkommunikationen, die zu diesem Zeitpunkt laufen, führen zu feh +             lerhaftem Verhalten. Dies liegt daran, daß durch #on("bold")#define station#off("bold")# alle +             #ib#Task-Id#ie#'s geändert werden müssen, weil eine #ib#Task-Id#ie# u.a. die +             Stationsnummer der eigenen Station enthält (siehe 1.3). TASK- +             Variablen, die noch Task-Id's mit keiner oder falscher Stationsnum +             mer enthalten, können nicht mehr zum Ansprechen einer Task ver +             wendet werden.  +  +   Beispiel: Der #ib#Spoolmanager#ie# [3] richtet beim Kommando #on("bold")#start#off("bold")# einen #ib#Worker#ie# ein +             und merkt sich dessen #ib#Task-Id#ie# in einer TASK-Variablen, um sicher +             zustellen, daß nur der Worker #ib#Datei#ie#en zum Drucken abholt. Wird jetzt +             das Kommando #on("bold")# define station#off("bold")# gegeben, kann der Spoolmanager +             seinen Worker nicht mehr identifizieren, weil der Worker eine neue +             Task-Id erhalten hat. Man muß daher vor #on("b")#define station#off("b")# den Worker +             löschen und ihn danach mit dem Kommando #on("bold")##ib#start#ie##off("bold")# im Spoolmanager +             wieder neu einrichten.  +  +  +   Sinnvollerweise gibt man #on("bold")#define station#off("bold")# sofort nachdem man ein frisches System +   vom Archiv geladen hat.  +  +   Zum Anschluß einer #ib#Datenbox#ie# #ib#konfigurieren#ie# Sie mit dem Kommando #on("bold")##ib#configurate#ie##off("bold")# +   den für das Netz vorgesehenen #ib#Kanal#ie# auf  +  +   -  transparent  +   -  9600 #ib#Baud#ie# (Standardeinstellung der Boxen)  +   -  #ib#RTS/CTS#ie#-#ib#Protokoll#ie#  +   -  großen Puffer  +   -  8 bit  +   -  even parity  +   -  1 stopbit.  +  +   Falls diese Einstellungen nicht alle angeboten werden, klären Sie mit Ihrem +   Rechnerlieferanten, ob und wie diese Einstellungen erreicht werden können.  +  +   Hinweis:  Notfalls kann auf das #ib#RTS/CTS#ie#-Protokoll verzichtet werden, wenn der +             Eingabepuffer der #ib#Station#ie# groß genug ist. Die Anzahl simultan laufen +             der Netzkommunikationen ist dann auf  +  +                    puffergröße DIV 150  +  +             begrenzt (bei Z80, 8086: 3; bei M20: 10).  +  +   Hinweis:  Es können auch andere #ib#Baud#ie#raten (2400, 4800, 19200) an der Box +             eingestellt werden.  +  +  +c) Achten Sie bei der #ib#Verbindung#ie# von der Station zur #ib#Netzbox#ie# (bzw. zur Gegen +   station bei einem Zweistationennetz ohne Boxen) darauf, daß neben den Emp +   fangs- und Sendeleitungen auch die Leitungen RTS und CTS verdrahtet wer +   den, also ein 5-poliges Kabel verwendet wird [2]. Die #ib#Pin-Belegung#ie# der Boxen +   entspricht der eines Kabels zur Rechner-Rechner-Kopplung.  +  +   Beispiel:  +  +   Verbindung eines BICOS-Systems mit der Box:  +  +   Stecker                  Stecker  +   Pin                      Pin  +  +   2  <--------->           3  +   3  <--------->           2  +   4  <--------->           5  +   5  <--------->           4  +   7  <--------->           7  +  +  +d) Richten Sie eine Task #on("bold")##ib#net#ie##off("bold")# unter #on("bold")#SYSUR#off("bold")# ein und legen Sie eine #ib#Datei#ie# #on("b")##ib#netz#ie##off("b")# an, die +   Ihre #ib#Netzkonfiguration#ie# enthält, oder ändern Sie die mitgelieferte Datei ent +   sprechend ab (siehe auch 1.5.).#goalpage("sperre")#  +  +  +   Dem bisherigen Netz entspricht eine Datei #on("b")#netz#off("b")# mit folgendem Inhalt:  +  +     definiere netz;  +     routen (1,127,k);  +     starte kanal (k,1,x);  +     aktiviere netz.  +  +     k: ihr netzkanal.  +     x: IF yes ("#ib#Flußkontrolle#ie#") THEN 10 ELSE 3 FI.  +  +  +  +   Laden Sie die Datei #on("b")##ib#net install#ie##off("b")# vom Archiv #on("b")#net#off("b")# und übersetzen Sie diese. Je nach +   dem, welche EUMEL-Version auf der Maschine installiert ist, werden die notwen +   digen Programmdateien insertiert.  +  +   Es sind dies  +  +                          net report  +                          net hardware interface  +                          basic net  +                          net manager  +  +  +   Das Netz wird dabei gestartet.  +  +  +   Hinweis:  Obwohl die Task #on("b")#net#off("b")# sich noch mit #on("bold")##ib#continue#ie##off ("bold")# an ein Terminal holen +             läßt, sollte man dies nur kurzzeitig tun, da der Netzverkehr solange +             blockiert ist.  +  +             In der #ib#Datei#ie# #on("b")#netz#off("b")# sollte der #ib#Kanal#ie#, über den der meiste Verkehr erwar +             tet wird, zuerst gestartet werden. Für ihn wird die Task #on("b")##ib#net port#ie##off("b")# gene +             riert, für jeden weiteren Kanal wird eine Task #on("b")##ib#net port#ie# k#off("b")# (k=Kanal +             nummer) generiert.  +#page#  + +1.3. Benutzung des Netzes   +#goalpage("1.3")#  +  +  +Zur Benutzung des Netzes stehen folgende Operatoren und Prozeduren zur Verfü +gung:  +  +  +  +TASK OP #ib#/#ie# (INT CONST station, TEXT CONST taskname)  +  +liefert die Task #on("bold")#taskname#off("bold")# von der #ib#Station#ie# #on("bold")#station#off("bold")#.  +  +  +#ib#Fehlerfälle#ie#:  +  +  -  #ib(4)#Task "...." gibt es nicht#ie(4)#  +  +     Die angeforderte Task gibt es auf der #ib#Zielstation#ie# nicht.  +  +  -  #ib(4)##ib#Collectortask#ie# fehlt#ie(4)#  +  +     die Task #on("b")##ib#net port#ie##off("b")# existiert nicht (siehe 6).  +  +     Hinweis:  #on("b")#net port#off("b")# wird bei jedem Start des Netzes neu generiert und beim +               Auftreten eines nicht vorhergesehenen #ib#Fehler#ie#s beendet. Die Feh +               lermeldung steht im #on("b")##ib#report#ie##off("b")# (siehe 4).  +  +  -  #ib(4)#Station x antwortet nicht#ie(4)#  +  +     Eine nicht vorhandene oder abgeschaltete Station wurde angesprochen.  +  +     Hinweis: Dieser #ib#Fehler#ie# wird angenommen, wenn eine Überwachungszeit von +              ca. 30 Sekunden verstrichen ist, ohne daß Station x die Taskidenti +              fikation angeliefert hat.  +  +  -  #ib(4)#Station x gibt es nicht#ie(4)#  +  +     #ib#Station#ie# x steht nicht in den #ib#Routentabelle#ie#n.  +  +     Diese Meldung kann auch erscheinen, wenn Station x erst kürzlich an das Netz +     angeschlossen wurde. Sie steht dann noch nicht in den Routentabellen (siehe +     auch 5.3.).  +  +     Beispiel:  +  +        list (5/"PUBLIC")  +  +     Die Dateiliste von PUBLIC der Station 5 wird angefordert.  +  +  +  +TASK OP #ib#/#ie# (INT CONST station, TASK CONST task)  +  +liefert  +  +station / name (task)  +  +Beispiel:  +  +   list (4/public)  +  +  +Fehlerfall:  +  +   "......" #ib(4)#gibt es nicht#ie(4)#  +  +   Auf der eigenen Station gibt es die Task #on("b")#task#off("b")# nicht.  +   Der Taskname wird auf der eigenen Station bestimmt, wenn es dort die Task  +   nicht gibt, führt dies zur obigen Fehlermeldung.  +  +Abhilfe:  +  +   Statt list(4/public) das Kommando list (4/"PUBLIC") verwenden.  +  +  +  +INT PROC #ib#station#ie# (TASK CONST task)  +  +liefert die #ib#Stationsnummer#ie# der Task #on("bold")#task#off("bold")#.  +  +Beispiel:  +  +   put (station (myself))  +  +   gibt die eigene Stationsnummer aus.  +  +  +  +  +PROC #ib#reserve#ie# (TEXT CONST archivename, TASK CONST archivetask)  +  +dient dazu, das Archiv auf der #ib#Station#ie# #on("bold")#station#off("bold")# anzumelden.  +  +Beispiel:  +  +   reserve ("std", 4/"ARCHIVE"); #ib#list#ie# (4/"ARCHIVE")  +  +   gibt das Inhaltsverzeichnis der Archivfloppy im Laufwerk der Station 4 aus.  +  +   Hinweis: Vergessen Sie bei solchen #ib#Querarchivierungen#ie# nicht die Stationsangabe +            bei jedem einzelnen Archivkommando (z.B fetch ("xxx", #on("bold")#4/#off("bold")# +            "ARCHIVE")).  +  +   Hinweis: Querarchivieren ist langsam. Verwenden Sie es nur, wenn Sie Floppy +            formate umsetzen wollen.  +  +  +  +  +PROC #ib#free global manager#ie#  +  +dient dazu, die eigene Task über das Netz ansprechbar zu machen. Jede andere +Task im Netz kann dann die üblichen #ib#Manager#ie#aufrufe (#on("bold")##ib#save#ie##off ("bold")#, #on("bold")##ib#fetch#ie##off ("bold")#, usw.) an die +eigene Task machen, sofern diese nicht an ein Terminal gekoppelt ist.  +  +Die Task wird (wie bei #on("bold")#break#off ("bold")#) abgekoppelt und meldet sich in Zukunft mit #on("bold")#mainte +nance#off ("bold")# statt mit #on("bold")#gib kommando#off ("bold")#.  +  +Beispiel:  +  +   An Station 4 ruft man in der Task "hugo" das Kommando #on("bold")#free global manager#off("bold")# +   auf. Anschließend kann man von jeder Station aus z.B. #on("bold")#list (4/"hugo")#off ("bold")# usw. auf +   rufen.  +  +  +  +  +TEXT PROC #ib#name#ie# (TASK CONST t)  +  +Diese (schon immer vorhandene) Prozedur wurde dahingehend erweitert, daß der +Name einer auf einer anderen Station existierenden Task über Netz angefordert wird.  +  +Existiert die Task nicht, so wird #on("bold")##ib#niltext#ie##off ("bold")# geliefert.  +  +Hinweis: Die Prozedur #on("bold")##ib#exists#ie##off ("bold")# wurde nicht auf das Netz ausgedehnt, da sie in Situa +         tionen eingesetzt wird, wo es auf eine sehr schnelle Antwort ankommt. +         Daher liefert #on("bold")#exists#off ("bold")# für eine stationsfremde Task immer FALSE. Will man +         wissen, ob eine solche Task existiert, verwende man die Abfrage  +  +         #on("bold")#IF name (task) <> "" THEN ... #off ("bold")#.  +  +#ib#Fehlerfall#ie#:  +  +   - #ib(4)#Station x antwortet nicht#ie(4)#  +  +   - #ib(4)##ib#Station#ie# x gibt es nicht#ie(4)#  +  +#page#  +  +1.4. Informationsmöglichkeiten  +  +#goalpage("1.4")#  +  +In der Task #on("bold")#net#off("bold")# wird eine #ib#Datei#ie# #on("bold")##ib#report#ie##off("bold")# geführt, in der #ib#Fehlersituationen#ie# des Netzes +verzeichnet werden. Diese Datei kann in jeder anderen Task auf derselben Station mit +#on("bold")##ib#list#ie# (/"#ib#net#ie#")#off("bold")# angesehen werden. Eine Erklärung der wichtigsten Meldungen finden Sie +im Anhang.  +  +In jeder Task kann durch das Kommando #on("bold")##ib#list#ie# (/"#ib#net port#ie#")#off("bold")# eine Übersicht über die +momentan laufenden #ib#Netzübertragungen#ie# der eigenen #ib#Station#ie# erhalten werden (nur für +den #ib#Kanal#ie#, an dem #on("b")##ib#net port#ie##off("b")# hängt). Entsprechendes gilt für die weiteren Netports der +eigenen Station.  +  +Mit #on("bold")##ib#list#ie# (/"#ib#net list")#ie##off("bold")# erhält man die Informationen, die man mit #on("b")#list (/"net")#off("b")# und #on("b")##ib#list#ie##off("b")# auf +alle Netports bekommt, sofern #on("b")##ib#listoption#ie##off("b")# (siehe S. #topage("listop")#) beim Generieren des Netzes +aufgerufen wurde. Dieser Aufruf funktioniert auch bei fremden Stationen (z.B. #on("b")#list +(5/"net list")#off("b")#).  +  +#page#  +  +1.5. Eingriffsmöglichkeiten  +  +#goalpage("1.5")#  +  +-  Jede Task kann #ib#Sende#ie(1,"ströme")#- und #ib#Empfangsströme#ie#, die bei #on("bold")#list (/"net port")#off("bold")# gemel +   det worden sind und die eigene Task betreffen, abbrechen. Hierzu ist das Kom +   mando #on("bold")##ib#erase#ie# ("x", /"#ib#net port#ie#")#off ("bold")# zu geben, wobei x die #ib#Stromnummer#ie# (aus dem #on("bold")#list#off ("bold")#) +   ist.  +   Unberechtigte #ib#Löschversuche#ie# werden abgewiesen.  +   Von privilegierten Tasks aus können jedoch mit #on("b")##ib#erase#ie##off("b")# beliebige Ströme abge +   brochen werden.  +  +  +-  Durch das Kommando #on("bold")##ib#start#ie##off("bold")# kann von der Task #on("b")##ib#net#ie##off("b")# aus das Netz neu gestartet +   werden. Dies setzt eine gültige #ib#Datei#ie# #on("bold")#netz#off("bold")# voraus. Es wird ein #on("bold")##ib#run#ie##off("bold")# auf diese Datei +   gegeben. Das Kommando #on("b")##ib#start#ie##off("b")# ist nur noch aus Kompatibilitätsgründen zum alten +   Netz vorhanden.  +  +  +-  Durch das Kommando #on("bold")##ib#routen aufbauen#ie##off("bold")# in der Task #on("b")##ib#net#ie##off("b")# werden die #ib#Routentabelle#ie#n +   neu aufgebaut. Dies kann notwendig werden, wenn eine neue #ib#Station#ie# ans Netz +   angeschlossen wurde (#ib#Fehlermeldung#ie# '#ib(4)#Station x gibt es nicht#ie(4)#'). #on("bold")#routen aufbauen#off ("bold")# +   muß zuvor auch an allen dazwischenliegenden #ib#Knotenstation#ie#en gegeben werden.  +  +   #on("bold")#routen aufbauen#off ("bold")# erzeugt eine Task #on("b")##ib#router#ie##off("b")#, die sich an das Terminal koppelt (die +   Task #on("b")#net#off("b")# koppelt sich ab) und ein #ib#Protokoll#ie# ausgibt. Sind die #ib#Route#ie#n aufgebaut, +   beendet sich die Task #on("b")#router#off("b")# mit der Meldung #on("b")#fertig#off("b")#. Es werden nur Stationen +   bearbeitet, die nicht #ib#gesperrt#ie# (siehe S. #topage("sperre")#), und für die keine festen Routen +   vereinbart sind. Der Vorgang dauert ca. 5 Sek. pro nicht gesperrter Station und +   #ib#Netzkanal#ie#. Die #ib#Route#ie#n werden in einem #ib#Datenraum#ie# #on("b")##ib#port intern#ie##off("b")# hinterlegt.  +  +  +-  Der Aufruf #on("bold")##ib#definiere netz#ie##off("bold")# leitet eine #ib#Netzdefinition#ie# in der #ib#Datei#ie# #on("bold")##ib#netz#ie##off("bold")# ein. Dabei +   werden alle augenblicklichen Netzkommunikationen gelöscht. Die Tasks #on("b")##ib#net port#ie# +   (k)#off("b")#, wobei #on("b")#k#off("b")# die #ib#Kanalnummer#ie# ist, und #on("b")##ib#net timer#ie##off("b")# werden gelöscht.  +  +   Dieser Aufruf muß vor den Aufrufen von #on("bold")##ib#starte kanal#ie#, #ib#erlaube#ie#, #ib#sperre#ie#, #ib#routen#ie#, +   #ib#aktiviere netz#ie# und #ib#list option#ie##off("bold")# erfolgen.  +  +  +-  PROC #ib#sperre#ie# (INT CONST a,z)  +   bewirkt, daß die Stationen #on("bold")#a#off("bold")# bis #on("bold")#z#off("bold")# keine Manageraufrufe an Tasks dieser Station +   geben dürfen (Genauer gesagt werden sendecodes > 6 nicht weitergeleitet, son +   dern ein errornak mit dem Text "#ib(4)#kein Zugriff auf Station#ie(4)#" zurückgeschickt).  +  +   Dieser Aufruf muß vor dem ersten #on("bold")##ib#starte kanal#ie##off("bold")# erfolgen.  +  +  +-  PROC #ib#erlaube#ie# (INT CONST a,z)  +   bewirkt, daß die Stationen #on("bold")#a#off("bold")# bis #on("bold")#z#off("bold")# Manageraufrufe an Tasks dieser Station geben +   dürfen.  +  +   Dieser Aufruf muß vor dem ersten #on("bold")##ib#starte kanal#ie##off("bold")# erfolgen.  +  +   Beispiel: Alle Stationen außer 8 und 10 sollen #ib#gesperrt#ie# sein:  +  +             #ib#sperre#ie# (1,127); erlaube (8,8); erlaube (10,10)  +  +   Hinweis: 127 ist z.Zt. die maximale #ib#Stationsnummer#ie(1," maximale")#.  +  +  +-  PROC #ib#routen#ie# (INT CONST a,z,k)  +   legt fest, daß die Stationen #on("bold")#a#off("bold")# bis #on("bold")#z#off("bold")# an #ib#Kanal#ie# #on("bold")#k#off("bold")# direkt angeschlossen sind. Sen +   dungen dieser Stationen werden nur bearbeitet, wenn sie über diesen Kanal her +   einkommen (siehe 1.7.). Fehlt für eine Station ein entsprechender Routenaufruf, so +   darf sie über einen beliebigen #ib#Netzkanal#ie# angeschlossen sein. Dies wird dann von +   #on("bold")##ib#routen aufbauen#ie##off("bold")# ermittelt.  +  +   PROC routen (INT CONST a,z,k,zw)  +   legt fest, daß die Stationen #on("bold")#a#off("bold")# bis #on("bold")#z#off("bold")# indirekt über die #ib#Knotenstation#ie# #on("bold")#zw#off("bold")# angeschlos +   sen sind, und #on("b")#zw#off("b")# am Kanal #on("bold")#k#off("bold")# hängt.  +  +  +-  PROC #ib#starte kanal#ie# (INT CONST k,m,q)  +   startet eine #ib#Netztask#ie# am #ib#Kanal#ie# #on("bold")#k#off("bold")# im Modus #on("bold")#m#off("bold")# [4]. Dabei wird mit #on("bold")#q#off("bold")# die Anzahl +   paralleler #ib#Empfangsströme#ie# festgelegt. Dadurch kann erreicht werden, daß der +   #ib#Empfangspuffer#ie# nicht überläuft, indem nicht mehr als #on("b")#q#off("b")# Ströme quittiert werden. +   Bei #ib#V.24#ie#-#ib#Schnittstelle#ie#n gebe man 3 (ohne #ib#Flußkontrolle#ie#) bzw. 10 (mit Flußkon +   trolle) an.  +  +  +-  PROC #ib#aktiviere netz#ie#  +   muß als Abschluß in der Datei #on("bold")##ib#netz#ie##off("bold")# aufgerufen werden. Dabei wird die Task vom +   Terminal abgekoppelt. Falls es bei #on("bold")##ib#definere netz#ie##off("bold")# den #ib#Datenraum#ie# #on("b")##ib#port intern#ie##off("b")#, der +   die #ib#Route#ie#n enthält, nicht gab, wird #on("bold")##ib#routen aufbauen#ie##off("bold")# aufgerufen.  +  +  +-  PROC #ib#listoption#ie##goalpage("listop")#  +   erzeugt eine Task #on("b")##ib#net list#ie##off("b")#, die bei #on("bold")#list#off("bold")# den #ib#Fehlermeldung#ie#sreport und den Zustand +   aller Netports liefert. Diese Task ist auch über Netz ansprechbar. In der Regel +   sollte man #on("b")#listoption#off("b")# in der Datei #on("b")#netz#off("b")# aufrufen, es sei denn, das System ist sehr +   klein.  +  +#page#  +  +1.6. #ib#Fehlersuche#ie# im Netz  +  +#goalpage("1.6")#  +  +#ib#Fehler#ie# im Netz können sich verschiedenartig auswirken. Im folgenden wird auf einige +Beispiele eingegangen:  +  +Beispiel:  +  +   Auf #on("bold")#list (4/public)#off("bold")# erfolgt die Meldung '#ib(4)#Station#ie(4, " x antwortet nicht")# 4 antwortet nicht'.  +  +  +#ib#Fehler#ie#möglichkeiten:  +  +   -  #ib#Station#ie# 4 ist nicht eingeschaltet.  +      Abhilfe: Station 4 einschalten. Kommando erneut geben.  +  +  +   -  #ib#Netztask#ie# an Station 4 ist nicht arbeitsfähig.  +      Abhilfe: Kommando #on("bold")##ib#start#ie##off ("bold")# in der Task "net" auf Station 4.  +  +  +   -  Stationsnummern und Boxnummern stimmen nicht überein.  +      Abhilfe: Mit #on("bold")#define station#off ("bold")# #ib#Stationsnummer#ie#n korrigieren (siehe 3.2).  +  +  +   -  #ib#Verbindung#ie# Rechner/Box am eigenen Rechner oder an Station 4 fehlt.  +      Abhilfe: Verbindungen überprüfen. Durch Ansprechen einer dritten Station +               kann oft schnell geklärt werden, welche Rechner/Box-Verbindung +               defekt sein muß.  +  +  +   -  Verbindung der Boxen untereinander defekt.  +      Abhilfe: Fehlende Verbindung, #ib#Masseschluß#ie# und #ib#Dreher#ie# (keine 1:1 Verbin +               dung) überprüfen und beheben.  +  +      Hinweis: Liegt z.B. ein Masseschluß vor, so kann es durchaus sein, daß +               Boxen, die nicht in der Nähe des Masseschlusses stehen, noch +               miteinander arbeiten können. Man kann aus der Tatsache, daß zwei +               Boxen miteinander arbeiten können, also nicht schließen, daß man +               nicht nach diesem Fehler suchen muß.  +  +  +  +Beispiel:  +  +   Auf #on("bold")#list (4/public)#off("bold")# erfolgt keine Reaktion.  +  +  +   -  Station 4 ist während dieser Sendung zusammengebrochen.  +      Abhilfe: Station 4 wieder starten. Die Bearbeitung des #on("bold")##ib#list#ie##off ("bold")#-Kommandos wird +               automatisch wieder aufgenommen.  +  +  +   -  PUBLIC auf Station 4 ist nicht im Managerzustand.  +      Abhilfe: PUBLIC in den Managerzustand versetzen.  +  +  +   -  #ib#Fehler#ie# in der #ib#Netzhardware#ie#.  +      Überprüfen Sie, ob  +  +      -  die Boxen eingeschaltet sind,  +      -  die Bereitlampe blinkt (wenn nicht: #ib#RESET#ie# an der Box),  +      -  die #ib#V.24#ie#-Kabel richtig stecken,  +      -  die Boxen untereinander verbunden sind (1 zu 1 Verbindungen der 5 poli +         gen Diodenbuchsen).  +  +  +   -  Fehler bei der #ib#Netzinstallation#ie#.  +      Überprüfen Sie, ob  +  +      -  alle Stationen an einem #ib#Strang#ie# gleiche oder kompatible Netzmodi einge +         stellt haben [4],  +      -  alle Stationen an einem #ib#Netzstrang#ie# auf die gleiche #ib#Nutzdatenlänge#ie# einge +         stellt sind,  +      -  bei der #ib#Kommunikation#ie# über #ib#Knoten#ie# alle Stationen die gleiche Nutzdaten +         länge bei indirekten Sendungen eingestellt haben,  +      -  die #ib#Route#ie#n auf allen beteiligten Stationen korrekt eingestellt sind.  +  +  +  +Beispiel:  +  +   Auf #on("bold")#list (4/public)#off("bold")# erfolgt die Meldung '#ib(4)##ib#Collectortask#ie# fehlt#ie(4)#'.  +  +   -  Das Kommando #on("b")##ib#start#ie##off("b")# (bzw #on("b")##ib#aktiviere netz#ie##off("b")# in der #ib#Datei#ie# #on("b")#netz#off("b")#) wurde nicht gege +      ben. Somit existiert #on("b")##ib#net port#ie##off("b")# nicht.  +      Abhilfe: Kommando #on("bold")#start#off ("bold")# in der Task #on("b")#net#off("b")# geben.  +  +  +   -  Die #ib#Netzsoftware#ie# ist auf einen nicht vorhergesehenen #ib#Fehler#ie# gelaufen. Dieser +      wird im #ib#Report#ie# vermerkt. #on("b")##ib#net port#ie##off("b")# wird dabei gelöscht.  +      Abhilfe: Geben Sie in der Task #on("bold")#net#off("bold")# das Kommando #on("bold")#start#off("bold")#. Dadurch wird die +               Netzsoftware neu gestartet. Alle Netzkommunikationen dieser Station +               gehen verloren.  +  +  +  +Beispiel:  +  +   Nach #on("bold")##ib#fetch#ie# ("hugo",4/public)#off("bold")# sind Teile der Datei "hugo" verfälscht.  +  +   -  Die #ib#V.24#ie#-#ib#Verbindung#ie# zur Box ist nicht in Ordnung.  +      Abhilfe: Abstand zwischen Rechner und Box verkürzen; #ib#Baud#ie#rate ernie +               drigen; durch Wechseln der #ib#V.24#ie#-#ib#Schnittstelle#ie# feststellen, ob diese +               defekt ist.  +      Hinweis: Die Verbindung zwischen den Boxen ist durch #ib#Prüfsummen#ie# abge +               sichert (Hardware).  +  +#page#  +  +1.7. Sicherheit im Netz  +  +#goalpage("1.7")#  +  +Bei Benutzung eines Rechnernetzes tauchen neue #ib#Sicherheitsprobleme#ie# auf. Um sie +verstehen und eingrenzen zu können, muß man sich mit dem #ib#Sicherheitskonzept#ie# des +Betriebssystems EUMEL vertraut machen:  +  +Eine Task im EUMEL kann nur manipuliert werden, wenn man sie entweder an ein +Terminal koppelt oder ihr Sendungen zustellt.  +  +Das Ankoppeln kann über #ib#Paßwort#ie# abgesichert werden. Nach dem Ankoppeln kann +die Task außerdem selbst bestimmen, wie sie die dann möglichen Eingaben behan +delt. So kann z.B. noch ein komplizierter Paßalgorithmus zu durchlaufen sein, bis +man auf einer offenen Programmierumgebung landet.  +  +Sendungen können eine Task auch nur mit ihrem Einverständnis beeinflussen, da +eine Sendung nur zugestellt wird, wenn die Task in der Prozedur #on("b")##ib#wait#ie##off("b")# steht. Insbe +sondere kann die Task den Absender einer Sendung überprüfen und gewisse Opera +tionen nur bei gewissen Absendern zulassen. So lehnt ein #on("b")##ib#global manager#ie##off("b")# z.B. alle +Dateimanagerkommandos ab, die nicht von Nachkommen (z.B. Söhnen) der Task +kommt. #on("b")##ib#free global manager#ie##off("b")# hingegen läßt Operationen wie #on("b")##ib#save#ie##off("b")# oder #on("b")##ib#erase#ie##off("b")# von +beliebigen Tasks, auch von fremden #ib#Station#ie#en, zu. Will man nur bestimmte Fremd +stationen zulassen, kann man z.B. folgendes Schema verwenden:  +  +   PROC my #ib#manager#ie#  +      (DATASPACE VAR ds, INT CONST code, phase, TASK CONST source):  +  +     IF station (source) = station (myself) OR station (source) = 10  +     THEN  +       free manager (ds, code, phase, source)  +     ELSE  +       errorstop ("kein Zugriff")  +     FI  +  +  END PROC my manager;  +  +  global manager (PROC my manager)  +#page#  +Hier werden nur #on("b")#save#off("b")# usw. von Tasks der eigenen Station und der Station 10 zuge +lassen. Der Rest erhält die #ib#Fehlermeldung#ie# "kein Zugriff".  +  +Dieses Verfahren gewährt nur dann Sicherheit, wenn es nicht möglich ist, daß eine +beliebige Station sich als Station 10 ausgibt.  +  +Damit das Netz diese Sicherheit garantieren kann, müssen natürlich gewisse phy +sische Voraussetzungen erfüllt sein. Wenn z.B. die Station 10 über eine #ib#V.24#ie# ange +schlossen ist, aber jeder die Möglichkeit hat, an diese #ib#Schnittstelle#ie# seinen eigenen +Rechner anzuschliessen, dann kann das Netz natürlich nicht erkennen, ob es mit der +echten Station 10 verkehrt.  +  +Es muß also sichergestellt sein, daß an Kanälen für das Netz nicht manipuliert werden +kann. Bei einem #ib#Strang#ie# (Anschluß über #ib#Netzbox#ie#en) heißt das für die Boxen, daß sie +nur #ib#Telegramm#ie#e weitervermitteln, die die eingestellte #ib#Quellstationsnummer#ie# enthalten. +Sonst könnte jemand, der an denselben Strang wie #ib#Station#ie# 10 angeschlossen ist, +#ib#Telegramm#ie#e erzeugen, die so aussehen, als kämen sie von 10.  +  +Die #ib#Netzsoftware#ie# ihrerseits darf nur Telegramme auswerten, die über die richtige +#ib#Route#ie# (#ib#Kanal#ie# und #ib#Knotenstation#ie#) einlaufen.  +  +Leider hat dies die unangenehme Konsequenz, daß man automatisches Aufbauen und +Ändern von Routen verbieten muß, wodurch die Wartung der #ib#Netzkonfiguration#ie# +erschwert wird.  +  +Diese Version der #ib#Netzsoftware#ie# bietet den folgenden Kompromiß an: Nur für sicher +heitsrelevante #ib#Stationen#ie(1,", sicherheitsrelevante")# (im Beispiel Station 10) muß in der #ib#Datei#ie# #on("b")##ib#netz#ie##off("b")# die Route +angegeben werden. Dies muß in allen Stationen geschehen, für die die Station +sicherheitsrelevant ist, und in allen #ib#Knoten#ie# dazwischen.  +  +Für nicht sicherheitsrelevante Stationen werden #ib#Routeninformationen#ie# automatisch +aufgebaut und geändert.  +  +Hinweis:  +Man wird oft ohne sicherheitsrelevante Stationen auskommen, indem man auf Ebenen +oberhalb der Netzebene Paßwortkontrollen einführt. So ist es z.B. ja möglich, Dateien +durch Paßworte zu schützen. Ein weiteres Beispiel ist ein #ib#Printerserver#ie#, der nur +ausdruckt, wenn eine mitgegebene Abrechnungskennung stimmt. Dabei ist es sogar +wünschenswert, daß die #ib#Station#ie# irrelevant ist, die den Druckauftrag gibt.  +#pagenr ("%",21)##setcount (1)##block##pageblock##count per page#  +#headeven#  +#center#EUMEL Netzbeschreibung  +#center#____________________________________________________________  +  +#end#  +#headodd#  +#center#Teil 2 :  Arbeitsweise der Netzsoftware  +#center#____________________________________________________________  +  +#end#  +#bottomeven#  +#center#____________________________________________________________  +Netz - % #right#GMD  +#end#  +#bottomodd#  +#center#____________________________________________________________  +GMD #right#Netz - %  +#end#  +#page#  +  +Teil 2: Arbeitsweise der Netzsoftware  +#goalpage("2")#  +  +  +  +2.1. Die Netztask  +#goalpage("2.1")#  +  +  +In diesem Kapitel wird beschrieben, wie eine #ib#Netztask#ie# in das System eingebettet ist +und welche Aufgaben sie hat. Unter Einhaltung dieser Konzepte kann die ausgeliefer +te Netzsoftware so geändert werden, daß sie beliebige andere #ib#Netzhardware#ie# unter +stützt. Die Netzsoftware ist so gegliedert, daß i.allg. nur eine hardwareabhängige +Komponente ausgetauscht werden muß (siehe Teil 3).  +  +Die Kommunikation zwischen Tasks im EUMEL-Betriebssystem basiert auf einem +#ib#Rendezvouskonzept#ie#: Die #ib#Zieltask#ie# einer Sendung muß empfangsbereit sein, wenn die +#ib#Quelltask#ie# sendet.  +  +Die Kommunikationsprozeduren auf der niedrigsten Ebene sind #on("bold")##ib#send#ie##off ("bold")# (Senden) und +#on("bold")##ib#wait#ie##off ("bold")# (Warten auf Empfang). Bei der Kommunikation werden ein Integer #on("bold")#code#off ("bold")# und ein +#ib#Datenraum#ie# #on("bold")#dr#off ("bold")# übergeben. #on("bold")#code#off ("bold")# muß >= 0 sein, da negative Codes systemintern ver +wandt werden. Ist die empfangende Task an einen #ib#Kanal#ie# gekoppelt (#on("bold")##ib#continue#ie##off ("bold")#), so +führt eine Zeicheneingabe auf diesem Kanal dazu, daß eine Sendung mit dem Code +-4 ankommt. Die Eingabedaten müssen mit den üblichen #ib#Eingabeprozeduren#ie# (#on("bold")##ib#inchar#ie##off ("bold")# +usw.) abgeholt werden. Der übermittelte #ib#Datenraum#ie# und die Absendertask sind dabei +ohne Bedeutung und dürfen nicht interpretiert werden.  +  +Die Prozedur #on("bold")#send#off ("bold")# hat einen #ib#Rückmeldeparameter#ie#, der besagt, ob die Sendung +übermittelt wurde. Gibt es die Zieltask nicht oder steht sie nicht im #on("bold")#wait#off ("bold")#, so kann die +Sendung nicht übermittelt werden.  +  +Ein Entwicklungskriterium für das EUMEL-Netz war es, möglichst wenig Unterstüt +zung von der virtuellen EUMEL-Maschine (#ib#EUMEL0#ie#) zu fordern, damit weitgehend in +ELAN programmiert werden kann. Dadurch ist es möglich, eine (privilegierte) Task mit +der Netzabwicklung zu betrauen.  +#page#  +Zunächst wird auf die #ib#EUMEL0#ie#-Unterstützung eingegangen:  +  +a)  Es gibt die Prozedur #on("bold")##ib#define collector#ie##off ("bold")#, mit der die für das Netz verantwortliche +    Task der EUMEL0-Maschine bekannt gemacht wird. Diese Task wird im fol +    genden #ib#Collector#ie# genannt.  +  +b)  Es gibt die Prozedur #on("bold")##ib#define station#ie##off ("bold")#, die für den Rechner eine #ib#Stationsnummer#ie# +    einstellt. Anhand dieser Nummer werden die Rechner eines Netzes unterschie +    den. Das Einstellen bewirkt, daß für alle Tasks die Stationsnummer in ihre +    #ib#Task-Id#ie# eingetragen wird (Task-Id's sind die Werte, die der Typ TASK anneh +    men kann).  +  +c)  Der Befehl #on("bold")##ib#station#ie# (task)#off ("bold")# liefert die Stationsnummer der #on("bold")#task#off ("bold")#. So liefert z.B. +    #on("bold")##ib#station#ie# (myself)#off ("bold")# die #ib#Stationsnummer#ie# des eigenen Rechners.  +  +d)  Eine Sendung, deren #ib#Zieltask#ie# auf einem anderen Rechner liegt (also station (ziel) +    <> station (myself)), wird auf die #ib#Collectortask#ie# geleitet.  +  +e)  Es gibt eine Prozedur #on("bold")##ib#collected destination#ie##off ("bold")#, die es dem Collector erlaubt, die +    eigentliche Zieltask einer auf ihn geleiteten Sendung zu erfahren.  +  +f)  Es gibt eine Variante der Prozedur #on("bold")##ib#send#ie##off ("bold")#, die es dem Collector gestattet, der +    #ib#Zieltask#ie# eine andere Task als Absender vorzutäuschen.  +  +g)  Es gibt eine spezielle #ib#Task-Id#ie# #on("bold")##ib#collector#ie##off ("bold")#, durch die der augenblicklich eingestell +    te #ib#Collector#ie# erreicht wird. Diese wird als Zieltask beim Aufruf der Vermittlungs +    dienste angegeben (siehe S. #topage("collector")#). Eine Sendung an #on("bold")#collector#off ("bold")# wird von EUMEL0 +    an den derzeitig eingestellten Collector geschickt.  +  +Ein Collector kann also auf drei Wegen von den übrigen Tasks desselben Rechners +Sendungen erhalten:  +  +  1. Über ein normales #on("b")#send#off("b")# (z.B. bei #on("bold")#list (/"net port")#off ("bold")#, wenn #on("b")#net port#off("b")# der derzeitige +     #ib#Collector#ie# ist),  +  +  2. über ein #on("b")#send#off("b")# an die Task #on("bold")#collector#off ("bold")# (s.u.) und  +  +  3. als umgeleitete Sendung (z.B. bei #on("bold")#list#off ("bold")# an eine Task auf einem anderen +     Rechner).  +  +Der Collector kann diese Fälle anhand von #on("bold")#collected destination#off ("bold")# unterscheiden.  +  +Die Punkte d) bis f) dienen dazu, den Collector für über Netz kommunizierende Tasks +unsichtbar zu machen: Der Collector taucht nicht als Ziel oder #ib#Quelle#ie# von Sendungen +auf. Das ist notwendig, damit normale Tasks sich nicht darum kümmern müssen, ob +eine Sendung übers Netz geht oder im eigenen Rechner bleibt.  +  +Wenn ein #ib#Datenraum#ie# an einen anderen Rechner geschickt wird, muß der gesamte +Inhalt (z. Zt. max. 1 MB) übertragen werden. Dies macht bei der üblichen Netzhard +ware eine Zerlegung in #ib#Paket#ie#e nötig [5]. Bei der Zerlegung eines Datenraumes in +Pakete (#ib#Telegramm#ie#e) gelten folgende Einschränkungen:  +  +  -  Ein Paket kann maximal eine #ib#Datenraumseite#ie# als #ib#Nutzdaten#ie# enthalten.  +  +  -  Die #ib#Nutzdatenlänge#ie# ist für einen #ib#Übertragungsweg#ie# konstant.  +  +  -  Alle Stationen eines #ib#Netzstrang#ie#s senden mit gleicher Nutzdatenlänge (#on("b")##ib#data +     length#ie##off("b")#).  +  +  -  Bei indirekter #ib#Kommunikation#ie(1,"indirekte")# (über #ib#Knoten#ie#) muß die Nutzdatenlänge für in +     direkte Verbindungen (#on("b")##ib#data length via node#ie##off("b")#) auf allen beteiligten Stationen +     gleich eingestellt sein.  +  +  +Für Netze stehen spezielle Blockbefehle zur Verfügung:  +  +  +g)  #ib#blockin#ie# / #ib#blockout#ie# (dr,seite,512+abstand,anzahl,rest)  +  +    Es werden maximal #on("bold")#anzahl#off ("bold")# Bytes transferiert. In #on("bold")#rest#off ("bold")# wird zurückgemeldet, wie +    viele Bytes nicht bearbeitet wurden (z.B. weil der #ib#Kanal#ie# nichts anliefert). Bear +    beitet werden die Bytes  +  +       #on("bold")#seite#off ("bold")# * 512 + #on("bold")#abstand#off ("bold")#  +  +    bis maximal  +  +       #on("bold")#seite#off ("bold")# * 512 + #on("bold")#abstand#off ("bold")# + #on("bold")#anzahl#off ("bold")# - 1  +  +    Der Kanal, an den die Task gekoppelt ist, wird dabei über #ib#Stream-IO#ie# (d.h. +    #on("bold")##ib#incharety#ie##off ("bold")#, bei #on("bold")#blockin#off ("bold")# bzw. #on("bold")#out#off ("bold")# bei #on("bold")#blockout#off ("bold")#) angesprochen.  +  +    Hinweis: Die Anforderung darf nicht über #ib#Seitengrenze#ie# gehen, d.h.  +  +    #on("bold")#abstand#off ("bold")# + #on("bold")#anzahl#off ("bold")# <= 512  +  +    muß erfüllt sein.  +  +  +Eine Netzsendung läuft wie folgt ab:  +  +Die Task q auf Rechner rq mache ein #on("bold")##ib#send#ie##off ("bold")# an die Task z auf Rechner rz.  +  +1. Die Prozedur #on("bold")#send#off ("bold")# ist ein #ib#EUMEL0#ie#-Befehl. Die EUMEL0-Ebene erkennt, daß die +   Sendung an die #ib#Station#ie# rz geht, da die #ib#Stationsnummer#ie# in der #ib#Task-Id#ie# enthalten +   ist. Daher wird die Sendung zum #ib#Collector#ie# umgeleitet, den EUMEL0 wegen der +   Einstellung durch #on("bold")##ib#define collector#ie##off ("bold")# kennt, umgeleitet.  +  +2. Die Task Collector empfängt über #on("bold")##ib#wait#ie##off ("bold")# den #ib#Datenraum#ie#, den #ib#Sendecode#ie# und die +   Absendertask q. Die #ib#Zieltask#ie# z erfährt sie durch #on("bold")##ib#collected destination#ie##off ("bold")#.  +  +3. Der Collector nimmt Kontakt mit dem Collector des Rechners #on("b")#rz#off("b")# auf, dessen Sta +   tionsnummer ja #on("bold")##ib#station#ie#(z)#off ("bold")# ist, und übermittelt diesem Sendecode, #ib#Quelltask#ie# (q), +   eigentliche Zieltask (z) und den #ib#Datenraum#ie#. Da die Collectoren in ELAN geschrie +   ben sind, können sie an beliebige #ib#Netzhardware#ie# und #ib#Protokoll#ie#e angepaßt werden.  +  +4. Der #ib#Collector#ie# auf Rechner #on("b")#rz#off("b")# verwendet das spezielle #on("bold")#send#off ("bold")#, um der Zieltask die +   Sendung zuzustellen. Dadurch erscheint nicht der Collector, sondern die Task #on("b")#q#off("b")# +   als Absender der Sendung.  +  +Zur Abwicklung der #ib#Vermittlungsebene#ie# (siehe S. #topage("vermittlung")#) muß der Collector noch spe +zielle Funktionen beherrschen. Diese sind  +  +   der #on("b")##ib#/#ie#-Operator#off("b")# (Taskname in #ib#Task-Id#ie# wandeln) und  +   die #on("b")##ib#name#ie##off("b")#-Prozedur (Task-Id in Namen wandeln).  +  +Der #on("b")#/#off("b")#-Operator macht eine Sendung an den #on("bold")##ib#collector#ie##off ("bold")#, wobei im #ib#Datenraum#ie# der Name +der Task steht und der #ib#Sendecode#ie# gleich der Stationsnummer ist (siehe [6] ). Der +#ib#Collector#ie# setzt sich mit dem Collector dieser Station in Verbindung, damit dieser die +Task-Id ermittelt und zurückschickt. Der eigene Collector schickt dann dem #on("b")#/#off("b")#-Oper +ator als Antwort einen Datenraum, der die #ib#Task-Id#ie# enthält.  +  +Umgekehrt läuft #on("bold")##ib#name#ie##off ("bold")# ab: Wenn die Task-Id von einer fremden Station ist, schickt +#on("bold")#name#off ("bold")# eine Sendung an den #on("bold")##ib#collector#ie##off ("bold")#, wobei im Datenraum die Task-Id steht und +Sendecode = 256 ist. Der Collector entnimmt die #ib#Stationsnummer#ie# der Task aus der +Task-Id und läßt sich vom entsprechenden Collector den Tasknamen geben. Dieser +wird der #on("bold")#name#off ("bold")#-Prozedur im Antwortdatenraum übergeben.  +  +Netztasks bauen sich #ib#Routentabellen#ie# auf (#ib#Datei#ie#name #on("b")##ib#port intern#ie##off("b")#). Aufgrund dieser +Tabellen weiß jede #ib#Netztask#ie#, über welchen #ib#Kanal#ie# und welche #ib#Nachbarstation#ie# eine +#ib#Zielstation#ie# erreichbar ist. Wenn der #ib#Collector#ie# einen Sendeauftrag erhält, prüft er, ob +die Zielstation über seinen Kanal erreichbar ist. Wenn nicht, leitet er Parameter und +#ib#Datenraum#ie# der Sendung an die geeignete Netztask weiter.  +#page#  +  +2.2. Ebenen  +  +#goalpage("2.2")#  +  +In diesem Kapitel werden die #ib#Protokollebenen#ie# für das Netz beschrieben, wie sie die +ausgelieferte Netzsoftware benutzt und erwartet. Bei anderer Netzhardware als Daten +boxen müssen die Ebenen a) bis c) ausgetauscht werden [4]. Unter Einhaltung der im +vorigen Kapitel beschriebenen Randbedingungen können auch die höheren Ebenen +geändert werden.  +  +  +a) Physikalische Ebene  +  +   -  #ib#Station#ie# <--> Box  +  +      #ib#V.24#ie#-#ib#Schnittstelle#ie# mit #ib#RTS/CTS#ie#-Handshake. Vollduplex.  +  +   -  Box <--> Box  +  +      #ib#RS422#ie# über 2 verdrillte Leitungspaare (Takt und Daten).  +  +  +b) Verbindungsebene  +  +   -  Station <--> Box  +  +      Asynchron  +      8 Bit  +      Even Parity  +      2400/4800/9600/19200 #ib#Baud#ie# einstellbar über Lötbrücken)  +  +   -  Box <--> Box  +  +      #ib#SDLC#ie#  +      400 KBaud  +#page#  +c) #ib#Netzebene#ie#  +#goalpage("quelle")#  +  +   -  Station <--> Box  +  +      #ib#Telegrammformat#ie#:  #ib#STX#ie#, <n>, <ziel>, <#ib#quelle#ie#>, <(n-4) byte>  +  +      <n> ist #ib#Längenangabe#ie# ( 8 <= n <= 160)  +      <ziel>, <quelle> sind #ib#Stationsnummer#ie#n. Diese müssen an den jeweiligen +      Boxen eingestellt sein.  +  +      Box --> Station:  +  +      Ein #ib#Telegramm#ie# kommt nur bei der #ib#Station#ie# an, bei deren Box die Nummer +      <ziel> eingestellt ist. Dadurch ist ein Mithören fremder #ib#Übertragung#ie# nicht +      möglich (Datenschutz).  +  +      Zwischen Telegrammen können #ib#Fehlermeldung#ie#en der Box (Klartext) übermittelt +      werden (z.B. 'skipped x', wenn ein #ib#STX#ie# von der Box erwartet wurde, aber 'x' +      von der Station ankommt).  +  +      Station --> Box:  +  +      Ein Telegramm wird nur abgeschickt, wenn <#ib#quelle#ie#> mit der eingestellten +      Nummer übereinstimmt (Datenschutz: Man kann nicht vorschwindeln, eine +      beliebige Station zu sein, es sei denn, man hat physischen Zugriff zur Box und +      stellt dort die Stationsnummer um).  +  +   -  Box <--> Box  +  +      #ib#Telegrammformat#ie#:  +          FRAME, <ziel>, <#ib#quelle#ie#>, <daten>, <CRC-Code>  +  +      Eine #ib#Längenangabe#ie# ist nicht nötig, da #ib#SDLC#ie# eine Rekonstruktion der Länge +      erlaubt.  +  +      Telegramme mit falschen #ib#CRC-Code#ie# werden vernichtet. Auf höheren Ebenen +      muß dies durch #ib#Zeitüberwachung#ie# erkannt und behandelt werden.  +  +#page#  +d) Transportebene  +  +   Diese Ebene wickelt das Rendezvous zwischen einer Task, die #on("bold")##ib#send#ie##off ("bold")# macht, und +   einer Task, die im #on("bold")##ib#wait#ie##off ("bold")# steht, ab [1].  +  +   Der im #on("bold")#send#off ("bold")# angegebene #ib#Datenraum#ie# wird als Folge von #ib#Seiten#ie# (im EUMEL- +   Sinne: Pagingeinheit und Allokiereinheit) übermittelt, wobei jede Seite ggf. noch in +   n Byte große Stücke zerlegt wird. Es werden nur echt allokierte Seiten übermit +   telt. Um nicht jedes #ib#Telegramm#ie# voll qualifizieren zu müssen, wird zunächst eine +   Art virtuelle #ib#Verbindung#ie# durch ein #ib#OPEN#ie#-Telegramm eröffnet. Danach folgen +   variabel viele #ib#DATA#ie#-Telegramme. Beide Sorten werden durch #ib#QUIT#ie#-Tele +   gramme quittiert, um folgende Funktionen zu ermöglichen:  +  +   #ib#Flußkontrolle#ie# (z.B. Zielrechner langsam),  +   Wiederaufsetzen (verlorene Telegramme),  +   Abbruch (z.B. weil Zieltask inzwischen beendet).  +  +   Ein #ib#CLOSE#ie#-Telegramm ist nicht nötig, da das letzte DATA-Telegramm als +   solches erkannt werden kann (siehe unten).  +#page#  +   -  #ib#OPEN#ie#-Telegramm  +  +#clear pos#  +    0      1      2      3      4      5      6      7      8      9. Byte  ++------+------+------+------+-------------+-------------+-------------------+  +I STX  I  24  I Ziel IQuelleI Endziel     I Endquelle   I Strom             I  ++------+------+------+------+-------------+-------------+-------------------+  +  +   10     11     12     13     14     15     16     17                 ++-------------+-------------+---------------------------+  +I Sequenz     I  Seite      I  Quelltask                I  ++-------------+-------------+---------------------------+  +  +   18     19     20     21     22     23                            ++---------------------------+-------------+  +I  Zieltask                 I  Code       I  ++---------------------------+-------------+  +  +  +  +          <#ib#ziel#ie#>, <#ib#quelle#ie#> siehe S. #topage("quelle")#  +  +          <#ib#endziel#ie#>    Eigentliche #ib#Zielstation#ie#. Ist <ziel> = <endziel>, so ist +                       das #ib#Telegramm#ie# angekommen. Andernfalls muß die Station +                       <ziel> den #ib#Nachbarn#ie# zum Erreichen des <endziel> als +                       neues <ziel> einsetzen und das Telegramm an diesen +                       Nachbarn weiterleiten.  +  +          <#ib#endquelle#ie#>  Eigentliche #ib#Absenderstation#ie#. <quelle> ist dagegen immer +                       die Nummer der sendenden #ib#Nachbarstation#ie#.  +  +          <#ib#strom#ie#>      Die #ib#Stromnummer#ie# identifiziert die virtuelle #ib#Verbindung#ie#. Sie +                       muß in den #ib#QUIT#ie#-Telegrammen angegeben werden.  +  +          <#ib#sequenz#ie#>    -1 (Kennzeichen für OPEN)  +  +          <#ib#seite#ie#>      Nummer der ersten echt allokierten #ib#Seite#ie# des #ib#Datenraum#ie#s +                       (=-1, falls Nilspace)  +  +          <#ib#quelltask#ie#>  #ib#Task-Id#ie# der sendenden Task  +  +          <#ib#zieltask#ie#>   Task-Id der empfangenden Task  +  +          <code>       Wert des im #on("bold")##ib#send#ie##off ("bold")# angegebenen Codes  +#page#  +   -  #ib#DATA#ie#-Telegramm  +  +  +  +  +  +    0      1      2      3      4      5      6      7      8      9. Byte     ++------+------+------+------+-------------+-------------+-------------------+  +I STX  I LängeI Ziel IQuelleI Endziel     I Endquelle   I Strom             I  ++------+------+------+------+-------------+-------------+-------------------+  +  +   10     11     12     13     14                                        ++-------------+-------------+-----------------------------------------------+  +I Sequenz     I Seite       I n Byte Daten  (Länge = 14 + n)                I  ++-------------+-------------+-----------------------------------------------+  + +  +          <#ib#laenge#ie#>     Gesamtlänge des Telegramms.  +                       #on("b")#laenge#off("b")# = #on("b")##ib#nutzlaenge#ie##off("b")# + 14.  +                       Für #on("b")#nutzlaenge#off("b")# sind nur die Werte 64,128,256 und 512 +                       zugelassen (siehe 1). #on("b")#laenge#off("b")# wird codiert dargestellt (siehe +                       Teil 3).  +  +  +          <#ib#sequenz#ie#>    wird von Telegramm zu Telegramm hochgezählt. Sie dient +                       der Überwachung bzgl. verlorengegangener Telegramme +                       bzw. durch #ib#Zeitüberwachung#ie# verdoppelter Telegramme.  +  +          <#ib#seite#ie#>      Nummer der x-ten echt allokierten Seite des #ib#Datenraum#ie#s +                       (x = ((<sequenz> DIV anzahl pakete pro seite) + 2)  +  +          <n byte>     #ib#Nutzinformation#ie#. Diese gehört zur #ib#Adresse#ie# a des Daten +                       raums.  +  +                       a =  +                       N (<sequenz> DIV anzahl pakete pro seite + 1) * 512  +                           + (<sequenz> MOD anzahl pakete pro seite) * n  +  +                       wobei N (x) die Nummer der x-ten Seite und  +                       n die #ib#Nutzdatenlänge#ie# ist.  +  +                       Aus den Formeln ergibt sich, daß diese Nummer schon in +                       einem vorhergehenden DATA/OPEN-Telegramm über +                       mittelt wurde (im Feld <seite>).  +  +   -  #ib#QUIT#ie#-Telegramm  +  +  +    0      1      2      3      4      5      6      7      8      9. Byte     ++------+------+------+------+-------------+-------------+-------------------+  +I STX  I  12  I Ziel IQuelleI Endziel     I Endquelle   I Strom             I  ++------+------+------+------+-------------+-------------+-------------------+  +  +   10     11                                                     ++-------------+  +I Quit        I  ++-------------+  +  +  +  +          <#ib#strom#ie#>      muß die #ib#Stromnummer#ie# sein, die in dem #ib#OPEN#ie#/#ib#DATA#ie# +                       Telegramm stand, das quittiert wird.  +  +          <quit>       0 :  ok. Nächstes Telegramm schicken.  +  +                       -1:  #ib#Übertragung#ie# neu starten (mit #ib#OPEN#ie#), weil die Emp +                            fangsstation das OPEN nicht erhalten hat.  +  +                       -2:  Übertragung ca. 20 Telegramme zurücksetzen.  +  +                       -3:  Übertragung abbrechen.  +  +                       -4:  #ib#Quittung#ie# für letztes Telegramm einer Sendung.  +  +  +e) #ib#Vermittlungsebene#ie##goalpage("vermittlung")# #goalpage("collector")#  +  +   Diese Ebene ist dafür zuständig, Namen von Tasks auf anderen Stationen in +   #ib#Task-Id#ie#'s (Werte des Typs TASK) zu wandeln und umgekehrt. Hierzu wird im +   entsprechenden #ib#OPEN#ie#-Telegramm der Code -6 (bzw. -7) als <code> ein +   getragen. Die #ib#Netzempfangstask#ie# erkennt diese #ib#Codes#ie# und wickelt die Aufgaben +   selbst ab, so daß es dabei nicht nötig ist, irgendeine Task-Id der #ib#Zielstation#ie# zu +   kennen.  +  +   Dieses Verfahren ist möglich, weil im #on("bold")##ib#send#ie##off ("bold")# nur positive Codes erlaubt sind.  +#page#  +f) #ib#Höhere Ebenen#ie#  +  +   Höhere Ebenen sind nicht mehr netzspezifisch. Sie basieren alle auf dem Send/ +   Wait-Konzept des EUMEL. So gibt es z.B. den #on("bold")##ib#global manager#ie##off ("bold")#, der Aufbewah +   rung und Zugriff von #ib#Datei#ie#en in einer Task regelt. Dabei darf diese Task (bei der +   Variante #on("bold")##ib#free global manager#ie##off ("bold")#) auf einer beliebigen #ib#Station#ie# im Netz liegen. Wegen +   des #ib#Rendezvous-Konzept#ie#s können beliebige Sicherheitsstrategien benutzt werden +   (z.B.: keine Dateien an Station 11 ausliefern). Von großem Wert ist z.B., daß +   man ohne weiteres das Archiv (Floppylaufwerk) einer anderen Station anmelden +   und benutzen kann, wodurch eine einfache Konvertierung von Floppyformaten +   möglich ist. Dies ist möglich, weil auch die Archiv-Task der Stationen sich an +   das Globalmanagerprotokoll halten.  +  +  +  +  +  +Bemerkungen  +  +#ib#Fehlerbehandlung#ie# besteht bis Ebene c) darin, fehlerhafte #ib#Telegramm#ie#e einfach zu +entfernen. Die Ebene d) überwacht den Netzverkehr sowieso über #ib#Timeout#ie#s, die eine +Wiederholung eines Telegrammes bewirken, wenn die #ib#Quittung#ie# ausbleibt.  +  +Da bei der sendenden #ib#Station#ie# der ganze #ib#Datenraum#ie# zur Verfügung steht, ist eine +#ib#Fenstertechnik#ie# (wie bei #ib#HDLC#ie#) nicht nötig. Es kann zu jedem Zeitpunkt um beliebig +viele Telegramme zurückgesetzt werden.  +  +Da im EUMEL eine #ib#Textdatei#ie# ein #ib#Datenraum#ie# mit sehr komplexer Struktur ist (wegen +der Insert/Delete-Möglichkeiten, ohne den Rest der #ib#Datei#ie# zu verschieben), ist es ein +hoher Aufwand, von einem fremden Betriebssytem aus eine Textdatei in das +EUMEL-Netz zu senden. Für solche Zwecke muß noch eine einfachere Dateistruktur +definiert und entsprechende Dateikonverter erstellt werden.  +#page#  +  +2.3. Stand der Netzsoftware  +  +#goalpage("2.3")#  +  +Das EUMEL-System wickelt die Prozedur #on("bold")##ib#send#ie##off("bold")# über das Netz ab, wenn die Sta +tionsnummer der #ib#Zieltask#ie# ungleich der eigenen #ib#Stationsnummer#ie# ist. Umgekehrt kann +man der von der Prozedur #on("bold")##ib#wait#ie##off("bold")# gelieferten Absendertask die #ib#Absenderstation#ie# entneh +men (siehe Prozedur #on("bold")##ib#station#ie##off("bold")# in Teil 1).  +  +Anders als bei einem #on("bold")##ib#send#ie##off("bold")# innerhalb einer Station meldet ein #on("bold")#send#off("bold")# an eine Task einer +fremden Station immer 0 zurück (Task gibt es und Task war im wait), obwohl dies +nicht der Fall sein muß. Ist die Sendung vollständig zur Zielstation übertragen, so +versucht der dortige #ib#Collector#ie# diese hundertmal im Sekundenabstand zuzustellen. +Bleibt das erfolglos, wird die Sendung vernichtet.  +#pagenr ("%", 33)##setcount (1)##block##pageblock##count per page#  +#headeven#  +#center#EUMEL Netzbeschreibung  +#center#____________________________________________________________  +  +#end#  +#headodd#  +#center#Teil 3 :  Netz Hardware Interface  +#center#____________________________________________________________  +  +#end#  +#bottomeven#  +#center#____________________________________________________________  +Netz - % #right#GMD  +#end#  +#bottomodd#  +#center#____________________________________________________________  +GMD #right#Netz - %  +#end#  +#page#  +  +Teil 3: Netz-Hardware-Interface       +  +  +#goalpage("3")#  +  +  +3.1. Einführung  +  + #goalpage("3.1")#  +  +In diesem Teil der Netzbeschreibung wird die #ib#Schnittstelle#ie# beschrieben, über die +#ib#Netzhardware#ie# (also #ib#Datenbox#ie#en, #ib#Netzbox#ie#en oder Netzkarten) an die EUMEL-Netz +Software angepaßt werden kann. Dieser Teil der Beschreibung ist also nur für Netz +implementatoren wichtig.  +  +Das EUMEL-Netz wurde dazu konzipiert, zwei oder mehr EUMEL-Rechner über +#ib#V.24#ie#-Leitungen oder Datenboxen miteinander zu vernetzen. Dem heutigen Stand der +Technik entsprechend, werden auf dem Markt eine Reihe von Möglichkeiten ange +boten, um PC's zu vernetzen. Diese Netze unterscheiden sich auch dadurch, daß +unterschiedliche Medien zur Datenübertragung benutzt werden. Das #ib#EUMEL- +Datenboxen-Netz#ie# benutzt Telefonkabel, #ib#Ethernet#ie# beispielsweise Koax-Kabel. Auch +Lichtleiter werden zur Datenübertragung benutzt. Entsprechend gibt es eine ganze +Menge Hardware (#ib#Treiber#ie#, Netzzugangsgeräte, Datenboxen, Anschlußkarten), die die +Kopplung zwischen einem #ib#I/O-Kanal#ie# eines Rechners und dem Übertragungsmedium +(Kabel) übernimmt. Das Netz-Hardware-Interface soll als #ib#Schnittstelle#ie# zwischen der +NetzSoftware und dem Treiber dienen. Damit wird es möglich, mehrere EUMEL- +Rechner über verschiedene (Teil-) Netze (in dieser Beschreibung Stränge genannt) +und unterschiedliche #ib#Netzhardware#ie# (Treiber) miteinander zu verbinden. Für den +EUMEL-Benutzer soll dabei kein Unterschied in der Benutzung des EUMEL-Netzes +feststellbar sein.  +#page#  +Neben unterschliedlichen Übertragungsmedien und Treibern gibt es weitere Unter +schiede zwischen Netzen:  +  +     -  in der Netztopologie (Bus-, Ring- oder Sternnetze),  +  +     -  in den Netzzugangsverfahren (Token passing, time slice token, slotting oder +        CSMA/CD),  +  +     -  in der #ib#Übertragungsgeschwindigkeit#ie#,  +  +     -  im Aufbau der einzelnen #ib#Pakete#ie(1,", Aufbau der")# (#ib#Netztelegramm#ie#e).  +  +Alles, was mit den ersten drei Punkten zusammenhängt, wird von den Netzzugangs +geräten behandelt.  +  +Der Paketaufbau aber muß zumeist im Rechner geschehen und kann in den seltens +ten Fällen ganz vom Treiber übernommen werden. Ebenso kann der Treiber aus den +empfangenen Paketen nicht immer die Teile herausfiltern, die von der EUMEL- +#ib#Netzsoftware#ie# gebraucht werden. Diese Aufgaben übernimmt das #ib#Netz-Hardware- +Interface#ie#. Das Netz-Hardware-Interface stellt die #ib#Verbindung#ie# zwischen EUMEL- +#ib#Netzsoftware#ie# und den verschiedenen Netzhardwarearten dar. Ähnlich wie bei den +Drucker- und Terminal-Anpassungen wurde ein hardwareabhängiger Teil aus der +Netzsoftware abgetrennt und in einem eigenen #ib#Paket#ie# zusammengefaßt. Beim Start +des Netzes wird durch Angabe des entsprechenden #ib#Netzmodus#ie# für den jeweiligen +#ib#Kanal#ie# die entsprechende Anpassung für den benutzten Treiber ausgewählt. Wenn +andere, neue Treiber angepaßt werden sollen, so müssen lediglich in dem Paket #on("b")##ib#net +hardware interface#ie##off("b")# die entsprechenden Prozeduren hinzugefügt und die #ib#Sprungleisten#ie# +(#ib#SELECT#ie#-Statements) erweitert werden.  +  +Durch das #ib#Knotenkonzept#ie# in der #ib#Netzsoftware#ie# ist es möglich, über einen #ib#Knoten +rechner#ie# Teilnetze (Stränge), die mit unterschiedlicher #ib#Netzhardware#ie# arbeiten, mitein +ander zu verbinden. Es sind dann beispielsweise Verbindungen zwischen Rechnern, +die über #ib#Ethernet#ie# vernetzt sind, und Rechnern auf dem EUMEL-Datenboxen-Netz +möglich. Es ist auch möglich, mit einem Rechner Zugang zu einem Netz zu erhalten, +für das spezielle #ib#Netzhardware#ie# erforderlich ist (Datenboxen, Ethernet-Anschluß). Man +kann den Rechner über eine Rechner-Rechner-Kopplung (#ib#V.24#ie#) mit einem Rechner +verbinden, der bereits ans Netz angeschlossen ist, und so (allerdings auf Kosten der +Leistung des #ib#Knotenrechner#ie#s) Netzhardware einsparen.  +#page#  +  +3.2.  Arbeitsweise des  +      Netz-Hardware-Interfaces +       +  +  +  +  +    #goalpage("3.2")#  +  +Grob vereinfacht kann man sich die Arbeitsweise der #ib#EUMEL-Netz-Software#ie# so vor +stellen:  +  +       reset box;  +       REP  +          IF zeichen da THEN lies telegramm ein  +             ELIF telegramm auszugeben THEN gib telegramm aus  +          FI  +       PER .  +  +(Es ist nur der Teil der Software beschrieben, der die Kanalbehandlung betrifft).  +  +  +Das Zusammenspiel zwischen EUMEL-Netz und Netz-Hardware-Interface ge +schieht auf folgende Weise:  +  +  +     #on("b")#reset box;#off("b")#  +     REP  +        IF zeichen da THEN  #on("b")#next packet start#off("b")#;  +                            lies telegramm ein  +           ELIF telegramm auszugeben THEN gib telegramm aus  +        FI  +     PER.  +  +     gib telegramm aus:  +         #on("b")#transmit header#off("b")#;  +         gib eumelnetztelegramm aus;  +         #on("b")#transmit trailer #off("b")#.  +  +Die fett gedruckten Programmteile werden im Netz-Hardware-Interface realisiert, die +anderen Teile stecken in den darüberliegenden Teilen der EUMEL-Netz-Software.  +#page#  +Beim Senden eines #ib#Telegramm#ie#s wird von der #ib#Netzsoftware#ie# zuerst der #ib#Vorspann#ie# in +einem #ib#Datenraum#ie# an das Hardware-Interface übergeben (#on("b")##ib#transmit header#ie##off("b")#). Im Hard +ware-Interface können aus dem Vorspann die entsprechenden Informationen (Tele +grammlänge, #ib#Zielstation#ie# usw.) entnommen werden. Dann wird von der Netzsoftware +das Telegramm (inklusive Vorspann) per #on("b")##ib#blockout#ie##off("b")# übergeben. Danach wird #on("b")##ib#transmit +trailer#ie##off("b")# aufgerufen, um dem Hardware-Interface das Ende des Telegramms zu mel +den. Beim Empfang ruft die Netzsoftware zuerst die #ib#I/O Control#ie# #ib#Telegrammfreigabe#ie# +auf [7]. Danach wird das erste #ib#Zeichen#ie# des Telegramms angefordert (#on("b")##ib#next packet +start#ie##off("b")#). Falls ein #ib#STX#ie# geliefert wurde, wird das Telegramm per #on("b")##ib#blockin#ie##off("b")# eingelesen. Falls +#ib#Niltext#ie# zurückgeliefert wird, wird von der Netzsoftware #ib#Timeout#ie# angenommen. Alle +anderen Zeichen werden so interpretiert, als ob Störungen aufgetreten wären. Die +Netzsoftware übernimmt die #ib#Fehlerbehandlung#ie#. Dazu wird u. U. ein Leerlesen des +Puffers vom Hardware-Interface verlangt (#on("b")##ib#flush buffers#ie##off("b")#).  +  +Bei der Einstellung der #ib#Nutzdatenlänge#ie# (#on("b")##ib#data length#ie##off("b")#) ist zu beachten, daß  +  +a)  alle #ib#Station#ie#en, die an einem #ib#Strang#ie# hängen, auf die gleiche Nutzdatenlänge +    eingestellt sein müssen.  +  +b)  Wenn mehrere Stränge über #ib#Knoten#ie# miteinander verbunden sind, muß die Nutz +    länge für Sendungen über Knoten (#on("b")##ib#data length via node#ie##off("b")#) auf allen Stationen des +    gesamten Netzes gleich eingestellt sein. Die Zusammenfassung oder Aufteilung +    von #ib#Telegramm#ie#en in Knoten ist nicht möglich.  +  +c)  Als mögliche Nutzdatenlänge sind folgende Werte erlaubt:  +  +    64, 128, 256 und 512 Byte.  +  +    Größere Nutzdatenlängen sind zur Zeit nicht möglich.  +  +d)  Je größer die #ib#Nutzdatenlänge#ie# ist, desto geringer ist der Overhead an #ib#Zeichen#ie#, +    die auf den Rechnern verarbeitet werden müssen. Allerdings muß der Rechner +    leistungsfähig genug sein, die ankommenden Blöcke schnell genung zu verarbei +    ten, und die Netztreiber müssen entsprechend große Puffer haben.  +  +  +Alle implementierten Netzanpassungen sollen in einem Netz-Hardware-Interface +zusammengefaßt werden. Dies ist notwendig, um über #ib#Knotenrechner#ie# Netzstränge +verbinden zu können, die mit unterschiedlicher #ib#Netzhardware#ie# arbeiten. So können +zum Beispiel ein #ib#Strang#ie#, der mit Datenboxen aufgebaut ist, und ein #ib#Ethernet#ie#-#ib#Strang#ie# +über einen Knotenrechner miteinander verkoppelt werden.  +#page#  +Aus diesem Grund wurden #on("b")#Netzmodi#off("b")# eingeführt. Man kann dadurch, daß die Netz +modi, genau wie die #ib#Kanal#ie#angaben, in der #ib#Datei#ie# #on("b")##ib#netz#ie##off("b")# niedergelegt sind, ohne Aus +tausch einer Softwarekomponente die Netzhardware wechseln. Es gibt auch die +Möglichkeit, durch verschiedene Netzmodi unterschiedliche Treiber an ein und das +selbe Netz anzuschließen. Beispielsweise gibt es für einige Rechnertypen Steckkarten, +mit denen der Rechner an das Ethernet angeschlossen werden kann. Man kann, +wenn diese Karten angepaßt sind, den #ib#Ethernet#ie#-Zugang über verschiedene Netz +anschlußkarten realisieren.  +  +Das Netz-Hardware-Interface muß folgende Aufgaben übernehmen:  +  +    Bei der Ausgabe an den Treiber:  +  +        -  Generieren und Ausgeben des #ib#Paket#ie#headers,  +        -  Umsetzen von logischen Stationsadressen (#ib#Stationsnummer#ie#n) in phy +           sische #ib#Adresse#ie#n,  +        -  Ausgeben der Daten (EUMEL-Netz-#ib#Telegramm#ie#e),  +        -  Generieren und Ausgeben des Trailers und evtl. Auffüllen des Pakets mit +           #ib#Füllzeichen#ie#, falls auf dem Netz eine Mindestlänge für Pakete gefordert +           wird.  +  +    Bei der Eingabe vom Treiber:  +  +        -  Weglesen von #ib#Füllzeichen#ie#,  +        -  Prüfen der #ib#Adresse#ie#n,  +        -  Weglesen von #ib#Paket#ie#teilen, die in der EUMEL-Netz-Software nicht +           gebraucht werden.  +  +    Weiterhin können Funktionen wie  +  +        -  Reset des Treibers,  +        -  Prüfung, ob Stationsadresse und #ib#Adresse#ie# im Treiber übereinstimmen,  +        -  Statistik und Service  +  +    durch das Netz-Hardware-Interface übernommen werden.  +  +Dazu wird ein Satz von Prozeduren über die #ib#DEFINES#ie#-#ib#Schnittstelle#ie# des Netz- +Hardware-Interfaces zur Verfügung gestellt. Wenn neue Treiber oder Netzarten +implementiert werden sollen, so muß an diesem Interface nichts geändert werden. Die +herausgereichten Prozeduren realisieren #ib#Sprungleisten#ie# (#ib#SELECT#ie#-Statements), über +die durch Erweiterung (#ib#CASE#ie#) die Prozeduren erreicht werden können, die den ent +sprechenden #ib#Netzmodus#ie# realisieren. Außerdem werden Informationsprozeduren für die +darüberliegenden Programmteile zur Verfügung gestellt.  +#page#  +  +3.3. Netztreiber  +  + #goalpage("3.3")#  +Unter #ib#Netztreiber#ie#n versteht man die Einheiten, die den Anschluß des Rechners an ein +Netz realisieren. Das können #ib#Netzbox#ie#en sein, die mit dem Rechner über eine #ib#V.24#ie#- +Leitung verbunden sind, aber auch Anschlußkarten, die direkt auf den Datenbus des +Rechners gehen. Falls die #ib#Schnittstelle#ie# der Treiber-Hardware eine andere als die +serielle #ib#V.24#ie# ist, muß in der Regel eine Anpassung für die Hardware im #ib#SHard#ie# vorge +nommen werden.  +  +Falls der Treiber über eine serielle #ib#V.24#ie#-#ib#Schnittstelle#ie# mit dem Rechner verbunden +ist, wie das auch bei der direkten Kopplung oder dem Datenboxennetz der Fall ist, +wird die hohe #ib#Übertragungsgeschwindigkeit#ie# auf dem eigentlichen Netz durch die +relativ geringe Übertragungsgeschwindigkeit auf der #ib#V.24#ie#-#ib#Schnittstelle#ie# zwischen +Rechner und Treiber (Box) gebremst. Über andere Schnittstellen im Rechner, wenn +sie mit #ib#Stream I/O#ie# [7] betrieben werden, kann man dies vermeiden. Diese Schnitt +stellen müssen vom SHard bedient werden.  +  +Wenn in den Rechner integrierte Netztreiber (Netzanschlußkarten) benutzt werden +sollen, so muß in der Regel die Behandlung dieser Netzanschlußkarte im SHard +durchgeführt werden.  +  +Um effizient implementieren zu können, sollte darauf geachtet werden, daß möglichst +wenig zusätzliche #ib#Zeichen#ie# von der #ib#Netzsoftware#ie# bzw. dem Netz-Hardware-Inter +face bearbeitet werden müssen. Das Auffüllen von Paketen auf eine Mindestlänge +sollte möglichst vom Treiber gemacht werden, ebenso wie das Weglesen dieser +Zeichen.  +  +Um einen sicheren und effektiven Netzbetrieb zu garantieren, sollten die Treiber +folgende Eigenschaften haben:  +  +     -  Die #ib#Stationsadresse#ie# ist im Treiber festgelegt, sie soll nicht ohne weiteres +        verändert werden können (Datenschutz).  +     -  Der Treiber reicht nur #ib#Paket#ie#e mit richtiger #ib#Zieladresse#ie#, keine #ib#Broad- oder +        Multicasts#ie# an die Netzsoftware weiter.  +     -  Der Treiber sendet nur #ib#Paket#ie#e mit richtiger #ib#Absenderadresse#ie# bzw. setzt die +        Absenderadresse selbst ein.  +     -  Die am Treiber eingestellte #ib#Adresse#ie# kann abgefragt werden, oder es wird, +        wenn ein Paket mit falscher #ib#Absenderadresse#ie# vom Rechner kommt, eine +        #ib#Fehlermeldung#ie# an den Rechner gegeben. Die Fehlermeldung muß durch das +        Netz-Hardware-Interface in den #on("b")##ib#report#ie##off("b")# eingetragen werden.  +     -  Falls Pakete mit #ib#Füllzeichen#ie# aufgefüllt werden müssen, sollten die Füll +        zeichen durch den Treiber generiert und beim Empfang wieder entfernt +        werden.  +     -  Falls mehrere Betriebsmodi möglich sind, so sollten sie softwaremäßig +        einstellbar sein.  +     -  Falls die Treiber über eine serielle #ib#Schnittstelle#ie# an den Rechner angeschlos +        sen werden, so sollte der Treiber konfigurierbar sein. In jedem Fall sollte die +        serielle Schnittstelle mit #ib#Flußkontrolle#ie# (#ib#RTS/CTS#ie#) implementiert werden.  +  +Zusätzlich ist ein Transparent-Modus als #ib#Netzmodus#ie# von Vorteil:  +  +     -  Der Modus (transparent) kann zu Testzwecken benutzt werden. Beispiels +        weise um auch mit Rechnern kommunizieren zu können, die über Netz +        erreichbar sind, aber kein EUMEL-Netz-#ib#Protokoll#ie# benutzen.  +  +        Modus n:  transparent.  +  +                  Ausgabeseitig: Das #ib#Paket#ie# wird unverändert ausgegeben. +                                 #ib#Adresse#ie#n usw. müssen schon im Paket vor +                                 handen sein. Es wird nicht mit #ib#Füllzeichen#ie# +                                 aufgefüllt.  +                  Eingabeseitig: Das Paket wird unverändert an die Netzsoft +                                 ware weitergegeben.  +  +#page#  +  +3.4.  Prozedurschnittstelle  +      des EUMEL-Netzes  +       +  +  +  +  +     #goalpage("3.4")#  +Im PACKET #on("b")##ib#net hardware interface#ie##off("b")# sind folgende Prozeduren untergebracht:  +  +  +  +      BOOL PROC #ib#blockin#ie#  +          (DATASPACE VAR ds, INT CONST seite, abstand, länge):  +  +           Versucht, #on("b")#länge#off("b")# Zeichen vom #ib#Kanal#ie# einzulesen. Liefert TRUE, wenn alle +           Zeichen eingelesen wurden, FALSE, wenn innerhalb einer bestimmten +           Zeit nicht alle #on("b")#länge#off("b")# Zeichen eingelesen werden konnten (z.B. weil der +           Kanal nicht mehr Zeichen anliefert). Die eingelesenen Zeichen werden im +           #ib#Datenraum#ie# #on("b")#ds#off("b")# in #ib#Seite#ie# #on("b")#seite#off("b")# ab #on("b")#abstand#off("b")# bis #on("b")#abstand#off("b")# + #on("b")#länge#off("b")# - 1 abge +           legt.  +  +               #ib#Fehlerfall#ie#:  +  +                     #on("b")#blockin Abbruch#off("b")#  +  +           Es werden weniger #ib#Zeichen#ie# innerhalb einer festgelegten Zeitspanne über +           den Kanal angeliefert, als mit #on("b")#länge#off("b")# gefordert.  +  +           Passiert z.B., wenn die Kabel während einer Netzübertragung unter +           brochen werden, oder wenn die Gegenstelle abgeschaltet wird. Das +           #ib#Telegramm#ie# wird vernichtet, die Prozedur liefert FALSE, es wird eine +           entsprechende Meldung im #on("b")##ib#report#ie##off("b")# erzeugt.  +  +      PROC #ib#blockout#ie#  +          (DATASPACE CONST ds, INT CONST seite, abstand, länge):  +  +          Der Inhalt von Seite #on("b")#seite#off("b")# des #ib#Datenraum#ie#s #on("b")#ds#off("b")# wird von #on("b")#abstand#off("b")# bis +          #on("b")#abstand#off("b")# + #on("b")#länge#off("b")# - 1 ausgegeben.  +#page#  +      PROC #ib#set net mode#ie# (INT CONST mode):  +  +          Es wird der #ib#Netzmodus#ie# #on("b")#mode#off("b")# eingestellt. Im Netz-Hardware-Interface +          müssen alle Initialisierungen und Einstellungen vorgenommen werden, +          damit die mit #on("b")#mode#off("b")# geforderte #ib#Netzhardware#ie# unterstützt wird. Diese +          Prozedur wird bei jedem #on("b")##ib#start#ie##off("b")#-Kommando in der Netztask aufgerufen. +          Kann als Initialisierungsprozedur für dieses PACKET verwendet werden. +          Übergibt den in der #ib#Datei#ie# #on("b")##ib#netz#ie##off("b")# für diesen #ib#Kanal#ie# verlangten Netzmodus an +          das Netz-Hardware-Interface. Nach Aufruf dieser Prozedur müssen die +          wertliefernden Prozeduren #on("b")##ib#net mode#ie#, #ib#mode text#ie#, #ib#data length#ie##off("b")# und #on("b")##ib#data +          length via node#ie##off("b")# korrekt initialisiert sein. Der Aufruf von #on("b")##ib#net addess#ie##off("b")# muß +          die korrekten (physikalischen) #ib#Adresse#ie# der #ib#Station#ie#en liefern.  +  +      TEXT PROC net address (INT CONST stationsnummer):  +  +          Liefert die (Hardware-) Netz-#ib#Adresse#ie#, über die der EUMEL-Rechner +          mit der Stationsnummer #on("b")##ib#stationsnummer#ie##off("b")# beim aktuell für diesen Kanal +          eingestellten #ib#Netzmodus#ie# erreichbar ist. Auf diese #ib#Adresse#ie# muß der Treiber +          des entsprechenden Rechners eingestellt sein. Auch die eigene Netz- +          Adresse muß mit der im Treiber eingestellten #ib#Adresse#ie# übereinstimmen. +          Insbesondere müssen alle Stationen, die auf dem Netz arbeiten, dieselbe +          Netz-Adresse für eine #ib#Stationsnummer#ie# errechnen.  +  +      TEXT PROC #ib#mode text#ie#:  +  +          Liefert den Text (Namen) des eingestellten #ib#Netzmodus#ie#. Wird in #on("b")##ib#net +          manager#ie##off("b")# benutzt, um den Netzmodus im #on("b")##ib#report#ie##off("b")# anzugeben.  +  +      TEXT PROC mode text (INT CONST mode):  +  +          Liefert den Text (Namen) zu dem #ib#Netzmodus#ie# #on("b")#mode#off("b")#.  +  +      INT PROC #ib#data length#ie# (INT CONST mode):  +  +          Liefert die #ib#Nutzdatenlänge#ie# (#ib#Länge#ie# der Nettodaten des Eumel- +          Telegramms) im Netz. Wird von #on("b")##ib#basic net#ie##off("b")# beim Neustart aufgerufen. Muß +          in einem Netz auf allen Stationen eines #ib#Strang#ie#s denselben Wert liefern.  +  +          Erlaubte Werte:  64, 128, 256 und 512.  +#page#  +      INT CONST #ib#data length via node#ie#:  +  +          Liefert die #ib#Nutzdatenlänge#ie# für Sendungen, die über #ib#Knoten#ie# gehen.  +          Muß auf allen Stationen des Netzes gleich sein.  +  +          Erlaubte Werte:  64, 128, 256 und 512.  +  +      PROC #ib#decode packet length#ie# (INT VAR value):  +  +          Die #ib#Länge#ie# eines Netztelegramms ist im #ib#Telegramm#ie# codiert enthalten. Mit +          dieser Prozedur wird aus dem Telegrammkopf die Telegrammlänge ermit +          telt:  +  +          Falls beim Aufruf dieser Prozedur in #on("b")#value#off("b")# der Wert des Feldes #on("b")#head#off("b")# aus +          der Struktur #on("b")#vorspann#off("b")#, die in #on("b")#ds#off("b")# per #on("b")##ib#transmit header#ie##off("b")# übergeben wurde, +          enthalten ist, so wird in #on("b")#value#off("b")# die Länge des EUMEL-Netztelegramms +          zurückgeliefert.  +  +      PROC #ib#flush buffers#ie#:  +  +          Liest den Eingabepuffer des #ib#Netzkanal#ie#s leer. Die eingelesenen Zeichen +          werden vernichtet. Wird nach Erkennen von #ib#Übertragungsfehler#ie#n aufge +          rufen.  +  +      TEXT PROC #ib#next packet start#ie#:  +  +          Liefert genau ein #ib#Zeichen#ie# (in der Regel das erste Zeichen des EUMEL- +          Netztelegramms). Wird von der Netzsoftware immer dann aufgerufen, +          wenn ein neues #ib#Paket#ie# erwartet wird.  +  +          Bedeutung des gelieferten Zeichens für die #ib#Netzsoftware#ie#:  +  +          #ib#STX#ie#:      korrekter #ib#Telegrammanfang#ie# (ist das erste Zeichen des +                    EUMEL-Netztelegramms). Der Rest des EUMEL-Netztele +                    gramms steht im Eingabepuffer, ist also über #ib#blockin#ie# lesbar. +                    Vorher wurden nur Zeichen eingelesen, die zum verwendeten +                    #ib#Netzprotokoll#ie# gehören (z.B. #ib#Ethernet#ie#-#ib#Adresse#ie#n, #ib#Füllzeichen#ie# +                    usw.).  +          niltext:  kein neues Telegramm da  +  +          jedes andere Zeichen:  +                    Fehler. Entweder wurden Störzeichen eingelesen oder es +                    gingen Zeichen verloren. #ib#Fehlerbehandlung#ie# erfolgt durch die +                    Netzsoftware.  +#page#  +      PROC #ib#transmit header#ie# (DATASPACE CONST ds):  +  +          Wird vor Ausgabe eines jeden #ib#Telegramm#ie#s aufgerufen. In dem #ib#Datenraum#ie# +          #on("b")#ds#off("b")# wird von der EUMEL-Netz-Software der #on("b")##ib#Vorspann#ie##off("b")# übergeben. Über +          den jeweiligs eingestellten #ib#Netzmodus#ie# kann für jede implementierte Netz +          art über eine #ib#Sprungleiste#ie# (#ib#SELECT#ie#) die Prozedur angesprungen werden, +          die den #ib#Header#ie# für den eingestellten Netzmodus erstellt und ausgibt. +          Struktur des von der EUMEL-Netz-Software benutzten Headers:  +  +              BOUND STRUCT  +              (INT  head,  +                    zwischenziel,  +                    zielrechner,  +                    quellrechner,  +                    strom,  +                    sequenz,  +                    seitennummer ) VAR vorspann.  +  +          Aus dem Inhalt des Feldes #on("b")#head#off("b")# kann mittels #on("b")##ib#decode packet length#ie##off("b")# die +          Gesamtlänge des EUMEL-Netztelegramms errechnet werden.  +  +      PROC #ib#transmit trailer#ie#:  +  +          Wird nach Ausgabe eines jeden Telegramms aufgerufen. Evtl. notwendige +          Nachspänne können ausgegeben werden. Die notwenigen Informationen +          wurden  in #on("b")##ib#transmit header#ie##off("b")# übergeben und müssen aufbewahrt werden, +          falls sie im Trailer mitgeliefert werden müssen. Kann auch dazu benutzt +          werden, den unter diesem Packet liegenden Schichten (#ib#SHard#ie# oder Hard +          ware) das Ende des Telegramms mitzuteilen. Notwendige #ib#Füllzeichen#ie# +          können in dieser Prozedur in das #ib#Paket#ie# eingebaut werden.  +  +      PROC #ib#reset box#ie# (INT CONST net mode):  +  +          Kann zur Initialisierung der #ib#Netzhardware#ie# benutzt werden. Wird von #on("b")##ib#basic +          net#ie##off("b")# beim jedem Neustart aufgerufen.  +  +     INT PROC #ib#max mode#ie#:  +  +          Liefert den Wert des größten erlaubten (implementierten) #ib#Netzmodus#ie#.  +  +     INT PROC #ib#net mode#ie#:  +  +          Liefert den eingestellten Netzmodus.  +#page#  +#pagenr ("%", 45)##setcount (1)##block##pageblock##count per page#  +#headeven#  +#center#EUMEL Netzbeschreibung  +#center#____________________________________________________________  +  +#end#  +#headodd#  +#center#Anhang  +#center#____________________________________________________________  +  +#end#  +#bottomeven#  +#center#____________________________________________________________  +Netz - % #right#GMD  +#end#  +#bottomodd#  +#center#____________________________________________________________  +GMD #right#Netz - %  +#end#  +#clear pos##lpos(1.0)##rpos(9.5)##goalpage("A")#  + +Anhang: Netz-Meldungen#goalpage("A.1")#  +  +Mit dem Kommando #on("b")##ib#list#ie# (/"net list")#off("b")# (siehe Teil 1) erhalten Sie eine temporäre #ib#Datei#ie# +auf den Bildschirm. Diese Datei könnte ungefähr so aussehen:  +  +____________________________________________________________________________  +    +   N e u e r   S t a r t 12:44      Stationsnummer : 38  +  01.06.87 12:55 net port 8:20:Nicht zustellbar. . Empfänger: "net dok". Quelle 34 Taskindex: 255  +  02.06.87 06:30 net port 8:1:wdh data. sqnr 7. Absender: "net dok". Ziel 34 Taskindex: 255  +  02.06.87 07:03 net port:20:Sequenzfehler: soll 13 ist 14. Empfänger: "POST". Quelle 33 Taskindex:  +  02.06.87 07:03 net port:blockin abbruch  +  02.06.87 07:03 net port:20:Sequenzreset von 13 auf 10. Empfänger: "POST". Quelle 33 Taskindex: 29  +  02.06.87 07:36 net port:Call gelöscht."net dok". Strom 1  +  02.06.87 07:43 net port 8:verbotene Route: 34  +  02.06.87 07:50 net port:Header inkorret eingelesen: %0 %2  +  02.06.87 07:50 net port:buffers flushed  +  02.06.87 07:52 net port:Weiterleitung nicht möglich für 34  +  02.06.87 07:53 net port 8:skipped0 6 G O 1 0 . 0 %13 %10 2 8 0 6   0 6 G O 1 0 . 0 %13 %10 2 8 0  +  02.06.87 08:14 net port 8:skipped%13 %10 S p e c .   R e c e i v e   E r r o r   C 2  +  02.06.87 08:21 net port:20:Reopen. Empfänger: "WÜFE". Quelle 40 Taskindex: 22  +  02.06.87 09:25 net port:1:etwas rueckgespult. Absender: "-". Ziel 33 Taskindex: 51  +  02.06.87 09:25 net port:1:wdh data. sqnr 20. Absender: "-". Ziel 33 Taskindex: 51  +  02.06.87 09:54 net port:20:Blocknummer falsch, neu: 192, alt : -1. Empfänger: "WÜFE". Quelle 44  +  02.06.87 10:12 net port:Daten ohne Eroeffnung von 40  Sequenznr 7  +  02.06.87 10:23 net port:Header inkorret eingelesen: O X 0 3 8 B O X 0 4 4 E U %2  +  02.06.87 10:23 net port:buffers flushed  +  02.06.87 10:49 net port:1:wdh open. Absender: "-". Ziel 33 Taskindex: 255  +  02.06.87 10:49 net port:2:wdh open. Absender: "net dok". Ziel 33 Taskindex: 255  +  02.06.87 10:53 net port:1:Sequenzfehler: soll 2 ist 3. Empfänger: "net dok". Quelle 33 Taskindex:  +  02.06.87 10:54 net port:1:Sequenzreset von 8 auf 5. Empfänger: "net dok". Quelle 33 Taskindex: 11  +  02.06.87 10:56 net port:2:etwas rueckgespult. Absender: "-". Ziel 33 Taskindex: 51  +  bekannte Stationen:  +  1(8,1) 2(8,2) 3(8,3) 4(8,4) 5(8,5) 6(8,6) 7(8,7) 8(8,8) 9(8,9) 10(8,10)  +  11(8,11) 12(8,12) 13(8,13) 14(8,14) 15(8,15) 16(8,16) 17(8,17) 18(8,18)  +  19(8,19) 20(8,20) 21(8,21) 22(8,22) 23(8,23) 24(8,24) 25(8,25) 26(8,26)  +  27(8,27) 28(8,28) 29(8,29) 30(8,30) 31(8,31) 32(8,32) 33(9,33) 34(8,34)  +  35(9,35) 36(9,36) 37(9,37) 39(9,39) 40(9,40) 41(9,41) 42(9,42) 43(9,43)  +  44(9,44) 45(9,45) 46(9,46) 47(9,47) 48(9,48)  +  --------  +  Eingestellte Netzmodi:  +  net port 8 haengt an Kanal 8, Modus: (1)  EUMEL-Netz            64 Byte  +  net port haengt an Kanal 9, MODUS: (11) ETHERNET via V.24     512 Byte  +  +  Nutzdatenlänge 512 Byte  +  Nutzdatenlänge bei indirekter Verbindung: 64 Byte  +  ********  +  Netz-Software vom  23.05.87  +  Rechner 38  um 11:11  +  net port 8  +  +  Strom 1 (sqnr7/8) sendet an 34 . Absender ist "net dok".  +  net port  +  +  Strom 1 (sqnr45/45) empfaengt von 40 . Empfaenger ist "PUBLIC".  +  +____________________________________________________________________________  +#page#  +Die Datei enthält den aktuellen #on("b")##ib#report#ie##off("b")#, in dem #ib#Fehlermeldung#ie#en der einzelnen Tasks +gesammelt werden. Außerdem wird der Zustand aller Verbindungen (Ströme) von allen +#on("b")##ib#net port#ie##off("b")#'s angezeigt. Im #on("b")#report#off("b")#-Teil kann man drei Informationsblöcke unterscheiden:  +  +a) den Block mit den Fehlermeldungen. Es werden jeweils Datum, Uhrzeit, der Name +   des betroffenen #on("b")#net port#off("b")# und, wenn notwendig, die #ib#Stromnummer#ie# angegeben. +   Darauf folgt der Meldungstext, der auch Informationen über Absender und Emp +   fänger enthalten kann.  +  +   <Datum> <Zeit> <Name der #ib#Kanaltask#ie#> : [<#ib#Stromnummer#ie#> : ] <Meldung>  +  +  +b) den Block mit der Liste der bekannten #ib#Station#ie#en. Ein Eintrag in dieser Liste ent +   hält jeweils die Stationsnummer der bekannten Station und in Klammern dahin +   ter die Nummer des Kanals auf diesem Rechner, über den die Station erreichbar +   ist und die Nummer der nächsten #ib#Zwischenstation#ie#.  +  +   <Zielstation> (<Kanalnr>,<Zwischenstation>)  +  +   Bei direkt erreichbaren Stationen ist Zwischenstation gleich #ib#Zielstation#ie#.  +  +   Hinweis: Auch #ib#gesperrt#ie#e Stationen erscheinen in dieser Liste.  +  +  +c) den Block, der Auskunft über die Netzinstallation gibt. Es werden für jeden Netz +   kanal die eingestellten Netzmodi angegeben. Des weiteren werden die beiden +   Größen #on("b")##ib#data length#ie##off("b")# (#ib#Nutzdatenlänge#ie#) und #on("b")##ib#data length via node#ie##off("b")# (Nutzdatenlänge bei +   indirekter Verbindung) angegeben. Zusätzlich erscheinen noch die #ib#Netzversion#ie# und +   die genaue Uhrzeit, zu der dieser #on("b")#report#off("b")# erstellt wurde.  +  +#page#  +Für jeden #on("b")##ib#net port#ie##off("b")# wird pro aktivem #ib#Strom#ie# folgende Meldung generiert:  +  +Strom <Stromnr> (sqnr<akt Seqnr>/<max Seqnr>) <Zustand> <Partner>  +  +  +<Stromnr>        #ib#Stromnummer#ie#  +  +<akt Seqnr>      #ib#Sequenznummer#ie# des gerade bearbeiteten #ib#Telegramm#ie#s  +  +<max Seqnr>      Bei #ib#Sendeströme#ie#n die Nummer der letzten zu übertragenden +                 #ib#Sequenz#ie#, bei Empfangsströmen in der Regel die Nummer der +                 letzten Sequenz der gerade übertragenen #ib#Datenraumseite#ie#.  +  +<#ib#Zustand#ie#>        Hier wird die Aktion (senden, empfangen usw.) und die Partner +                 station angegeben.  +  +<#ib#Partner#ie#>        Der Name der Task mit der kommuniziert wird.  +  +  +Die Meldungen, die in der #ib#Datei#ie# #on("b")##ib#report#ie##off("b")# protokolliert werden, kann man in verschiedene +Gruppen einordnen. Die eine Gruppe beschreibt Störungen durch #ib#Zeichenverluste#ie# +oder verfälschungen, eine andere Gruppe protokolliert besondere Situationen, bei +spielsweise den Abbruch von #ib#Übertragung#ie#en, und die letzte Gruppe befasst sich mit +#ib#Fehlermeldung#ie#en, die ein Eingreifen von aussen notwendig machen. Je nachdem, ob +die Station, auf der die Meldung protokolliert wird, Empfänger oder Absender ist, wird +bei den Meldungen #ib#Stationsnummer#ie# und Taskname des Kommunikationspartners mit +angegeben.  +  +Zur ersten Gruppe gehören:  +  +#ib(4)##ib#skipped#ie##ie(4)#  +               'skipped' oder skipped mit einem Zusatztext erscheint, wenn Zei +               chen eingelesen wurden, die zu keinem gültigen #ib#Telegramm#ie# ge +               hören. Dies kann passieren, wenn auf der Leitung zwischen +               Rechner und Box #ib#Zeichen#ie# verlorengegangen sind. Auch nach dem +               Einschalten oder nach einem Reset auf Box oder Rechner kann +               diese Meldung kommen. Mindestens ein Teil der eingelesenen +               Daten wird mit ausgegeben, wobei Steuerzeichen durch % und den +               Code des Steuerzeichens dargestellt werden. Die einzelnen Zeichen +               werden durch ein Blank voneinander getrennt.  +#page#  +#ib(4)##ib#Sequenzfehler#ie##ie(4)#  +               Die #ib#Sequenznummer#ie# ist zu groß, es fehlen also Telegramme. Die +               Gegenstation wird aufgefordert, ab einem früheren Telegramm zu +               wiederholen.  +  +#ib(4)#wdh data#ie(4)#  +               Das letzte Telegramm wird erneut geschickt. Passiert, wenn die +               #ib#Quittung#ie# für dieses Telegramm nach einer bestimmten Zeit nicht +               angekommen ist.  +  +#ib(4)##ib#Sequenzreset#ie##ie(4)#  +               Die #ib#Sequenznummer#ie# des empfangenen Telegramms ist kleiner als +               die Sequenznummer des vorher empfangenen Telegramms. Die +               Verbindung wird bei der zuletzt empfangenen Sequenznummer +               fortgesetzt.  +  +#ib(4)#Blocknummer falsch#ie(4)#  +               Die #ib#Seitennummer#ie# in dem #ib#Telegramm#ie# ist falsch.  +  +#ib(4)#etwas rueckgespult#ie(4)#  +               Auf Anforderung der Gegenseite werden die letzten drei #ib#Datenraum +               seite#ie#n erneut übertragen.  +  +#ib(4)#Daten ohne Eroeffnung#ie(4)#  +               Es werden Telegramme mit einer #ib#Stromnummer#ie# empfangen, zu der +               vorher kein OPEN-Telegramm empfangen wurde. In diesem Fall +               wird die Gegenstation aufgefordert, die #ib#Übertragung#ie# von vorn zu +               beginnen. Diese Meldung kann auch kommen, wenn das Netz neu +               gestartet wurde.  +  +#ib(4)#wdh open#ie(4)#  +               Die Übertragung wird mit dem #ib#OPEN#ie#-Telegramm von vorn begon +               nen. Passiert auf Aufforderung durch die Gegenstation oder wenn +               das erste OPEN-Telegramm nicht quittiert wurde.  +  +#ib(4)##ib#buffers flushed#ie##ie(4)#  +               Alle bereits eingelesenen, aber noch nicht bearbeiteten Zeichen +               wurden gelöscht (der #ib#Eingabepuffer#ie# wurde komplett gelöscht). Verur +               sacht durch schwere Störungen (#ib#Zeichenverluste#ie# oder -verfäl +               schungen).  +#page#  +#ib(4)#blockin abbruch#ie(4)#  +               Es wurden nicht alle Zeichen eines Telegramms innerhalb eines +               bestimmten Zeitraums angeliefert.  +  +#ib(4)#Header inkorrekt eingelesen#ie(4)#  +               Es wurde ein Fehler in dem Teil des Netztelegramms gefunden, der +               nicht zum EUMEL-Netz gehört.  +  +#ib(4)#Strom falsch in Quittung#ie(4)#:  +               In der #ib#Quittung#ie# wurde eine nicht zulässige #ib#Stromnummer#ie# festge +               stellt. Zulässig sind Stromnummern zwischen 1 und 20.  +  +#ib(4)#Neustart#ie(4)#  +               Die Gegenstation hat die #ib#Verbindung#ie# von vorne begonnen.  +  +#ib(4)#Falsche Seitennummer#ie(4)#  +               Die #ib#Seitennummer#ie# in dem empfangenen Telegramm ist falsch. +               Einige Telegramme werden wiederholt.  +  +#ib(4)#Absteigende Seitennummern#ie(4)#  +               Die Seitennummer in dem empfangenen Telegramm ist kleiner als +               die Seitennummer im vorigen #ib#Telegramm#ie#. Es müssen einige Tele +               gramme wiederholt werden.  +  +  +Die folgenden Meldungen beschreiben Situationen, die nicht durch #ib#Zeichenverluste#ie# +entstehen, mit denen die #ib#Netzsoftware#ie# selbst fertig wird:  +  +  +#ib(4)#Sendung von Gegenstelle gelöscht#ie(4)#  +               Die Verbindung wurde von der Gegenstelle abgebrochen.  +  +#ib(4)#Empfangseintrag freigegeben#ie(4)#  +               Die Verbindung wurde von der empfangenden #ib#Station#ie# gelöscht, weil +               seit dem Eintreffen des letzten Telegramms zuviel Zeit vergangen ist +               (#ib#Timeout#ie#).  +  +#ib(4)#Irrläufer#ie(4)#  +               Eine #ib#Intertaskkommunikation#ie# innerhalb der eigenen Station wurde +               fälschlicherweise über den #on("b")##ib#Collector#ie##off("b")# abgewickelt. Dieser Vorgang +               wird abgebrochen.  +#page#  +#ib(4)#Call-Löschung vorgemerkt#ie(4)#  +               Sobald der Call abgewickelt ist, wird diese Verbindung gelöscht. +               Beispielsweise führt ein vom Benutzer abgebrochenes #on("b")##ib#name#ie##off("b")# zu +               dieser Meldung.  +  +#ib(4)#Call gelöscht#ie(4)#  +               Die #ib#Verbindung#ie# wurde auf Anforderung durch den Auftraggeber +               gelöscht.  +  +#ib(4)#Quellrechner#ie(4)#  +               Als #ib#Quellrechnernummer#ie# wurde ein unzulässiger Wert festgestellt. +               Zulässig sind Zahlen zwischen 1 und 127.  +  +#ib(4)#Nicht zustellbar#ie(4)#  +               Innerhalb eines bestimmten Zeitraums war die #ib#Zieltask#ie# nicht emp +               fangsbereit. Die Verbindung wird abgebrochen.  +  +Bei diesen Meldungen sollten die #ib#Routenanweisungen#ie# überprüft werden:  +  +#ib(4)#Verbotene Route bei Quittung#ie(4)#  +               Die #ib#Quittung#ie# kommt auf einer nicht erlaubten #ib#Route#ie# an. Dies kann +               bei #ib#Vermaschung#ie# passieren, oder aber, wenn eine Station versucht, +               sich für eine andere Station auszugeben.  +  +#ib(4)#Verbotene Route#ie(4)#  +               Die danach bezeichnete Station versucht, auf einer anderen Route +               mit diesem Rechner zu kommunizieren, als auf der Route, die für +               diesen Rechner in der Datei #on("b")##ib#netz#ie##off("b")# festgelegt wurde.  +  +               Abhilfe:  +               #ib#Routentabellen#ie# der beiden (oder, falls die Meldung auf einer +               #ib#Knotenstation#ie# erscheint, auf allen beteiligten) Stationen abgleichen.  +  +#ib(4)#Weiterleitung nicht möglich#ie(4)#  +               Die #ib#Routeninformationen#ie# auf dem #ib#Knotenrechner#ie#, wo diese Meldung +               erscheint, und der sendenden #ib#Station#ie# stimmen nicht überein. Die +               angegebene Station ist von dieser Station aus nicht erreichbar.  +  +               Abhilfe:  +               #ib#Routentabellen#ie# der Stationen überprüfen.  +  +#ib(4)#Fremdzugriff#ie(4)#  +               Eine #ib#gesperrt#ie#e Station hat versucht, auf diesen Rechner mit #ib#Sende +               codes#ie# > 6 zuzugreifen.  +  +  +Folgende Meldungen betreffen '#ib#harte Fehler#ie#'. Diese Fehler werden von der Netzsoft +ware nicht abgefangen. In jedem Fall muß das Netz nach einer solchen #ib#Fehler +meldung#ie# neu gestartet werden.  +  +#ib(4)#++++++#ie(4)#  +               Meldungen dieser Form sind 'harte' Fehler. Der aufgetretene Fehler  +               wird mit angegeben. Das Netz muß neu gestartet werden, da die +               Task, in welcher der Fehler aufgetreten ist, gelöscht wird.  +  +#ib(4)#Verbindungsengpaß#ie(4)#  +               Es sind mehr Verbindungen festgestellt worden, als zulässig sind. +               Nach dieser Meldung wurde der entsprechende Netport gelöscht.  +  +  +Literaturverzeichnis  +  +  +#goalpage("A.2")#  +  +#clear pos#  +#lpos(1.0)##lpos(2.5)#  +#table#  +[1]   EUMEL-Systemhandbuch, Teil 5, Intertaskkommunikation  +      GMD St. Augustin, 1986  +[2]   EUMEL-Systemhandbuch, Teil 2, Hardware und ihre Steuerung  +[3]   EUMEL-Systemhandbuch, Teil 8, Spooler  +[4]   EUMEL-Netz Installationsanweisung  +      GMD St. Augustin, 1987  +[5]   EUMEL-Systemhandbuch, Teil 4, Blockorientierte Ein/Ausgabe  +[6]   EUMEL-Quellcode, Packet #on("b")#tasks#off("b")#  +      GMD St. Augustin, 1986  +[7]   EUMEL-Portierungshandbuch 8086, Version 8  +      GMD St. Augustin, 1987  +  +#table end# + + diff --git a/system/net/1.8.7/doc/netzhandbuch.anhang b/system/net/1.8.7/doc/netzhandbuch.anhang new file mode 100644 index 0000000..17d1ece --- /dev/null +++ b/system/net/1.8.7/doc/netzhandbuch.anhang @@ -0,0 +1,58 @@ +#pagenr ("%", 51)##setcount##block##pageblock##count per page#  +#headeven#  +#center#EUMEL Netzbeschreibung  +#center#____________________________________________________________  +  +#end#  +#headodd#  +#center#Anhang  +#center#____________________________________________________________  +  +#end#  +#bottomeven#  +#center#____________________________________________________________  +Netz - % #right#GMD  +#end#  +#bottomodd#  +#center#____________________________________________________________  +GMD #right#Netz - %  +#end#  +#clear pos##lpos(0.0)##rpos(11.0)##fillchar(".")#  +Anhang: Netz-Fehlermeldungen  +  +#table#  +++++++   50  +Absteigende Seitennummern   48  +blockin abbruch   48  +Blocknummer falsch   47  +buffers flushed   47  +Call gelöscht   49  +Call-Löschung vorgemerkt   49  +Collectortask fehlt   8, 18  +Daten ohne Eroeffnung   47  +Empfangseintrag freigegeben   48  +etwas rueckgespult   47  +Falsche Seitennummer   48  +Fremdzugriff   50  +Header inkorrekt eingelesen   48  +Irrläufer   48  +kein Zugriff auf Station   14  +Neustart   48  +Nicht zustellbar   49  +Quellrechner   49  +Sendung von Gegenstelle gelöscht   48  +Sequenzfehler   47  +Sequenzreset   47  +skipped   46  +Station x antwortet nicht   8, 11, 16  +Station x gibt es nicht   9, 11, 13  +Strom falsch in Quittung   48  +Task "..." gibt es nicht   8  +Verbindungsengpaß   50  +Verbotene Route   49  +Verbotene Route bei Quittung   49  +wdh data   47  +wdh open   47  +Weiterleitung nicht möglich   49  +#table end# + diff --git a/system/net/1.8.7/doc/netzhandbuch.index b/system/net/1.8.7/doc/netzhandbuch.index new file mode 100644 index 0000000..01d8a0f --- /dev/null +++ b/system/net/1.8.7/doc/netzhandbuch.index @@ -0,0 +1,259 @@ +#pagenr ("%", 52)##setcount (1)##block##pageblock##count per page#  +#headeven#  +#center#EUMEL Netzbeschreibung  +#center#____________________________________________________________  +  +#end#  +#headodd#  +#center#Anhang  +#center#____________________________________________________________  +  +#end#  +#bottomeven#  +#center#____________________________________________________________  +Netz - % #right#GMD  +#end#  +#bottomodd#  +#center#____________________________________________________________  +GMD #right#Netz - %  +#end#  +#clear pos##lpos(0.0)##rpos(11.0)##fillchar(".")#  +Anhang: Index  +  +#table#  +/   8, 9, 24  +Absenderadresse   39  +Absenderstation   28, 32  +Adresse   29, 37, 39, 41, 42  +aktiviere netz   14, 15, 18  +basic net   41, 43  +Baud   6, 18, 25  +blockin   23, 36, 40, 42  +blockout   23, 36, 40  +Broad- oder Multicasts   38  +buffers flushed   47  +CASE   37  +CLOSE   27  +collected destination   22, 24  +Collector   22, 24, 32, 48  +Collectortask   8, 18, 22  +configurate   6  +continue   7, 21  +CRC-Code   26  +DATA   27, 29, 30  +data length   23, 36, 41, 45  +data length via node   23, 36, 41, 42, 45  +Datei   2, 5, 7, 12, 13, 14, 18, 20, 24, 31, 37, 41, 44, 46  +Datenbox   2, 6, 33  +Datenraum   13, 15, 21, 23, 24, 27, 28, 29, 31, 36, 40, 43  +Datenraumseite   23, 46, 47  +decode packet length   42, 43  +define collector   22, 24  +definere netz   15  +DEFINES   37  +define station   5, 22  +definiere netz   14  +Dreher   16  +Durchsatz   3  +Eingabeprozeduren   21  +Eingabepuffer   47  +Empfangspuffer   15  +Empfangsströme   13, 15  +endquelle   28  +endziel   28  +erase   13, 19  +erlaube   14  +Ethernet   33, 34, 36, 37, 42  +EUMEL0   21, 22, 24  +EUMEL-Datenboxen-Netz   33  +EUMEL-Netz-Software   35  +exists   11  +Fehler   8, 16, 17, 18  +Fehlerbehandlung   31, 36, 42  +Fehlerfälle   8  +Fehlerfall   11, 40  +Fehlermeldung   13, 15, 20, 26, 39, 45, 46, 50  +Fehlersituationen   12  +Fehlersuche   16  +Fenstertechnik   31  +fetch   10, 18  +flush buffers   36, 42  +Flußkontrolle   7, 15, 27, 39  +free global manager   10, 19, 31  +Füllzeichen   37, 39, 42, 43  +gesperrt   13, 14, 45, 50  +global manager   19, 31  +harte Fehler   50  +HDLC   31  +Header   43  +Höhere Ebenen   31  +inchar   21  +incharety   23  +Installation   2  +Installationsanleitung   2  +Intertaskkommunikation   48  +I/O Control   36  +I/O-Kanal   33  +Kanal   3, 6, 7, 12, 14, 15, 20, 21, 23, 24, 34, 37, 40, 41  +Kanalnummer   14  +Kanaltask   45  +Knoten   3, 4, 17, 20, 23, 36, 42  +Knotenkonzept   3, 34  +Knotenrechner   34, 36, 49  +Knotenstation   13, 14, 20, 49  +Kommunikation   17  +Kommunikationindirekte   23  +konfigurieren   6  +Länge   29, 41, 42  +Längenangabe   26  +list   10, 12, 17, 44  +listoption   12, 14, 15  +Löschversuche   13  +Manager   10, 19  +Masseschluß   16  +max mode   43  +mode text   41  +Nachbarn   4, 28  +Nachbarstation   24, 28  +name   11, 24, 49  +net   7, 12, 13  +net addess   41  +net hardware interface   34, 40  +net install   7  +net list   12, 15  +net manager   41  +net mode   41, 43  +net port   7, 8, 12, 13, 18, 45, 46  +net timer   14  +netz   7, 14, 15, 20, 37, 41, 49  +Netzbox   3, 6, 20, 33, 38  +Netzdefinition   14  +Netzebene   26  +Netzempfangstask   30  +Netzhardware   2, 17, 21, 24, 33, 34, 36, 41, 43  +Netz-Hardware-Interface   34  +Netzinstallation   17  +Netzkanal   13, 14, 42  +Netzknoten   3  +Netzkonfiguration   7, 20  +Netzmodus   34, 37, 39, 41, 43  +Netzprotokoll   42  +Netzsoftware   2, 3, 18, 20, 34, 36, 38, 42, 48  +Netzstrang   4, 17, 23  +Netztask   15, 16, 21, 24  +Netztelegramm   34  +Netztreiber   38  +Netzübertragungen   12  +Netzversion   2, 45  +next packet start   36, 42  +niltext   11, 36  +Nutzdaten   23  +Nutzdatenlänge   17, 23, 29, 36, 41, 42, 45  +Nutzinformation   29  +nutzlaenge   29  +OPEN   27, 28, 30, 47  +Paket   23, 34, 37, 38, 39, 42, 43  +Pakete, Aufbau der   34  +Partner   46  +Paßwort   19  +Pin-Belegung   6  +port intern   13, 15, 24  +Printerserver   20  +Protokoll   6, 13, 24, 39  +Protokollebenen   25  +Prüfsummen   18  +Quelle   23, 26, 28  +Quellrechnernummer   49  +Quellstationsnummer   20  +quelltask   21, 24, 28  +Querarchivierungen   10  +QUIT   27, 28, 30  +Quittung   30, 31, 47, 48, 49  +Rechnerkopplung   3  +Rendezvouskonzept   21, 31  +report   8, 12, 18, 39, 40, 41, 45, 46  +reserve   10  +RESET   17  +reset box   43  +Route   13, 15, 17, 20, 49  +routen   14  +Routenanweisungen   49  +routen aufbauen   13, 14, 15  +Routeninformationen   20, 49  +Routentabelle   9, 13  +Routentabellen   24, 49  +router   13  +RS422   25  +RTS/CTS   6, 25, 39  +Rückmeldeparameter   21  +run   13  +save   10, 19  +Schnittstelle   3, 15, 18, 20, 25, 33, 37, 38, 39  +SDLC   25, 26  +seite   28, 29, 40  +Seiten   27  +Seitengrenze   23  +Seitennummer   47, 48  +SELECT   34, 37, 43  +send   21, 22, 24, 27, 28, 30, 32  +Sendecode   24  +Sendecodes   50  +Sendeströme   13, 46  +Sendungskonzept   2  +sequenz   28, 29, 46  +Sequenzfehler   47  +Sequenznummer   46, 47  +Sequenzreset   47  +set net mode   41  +SHard   38, 43  +Sicherheitskonzept   19  +Sicherheitsprobleme   19  +skipped   46  +sperre   14  +Spoolmanager   5  +Sprungleiste   43  +Sprungleisten   34, 37  +start   5, 13, 16, 18, 41  +starte kanal   14, 15  +station   2, 5, 8, 10, 12, 13, 16, 19, 20, 22, 24, 26, 31, 32, 36, 41, 45, 48, 49  +Stationen, sicherheitsrelevante   20  +Stationsadresse   38  +Stationsnummer   5, 10, 16, 22, 24, 26, 32, 37, 41, 46  +Stationsnummer maximale   14  +Strang   3, 17, 20, 36, 41  +Stream I/O   23, 38  +strom   28, 30, 46  +Stromnummer   13, 28, 30, 45, 46, 47, 48  +STX   26, 36, 42  +Task-Id   5, 22, 24, 28, 30  +Telegramm   20, 23, 26, 27, 28, 31, 36, 37, 40, 42, 43, 46, 47, 48  +Telegrammanfang   42  +Telegrammformat   26  +Telegrammfreigabe   36  +Textdatei   31  +Timeout   31, 36, 48  +transmit header   36, 42, 43  +transmit trailer   36, 43  +Treiber   33  +Übertragung   26, 30, 46, 47  +Übertragungsfehler   42  +Übertragungsgeschwindigkeit   34, 38  +Übertragungsweg   23  +V24   3, 4, 15, 17, 18, 20, 25, 33, 34, 38  +Verbindung   3, 6, 16, 18, 27, 28, 34, 48, 49  +Vermaschung   4, 49  +Vermittlungsebene   24, 30  +Vorspann   36, 43  +wait   19, 21, 24, 27, 32  +Worker   5  +Zeichen   36, 38, 40, 42, 46  +Zeichenverluste   46, 47, 48  +Zeitüberwachung   26, 29  +ziel   28  +Zieladresse   38  +Zielstation   4, 8, 24, 28, 30, 36, 45  +Zieltask   21, 22, 24, 28, 32, 49  +Zustand   46  +Zwischenstation   45  +#table end# + diff --git a/system/net/1.8.7/source-disk b/system/net/1.8.7/source-disk new file mode 100644 index 0000000..5a39f6c --- /dev/null +++ b/system/net/1.8.7/source-disk @@ -0,0 +1 @@ +grundpaket/11_austausch.img diff --git a/system/net/1.8.7/src/basic net b/system/net/1.8.7/src/basic net new file mode 100644 index 0000000..c5e9278 --- /dev/null +++ b/system/net/1.8.7/src/basic net @@ -0,0 +1,1148 @@ +PACKET basic net DEFINES                          (* D. Heinrichs *) +                          (* Version  10 (!) *)   (* 18.02.87     *) +  nam,                                            (* 03.06.87     *) +  max verbindungsnummer,                          (*              *) +  neuer start, +  neue routen, +  packet eingang, +  neue sendung, +  zeitueberwachung, +  verbindung, +  loesche verbindung: + +TEXT PROC nam (TASK CONST t): +  IF t = collector THEN name (t) +  ELIF station (t) <> station (myself)  +  THEN "** fremd "+text(station(t))+" **" +  ELSE name (t) +  FI +END PROC nam; + +INT PROC tasknr (TASK CONST t): +  IF t = collector THEN maxtasks +  ELSE index (t) +  FI +END PROC tasknr; + +LET +    maxtasks = 127, +    maxstat = 127, +    max strom = 20, +    max strom 1 = 21, +    stx = ""2"", +    code stx = 2,  +    error nak = 2, +    seiten groesse = 512, +    dr verwaltungslaenge = 8, +    dr verwaltungslaenge2=10, +    openlaenge = 24, +    vorspannlaenge = 14,  +    ack laenge = 12, +    min data length = 64, +    (* Codes der Verbindungsebene *)  +  +    task id code = 6,  +    name code = 7, +    task info code = 8,  +    routen liefern code = 9,  + +    (* Typen von Kommunikationsströmen *) + +    send wait = 0, +    zustellung = 1, +    call pingpong = 2, +    call im wait = 3, +    call im abbruch = 4, +    call in zustellung = 5, + +    (*quittungscodes*) + +    ok = 0, +    von vorne = 1, +    wiederhole = 2, +    loesche = 3, +    beende = 4; + +LET STEUER = +      STRUCT (  +      INT  head,  +           zwischenziel, +           zielrechner,  +           quellrechner, +           strom, +           sequenz, +           seitennummer, +      TASK quelle,ziel, +      INT  sende code); +  +BOUND STEUER VAR open block; + +BOUND STRUCT (STEUER steuer, INT typ, maxseq) VAR info block;  +  +BOUND STRUCT ( +      INT  head,  +           zwischenziel, +           zielrechner,  +           quellrechner, +           strom, +           sequenz, +           seitennummer) VAR vorspann ; +  +LET ACK = STRUCT (  +      INT  head,  +           zwischenziel, +           zielrechner,  +           quellrechner, +           strom,  +           code); +BOUND ACK VAR ack packet ;  +BOUND ACK VAR transmitted ack packet; + +BOUND STRUCT (ROW maxstat INT port,  +              ROW maxstat INT zwischen)  VAR route; +  +INT CONST max verbindungsnummer := max strom; +INT VAR codet,net mode, nutzlaenge := data length, +        data len via node := data length via node; + +TEXT VAR buffer first; +  +DATASPACE VAR work space := nilspace; +DATASPACE VAR transmitted ack space := nilspace; +  +  +INT VAR pakete pro seite, +        pakete pro seite minus 1, +        packets per page via node, +        packets per page via node minus 1, +        datenpacketlaenge via node, +        datenpacketlaenge ; +  +INT VAR strom;  +INT VAR last data := -1; +INT VAR   own:=station (myself) , +          quit max := 3, +          quit zaehler := 3, +          own256 := 256*own; +INT CONST stx open := code stx+256*openlaenge, +          stx quit := code stx+256*acklaenge; + +  STEUER VAR opti;  +  ROW maxstrom1 STEUER VAR verbindungen;  +  ROW maxstrom1 DATASPACE VAR netz dr;  +  ROW maxstrom1 INT VAR zeit, typ, open try; +  FOR strom FROM 1 UPTO maxstrom1 REP vdr := nilspace; forget (vdr) PER; +  ROW maxstrom INT VAR dr page ; +  ROW maxtasks INT VAR alter call; + +.vx : verbindungen (strom).  +  +vdr: netz dr (strom).  + + via node: +    vx.zielrechner <= 0 OR vx.quellrechner <= 0 OR +    transmit via node  OR receive via node. + + transmit via node: +    route.zwischen (vx.zielrechner) <> vx.zielrechner AND vx.zielrechner <> own. + + receive via node: +    route.zwischen (vx.quellrechner) <> vx.quellrechner AND vx.quellrechner <> own. + +falsche stromnummer: strom < 1 OR strom > maxstrom. + +zielrechner ok: vorspann.zielrechner > 0 AND vorspann.zielrechner <= maxstat. + +quellrechner ok: vorspann.quellrechner > 0 +                 AND vorspann.quellrechner <= maxstat. + +call aufruf: typ(strom) >= call pingpong. + +alles raus: vx.seitennummer = -1 AND letztes packet der seite .  + +letztes packet der seite : +(vx.sequenz AND packets per page minus 1) = packets per page minus 1. + +neue verbindung: code t = open laenge. + +PROC neue routen: +  route := old ("port intern"); +END PROC neue routen; + +PROC neuer start (INT CONST empfangsstroeme, mode): +  net mode := mode; +  strom := 1; +  neue routen; +  transmitted ack space := nilspace; +  workspace := nilspace; +  open block := workspace;  +  info block := workspace; +  nutzlaenge := data length; +  data len via node := data length via node; +  pakete pro seite:= seitengroesse DIV nutzlaenge; +  pakete pro seite minus 1 := pakete pro seite -1; +  packets per page via node := seitengroesse DIV data len via node; +  packets per page via node minus 1 := packets per page via node - 1; +  datenpacketlaenge := vorspannlaenge + nutzlaenge; +  datenpacketlaenge via node := vorspannlaenge + data len via node; +  vorspann := workspace;  +  ack packet := workspace; +  transmitted ack packet := transmitted ack space; +  FOR strom FROM 1 UPTO maxstrom1 REP  +  vx.strom := 0;  forget (vdr) +  PER;  +  INT VAR i; +  FOR i FROM 1 UPTO maxtasks REP alter call (i) := 0 PER; +  quitmax := empfangsstroeme; +  own:=station (myself); +  quit zaehler := quit max; +  own256 := 256*own;  +  reset box (net mode); +  buffer first := ""; +  flush buffers; +  INT VAR err; +  fehlermeldung ruecksetzen. + + fehlermeldung ruecksetzen: +  control (12,0,0,err). + +END PROC neuer start; + +DATASPACE PROC verbindung (INT CONST nr): +  INT VAR memory := strom; +  strom := nr; +  infoblock.steuer := verbindungen (nr); +  infoblock.typ := typ (nr); +  infoblock.maxseq := dspages (netzdr(nr)) * packets per page; +  strom := memory; +  workspace +END PROC verbindung; + +PROC neue sendung (TASK CONST q,z, INT CONST cod,z stat, DATASPACE CONST dr): + +  naechste verbindung vorbereiten; +  forget (vdr); vdr := dr; +  sendung starten (q, z, z stat, cod) +END PROC neue sendung;  + +PROC zeitueberwachung +     (INT VAR snr, TASK VAR  q, z, INT VAR ant,DATASPACE VAR  dr): +  snr INCR 1; +  FOR strom FROM snr UPTO maxstrom REP zeitkontrolle PER; +  snr := 0.  + +zeitkontrolle:  +  IF vx.strom <> 0 AND zeit(strom) > 0 +  THEN  +    zeit(strom) DECR 1;  +    IF sendung noch nicht zugestellt +    THEN  +      IF zeit(strom) = 0 +      THEN +         empfangsreport ("Nicht zustellbar. "); +         loesche verbindung (strom) +      ELSE +         snr := strom; +         q := vx.quelle; +         z := vx.ziel; +         ant := vx.sendecode; +         dr := vdr; +         LEAVE zeitueberwachung +      FI +    ELIF zeit(strom) = 0 +    THEN wiederholen +    FI  +  FI.  +  +sendung noch nicht zugestellt: +  typ (strom) = zustellung. + +wiederholen:  +  IF sendeeintrag  +  THEN  +    sendung wiederholen +  ELSE +    empfangseintrag freigeben +  FI.  +  +sendeeintrag : vx.quellrechner = own .  +  +sendung wiederholen: +  IF wiederholung noch sinnvoll  +  THEN +    IF frisch  +    THEN  +      time out bei open +    ELSE  +      datenteil wiederholen  +    FI +  ELSE +    sendung loeschen +  FI. + +wiederholung noch sinnvoll: +  task noch da AND bei call noch im call. + +task noch da: vx.quelle = collector OR exists (vx.quelle). + +bei call noch im call:  +  IF call aufruf +  THEN +    callee (vx.quelle) = vx.ziel +  ELSE +    TRUE +  FI. + +frisch: vx.sequenz = -1.  +  +time out bei open: +  IF vx.sendecode > -4 OR opentry (strom) > 0 +  THEN +    open wiederholen ; +    opentry (strom) DECR 1 +  ELSE +    nak an quelle senden +  FI. + +nak an quelle senden: +  dr := nilspace; +  BOUND TEXT VAR erm := dr; +  erm := "Station "+text(vx.zielrechner)+" antwortet nicht"; +  snr := strom; +  q := vx.ziel; +  z := vx.quelle; +  ant := error nak; +  sendung loeschen; +  LEAVE zeitueberwachung . + +open wiederholen:  +  sendereport ("wdh open");  +  IF opentry (strom) > 0 THEN zeit(strom) := 4 ELSE zeit(strom) := 40 FI; +  openblock := vx;  +  openblock.head := stx open;  +  ab die post.  +  +datenteil wiederholen:  +  sendereport ("wdh data. sqnr "+text (vx.sequenz)); +  senden . + +empfangseintrag freigeben: +  IF antwort auf call  +  THEN +    weiter warten +  ELSE +    empfangsreport ("Empfangseintrag freigegeben"); +    loesche verbindung (strom) +  FI. +antwort auf call: callee (vx.ziel) = vx.quelle. + +weiter warten: zeit (strom) := 400. + +END PROC zeitueberwachung; + +PROC sendereport (TEXT CONST txt): +  report (text (strom)+":"+txt+". Absender: """+nam (vx.quelle)+ +          """. Ziel "+text(vx.zielrechner) + " Taskindex: " + +          text (index (vx.ziel)));  +END PROC sendereport; + +PROC empfangsreport  (TEXT CONST txt): +  report (text (strom)+":"+txt+". Empfänger: """ +          +nam (vx.ziel)+""". Quelle "+text (vx.quellrechner) + +          " Taskindex: " + text (index (vx.quelle))); +END PROC empfangsreport  ; + +PROC sendung loeschen: +  strom loeschen (tasknr (vx.quelle)) +END PROC sendung loeschen; + +PROC strom loeschen (INT CONST tasknr): +    IF callaufruf CAND alter call (tasknr ) = strom +    THEN +       alter call (tasknr ) := 0 +    FI; +    vx.strom := 0; +    forget (vdr) +END PROC strom loeschen; + +PROC empfang loeschen: +    quit zaehler INCR 1; +    strom loeschen (tasknr (vx.ziel)) +END PROC empfang loeschen; + +PROC loesche verbindung (INT CONST nr): +  strom := nr; +  IF sendeeintrag +  THEN +    sendung loeschen +  ELSE +    gegenstelle zum loeschen auffordern;  +    empfang loeschen +  FI. + +gegenstelle zum loeschen auffordern: +  IF verbindung aktiv THEN quittieren (-loesche) FI. + +verbindung aktiv: vx.strom > 0. + +sendeeintrag: vx.quellrechner = own .  + +END PROC loesche verbindung; + +PROC weiter senden:  +  IF NOT alles raus +  THEN +    sequenz zaehlung;  +    IF neue seite THEN seitennummer eintragen FI; +    senden +  FI. + +sequenz zaehlung:  +  vx.sequenz INCR 1.  +  +neue seite:  +  IF  via node THEN (vx.sequenz AND packets per page via node minus 1) = 0 +                       ELSE (vx.sequenz AND pakete pro seite minus 1) = 0 +  FI. + +seitennummer eintragen:  +  dr page (strom) :=  vx.seiten nummer; +  vx.seitennummer := next ds page (vdr, dr page (strom)).  +  +  +END PROC weiter senden; +  +.packets per page: + +  IF via node THEN packets per page via node +              ELSE pakete pro seite +  FI. + +packets per page minus 1: +   IF via node THEN packets per page via node minus 1 +               ELSE pakete pro seite minus 1 +   FI. + +used length: + +   IF via node THEN data len via node +               ELSE nutzlaenge +   FI. + +PROC senden: +  INT VAR nl; +  zeit(strom) := 6; +  openblock := vx; +  nl := used length; +  transmit header (workspace); +  vorspann senden; +  daten senden; +  transmit trailer. + +vorspann senden:  +  blockout (workspace, 1, dr verwaltungslaenge, vorspannlaenge).  +  +daten senden:  +  blockout (vdr,dr page (strom),distanz,nl).  +  +distanz: nl* (vx.sequenz AND packets per page minus 1).  + +END PROC senden; + +PROC naechste verbindung vorbereiten:  +  FOR strom FROM 1 UPTO maxstrom REP  +  UNTIL vx.strom = 0 PER;  +  IF vx.strom <> 0 THEN errorstop ("Verbindungsengpass") FI.  +END PROC naechste verbindung vorbereiten; + +PROC sendung starten (TASK CONST quelle, ziel, INT CONST code):  +  sendung starten (quelle,ziel, station(ziel), code)  +END PROC sendung starten; +  +PROC sendung starten (TASK CONST quelle, ziel, INT CONST ziel station,code): +  IF ziel station = own  +  THEN +    report ("Irrläufer: Sendung an eigene Station. Absender:"""+ +            nam (quelle)+"""."); +    vx.strom := 0; +    forget (vdr) +  ELSE +    openblock.ziel := ziel; +    openblock.quelle :=quelle;  +    openblock.sendecode := code; +    openblock.zielrechner:= ziel station; +    openblock.quellrechner :=own; +    openblock.zwischenziel := route.zwischen (ziel station)+own256; +    alten call loeschen (quelle); +    IF call oder ping pong +    THEN typ (strom) := call pingpong; call merken +    ELSE typ (strom) := send wait FI; +    sendung neu starten +  FI. + +call oder pingpong: openblock.ziel = callee (openblock.quelle). + +call merken: alter call (tasknr (quelle)) := strom. + +END PROC sendung starten; + +PROC encode packet length (INT VAR val): + +   IF val < 96 THEN +     ELIF val < 160 THEN val DECR 32 +       ELIF val < 288 THEN val DECR 128 +         ELIF val < 544 THEN val DECR  352 +           ELIF val < 1056 THEN val DECR 832 +             ELIF val < 2080 THEN val DECR 1824 +    FI; +    rotate (val, 8) + +ENDPROC encode packet length; + +PROC sendung neu starten: +  INT VAR value; +  openblock.head:= stx open;  +  openblock.sequenz := -1;  +  openblock.seitennummer:= next ds page (vdr,-1);  +  openblock.strom := strom; +  vx := open block;  +  schnelles nak bei routen liefern; +  ab die post; +  value := vorspannlaenge + used length; +  encode packet length (value); +  vx.head:=code stx+value. + +schnelles nak bei routen liefern: +  IF openblock.sendecode = -routen liefern code +  THEN +    openblock.zwischenziel := openblock.zielrechner+own256; +    zeit(strom) := 2; +    opentry (strom) := 0 +  ELSE +    zeit (strom) :=8; +    opentry (strom) := 2 +  FI. +    +END PROC sendung neu starten; . + +ab die post:  +   transmit header (workspace); +   block out (work space,1, dr verwaltungslaenge,open laenge); +   transmit trailer. + +PROC alten call loeschen (TASK CONST quelle): +  IF alter call aktiv +  THEN +    INT VAR lstrom := strom; +    vx:=openblock; +    strom := alter call (tasknr (quelle)); +    IF in ausfuehrungsphase +    THEN +      sendereport ("Call-Löschung vorgemerkt"); +      loeschung vormerken +    ELSE +      report ("Call gelöscht."""+nam(quelle)+""". Strom "+text(strom)); +      loesche verbindung (strom) +    FI; +    strom := lstrom; +    openblock := vx +  FI. + +in ausfuehrungsphase: +  typ(strom) = call im wait OR typ (strom) = call in zustellung. + +loeschung vormerken: +  typ(strom) := call im abbruch; +  alter call (tasknr (quelle)) := 0. + +  +  alter call aktiv: +    alter call (tasknr (quelle)) > 0. + +END PROC alten call loeschen; + +PROC packet eingang +  ( INT VAR snr, TASK VAR  q, z, INT VAR ant,DATASPACE VAR  dr): +    snr := 0; +    fehlertest; +    vorspann holen;  +    IF NOT ring logik THEN daten teil FI. + +ring logik: FALSE. + +fehlertest: +# +    INT VAR c12; +    control (12,0,0,c12); +    IF c12 <> 0 +    THEN +      flush buffers; +      report ("E/A-Fehler "+text (c12)); +      control (12,0,0,c12); +      LEAVE packet eingang +    FI. + +                                                #. + +vorspann holen:  +  sync;  +  IF NOT blockin (workspace, 1, dr verwaltungslaenge2, block laenge) +  THEN LEAVE packeteingang  +  FI. + + +blocklaenge: IF code t  > min data length +             THEN  +               vorspannlaenge-2  +             ELSE  +               code t -2  +             FI.  + +sync:  + IF NOT packet start already inspected + THEN +   TEXT VAR skipped, t:= ""; +   skipped := next packet start; +   IF skipped = "" THEN LEAVE packet eingang FI; +   t := incharety (1); +   code t := code (t); + ELSE +   skipped := buffer first; +   buffer first := ""; +   t := incharety (1); +   code t := code (t); + FI; + decode packet length; +IF skipped=stx AND laenge ok THEN LEAVE sync FI; +  REP  +    skipped CAT t; +    t := incharety (1);  (* next character *) +    IF t = "" THEN  +      report ("skipped",skipped); +      LEAVE packet eingang +    FI ; +    codet := code (t); +  UNTIL blockanfang OR length (skipped) > 200 PER;  +  decode packet length; +  IF skipped <> stx THEN report ("skipped bei sync:", skipped)    FI.  +  +decode packet length: + +IF code t < 96 THEN +  ELIF code t < 128 THEN code t INCR 32 +    ELIF code t < 160 THEN code t INCR 128 +      ELIF code t < 192 THEN code t INCR 352 +        ELIF code t < 224 THEN code t INCR 832 +          ELIF code t < 256 THEN code t INCR 1824 +FI. + +packet start already inspected: buffer first <> "". + +blockanfang:  +  (skipped SUB length(skipped)) = stx AND laenge ok. + +laenge ok: +  (codet = datenpacketlaenge OR codet = datenpacketlaenge via node +  OR codet = ack laenge OR code t = openlaenge).  +  +zielnummer:    vorspann.zielrechner. + +daten teil:  +  IF zielnummer = own +  THEN +    ziel erreicht (openblock,snr,q,z,ant,dr) +  ELSE +    weiter faedeln +  FI. + +weiter faedeln: +  INT VAR value; +  IF zielrechner ok +  THEN +    IF neue verbindung +    THEN +      IF (openblock.sendecode = -routenlieferncode) OR NOT route ok +        THEN LEAVE packet eingang +      FI +    FI; +    value := code t; +    encode packet length (value); +    vorspann.head := code stx + value; +    vorspann.zwischenziel := own256 + route.zwischen (vorspann.zielrechner); +    nutzdaten einlesen; +    dr := workspace; +    snr := 1000; +    ant := zielnummer +  FI. + +nutzdaten einlesen: +  IF code t > data len via node +  THEN +    IF NOT blockin (workspace, 1, drverwaltungslaenge+vorspannlaenge, data len via node) +    THEN +      LEAVE packeteingang +    FI; +    IF NOT next packet ok THEN LEAVE packeteingang FI +  FI. + +END PROC packet eingang; + +PROC ziel erreicht (STEUER CONST prefix, +          INT VAR snr, TASK VAR  q, z, INT VAR ant,DATASPACE VAR  dr): +  last data := -1; +  IF NOT quellrechner ok +  THEN +    report ("Quellrechner "+text(prefix.quellrechner)); +    LEAVE ziel erreicht +  FI; +  IF neue verbindung  +  THEN +    IF NOT route ok OR NOT quelltask ok +    THEN report ("verbotene Route: " + text (prefix.quellrechner)); +         LEAVE ziel erreicht +    FI; +    verbindung bereitstellen +  ELIF quittung  +  THEN  +    strom := ack packet.strom;  +    IF falsche stromnummer THEN report ("Strom falsch in Quittung"); +                                LEAVE ziel erreicht FI; +    IF vx.strom = 0 THEN LEAVE ziel erreicht FI; +    IF ackpacket.code >= ok   THEN weiter senden +    ELIF NOT route ok THEN +        sendereport ("verbotene Route bei Quittung"); +        LEAVE ziel erreicht +    ELIF ackpacket.code = -von vorne THEN +        sendereport ("Neustart"); +        openblock := vx;  +        sendung neu starten  +    ELIF ackpacket.code = -wiederhole THEN back 16 +    ELIF ackpacket.code = -loesche    THEN fremdloeschung +    ELIF ackpacket.code = -beende AND alles raus THEN strom abschliessen +    FI +  ELIF verbindung festgestellt  +  THEN +    zeit(strom) := 400; +    opti := vx; +    datenpacket +  ELSE  +    strom := maxstrom1;  +    vx:=prefix; +    report ("Daten ohne Eroeffnung von " +text(prefix.quellrechner)  +    +"  Sequenznr "+text(prefix.sequenz));  +    daten entfernen (used length); +    IF alles raus THEN quittieren (-beende) ELSE quittieren(-von vorne) FI +  FI.  + +quelltask ok: +  prefix.quelle = collector OR antwort auf routen liefern +  OR station (prefix.quelle) = prefix.quellrechner. + +antwort auf routen liefern: prefix.quelle = myself. + +verbindung bereitstellen: +  IF (prefix.sendecode < 0 OR station (prefix.ziel) = own) +     AND quellrechner ok +  THEN +    freie verbindungsnummer;  +    vdr := nilspace; +    vx := open block;  +    zeit(strom) := 30; +    quittieren falls genug pufferplatz; +    vx.sequenz := 0 ;  +    opti := vx; +    dr page (strom) :=-2; +    IF abschluss THEN rueckmeldung FI +  FI. + +loeschung vorgemerkt: typ(strom) = call im abbruch. + +strom abschliessen: +  IF call aufruf +  THEN +    wdh data vor ablauf der zustellversuche bei der gegenstation; +    ausfuehrungsphase merken +  ELSE +    wdh data sperren +  FI. + +wdh data sperren: +    zeit (strom) := 12000. + +wdh data vor ablauf der zustellversuche bei der gegenstation: +    zeit (strom) := 80. + +ausfuehrungsphase merken: typ(strom) := call in zustellung. +  +back16: +  datenraum etwas rueckspulen;  +  opentry (strom) := 2; +  nicht sofort senden (* wegen vagabundierender Quittungen *). + +nicht sofort senden: zeit(strom) := 2. + +datenraum etwas rueckspulen: +  INT VAR pps := packets per page ; +  sendereport ("etwas rueckgespult"); +  INT VAR  vs :=-1; +  dr page (strom) := -1; +  INT VAR i; +  FOR i FROM 1 UPTO vx.sequenz DIV pps - etwas REP +    vs INCR pps; +    dr page (strom) := next ds page (vdr, dr page (strom))  +  PER; +  vx.seiten nummer := next ds page (vdr, dr page (strom)) ; +  vx.sequenz := vs. + +etwas: 3. + +fremdloeschung: +  IF fremdrechner ok und sendung  +  THEN +    IF typ (strom) = call in zustellung +    THEN +      typ (strom) := call im wait +    ELSE +      IF NOT alles raus +      THEN +        sendereport ("Sendung von Gegenstelle geloescht") +      FI; +      sendung loeschen +    FI +  FI. + +fremdrechner ok und sendung: +  ackpacket.quellrechner = vx.zielrechner . + + +quittieren falls genug pufferplatz: +  IF quit zaehler > 0 THEN +    quit zaehler DECR 1; +    open quittieren; +    block vorab quittieren +  ELSE +    quittieren (-wiederhole) +  FI. + +open quittieren: quittieren (ok). +block vorab quittieren: +  IF prio (myself) < 3 THEN quittieren (ok) FI. + +quittung:  code t <= ack laenge.  +  +  +verbindung festgestellt:  +  FOR strom FROM maxstrom DOWNTO 1 REP  +    IF bekannter strom +    THEN LEAVE verbindung festgestellt WITH TRUE FI  +  PER;  +  FALSE.  +  +bekannter strom:  +  vx.strom = prefix.strom AND vom selben rechner.  +  +vom selben rechner:  +  vx.quellrechner = prefix.quellrechner.  +  +daten:  +      IF neue seite da THEN check for valid pagenr; +                            dr page(strom) := prefix.seitennummer; +        ELIF prefix.seitennummer < dr page(strom) +              THEN empfangsreport ("Falsche Seitennummer, Soll: " + +                                  text(drpage(strom)) + " ist: " + +                                  text (prefix.seitennummer) +                                  + " bei Sequenznr: " + +                                  text(prefix.sequenz)); +                   flush buffers; +                   quittieren (- wiederhole); +                   LEAVE ziel erreicht +  FI; +  sequenz zaehlung; +  IF neue seite kommt  +  THEN  +    vx.seiten nummer := prefix.seiten nummer;  +    dr page(strom) := prefix.seitennummer; +  FI; +  quittieren(ok);  +  IF NOT blockin (vdr, opti.seiten nummer, distanz, nl) +  COR NOT next packet ok +  THEN quittieren (-wiederhole); +       LEAVE ziel erreicht +  FI;  +  last data := strom. +  +check for valid pagenr: +   IF prefix.seitennummer < dr page(strom) AND prefix.seitennummer > -1 +         THEN report ("Absteigende Seitennummern, alt: " + text(drpage(strom))+ +                      " neu: "+ text(prefix.seitennummer) + " Seq.nr: " + +                       text(vx.sequenz) ) ; +              flush buffers; +              quittieren (- von vorne); +              LEAVE ziel erreicht; +   FI. + +datenpacket: +  INT VAR nl := used length; +  INT VAR pps1 := packets per page minus 1; +  IF sendung wartet auf zustellung THEN auffrischen ELSE daten holen FI. + +sendung wartet auf zustellung: typ (strom) = zustellung. + +auffrischen: zeit (strom) := 200; daten entfernen (nl). + +daten holen: +  IF opti.sequenz >= prefix.sequenz AND opti.sequenz < prefix.sequenz+100 +     AND prefix.sequenz >= 0 +  THEN  +    IF opti.sequenz <> prefix.sequenz +    THEN empfangsreport ("Sequenzreset von "+text(opti.sequenz)+" auf "+ +                  text (prefix.sequenz)); +         vx.sequenz := prefix.sequenz; +         IF pagenumber ok +            THEN dr page (strom) := prefix.seitennummer +            ELSE empfangsreport ("Blocknummer falsch, neu: "+ +                 text (prefix.seitennummer) + ", alt : " + +                 text (drpage(strom)) ); +         FI; +         vorabquittung regenerieren  +    FI; +    daten  ;  +    IF abschluss THEN rueckmeldung FI; +  ELSE  +    empfangsreport ("Sequenzfehler: soll "+text(vx.sequenz)+" ist "+  +            text(prefix.sequenz)); +    quittieren (-wiederhole); +    daten entfernen (nl) +  FI.  +  +pagenumber ok: +   dr page (strom) >= prefix.seitennummer . + +rueckmeldung: +  snr := strom; +  q := vx.quelle; +  z := vx.ziel; +  ant := vx.sendecode; +  dr := vdr; +  LEAVE ziel erreicht. + +vorabquittung regenerieren: +  IF prio (myself) < 3 +  THEN +    quittieren (ok) +  FI. +  +distanz: (opti.sequenz AND  pps1 ) * nl.  +  +sequenz zaehlung:  +  vx.sequenz INCR 1.  +  +neue seite da: +  neue seite kommt. + +neue seite kommt:  +(vx.sequenz AND pps1) = 0.  +  +freie verbindungsnummer:  +  INT VAR h strom :=maxstrom1, cstrom := 0; +  FOR strom FROM 1 UPTO maxstrom REP  +    IF vx.strom = 0 THEN h strom := strom ; +                         typ(strom) := send wait +    ELIF bekannter strom +    THEN empfangsreport ("Reopen");  +         quit zaehler INCR 1; +         IF typ (strom) = zustellung THEN typ (strom) := send wait FI; +         forget (vdr); +         LEAVE freie verbindungsnummer  +    ELIF antwort auf call +    THEN +      IF loeschung vorgemerkt +      THEN  +        vx := prefix; +        loesche verbindung (strom); +        LEAVE ziel erreicht +      FI; +      cstrom := strom; +      typ (strom) := call pingpong; +      forget (vdr); +    FI +  PER;  +  IF cstrom > 0 THEN strom := cstrom ELSE strom := h strom FI;  +  IF strom = maxstrom1 THEN +    vx:=prefix; +    empfangsreport ("Verbindungsengpass"); +    quittieren (-wiederhole); +    LEAVE ziel erreicht +  FI.  + +antwort auf call: +  prefix.sendecode >= 0 AND +  call aufruf AND vx.quelle = prefix.ziel AND vx.ziel = prefix.quelle.  + +END PROC ziel erreicht; + +PROC daten entfernen (INT CONST wieviel): +    BOOL VAR dummy ; +    dummy:=blockin (workspace, 2, 0, wieviel)  +END PROC daten entfernen; + +BOOL PROC route ok: +  INT VAR zwischenquelle := vorspann.zwischenziel DIV 256, +          endquelle := vorspann.quellrechner; +    zwischenquelle abgleichen; +    endquelle abgleichen; +    TRUE. + +zwischenquelle abgleichen: +  IF NOT zwischenroute gleich +  THEN +    IF NOT zwischenabgleich erlaubt THEN LEAVE route ok WITH FALSE FI; +    route.port (zwischenquelle) := channel; +    route.zwischen (zwischenquelle) := zwischenquelle; +    abgleich (zwischenquelle, zwischenquelle) +  FI. + +zwischenabgleich erlaubt: route.port (zwischenquelle) < 256. + +endquelle abgleichen: +  IF NOT endroute gleich +  THEN +    IF NOT endabgleich erlaubt THEN LEAVE route ok WITH FALSE FI; +    route.port (endquelle) := channel; +    route.zwischen (endquelle) := zwischenquelle; +    abgleich (endquelle, zwischenquelle) +  FI. + +endabgleich erlaubt: route.port (endquelle) < 256. + +zwischenroute gleich: +  (route.port (zwischenquelle) AND 255) = channel +  AND +  route.zwischen (zwischenquelle) = zwischenquelle. + +endroute gleich: +  (route.port (endquelle) AND 255) = channel +  AND +  route.zwischen (endquelle) = zwischenquelle. + +END PROC route ok; + +BOOL PROC abschluss: + +  last data := -1; +  IF neue seite kommt AND vx.seiten nummer = -1  +  THEN  +    quittieren (-beende); +    an ziel weitergeben  +  ELSE +    FALSE +  FI.  +neue seite kommt:  +(vx.sequenz AND packets per page minus 1) = 0.  +  +an ziel weitergeben:  +  IF tasknummerfrage  THEN taskfrage beantworten ;pufferplatz ; FALSE +  ELIF tasknamenfrage THEN name senden ;pufferplatz ; FALSE +  ELIF taskinfofrage  THEN task info senden;pufferplatz ; FALSE +  ELIF routenfrage    THEN routen senden; pufferplatz; FALSE +  ELSE                     senden ; TRUE +  FI.  + +pufferplatz : quitzaehler INCR 1 . + +senden: +  IF  callaufruf +  THEN +    ein versuch  (* bei Antwort auf Call muß ein Zustellversuch reichen *) +  ELSE +    max 100 versuche;  +    typ (strom) := zustellung +  FI. + +tasknummerfrage:opti.sendecode = -taskid code. +  +tasknamenfrage: opti.sendecode = -name code. +  +taskinfofrage: opti.sendecode = -task info code. + +routenfrage: opti.sendecode = -routen liefern code. + +max 100 versuche: zeit(strom) := 100. + +ein versuch: zeit (strom) := 1. + +taskfrage beantworten: +  disable stop; +  BOUND TEXT VAR tsk := vdr;  +  TEXT VAR save tsk := tsk; +  forget (vdr); vdr := nilspace;  +  BOUND TASK VAR task id := vdr; +  task id := task(save tsk); +  IF is error THEN  +    clear error; enable stop; +    forget (vdr); vdr := nilspace;  +    BOUND TEXT VAR errtxt := vdr; +    errtxt := text(own)+"/"""+save tsk+""" gibt es nicht"; +    sendung starten (collector, opti.quelle, 2) +  ELSE +    enable stop; +    sendung starten (collector, opti.quelle, 0) +  FI. +  +name senden:  +  quittieren (-loesche); +  forget (vdr); vdr := nilspace; +  tsk := vdr;  +  tsk := nam (opti.ziel); +  sendung starten (collector, opti.quelle, 0).  +  +routen senden: +  forget (vdr); vdr := old ("port intern"); +  sendung starten (opti.ziel, opti.quelle, 0). + +task info senden: +  disable stop; +  BOUND INT VAR ti code := vdr; +  INT VAR ti cd := ti code; +  forget (vdr); vdr := nilspace; +  FILE VAR task inf := sequential file (output,vdr); +  head line (task inf,"Station "+text(own));  +  task info (ti cd, task inf); +  IF is error +  THEN +    forget (vdr); vdr := nilspace; +    errtxt := vdr; +    errtxt := errormessage; +    clear error; +    sendung starten (collector, opti.quelle, 2) +  ELSE +    sendung starten (collector,opti.quelle,0) +  FI; +  enable stop +END PROC abschluss ; + +PROC quittieren(INT CONST code) :  +  INT VAR quell := vx.quellrechner ; +  transmitted ackpacket := ACK:(stx quit, route.zwischen (quell)+own256, quell, own, +                    vx.strom, code); +  transmit header (transmitted ack space); +  blockout (transmitted ack space,1,dr verwaltungslaenge, ack laenge);  +  transmit trailer; +END PROC quittieren;  + +BOOL PROC next packet ok: +  buffer first := next packet start; +  buffer first = "" COR normal packet start. + +normal packet start: +  IF buffer first = stx +  THEN +    TRUE +  ELSE +    buffer first := ""; flush buffers; FALSE +  FI. + +END PROC next packet ok; +END PACKET basic net; + + diff --git a/system/net/1.8.7/src/net files-M b/system/net/1.8.7/src/net files-M new file mode 100644 index 0000000..ae6f9f3 --- /dev/null +++ b/system/net/1.8.7/src/net files-M @@ -0,0 +1,5 @@ +net report +net hardware interface +basic net +net manager + diff --git a/system/net/1.8.7/src/net hardware interface b/system/net/1.8.7/src/net hardware interface new file mode 100644 index 0000000..4e3466a --- /dev/null +++ b/system/net/1.8.7/src/net hardware interface @@ -0,0 +1,389 @@ +PACKET net hardware + +(************************************************************************) +(****  Netzprotokoll Anpassung                                          *) +(****  Komplette Version mit BUS Anpassung           10.06.87           *) +(****  mit I/0 Controls  fuer integrierte Karten                        *) +(****  Verschiedene Nutztelegrammgrössen                                *) +(****  Version: GMD 2.0                              A.Reichpietsch     *) +(************************************************************************) + +   DEFINES +        blockin, +        blockout, +        set net mode, +        net address, +        mode text, +        data length, +        data length via node, +        decode packet length, +        next packet start, +        flush buffers, +        transmit header, +        transmit trailer, +        version, +        reset box, +        max mode, +        net mode: + + + + +   LET                eak prefix laenge = 6, +               packet length before stx = 14  (*eth header =14 *), +                        maximum mode nr = 12, +                                    stx = ""2"", +                                niltext = "", +                                   null = "0", +                               hex null = ""0"", +                                  blank = " ", +                             eak prefix = ""0""0""0""0"", +                             typefield  = "EU", +                        prefix adresse  = "BOX", +                 second prefix adresse  = ""0"BOX", +             second address type bound  = 90; + +   INT CONST data length via node :: 64; +   TEXT CONST version :: "GMD 2.0  (10.6.87)"; + + +   TEXT VAR own address; +   INT VAR paketlaenge, eumel paket laenge, mode, rahmenlaenge, actual data length; + +BOOL PROC blockin (DATASPACE VAR ds, INT CONST seite, abstand, laenge):  +   INT VAR hilfslaenge:=laenge, code:= abstand+laenge+512; +   REAL VAR time out := clock (1) + 10.0; +   REP  +      blockin (ds,seite,code-hilfslaenge, hilfslaenge, hilfslaenge);  +   UNTIL hilfslaenge = 0 OR clock (1) > time out PER  ; +   IF hilfslaenge <> 0 +   THEN report ("blockin abbruch, fehlende Zeichen: "+text(hilfslaenge)); +    FI; +   hilfslaenge = 0 +END PROC blockin;  +  +PROC blockout (DATASPACE CONST ds, INT CONST seite, abstand, laenge):  +   INT VAR hilfslaenge:=laenge, code:= abstand+laenge+512;  +   REP  +      blockout (ds,seite,code-hilfslaenge, hilfslaenge, hilfslaenge);  +   UNTIL hilfslaenge = 0 PER  +END PROC blockout;  + +PROC set net mode (INT CONST new mode): +   mode := new mode ; +   own address := net address (station(myself)); +   SELECT mode OF +      CASE 1,3   : set data length (64); +      CASE 2     : std framelength; set data length (64) +      CASE 4,6   : set data length (128) +      CASE 5     : std framelength; set data length (128) +      CASE 7,9   : set data length (256) +      CASE 8     : std framelength; set data length (256) +      CASE 10,12 : set data length (512) +      CASE 11    : std framelength; set data length (512); + +      OTHERWISE +   END SELECT. + +   std framelength: +      rahmenlaenge := eak prefix laenge + packet length before stx. + +ENDPROC set net mode; + +INT PROC max mode: +   maximum mode nr +ENDPROC max mode; + +INT PROC net mode: +   mode +ENDPROC net mode; + +TEXT PROC mode text: +   mode text (mode) +ENDPROC mode text; + +TEXT PROC mode text (INT CONST act mode): +   SELECT act mode OF +      CASE 1:   "Modus: (1)  EUMEL-Netz           64 Byte" +      CASE 2:   "Modus: (2)  ETHERNET via V.24    64 Byte" +      CASE 3:   "Modus: (3)  ETHERNET integrated  64 Byte" +      CASE 4:   "Modus: (4)  EUMEL-Netz           128 Byte" +      CASE 5:   "Modus: (5)  ETHERNET via V.24    128 Byte" +      CASE 6:   "Modus: (6)  ETHERNET integrated  128 Byte" +      CASE 7:   "MODUS: (7)  EUMEL-Netz           256 Byte" +      CASE 8:   "MODUS: (8)  ETHERNET via V.24    256 Byte" +      CASE 9:   "MODUS: (9)  ETHERNET integrated  256 Byte" +      CASE 10:  "MODUS: (10) EUMEL-Netz           512 Byte" +      CASE 11:  "MODUS: (11) ETHERNET via V.24    512 Byte" +      CASE 12:  "MODUS: (12) ETHERNET integrated  512 Byte" +      OTHERWISE  errorstop ("Modus " + text(mode) + " gibt es nicht"); +                 error message +   END SELECT + +ENDPROC mode text; + +PROC set data length (INT CONST new data length): +    actual data length := new data length +ENDPROC set data length; + +INT PROC data length: +    actual data length +ENDPROC data length; + +PROC reset box (INT CONST net mode): +   SELECT net mode OF +      CASE 1,4,7,10   :   eumel net box reset +      CASE 2,5,8,11   :   eak reset +      OTHERWISE    controler reset +   END SELECT. + +   eumel net box reset: +      out (90*""4"");  +      REP UNTIL incharety (1) = niltext PER.  + +   eak reset: +      out ("E0"13"E0"13""). + +   controler reset: +      INT VAR dummy; +      control (-35, 0,0,dummy); +      control (22,0,0,dummy). + +ENDPROC reset box; + +PROC remove frame +   (TEXT VAR erstes zeichen vom eumel telegramm, BOOL VAR kein telegramm da): +   kein telegramm da := FALSE; +   SELECT net mode OF +      CASE 2,5,8,11  : remove ethernet frame +                       (erstes zeichen vom eumel telegramm, kein telegramm da) +   OTHERWISE +   END SELECT; +ENDPROC remove frame; + +PROC remove ethernet frame (TEXT VAR string, BOOL VAR schrott): +   TEXT VAR  speicher, t; +   INT VAR lg; + +   t := string; +   speicher := niltext; +   WHILE kein stx da REP +      lies zeichen ein; +      teste auf timeout; +   UNTIL textoverflow PER; +   melde eingelesene zeichen. + +   lies zeichen ein: +      speicher CAT t; +      t := incharety (1). + +   teste auf timeout: +      IF t = niltext THEN schrott := (speicher <> niltext) +                                         CAND not only fill characters; +                          string := niltext; +                          LEAVE remove ethernet frame +      FI. + +   not only fill characters: +      pos (speicher, ""1"", ""254"",1) <> 0. + +   kein stx da : +      t <> stx. + +   textoverflow: +      length (speicher) > 1000. + +   melde eingelesene zeichen: +      IF kein stx da +         THEN kein eumeltelegrammanfang +         ELSE untersuche ethernet header +      FI. + +   kein eumeltelegrammanfang: +      report ("skipped ,fehlendes <STX> ,letztes Zeichen:", t); +      string := t; +      schrott := TRUE. + +   untersuche ethernet header: +      string := t; +      IF ethernet header inkorrekt +         THEN melde fehler +      FI. + +   ethernet header inkorrekt: +      lg := length (speicher); +      packet zu kurz COR adresse falsch. + +   packet zu kurz: +      lg < packet length before stx. + +   adresse falsch: +      INT VAR adrpos := pos (speicher, own address); +      zieladresse falsch COR adresse nicht an der richtigen pos . + +   zieladresse falsch: +      adrpos < 1. + +   adresse nicht an der richtigen pos: +      adrpos <> lg - packet length before stx + 1. + +   melde fehler: +      report ("Header inkorrekt eingelesen: ", speicher + t); +      string := t; +      schrott := TRUE. + +ENDPROC remove ethernet frame; + +TEXT PROC next packet start: + +  TEXT VAR t := niltext; +  BOOL VAR schrott := FALSE; + +   t:= incharety (1); +   IF t = niltext THEN LEAVE next packet start WITH niltext +                  ELSE remove frame (t, schrott) +   FI; +   IF schrott THEN no stx or niltext +              ELSE t +   FI. + +   no stx or niltext: +      IF t = stx THEN "2" +        ELIF t = niltext THEN "0" +          ELSE t +      FI. + +ENDPROC next packet start; + +PROC flush buffers: +  REP UNTIL incharety (5) = niltext PER; +  report ("buffers flushed"); +ENDPROC flush buffers; + +PROC transmit header (DATASPACE CONST w): +   BOUND INT VAR laengeninformation := w; +   eumel paket laenge := laengeninformation ; +   decode packet length (eumel paket laenge); +   SELECT net mode OF +      CASE 1,4,7,10     : +      CASE 2,5,8,11     : eak und eth header senden (w) +      OTHERWISE         : telegrammanfang melden; +                          std ethernet header senden (w) +   END SELECT; + +ENDPROC transmit header; + +PROC decode packet length (INT VAR decoded length): + +  decoded length DECR 2; +  rotate (decoded length, 8); + +  IF decoded length < 96 THEN +    ELIF decoded length < 128 THEN decoded length INCR 32 +      ELIF decoded length < 160 THEN decoded length INCR 128 +        ELIF decoded length < 192 THEN decoded length INCR 352 +          ELIF decoded length < 224 THEN decoded length INCR 832 +            ELIF decoded length < 256 THEN decoded length INCR 1824 +  FI; + +ENDPROC decode packet length; + +PROC transmit trailer: +   INT VAR dummy; +   SELECT net mode OF +      CASE 3,6,9,12 : control (21,0,0,dummy) +       OTHERWISE +   END SELECT. + +ENDPROC transmit trailer; + +PROC std ethernet header senden (DATASPACE CONST x): +   TEXT VAR  eth adresse, ethernet kopf := niltext; +   INT VAR adresse; +   BOUND STRUCT (INT head, zwischennummern) VAR header := x; +   zieladresse holen; +   zieladresse senden; +   quelladresse senden; +   typfeld senden; +   ausgeben. +    +   zieladresse holen: +      adresse := header.zwischennummern AND 255; +      eth adresse := net address (adresse). + +   zieladresse senden: +      ethernetkopf CAT eth adresse. + +   quelladresse senden: +      ethernetkopf CAT own address. + +   typfeld senden: +      ethernetkopf CAT typefield. + +   ausgeben: +      out (ethernetkopf). + +ENDPROC std ethernet header senden; + +PROC telegrammanfang melden: +   INT VAR dummy; +      control (20,eumel paket laenge + packet length before stx,0, dummy). + +ENDPROC telegrammanfang melden; + +PROC eak und eth header senden (DATASPACE CONST x): +   TEXT VAR res:= niltext; + +   neue laenge berechnen; +   eak kopf senden; +   std ethernet header senden (x). + +   neue laenge berechnen: +      paket laenge := rahmenlaenge + eumel paket laenge. +     +   eak kopf senden: +      res := code (paket laenge DIV 256); +      res CAT (code (paket laenge AND 255)); +      res CAT eak prefix; +      out(res). + +ENDPROC eak und eth header senden; + +TEXT PROC net address (INT CONST eumel address): +   TEXT VAR res ; +   INT VAR low byte; + +SELECT mode OF +   CASE 1,4,7,10 : eumel net address +   OTHERWISE ethernet address +END SELECT. + +eumel net address: +    text(eumel address). + +ethernet address: +   IF second adress kind THEN second eth header +                         ELSE first eth header +   FI; +   res. + +   second adress kind: +      eumel address = 34 COR +       eumel address > second address type bound. + +   second eth header: +      low byte := eumel address AND 255; +      res := second prefix adresse + code (low byte); +      res CAT hex null. + +   first eth header: +      res := prefix adresse + text (eumel address, 3); +      changeall (res, blank, null). + +ENDPROC net address; + +ENDPACKET net hardware; + + + + diff --git a/system/net/1.8.7/src/net inserter b/system/net/1.8.7/src/net inserter new file mode 100644 index 0000000..c89d0f0 --- /dev/null +++ b/system/net/1.8.7/src/net inserter @@ -0,0 +1,145 @@ +(*************************************************************************) +(*** Insertiert alle notwendigen Pakete, die zum Betrieb des Netzes    ***) +(*** notwendig sind.                                                   ***) +(*** Berücksichtigt nur EUMEL - Versionen ab  1.8.1, sowie             ***) +(*** Multi-User-Version                                                ***) +(***                                                                   ***) +(***                                                                   ***) +(*** 23.05.87  ar                                                      ***) +(*************************************************************************) + +LET netfile = "netz", +    multi files = "net files/M"; + + +INT CONST version :: id (0); +THESAURUS VAR tesa; + +head; +IF no privileged task +     THEN errorstop (name (myself) + " ist nicht privilegiert!") +  ELIF station number wrong +       THEN errorstop ("'define station' vergessen ") +FI; + +IF version < 181 THEN versionsnummer zu klein +                 ELSE install net +FI. + +no privileged task: +   NOT (myself < supervisor). + +station number wrong: +   station (myself) < 1. + +install net : +   IF NOT exists (netfile) +        THEN errorstop ("Datei " + netfile +" existiert nicht") +   FI; +   IF is multi THEN insert multi net +               ELSE errorstop ("Diese Netzversion ist nur für Multi-user Versionen freigegeben") +   FI; +   forget ("net install", quiet); +   net start. + +net start : +    say line (" "); +    do ("start"); +    do ("global manager (PROC (DATASPACE VAR, INT CONST, INT CONST, TASK CONST) +                         net manager)"). + +is multi : +   (pcb(9) AND 255) > 1. + +insert multi net : +   hole dateien vom archiv; +   insert say and forget (tesa). + +hole dateien vom archiv : +   fetch if necessary (multi files); +   tesa := ALL (multi files); +   forget (multi files, quiet); +   fetch if necessary (tesa - all); +   say line (" "); +   say line ("Archiv-Floppy kann entnommen werden."); +   release (archive). +    +    +head : +   IF online THEN page; +                  put center (" E U M E L  -  Netz  wird  installiert."); +                  line; +                  put center ("----------------------------------------"); +                  line (2) +   FI. + +versionsnummer zu klein :  +   errorstop ("Netzsoftware erst ab Version 1.8.1 insertierbar !"). +  +PROC fetch if necessary (TEXT CONST datei) : +   IF NOT exists (datei) THEN say line ("Loading """ + datei + """..."); +                              fetch (datei, archive) +   FI. +END PROC fetch if necessary; + +PROC fetch if necessary (THESAURUS CONST tes) : +   do (PROC (TEXT CONST) fetch if necessary, tes) +END PROC fetch if necessary; + +PROC insert say and forget (TEXT CONST name of packet):  +   IF online THEN INT VAR cx, cy; +                  put ("Inserting """ + name of packet + """...");  +                  get cursor (cx, cy) +   FI; +   insert (name of packet);  +   IF online THEN cl eop (cx, cy); line FI; +   forget (name of packet, quiet) +END PROC insert say and forget; + +PROC insert say and forget (THESAURUS CONST tes):  +   do (PROC (TEXT CONST) insert say and forget, tes) +END PROC insert say and forget; + +PROC put center (TEXT CONST t): +   put center (t, xsize); +END PROC put center; + +PROC put center (INT CONST zeile, TEXT CONST t): +   put center (zeile, t, xsize); +END PROC put center; + +PROC put center (TEXT CONST t, INT CONST gesamtbreite): +   INT VAR cy; +   get cursor (cy, cy); +   put center (cy, t, gesamtbreite) +END PROC put center; + +PROC put center (INT CONST zeile, TEXT CONST t, INT CONST gesamtbreite): +   cursor ((gesamtbreite - length (t)) DIV 2, zeile); +   put (t). +END PROC put center; + +PROC cl eol:  +  out (""5"")  +END PROC cl eol; + +PROC cl eop:  +  out (""4"")  +END PROC cl eop;  +  +PROC cl eol (INT CONST cx, cy):  +   cursor (cx, cy);  +   cl eol  +END PROC cl eol;  +  +PROC cl eop (INT CONST cx, cy):  +   cursor (cx, cy);  +   cl eop  +END PROC cl eop;  + +PROC say line (TEXT CONST t): +    IF online THEN put line (t) FI +ENDPROC say line; + + + diff --git a/system/net/1.8.7/src/net manager b/system/net/1.8.7/src/net manager new file mode 100644 index 0000000..05f530e --- /dev/null +++ b/system/net/1.8.7/src/net manager @@ -0,0 +1,797 @@ +PACKET net manager DEFINES stop,net manager,frei, routen aufbauen,  + (*   175 net manager   8 (!)   *) +                           start, +                           definiere netz, +                           aktiviere netz, +                           list option, +                           erlaube, sperre, starte kanal, routen:  +  +TEXT VAR stand := "Netzsoftware vom  10.06.87  ";  +                 (*Heinrichs     *)            +LET +    maxstat = 127, +    ack = 0, +(*  nak = 1, *) +    error nak = 2, +(*  zeichen eingang = 4, *) +    list code = 15, +(*  fetch code = 11, *) +    freigabecode = 29, +    tabellencode = 500, +    continue code = 100, +    erase code = 14, +    report code = 99,  +    abgleichcode = 98, +    neue routen code = 97, +    dr verwaltungslaenge = 8, + +    (* Codes der Verbindungsebene *)  +  +    task id code = 6,  +    name code = 7,  +    task info code = 8,  +    routen liefern code = 9,  +  +    (* Weitergabecodes für Netzknoten *) + +    route code = 1001, +    out code = 1003, + +    (* Typen von Kommunikationsströmen *) + +    zustellung = 1, +    call im wait = 3, +    call im abbruch = 4,  +    call in zustellung = 5; + +LET STEUER = +      STRUCT (  +      INT  head,  +           zwischenziel, +           zielrechner,  +           quellrechner, +           strom, +      INT  sequenz, +           seiten nummer, +      TASK quelle,ziel, +      INT  sende code);  +  +LET INFO = STRUCT (STEUER steuer, INT typ,maxseq);  +  +LET PARA = STRUCT (TASK quelle, ziel, INT sendecode, zielstation);  +  +  +TASK VAR sohn; +INT VAR strom,c,kanalmode, rzaehler := 20; +BOUND STRUCT (ROW maxstat INT port,  +              ROW maxstat INT zwischen)  VAR route; +  +   +TASK PROC netport (INT CONST ziel):  +   INT VAR kan := route.port (ziel) AND 255;  +   IF kan < 1 OR kan > 15 +   THEN  +     niltask  +   ELSE  +     IF NOT exists (nettask (kan))  +     THEN  +       access catalogue; +       nettask (kan) := task (kan);  +       IF NOT (nettask (kan) < father) THEN nettask (kan) := niltask FI;  +     FI;  +     nettask (kan)  +   FI +END PROC netport;  +  +PROC frei (INT CONST stat,lvl):  +  DATASPACE VAR ds := nilspace; +  BOUND STRUCT (INT x,y) VAR msg := ds; +  msg.x := stat; msg.y := lvl; +  INT VAR return; +  call (netport (stat), freigabecode, ds, return) ; +  forget (ds) +END PROC frei;  +  +PROC net manager (DATASPACE VAR ds, INT CONST order, phase, TASK CONST +                  ordertask): +  +    IF order = report code AND ordertask < myself +    THEN  +      IF storage (old("report")) > 20 THEN forget ("report", quiet) FI; +      FILE VAR rp := sequential file (output, "report"); +      BOUND TEXT VAR rpt := ds; +      putline (rp, rpt); +      send (ordertask, ack, ds) +    ELIF order = abgleichcode AND ordertask < myself +    THEN   +      BOUND STRUCT (INT ende, zwischen) VAR x := ds;  +      route.port (x.ende) := channel (ordertask); +      route.zwischen (x.ende) := x.zwischen; +      send (ordertask, ack, ds) +    ELIF order = neue routen code AND ordertask < myself +    THEN +      forget ("port intern"); +      copy (ds,"port intern"); +      route := old ("port intern"); +      send (ordertask, ack, ds) +    ELIF station (ordertask) = station (myself) +    THEN +      IF ordertask < myself +      OR order = list code +      OR order > continue code +      THEN +        IF order = list code  +        THEN +          enable stop; +          forget (ds); ds := old ("report"); +          FILE VAR ff := sequential file (output,ds); +          putline (ff,"bekannte Stationen:"); +          stationen; line (ff); putline (ff,"--------"); +          putline (ff,"Eingestellte Netzmodi:");  +          kanaele ;  +          paketgroessen;  +          line (ff); putline (ff,"********");  +          putline (ff,stand); +          putline (ff,"Rechner "+text(station(myself))+"  um "+time of day); +          send (ordertask, ack, ds) +        ELSE +        free manager (ds,order,phase,order task)  +        FI +      ELSE +      errorstop ("nur 'list' ist erlaubt") +      FI +    FI . +   +stationen:  +INT VAR stat;  +INT VAR mystation := station (myself); +FOR stat FROM 1 UPTO maxstat REP  +  IF route.port (stat) > 0 AND stat <> mystation  +  THEN  +    put (ff,text(stat)+"("+text (route.port (stat) AND 255)+","+ +    text(route.zwischen(stat))+")")  +  FI  +PER.  +  +paketgroessen:  +  +  line(ff);  +  put (ff, "Nutzlaenge bei indirekter Verbindung "+  +           text (data length via node) + " Byte "); line (ff).  +  +kanaele:  +   INT VAR portnummer;  +   TASK VAR tsk;  +   FOR portnummer FROM 1 UPTO 15 REP  +      tsk := task (portnummer); +      IF tsk < myself THEN beschreibe kanal FI;  +   PER.  +  +beschreibe kanal:  +   putline (ff, name (tsk) + " haengt an Kanal " + text (channel (tsk)) +                + ", " + mode text (netz mode (portnummer))). +  +END PROC net manager;  + +TASK VAR cd,stask; +ROW maxstat INT VAR erlaubt;  + +PROC communicate:  +  enable stop; +  INT VAR scode, merken :=0; +  DATASPACE VAR dr := nilspace; +  neuer start (quit max, kanalmode);  +REP  +  forget (dr);  +  telegrammfreigabe;  +  wait (dr, scode, stask);  +  cd := collected destination; +  IF weiterleitung steht noch aus +  THEN  +    send (netport (merken), out code, mds, reply);  +    IF reply <> -2 THEN forget (mds); merken := 0 FI  +  FI; +  IF zeichen da OR zeit abgelaufen  +  THEN  +    packet +  ELIF cd = myself  +  THEN  +    netz info und steuerung  +  ELSE +    sendung untersuchen (stask, cd, scode, dr) +  FI  +PER.  +  +telegrammfreigabe:  +   INT VAR dummy;  +   control (22,0,0,dummy).  +  +zeichen da: scode < 0 .  +  +zeit abgelaufen: scode = ack AND cd = myself.  + +packet:  +    INT VAR snr, ant,err; +    TASK VAR quelle, ziel; +    snr := 0; +    IF NOT zeichen da THEN routen erneuern FI; +    REP  +      IF NOT zeichen da +      THEN  +        forget (dr); +        zeitueberwachung (snr, quelle, ziel, ant, dr);  +      ELIF NOT weiterleitung steht noch aus +      THEN +        packet eingang (snr, quelle, ziel, ant, dr);  +      FI; +      IF snr = 1000 +      THEN +        packet weiterleiten +      ELIF snr > 0 +      THEN  +        IF ant > 6 AND erlaubt(station (quelle)) < 0  +        THEN unerlaubt +        ELSE +          send (quelle,ziel,ant,dr,err);  +          fehlerbehandlung ; +        FI +      FI  +    UNTIL snr = 0 OR zeichen da PER. +  +routen erneuern:  +  rzaehler DECR 1;  +  IF rzaehler = 0  +  THEN  +    rzaehler := 20;  +    neue routen holen +  FI.  + +weiterleitung steht noch aus: merken <> 0.  +  +packet weiterleiten:  +  INT VAR reply; +  IF NOT ((route.port (ant) AND 255) = channel OR route.port (ant) < 0) +  THEN  +    send (netport (ant), out code, dr, reply); +    IF reply = -2  +    THEN +      merken := ant;  +      DATASPACE VAR mds := dr  +    FI +  ELSE +    report ("Weiterleitung nicht möglich für "+text(ant))  +  FI. + +fehlerbehandlung:  +  IF ok oder ziel nicht da THEN loesche verbindung (snr) FI.  +  +ok oder ziel nicht da: err=0 OR err=-1.  + +netz info und steuerung:  +    IF scode = list code THEN   list status  +  ELIF scode = erase code THEN strom beenden +  ELIF scode = freigabe code AND stask = father THEN freigabelevel  +  ELIF scode >= route code THEN weitergaben +  ELIF scode > tabellencode THEN routen ausliefern +  ELSE forget (dr); ablehnen ("nicht möglich")  +  FI.  +   +weitergaben:  +  IF stask < father +  THEN  +    IF scode = out code  +    THEN  +      BOUND INT VAR stx lng := dr;  +      INT VAR decoded lng := stx lng;  +      decode packet length (decoded lng);  +      transmit header (dr);  +      blockout (dr,1,drverwaltungslaenge,decoded lng);  +      transmit trailer   +    ELIF scode = route code  +    THEN  +      BOUND PARA VAR parah := dr;  +      PARA VAR para := parah;  +      pingpong (stask, ack, dr, reply);  +      neue sendung (para.quelle, para.ziel, para.sendecode,  +                    para.zielstation, dr);  +      forget (dr); dr := nilspace;  +      send (stask, ack, dr)  +    FI +  ELSE  +    forget (dr);  +    ablehnen ("nicht Sohn von "+name(father))  +  FI.  +   +routen ausliefern:  +  neue sendung (stask, myself, -routen liefern code, scode-tabellencode,dr).  +   +freigabelevel:  +  BOUND STRUCT (INT stat,lvl) VAR lv := dr;  +  IF lv.stat > 0 AND lv.stat <= maxstat THEN erlaubt (lv.stat) := lv.lvl FI;  +  send (stask,ack,dr).  +  +unerlaubt:  +  report ("Fremdzugriff von "+text(station (quelle))+" auf "+nam(ziel) +          +" code "+text(ant));  +  loesche verbindung (snr); +  forget (dr); dr := nilspace; +  BOUND TEXT VAR errtxt := dr;  +  errtxt:="Kein Zugriff auf Station "+text (station (myself));  +  neue sendung (ziel, quelle, error nak, station (quelle), dr).  +  +strom beenden: +  BOUND TEXT VAR stromtext := dr; +  INT VAR erase strom := int (stromtext); +  forget (dr); +  strom := erase strom; +  IF falsche stromnummer THEN ablehnen ("Strom gibt es nicht") +  ELSE  +    BOUND INFO VAR v := verbindung (strom);  +  IF +    stask < supervisor OR stask = vx.quelle OR stask = vx.ziel +  THEN +    loeschen +  ELSE ablehnen ("Nur Empfänger/Absender darf löschen") +  FI +  FI.  +  +loeschen: +  IF sendeeintrag  THEN +    IF callee (vx.quelle) = vx.ziel THEN absender warnen FI; +    loesche verbindung (strom) +  ELSE +    IF callee (vx.ziel) = vx.quelle THEN warnen FI;  +    loesche verbindung (strom) +  FI;  +  dr := nilspace; +  send (stask,ack,dr). + +absender warnen: + dr := nilspace; + send(vx.ziel,vx.quelle,1,dr,err) . +  +warnen: + dr := nilspace; +errtxt := dr; errtxt:= "Station antwortet nicht";  +send (vx.quelle,vx.ziel,error nak, dr, err).  +  +falsche stromnummer: strom < 1 OR strom > max verbindungsnummer. +sendeeintrag: vx.quellrechner = station (myself). +vx: v.steuer. +END PROC communicate;  +  +PROC list option:  +  begin ("net list",PROC list net, sohn)  +END PROC list option;  +  +PROC list net:  +  disable stop; +  DATASPACE VAR ds ; +  INT VAR scode; +  REP +    wait (ds, scode, stask);  +    forget (ds); ds := nilspace; +    FILE VAR f := sequential file (output, ds);  +    list (f, father); +    list netports;  +    IF is error THEN clear error;  +                     forget(ds);  +                     ds := nilspace;  +                     f := sequential file (output, ds);  +                     output (f); putline (f,errormessage);  +                     clear error  +    FI;  +    send (stask, ack, ds)  +  PER.  +  +list netports:  +  INT VAR k;  +  FOR k FROM 1 UPTO 15 REP +    TASK VAR tsk := task (k);  +    IF tsk < father   +    THEN  +      putline (f, name (tsk));  +      list (f,tsk)  +    FI  +  PER.  +  +END PROC list net;  +  +PROC neue routen holen:  +    forget ("port intern", quiet);  +    fetch ("port intern");  +    route := old ("port intern");  +    neue routen +END PROC neue routen holen;  +  +PROC sendung untersuchen (TASK CONST q, z, INT CONST cod, DATASPACE VAR dr):  +  IF z = collector  +  THEN  +    verbindungsebene  +  ELIF station (z) <> 0 +  THEN +    sendung (q,z,cod,station (z),dr) +  ELSE +    ablehnen ("Station 0") +  FI. + +verbindungsebene:  +  IF cod = 256 THEN name von fremdstation +  ELIF cod > 256 +  THEN +    taskinfo fremd  +  ELIF callee (q) = z  (* gegen errornak an collector *) +  THEN +    task id von fremd +  FI. + +taskinfo fremd: sendung  (q, collector,  -task info code,cod-256,dr). + +task id von fremd: sendung  (q, collector, -task id code, zielstation, dr) . + +name von fremdstation: +  BOUND TASK VAR tsk := dr; +  TASK VAR tsk1 := tsk; +  forget (dr);  +  dr := nilspace;  +  sendung  (q, tsk1, -name code, station (tsk1), dr). + +zielstation: cod. +END PROC sendung untersuchen; + +PROC sendung (TASK CONST q, z, INT CONST code, z stat, DATASPACE VAR dr): +  IF z stat < 1 OR z stat > maxstat +  THEN +    ablehnen ("ungültige Stationsnummer"); +    LEAVE sendung +  FI; +  INT VAR reply; +  INT VAR rp := route.port (z stat) AND 255; +  IF rp = 255 THEN neue routen holen ;rp := route.port (z stat) AND 255 FI; +  IF rp = channel +  THEN +     sendung selbst betreiben +  ELIF rp > 0 AND rp < 16 +  THEN +     sendung weitergeben +  ELSE +     ablehnen ("Station "+text(z stat)+" gibt es nicht") +  FI. + +sendung selbst betreiben: +  neue sendung (q, z, code, z stat, dr).  + +sendung weitergeben: +  DATASPACE VAR ds := nilspace; +  BOUND PARA VAR p := ds; +  p.quelle := q; +  p.ziel := z; +  p.zielstation := z stat; +  p.sendecode := code; +  call (netport (z stat), route code, ds, reply); +  forget (ds); +  pingpong (netport (z stat), 0, dr, reply); +  forget (dr); +  IF reply < 0 THEN ablehnen ("netport "+text(route.port(zstat)AND255) +                    + " fehlt") FI +END PROC sendung;  + +PROC ablehnen (TEXT CONST t): +  DATASPACE VAR vdr := nilspace; +  BOUND TEXT VAR errtxt := vdr;  +  INT VAR err; +  errtxt := t; +  send (cd,stask, error nak, vdr,err); +  forget (vdr). +END PROC ablehnen; + +PROC stop:  +  access catalogue; +  IF exists task ("net timer")  +  THEN  +    TASK VAR nets := father (/"net timer");  +  ELSE +    nets := myself +  FI;  +  nets := son (nets); +  WHILE NOT (nets = niltask) REP  +    IF text (name (nets),3) = "net" OR name (nets) = "router"  +    THEN +      end (nets)  +    FI;  +    nets := brother (nets) +  PER  +END PROC stop;  +  +PROC list status:  +  +  DATASPACE VAR ds := nilspace;  +  FILE VAR f:=sequential file (output, ds); +  line(f);  +  FOR strom FROM 1 UPTO max verbindungsnummer REP  +    IF strom > 0 THEN  +    BOUND INFO VAR v := verbindung (strom); +    IF vx.strom <> 0 THEN info FI  +    FI;  +  PER;  +  send (stask, ack, ds).  +  +info:  +  put (f,"Strom "+text(strom)); +  put (f,"(sqnr"+text(vx.sequenz)+"/"+text (v.maxseq)+")");  +  IF sendeeintrag THEN sendeinfo ELSE empfangsinfo FI;  +  line (f).  +  +sendeeintrag: vx.quellrechner = station(myself) .  +  +sendeinfo:  +  IF v.typ = call im wait THEN put (f,"erwartet Antwort von") +  ELIF v.typ = call in zustellung THEN put (f,"Ziel busy. Zielstation:")  +  ELIF v.typ = call im abbruch THEN put (f,"wird gelöscht bei Antwort von")  +  ELSE put (f,"sendet an")  +  FI;  +  put (f,vx.zielrechner);  +  put (f,". Absender ist """+nam (vx.quelle)+""".").  +  +empfangsinfo:  +  IF v.typ = zustellung THEN  +  put (f,"Sendung noch nicht zustellbar") +  ELSE +  put (f,"empfängt von"); +  put (f,vx.quellrechner);  +  FI; +  put (f,". Empfaenger ist """+nam (vx.ziel)+"""."). + +vx: v.steuer. +END PROC list status;  +  +INT VAR quitmax := 3; + +ROW 15 TASK VAR net task;   +ROW 15 INT VAR netz mode;  + +PROC erlaube (INT CONST von, bis): +  IF ein kanal gestartet +  THEN +    putline ("Warnung: 'erlaube' muß vor 'starte kanal'") +  FI; +  test (von); test (bis); +  INT VAR i; +  FOR i FROM von UPTO bis REP erlaubt (i) := 0 PER  +END PROC erlaube; + +PROC sperre  (INT CONST von, bis): +  IF ein kanal gestartet +  THEN +    putline ("Warnung: 'sperre' muß vor 'starte kanal'") +  FI; +  test (von); test (bis); +  INT VAR i; +  FOR i FROM von UPTO bis REP erlaubt (i) :=-1 PER  +END PROC sperre ; + +BOOL VAR  alte routen, ein kanal gestartet;  +  +PROC definiere netz:  +  stop; +  INT VAR i; +  FOR i FROM 1 UPTO 15 REP net task (i) := niltask PER;  +  ein kanal gestartet := FALSE; +  FILE VAR s := sequential file (output,"report");  +  putline (s," N e u e r   S t a r t " + date + " " + time of day );  +  alte routen := exists ("port intern"); +  IF alte routen +  THEN +    route := old ("port intern") +  ELSE +    route := new ("port intern");  +    initialize routes +  FI.  +  +  initialize routes:  +     FOR i FROM 1 UPTO maxstat REP  +        route.zwischen(i) := i  +     PER.  +  +END PROC definiere netz;  +  +PROC starte kanal (INT CONST k,modus,stroeme):  +  ein kanal gestartet := TRUE; +  IF exists (canal (k)) THEN end (canal (k)) FI; +  IF stroeme <= 0 THEN errorstop ("3.Parameter negativ") FI;  +  quitmax := stroeme; +  c := k;  +  IF c < 1 OR c > 15 THEN errorstop ("unzulässiger Kanal:"+text(c)) FI;  +  kanalmode := modus;  +  IF kanalmode < 1 OR kanalmode > max mode  +        THEN errorstop ("unzulässiger Netzbetriebsmodus:"+text(kanalmode))  +        ELSE netz mode (c) := kanalmode  +  FI;  +  IF NOT exists task ("net port")  +  THEN +    begin ("net port",PROC net io, net task (c)); +    define collector (/"net port") +  ELSE  +    begin ("net port "+text (c),PROC net io, net task (c)) +  FI.  +END PROC starte kanal; + +PROC routen (INT CONST von, bis, kanal, zw):  +  INT VAR i; +  IF kanal < 0 OR kanal > 15 THEN errorstop ("Kanal unzulässig") FI; +  test (von); test (bis);  +  FOR i FROM von UPTO bis REP  +      route.port (i) := kanal+256;  +      IF zw=0 +      THEN  +        route.zwischen (i) := i   +      ELSE  +        test (zw); +        route.zwischen (i) := zw +      FI  +  PER.  +END PROC routen;  +  +PROC routen (INT CONST von, bis, kanal):  +  routen (von, bis, kanal, 0)  +END PROC routen; + +PROC test (INT CONST station):  +  IF station < 1 OR station > maxstat  +  THEN  +    errorstop (text (station) + " als Stationsnummer unzulässig")  +  FI  +END PROC test;  +  +PROC aktiviere netz:  +vorgegebene routen pruefen;  +IF existstask ("net timer") THEN end (/"net timer") FI; +begin ("net timer",PROC timer,sohn); +IF NOT alte routen  +THEN  +  routen aufbauen +ELSE +  IF online THEN break FI +FI.  + +vorgegebene routen pruefen:  +  INT VAR i;  +  FOR i FROM 1 UPTO maxstat REP  +    INT VAR s := route.port (i) AND 255;  +    IF s > 0 AND s <= 15 CAND nettask (s) = niltask  +    THEN  +      errorstop ("Kanal "+text(s)+" nicht gestartet, steht aber in Routen")  +    FI  +  PER. +END PROC aktiviere netz;  +  +  +PROC routen aufbauen:  +  alte routen := TRUE; +  c := channel; +  break (quiet); +  begin ("router", PROC rout0, sohn).  +END PROC routen aufbauen;  +  +PROC rout0:  +  disable stop;  +  rout;  +  IF is error  +  THEN  +    put error  +  FI;  +  end (myself)  +END PROC rout0;  +  +PROC rout: +  IF c>0 THEN continue (c) FI; +  clear error;   enable stop; +  fetch ("port intern"); +  route := old ("port intern");  +  routen aufbauen; +  ds := old ("port intern"); +  call (father, neue routen code, ds, reply).  +  +routen aufbauen: +  access catalogue;  +  TASK VAR port := brother (myself);  +  WHILE NOT (port = niltask) REP  +    IF text (name (port),8) = "net port" THEN nachbarn FI;  +    port := brother (port)  +  PER;  +  IF online THEN putline ("Fertig. Weiter mit SV !") FI.  + +aenderbar: route.port (st) < 256. + +nachbarn:   +  INT VAR st,reply;  +  FOR st FROM 1 UPTO maxstat REP  +    IF erlaubt (st) >= 0 AND st <> station (myself) AND aenderbar +    THEN  +      IF online THEN put (name (port)); put (st) FI; +      DATASPACE VAR ds := nilspace;  +        call (port, tabellencode+st, ds, reply); +        IF reply = ack  +        THEN  +          BOUND STRUCT (ROW maxstat INT port,  +                        ROW maxstat INT zwischen)  VAR fremd := ds;  +          route.port (st) := channel(port);  +          route.zwischen (st) := st;  +          indirekte ziele  +        ELIF reply < 0 +        THEN +          errorstop ("netz läuft nicht (Kanalnummer falsch)") +        ELSE  +          BOUND TEXT VAR xt := ds; +          IF online THEN put (xt) FI; +        FI; +      IF online THEN line FI; +      forget (ds)  +    FI +  PER.  +  +indirekte ziele:    +  INT VAR kanal := fremd.port (station (myself)) AND 255; +  INT VAR ind;  +  FOR ind FROM 1 UPTO maxstat REP  +    IF ind bei st bekannt AND NOT ((fremd.port (ind) AND 255) = kanal) +      AND route.port (ind) < 256 +    THEN  +      route.port (ind) := channel (port);  +      route.zwischen (ind) := st  +    FI  +  PER. +  +ind bei st bekannt: NOT (fremd.port (ind) = -1). +  +END PROC rout; + + +PROC timer:  +  disable stop; +  access catalogue; +  INT VAR old session := 1; +  REP  +    IF session <> old session +    THEN +      define collector (/"net port"); +      old session := session +    FI; +    clear error; +    pause (30);  +    sende tick an alle ports  +  PER. +  +sende tick an alle ports : +  TASK VAR fb := son (father);  +  REP  +   IF NOT exists (fb) THEN access catalogue;LEAVE sende tick an alle portsFI; +   IF channel (fb) > 0 +   THEN  +     DATASPACE VAR ds := nilspace; +     send (fb, ack, ds);  +     pause (10) +   FI; +   fb := brother (fb)  +  UNTIL fb = niltask PER.  +  +END PROC timer;  + +PROC net io: +  disable stop;  +  set net mode (kanalmode);  +  fetch ("port intern");  +  route := old ("port intern"); +  commanddialogue (FALSE);  +  continue (c); +  communicate; +  TEXT VAR emsg := "++++++ "+error message +" Zeile "+text(errorline); +  clear error;  +  report (emsg); +  end (myself)  +END PROC net io;  +  +PROC start: run ("netz") END PROC start;  +  +END PACKET net manager; + diff --git a/system/net/1.8.7/src/net report b/system/net/1.8.7/src/net report new file mode 100644 index 0000000..ddc19d2 --- /dev/null +++ b/system/net/1.8.7/src/net report @@ -0,0 +1,41 @@ +PACKET net report DEFINES report, abgleich:  +(* Version   3 (!) *) +  +LET reportcode = 99, abgleichcode = 98;  + +PROC abgleich (INT CONST ende, zwischen):  +  DATASPACE VAR ds := nilspace;  +  BOUND STRUCT (INT ende, zwischen) VAR x := ds;  +  x.ende := ende;  +  x.zwischen := zwischen;  +  call (father, abgleichcode, ds, rep); +  INT VAR rep; +  forget (ds)  +END PROC abgleich; + +PROC report (TEXT CONST x): +  report(x,"")  +END PROC report; +  +PROC report (TEXT CONST txt, info):  +  DATASPACE VAR net report := nilspace; +  BOUND TEXT VAR rinfo := net report; +  rinfo := date; +  rinfo CAT " "+time of day +" ";  +  rinfo CAT name(myself)+":"; +  rinfo CAT txt; +  INT VAR i;  +  FOR i FROM 1 UPTO length (info) REP  +    INT VAR z :=  code (infoSUBi)  ; +    IF z < 32 OR z > 126  +      THEN rinfo CAT "%"+text(z)+" "  +      ELSE rinfo CAT (infoSUBi)+" " +    FI +  PER;  +  call (father, report code , net report, reply); +  INT VAR reply; +  forget (net report); +END PROC report;  +  +END PACKET net report; + diff --git a/system/net/1.8.7/src/netz b/system/net/1.8.7/src/netz new file mode 100644 index 0000000..c237ba2 --- /dev/null +++ b/system/net/1.8.7/src/netz @@ -0,0 +1,20 @@ +IF exists ("port intern") THEN forget ("port intern") FI;  +definiere netz;  +list option;  +erlaube(1,127);  +sperre (1,9);  +sperre (15,32);  +sperre (37,37);  +sperre (42,42);  +sperre (46,47);  +sperre (49,127);  +routen (1, 32,8);  +routen (33,43,  9);  +routen (34,34,8);  +routen (35,48,9);  +starte kanal (9,11,10);  +starte kanal (8,1,10);  +aktiviere netz; + + + diff --git a/system/net/unknown/doc/EUMEL Netz b/system/net/unknown/doc/EUMEL Netz new file mode 100644 index 0000000..941e2ea --- /dev/null +++ b/system/net/unknown/doc/EUMEL Netz @@ -0,0 +1,829 @@ +#type ("trium8")##limit (11.0)#  +#start(2.5,1.5)##pagelength (17.4)#  +#block#  +#headeven#  +  +%                        EUMEL-Netzbeschreibung  +  +  +#end#  +#headodd#  +  +#center#Inhalt#right#%  +  +  +#end#  +  +#type ("triumb12")#  +1. Einleitung  +  +  +Teil 1: Netz einrichten und benutzen  +#type ("trium8")#  +  +1. Benutzung des Netzes  +  +2. Hardwarevoraussetzungen  +  +3. Einrichten des Netzes  +  +4. Informationsmöglichkeiten  +  +5. Eingriffsmöglichkeiten  +  +6. Fehlerbehebung im Netz  +  +#type ("triumb12")#  +  +Teil 2: Arbeitsweise der Netzsoftware  +#type ("trium8")#  +  +1. Die Netztask  +  +2. Protokollebenen  +  +3. Stand der Netzsoftware  +  +#page#  +#headodd#  +  +#center#Einleitung#right#%  +  +  +#end#  +  +#type("triumb12")#  +1. Einleitung #type("trium8")#  +  +  +Das EUMEL-Netz dient dazu mehrere EUMEL-Rechner (sog. Stationen) mit +einander zu koppeln. Diese Kopplung wird von Betriebsystem dazu benutzt, das +Sendungskonzept (siehe Systemhandbuch 1.7, Intertaskkommunikation) so auszu +dehnen, daß Tasks verschiedener Stationen einander Datenräume zusenden +können. Auf dem Sendungskonzept aufbauende Konzepte nutzen daher automa +tisch das Netz aus: So ist es z.B. möglich  +  +- von einer Station aus auf einer anderen zu Drucken,  +  +- in PUBLIC einer anderen Station Dateien zu sichern (save), vorausgesetzt, daß +  PUBLIC dort ein free global manager ist,  +  +- auf einer anderen Station zu archivieren (z.B. wenn das eigene Archivlaufwerk +  defekt ist oder ein anderes Format hat).  +  +Das Netz kann ab EUMEL-Version 1.7.3 eingesetzt werden.  +  +  +#type("triumb12")#  +Teil 1: Netz einrichten und benutzen  +  +1. Benutzung des Netzes #type("trium8")#  +#headodd#  +  +#center#Teil 1: Netz einrichten und benutzen#right#%  +  +  +#end#  +  +   Zur Benutzung des Netzes stehen folgende Operatoren und Prozeduren zur +   Verfügung:  +  +  +1.1  +  +   TASK OP / (INT CONST station, TEXT CONST taskname)  +  +   liefert die Task #on("bold")#taskname#off("bold")# von der Station #on("bold")#station#off("bold")#.  +  +   Wenn die Station #on("bold")#station#off("bold")# nicht am Netz ist oder nicht eingeschaltet ist, wird +   solange gewartet, bis das der Fall ist.  +  +   Fehlerfälle:  +  +     - task "..." gibt es nicht  +  +       Die angeforderte Task gibt es in der Zielstation nicht.  +  +     - Collectortask fehlt  +  +       Das Kommando #on("bold")#define collector#off("bold")# wurde nicht gegeben (siehe 4.2).  +  +     - Station x antwortet nicht  +  +       Eine nicht vorhandene oder abgeschaltete Station wurde angesprochen.  +       Hinweis: Dieser Fehler wird angenommen, wenn eine Überwachungszeit +                von ca. 30 Sekunden verschrichen ist, ohne daß Station x die +                Taskidentifikation angeliefert hat.  +  +   Beispiel:  +  +     list (5/"PUBLIC")  +  +     Dateiliste von PUBLIC auf Station 5 wird angefordert.  +  +1.2  +  +   TASK OP / (INT CONST station, TASK CONST task)  +  +   liefert  +  +   station / name (task) .  +  +  +   Beispiel:  +  +     list (4/archive)  +  +  +1.3  +  +   INT PROC station (TASK CONST task)  +  +   liefert die Stationsnummer der Task #on("bold")#task#off("bold")#.  +  +   Beispiel:  +  +     put (station (myself))  +  +     gibt die eigene Stationsnummer aus.  +  +  +1.4  +  +   PROC archive (TEXT CONST archivename, INT CONST station)  +  +   dient dazu das Archiv auf der Station #on("bold")#station#off("bold")# anzumelden.  +  +   Beispiel:  +  +   archive ("std", 4); list (4/archive)  +  +   gibt das Inhaltsverzeichnis der Archivfloppy im Laufwerk der Station 4 aus.  +   Hinweis: Vergessen Sie bei solchen Querarchivierungen nicht die Stations +            angabe bei jedem einzelnen Archivkommando (z.B fetch ("xxx", #on("bold")#4/#off("bold")# +            archive).  +   Hinweis: Querarchivieren ist langsam. Verwenden Sie es nur, wenn Sie Flop +            pyformate umsetzen wollen.  +  +  +1.5  +  +   PROC free global manager  +  +   dient dazu, die eigene Task über das Netz ansprechbar zu machen. Jede +   andere Task im Netz kann dann die üblichen Manageraufrufe ('save', 'fetch', +   u.s.w.) an die eigene Task machen, sofern diese nicht an ein Terminal gekop +   pelt ist.  +  +   Die Task wird (wie bei 'break') abgekoppelt und meldet sich in Zukunft mit +   'maintenance' statt mit 'gib kommando'.  +  +   Beispiel:  +  +   An Station 4 ruft man in der Task 'hugo' das Kommando #on("bold")#free global manager#off("bold")# +   auf. Anschließend kann man von jeder Station aus z.B. 'list (4/"hugo")' u.s.w. +   machen.  +  +  +1.6  +  +  TEXT PROC name (TASK CONST t)  +  +  Diese (schon immer vorhandene) Prozedur wurde dahingehend erweitert, daß der +  Name einer Task einer anderen Station über Netz angefordert wird.  +  +  Fehlerfall:  +  +  Station x antwortet nicht  +  +  +  +  +#type("triumb12")#2. Hardwarevoraussetzungen#type("trium8")#  +  +2.1 Zwei Stationen  +  +      Sie können zwei Stationen miteinander Vernetzen, wenn Sie dafür an jeder +      Station eine V24-Schnittstelle zur Verfügung stellen.  +  +      Diese beiden Schnittstellen verbinden Sie mit einem Kabel zur Rechner +      kopplung (siehe Systemhandbuch 1.7 Teil 2).  +  +2.2 Mehrere Stationen  +  +      Wenn Sie mehr als zwei Stationen vernetzen wollen, brauchen neben je +      einer V24 an jeder Station noch je eine Netzanschlußbox.  +  +      Jede Box besitzt eine V24-Schnittstelle zum Anschluß an die V24- +      Schnittstelle der zugeorneten Station und eine weitere Schnittstelle zur +      Verbindung der Boxen untereinander.  +  +  +#type("triumb12")#3. Einrichten des Netzes #type("trium8")#  +  +Hinweis: Dieses Kapitel ist nur für Systembetreuer wichtig.  +  +3.1 Legen Sie Stationsnummern für die am Netz beteiligten Rechner fest (von 1 an +    aufsteigend).  +  +    Die Boxen haben ebenfalls Stationsnummern. Die Stationsnummern der Box +    und des zugeordneten Rechners müssen übereinstimmen.  +  +  +3.2 Holen Sie an jeder Station die Task #on("bold")#configurator#off("bold")# an ein Terminal und geben Sie +    das Kommando #on("bold")#define collector ("net port")#off("bold")#. Geben Sie außerdem das +    Kommando #on("bold")#define station (x)#off("bold")#, wobei #on("bold")#x#off("bold")# die gewählte Stationsnummer ist.  +  +    Hinweis: Taskkommunikationen, die zu dem Zeitpunkt laufen, führen zu feh +             lerhaften Verhalten. Dies liegt daran, daß durch #on("bold")#define station#off("bold")# alle +             Task-Id's geändert werden müssen, weil eine Task-Id u.a. die +             Stationsnummer der eigenen Station enthält (siehe 2.3). TASK- +             Variable, die noch Task-Id's mit keiner oder falscher Stationsnum +             mer enthalten, können nicht mehr zum Ansprechen einer Task +             verwendet werden.  +  +    Beispiel: Der Spoolmanager (siehe Benutzerhandbuch 1.7 Teil 12) richtet +              beim Kommando #on("bold")#start#off("bold")# einen Worker ein und merkt sich dessen +              Task-Id in einer TASK-Variablen, um sicherzustellen, daß nur der +              Worker Dateien zum Drucken abholt. Wird jetzt das Kommando #on("bold")# +              define station#off("bold")# gegeben, kann der Spoolmanager seinen Worker +              nicht mehr identifizieren, weil der Worker eine neue Task-Id er +              halten hat. Man muß daher den Worker löschen und mit dem +              Kommando #on("bold")#start#off("bold")# im Spoolmanager wieder neu einrichten.  +  +  +             Sinnvollerweise gibt man #on("bold")#define station#off("bold")# sofort nach den Laden eines +             frischen Systems von Archiv.  +  +    Konfigurieren Sie mit dem Kommando #on("bold")#configurate#off("bold")# den für das Netz vorgese +    henen Kanal auf  +  +    - transparent  +    - 9600 Baud (Standardeinstellung der Boxen)  +    - RTS/CTS-Protokoll  +    - großen Puffer  +    - 8 bit  +    - even parity  +    - 1 stopbit.  +  +    Falls diese Einstellungen nicht alle angeboten werden, klären Sie mit Ihrem +    Rechnerlieferanten, ob und wie diese Einstellungen erreicht werden können.  +    Hinweis: Notfalls kann auf das RTS/CTS-Protokoll verzichtet werden, wenn +             der Eingabepuffer der Station groß genug ist. Die Anzahl simultan +             laufender Netzkommunikationen ist dann auf  +  +             puffergröße DIV 150  +  +             begrenzt (bei Z80, 8086: 3; bei M20: 10).  +   Hinweis: Es können auch andere Baudraten (2400, 4800, 19200) an der Box +            eingestellt werden.  +  +3.3 Achten Sie bei der Verbindung von der Station zur Netzbox (bzw. zur Gegen +    station bei einem Zweistationennetz ohne Boxen) darauf, daß neben den +    Empfangs- und Sendeleitungen auch die Leitungen RTS und CTS verdrahtet +    werden, also ein 5 poliges Kabel verwendet wird (siehe Systemhandbuch 1.7 +    Teil 2). Die Pin-Belegung der Boxen entspricht den dortigen Angaben.  +  +    Beispiel:  +  +    Verbindung eines CSK-Systems mit der Box:  +  +    Stecker                  Stecker  +    Pin                      Pin  +  +    2  <--------->           3  +    3  <--------->           2  +    4  <--------->           5  +    5  <--------->           4  +    7  <--------->           7  +  +  +3.4 Richten Sie eine Task #on("bold")#net#off("bold")# unter #on("bold")#SYSUR#off("bold")# ein und insertieren Sie dort die Datei +en  +  +    net report/M  +    basic net  +    net manager/M.  +  +    Beantworten Sie die Frage nach dem Kanal für das Netz und nach der Fluß +    kontrolle (RTS/CTS).  +  +  +#type("triumb12")#4. Informationsmöglichkeiten #type("trium8")#  +  +   In der Task #on("bold")#net#off("bold")# wird eine Datei #on("bold")#report#off("bold")# geführt in der Fehlersituationen des +   Netzes verzeichnet werden. Diese Datei kann in jeder anderen Task mit #on("bold")#list +   (/"net")#off("bold")# angezeigt werden.  +  +   In jeder Task kann durch das Kommando #on("bold")#list (/"net port")#off("bold")# eine Übersicht über +   die momentan laufenden Netzübertragungen der eigenen Station erhalten +   werden.  +  +  +#type("triumb12")#5. Eingriffsmöglichkeiten #type("trium8")#  +#headodd#  +  +#center#Eingriffsmöglichkeiten#right#%  +  +  +#end#  +  +5.1 Jede Task kann Sende- und Empfangsströme, die bei #on("bold")#list (/"net port")#off("bold")# gemel +    det worden sind und die eigene Task betreffen, abbrechen. Hierzu ist das +    Kommando #on("bold")#erase ("x",/"net port")#off ("bold")# zu geben, wobei x die Stromnummer (aus +    dem 'list') ist.  +  +    Unberechtigte Löschversuche werden abgewiesen.  +  +    Von der Task 'net' aus können jedoch damit beliebige Ströme abgebrochen +    werden.  +  +5.2 Durch das Kommando #on("bold")#start#off("bold")# kann von der Task 'net' aus das Netz neu gestartet +    werden. Dabei werden alle augenblicklichen Netzkommunikationen gelöscht. +    Die Tasks 'net port' und 'net timer' werden dabei gelöscht und neu eingerich +    tet.  +  +    #on("bold")#start (kanal, quit)#off("bold")# wirkt wie #on("bold")#start#off("bold")#. Zustzlich wird als Netzkanal 'kanal' eingestellt +    und maximal 'quit' Empfangsströme zugelassen. 'quit' ist auf 3 zu setzen, +    wenn der Kanal ohne RTS/CTS angeschlossen ist (siehe 3.2).  +  +  +#type("triumb12")#6. Fehlersuche im Netz #type("trium8")#  +  +   Fehler im Netz können sich verschiedenartig auswirken. Im Folgenden wird auf +   einige Beispiele eingegangen:  +  +   Beispiel:  +  +   Auf #on("bold")#list (4/public)#off("bold")# erfolgt die Meldung 'Station 4 antwortet nicht'.  +  +   Fehlermöglichkeiten:  +  +   -  Station 4 gibt es nicht am Netz.  +      Abhilfe: Richtige Station angeben.  +  +   -  Station 4 ist nicht eingeschaltet.  +      Abhilfe: Station 4 einschalten. Kommando erneut geben.  +  +   -  Netztask an Station 4 ist nicht arbeitsfähig.  +      Abhilfe: Kommando 'start' in der Task 'net'.  +  +   -  Stationsnummern und Boxnummern stimmen nicht überein.  +      Abhilfe: Mit 'define station' Stationsnummern korrigieren (siehe 3.2).  +  +   -  Verbindung Rechner/Box am eigenen Rechner oder an Station 4 fehlt.  +      Abhilfe: Verbindungen überprüfen. Durch Ansprechen einer dritten Station +               kann oft schnell geklärt werden, welche Rechner/Box-Verbindung +               defekt sein muß.  +  +   -  Verbindung der Boxen untereinander defekt.  +      Abhilfe: Fehlende Verbindung, Masseschluß und Dreher (keine 1:1 Ver +               bindung) überprüfen und beheben.  +      Hinweis: Liegt z.B. ein Masseschluß vor, so kann es durchaus sein, daß +               Boxen, die nicht in der Nähe des Masseschluß stehen noch mitei +               nander arbeiten können. Man kann aus der Tatsache, daß zwei +               Boxen miteinander arbeiten können, also nicht schließen, daß man +               nicht nach diesem Fehler suchen muß.  +  +  +   Beispiel:  +  +   Auf #on("bold")#list (4/public)#off("bold")# erfolgt keine Reaktion.  +  +  +   -  Station 4 ist während dieser Sendung zusammengebrochen.  +      Abhilfe: Station 4 wieder starten. Die Bearbeitung des 'list'-Kommandos +               wird automatisch wieder aufgenommen.  +  +   -  PUBLIC auf Station 4 ist nicht im Managerzustand.  +      Abhilfe: PUBLIC in den Managerzustand versetzen.  +  +  +      Hinweis: Das Netz hat nocht nicht die volle Sendungslogik des EUMEL. So +               wird nur ca. 10 Minuten lang versucht, eine Sendung zuzustellen. +               Danach wird die Sendung gelöscht. Ist dies eingetreten, so muß +               das list-Kommando erneut gegeben werden.  +  +   -  Fehler in der Netzhardware.  +      Überprüfen Sie, ob  +  +      - die Boxen eingeschaltet sind,  +      - die Bereitlampe blinkt (wenn nicht: RESET an der Box)  +      - die V24-Kabel richtig stecken,  +      - die Boxen untereinander verbunden sind (1 zu 1 Verbindungen der 5 +        poligen Diodenbuchsen).  +  +  +   -  Die Netzsoftware ist auf einen nicht vorhergesehenen Fehler gelaufen.  +      Dieser wird im Report vermerkt.  +      Abhilfe: Geben Sie in der Task #on("bold")#net#off("bold")# das Kommando #on("bold")#start#off("bold")#. Dadurch wird die +               Netzsoftware neu gestartet. Alle Netzkommunikationen dieser +               Station gehen verloren.  +  +  +   Beispiel:  +  +   Auf #on("bold")#list (4/public)#off("bold")# erfolgt die Meldung 'Collectortask fehlt'.  +  +   -  In der Task 'configurator' wurde das Kommando 'define collector' (siehe 3.2) +      nicht gegeben.  +  +   -  Die Task 'net port' existiert nicht mehr.  +      Abhilfe: Kommando 'start' in der Task 'net'.  +  +  +   Beispiel:  +  +   Nach #on("bold")#fetch ("hugo",4/public)#off("bold")# sind Teile von der Datei "hugo" verfälscht.  +  +   -  Die V24-Verbindung zur Box ist nicht in Ordnung.  +      Abhilfe: Abstand zwischen Rechner und Box verkürzen; Baudrate ernie +               drigen; Durch Wechseln der V24-Schnittstelle feststellen, ob +               diese defekt ist.  +      Hinweis: Die Verbindung zwischen den Boxen ist durch Prüfsummen abge +               sichert (Hardware).  +  +#headodd#  +  +#center#Teil 2: Arbeitsweise der Netzsoftware#right#%  +  +  +#end#  +#page#  +#type("triumb12")#  +  +Teil 2: Arbeitsweise der Netzsoftware  +  +  +1. Die Netztask #type ("trium8")#  +  +In diesem Kapitel wird beschrieben, wie eine Netztask in das System +eingebettet ist und welche Aufgaben sie hat. Unter Einhaltung dieser +Konzepte kann die ausgelieferte Netztask so geändert werden, daß sie +beliebige andere Netzhardware unterstützt. Z.Zt. ist die Netzsoftware noch +nicht so gegliedert, daß nur eine hardwareabhängige Komponente ausgetauscht +werden muß.  +  +Die Kommunikation zwischen Tasks im EUMEL-Betriebssystem basiert auf einem +Rendevouskonzept: Die Zieltask einer Sendung muß empfangsbereit sein, wenn die +Quelltask sendet.  +  +Die Kommunikationsprozeduren auf der niedrigsten Ebene sind 'send' (Senden) +und 'wait' (Warten auf Empfang). Bei der Kommunikation werden eine Integer +'code' und ein Datenraum 'dr' übergeben. 'code' muß >= 0 sein, da negative +Codes systemintern verwandt werden. Ist die empfangende Task an einen Kanal +gekoppelt ('continue'), so führt eine Zeicheneingabe auf diesem Kanal dazu, +daß eine +Sendung mit dem Code -4 ankommt. Die Eingabedaten müssen mit den üblichen +Eingabeprozeduren ('inchar' u.s.w.) abgeholt werden. Der übermittelte Datenraum +und die Absendertask sind dabei ohne Bedeutung und dürfen nicht interpretiert +werden.  +  +Die Prozedur 'send' hat einen Rückmeldeparameter, der besagt, ob die Sendung +übermittelt wurde. Gibt es die Zieltask nicht oder steht sie nicht im 'wait', so kann +die Sendung nicht übermittelt werden.  +  +  +Ein Entwicklungskriterium für das EUMEL-Netz war es, möglichst wenig Unter +stützung von der virtuellen EUMEL-Maschine (EUMEL0) zu fordern, damit weit +gehend in ELAN programmiert werden kann. Dadurch ist es möglich eine (privili +gierte) Task mit der Netzabwicklung zu betrauen.  +  +Zunächst wird auf die EUMEL0-Unterstützung eingegangen:  +  +1.1. Es gibt die Prozedur 'define collector', mit der die für das Netz verantwort +     liche Task der EUMEL0-Maschine bekannt gemacht wird. Diese Task wird im +     folgenden Collector genannt.  +  +1.2. Es gibt die Prozedur 'define station', die für den Rechner eine Stationsnum +     mer einstellt. Anhand dieser Nummer werden die Rechner eines Netzes un +     terschieden. Das Einstellen bewirkt, daß für alle Tasks die Stationsnummer in +     ihre Task-Id eingetragen wird (Task-Id's sind die Werte, die der Typ TASK +     annehmen kann).  +  +1.3. Der Befehl 'station (task)' liefert die Stationsnummer der 'task'. So liefert z.B. +     'station (myself)' die Stationsnummer des eigenen Rechners.  +  +1.4. Eine Sendung, deren Zieltask in einem anderen Rechner liegt (also station +     (ziel) <> station (myself)), wird auf die Collectortask geleitet.  +  +1.5. Es gibt eine Prozedur 'collected destination', die es dem Collector erlaubt, die +     eigentliche Zieltask einer auf ihn geleiteten Sendung zu erfahren.  +  +1.6. Es gibt eine Variante der Prozedur 'send', die es dem Collector gestattet, der +     Zieltask eine beliebige andere Task als Absender vorzumachen.  +  +1.7. Es gibt eine spezielle Task-Id 'collector', durch die der augenblicklich ein +     gestellte Collector erreicht wird. Diese wird als Zieltask beim Aufruf der Ver +     mittlungsdienste angegeben (siehe 2.5). Eine Sendung an 'collector' wird von +     EUMEL0 an den derzeitigen Collector geschickt.  +  +Ein Collector kann also auf drei Wegen von den übrigen Tasks desselben Rechners +Sendungen erhalten:  +  +  1. Über ein normales Send (z.B. bei 'list (/"net port")', wenn "net port" der der +     zeitige Collector ist),  +  +  2. über ein Send an die Task 'collector' (s.u.) und  +  +  3. als umgeleitete Sendung (z.B. bei 'list' an eine Task auf einem anderen +     Rechner).  +  +Der Collector kann diese Fälle anhand von 'collected destination' unterscheiden.  +  +Die Punkte 1.4...1.6 dienen dazu, den Collector für über Netz kommunizierende +Task unsichtbar zu machen: Der Collector taucht nicht als Ziel oder Quelle von +Sendungen auf. Das ist notwendig, damit normale Tasks sich nicht darum kümmern +müssen, ob eine Sendung übers Netz geht oder im eigenen Rechner bleibt.  +  +Wenn ein Datenraum an einen anderen Rechner geschickt wird, muß der gesamte +Inhalt (z. Zt. max. 1 MB) übertragen werden. Dies macht bei der üblichen Netz +hardware eine Zerlegung in Packete nötig (siehe Systemhandbuch 173, Teil 4, +Punkt 5). Für Netze über V24-Kanäle stehen spezielle Blockbefehle zur verfü +gung:  +  +1.8. blockin / blockout (dr,seite,512+abstand,anzahl,rest)  +  +   Es werden maximal 'anzahl' Bytes transferiert. In 'rest' wird zurückgemeldet, +   wieviel Bytes nicht bearbeitet wurden (z.B. weil der Kanal nichts anliefert). +   Bearbeitet werden die Bytes  +  +      'seite' * 512 + 'abstand'  +  +   bis maximal  +  +      'seite' * 512 + 'abstand' + 'anzahl' - 1  +  +  Der Kanal, an den die Task gekoppelt ist, wird dabei über Stream-IO (d.h. +  'incharety' bei 'blockin' bzw. 'out' bei 'blockout') angesprochen.  +  +  Hinweis: Die Anforderung darf nicht über Seitengrenze gehen, d.h.  +  +  'abstand' + 'anzahl' <= 512  +  +  muß erfüllt sein.  +  +  +Eine Netzsendung läuft wie folgt ab:  +  +Die Task q auf Rechner rq mache ein 'send' an die Task z auf Rechner rz.  +  +1. Die Prozedur send ist ein EUMEL0-Befehl. Die EUMEL0-Ebene erkennt, daß +   die Sendung an die Station rz geht, da die Stationsnummer in der Task-Id +   enthalten ist. Daher wird die Sendung zum Collector, den EUMEL0 wegen 'de +   fine collector' kennt, umgeleitet.  +  +2. Die Task Collector empfängt über 'wait' den Datenraum, den Sendecode und +   die Absendertask q. Die Zieltask z erfährt sie durch 'collected destination'.  +  +3. Der Collector nimmt Kontakt mit dem Collector des Rechner rz, dessen Sta +   tionsnummer ja 'station(z)' ist, auf und Übermittelt diesem Sendecode, Quelltask +   (q), eigentliche Zieltask (z) und den Datenraum. Da die Collectoren in ELAN +   geschrieben sind, können sie an beliebige Netzhardware und Protokolle ange +   paßt werden.  +  +4. Der Collector auf Rechner rz verwendet das spezielle 'send', um der Zieltask die +   Sendung zuzustellen. Dadurch erscheint nicht der Collector sondern die Task q +   als Absender der Sendung.  +  +Zur Abwicklung der Vermittlungsebene (Teil 1: 2.4) muß der Collector noch +spezielle Funktionen beherrschen. Diese sind  +  +   der /-Operator (Taskname in Task-Id wandeln) und  +   die name-Prozedur (Task-Id in Namen wandeln).  +  +Der /-Operator macht eine Sendung an den 'collector', wobei im Datenraum der +Name der Task steht und der Sendecode gleich der Stationsnummer ist (siehe +Quellcode 173, Packet tasks). Der Collector setzt sich mit dem Collector dieser Sta +tion in Verbindung, damit dieser die Task-Id ermittelt und zurückschickt. Der +eigene Collector schickt dann dem /-Operator als Antwort einen Datenraum, der +die Task-Id enthält.  +  +Umgekehrt läuft 'name' ab: Wenn die Task-Id von einer fremden Station ist, +schickt 'name' eine Sendung an den 'collector', wobei im Datenraum die Task-Id +steht und Sendecode = 256 ist. Der Collector entnimmt die Stationnummer der +Task aus der Task-Id und läßt sich vom entsprechenden Collector den Tasknamen +geben. Dieser wird der 'name'-Prozedur im Antwortdatenraum übergeben.  +  +#type ("triumb12")#2. Ebenen #type("trium8")#  +  +In diesem Kapitel werden die Protokollebenen für das Netz beschrieben, wie +sie die ausgelieferte Netzsoftware benutzt und erwartet. Bei anderer +Netzhardware müssen die Ebenen 1 bis 3 ausgetauscht werden. Unter Einhaltung +der im vorigen Kapitel beschriebenen Randbedingungen können auch die höheren +Ebenen geändert werden.  +  +  +2.1 Physikalische Ebene  +  +    2.1.1  Station <--> Box  +  +           V24-Schnittstelle mit RTS/CTS-Handshake. Vollduplex.  +  +    2.1.2  Box <--> Box  +  +           RS422 über 2 verdrillte Leitungspaare (Takt und Daten).  +  +2.2 Verbindungsebene  +  +    2.2.1  Station <--> Box  +  +           Asynchron  +           8 Bit  +           Even Parity  +           2400/4800/9600/19200 Baud (einstellbar über Lötbrücken)  +  +    2.2.2  Box <--> Box  +  +           SDLC  +           400 KBaud  +  +2.3 Netzebene  +  +    2.3.1  Station <--> Box  +  +           Telegrammformat:  STX, <n>, <ziel>, <quelle>, <(n-4) byte>  +  +           <n> ist Längenangabe ( 8 <= n <= 160)  +           <ziel>, <quelle> sind Stationsnummern. Diese müssen an den je +           weiligen Boxen über Lötbrücken eingestellt sein.  +  +           Box --> Station:  +  +           Ein Telegramm kommt nur bei der Station an, bei deren Box die +           Nummer <ziel> eingestellt ist. Dadurch ist ein Mithören fremder +           Übertragungen nicht möglich (Datenschutz).  +  +           Zwischen Telegrammen können Fehlermeldungen der Box (Klartext) +           übermittelt werden (z.B. 'skipped x', wenn ein STX von der Box er +           wartet wurde, aber 'x' von der Station ankommt).  +  +           Station --> Box:  +  +           Ein Telegramm wird nur abgeschickt, wenn <quelle> mit der einge +           stellten Nummer übereinstimmt (Datenschutz: Man kann nicht eine +           beliebige Station zu sein vorschwindeln, es sei denn man hat physi +           schen Zugriff zur Box und stellt dort die Stationsnummer um).  +  +    2.3.2  Box <--> Box  +  +           Telegrammformat: FRAME, <ziel>, <quelle>, <daten> , +           <CRC-Code>  +  +           Eine Längenangabe ist nicht nötig, da SDLC eine Rekonstruktion der +           Länge erlaubt.  +  +           Telegramme mit falschen CRC-Code werden vernichtet. Auf höheren +           Ebenen muß dies durch Zeitüberwachung erkannt und behandelt +           werden.  +  +  +2.4 Transportebene  +  +    Diese Ebene wickelt das Rendevous zwischen einer Task, die 'send' macht, +    und einer Task, die im 'wait' steht, ab (siehe: EUMEL-Systemhandbuch).  +  +    Der im 'send' angegebene Datenraum wird als Folge von Seiten (im +    EUMEL-Sinne: Pagingeinheit und Allokiereinheit) übermittelt, wobei jede Seite +    noch in 64 Byte große Stücke zerlegt wird. Es werden nur echt allokierte Seiten +    übermittelt. Um nicht jedes Telegramm voll qualifizieren zu müssen, wird +    zunächst eine Art virtuelle Verbindung durch ein OPEN-Telegramm eröffnet. +    Danach folgen variable viele DATA-Telegramme. Beide Sorten werden durch +    QUIT-Telegramme quittiert, um folgende Funktionen zu ermöglichen:  +  +    Flußkontrolle (z.B. Zielrechner langsam)  +    Wiederaufsetzen (verlorene Telegramme)  +    Abbruch (z.B. weil Zieltask inzwischen beendet).  +  +    Ein CLOSE-Telegramm ist nicht nötig, da das letzte DATA-Telegramm als +    solches erkannt werden kann (siehe unten).  +  +    2.4.1 OPEN-Telegramm  +  +          STX, 20, <ziel>, <quelle>, <strom>, <sequenz>, <seite>,  +          <quelltask>, <zieltask>, <code>  +  +          <ziel>, <quelle> siehe 2.3.1  +  +          <strom>      Die Stromnummer identifiziert die virtuelle Verbindung. +                       Sie muß in den QUIT-Telegrammen angegeben wer +                       den.  +  +          <sequenz>    -1 (Kennzeichen für OPEN)  +  +          <seite>      Nummer der ersten echt allokierten Seite des Datenra +                       ums (=-1, falls Nilspace)  +  +          <quelltask>  Taskid der sendenden Task  +  +          <zieltask>   Taskid der empfangenden Task  +  +          <code>       Wert des im 'send' angegebenen Codes.  +  +    2.4.2 DATA-Telegramm  +  +          STX, 74, <ziel>, <quelle>, <sequenz>, <seite>, <64 byte>  +  +          <sequenz>    wird von Telegramm zu Telegramm hochgezählt. Dient +                       der Überwachung gegen verlorengegangene Telegramme +                       bzw. durch Zeitüberwachung verdoppelter Telegramme.  +  +          <seite>      Nummer der x.ten echt allokierten Seite des Datenra +                       ums. (x = (<sequenz>+16) DIV 8).  +  +          <64 byte>    Nutzinformation. Diese gehört zur Adresse a des Daten +                       raums.  +  +                       a = N (<sequenz> DIV 8 + 1) * 512  +                           + (<sequenz> MOD 8) * 64  +  +                       wobei N (x) die Nummer der x.ten Seite ist.  +  +                       Aus den Formeln ergibt sich, daß diese Nummer schon in +                       einem vorhergehenden DATA/OPEN-Telegramm über +                       mittelt wurde (im Feld <seite>).  +  +    2.4.3 QUIT-Telegramm  +  +          STX, 8, <ziel>, <quelle>, <strom>, <quit>  +  +          <strom>      muß die Stromnummer sein, die in dem OPEN/DATA- +                       Telegramm stand, das quittiert wird.  +  +          <quit>       0 :  ok. Nächstes Telegramm schicken.  +  +                       -1:  Übertragung neu starten (mit OPEN), weil die +                            Empfangsstation das OPEN nicht erhalten hat.  +  +                       -2:  Übertragung ca. 20 Telegramme zurücksetzen.  +  +                       -3:  Übertragung abbrechen.  +  +  +2.5 Vermittlungsebene  +  +    Diese Ebene ist dafür zuständig, Tasknamen von Task auf anderen Stationen +    in Taskids (Werte des Typs TASK) zu wandeln und umgekehrt. Hierzu wird im +    entsprechenden OPEN-Telegramm der Code -6 (bzw. -7) als <code> +    eingetragen. Die Netzempfangstask erkennt diese Codes und wickelt die +    Aufgaben selbst ab, sodaß es dabei nicht nötig ist, irgendeine Taskid der +    Zielstation zu kennen.  +  +    Dieses Verfahren ist möglich, weil im 'send' nur positive Codes erlaubt sind.  +  +2.6 Höhere Ebenen  +  +    Höhere Ebenen sind nicht mehr netzspezifisch. Sie basieren alle auf dem +    Send/Wait-Konzept des EUMEL. So gibt es z.B. den 'global manager', der +    Aufbewahrung und Zugriff von Dateien in einer Task regelt. Dabei darf diese +    Task (bei der Variante 'free global manager') auf einer beliebigen Station im +    Netz liegen. Wegen des Rendevous-Konzepts können beliebige Sicherheit +    strategien benutzt werden (z.B.: Keine Dateien an Station 11 ausliefern). Von +    großen Wert ist z.B., daß man ohne weiteres das Archiv (Floppylaufwerk) einen +    anderen Station anmelden und benuzten kann, wodurch eine einfache Kon +    vertierung von Floppyformaten möglich ist. Dies ist möglich, weil auch die Ar +    chiv-Task der Stationen sich an das Globalmanagerprotokoll halten.  +  +  +#type("triumb12")#  +Bemerkungen#type("trium8")#  +  +Fehlerbehandlung besteht bis Ebene 3 darin, fehlerhafte Telegramme einfach zu +entfernen. Die Ebene 4 überwacht den Netzverkehr sowieso über Timeouts, die +eine Wiederhohlung eines Telegrammes bewirken, wenn die Quittung ausbleibt.  +  +Da bei der sendenden Station der ganze Datenraum zur Verfügung steht, ist eine +Fenstertechnik (wie bei HDLC) nicht nötig. Es kann zu jedem Zeitpunkt um beliebig +viele Telegramme zurückgesetzt werden.  +  +Da im EUMEL eine Textdatei ein Datenraum mit sehr komplexer Struktur ist (wegen +der Insert/Delete-Möglichkeiten, ohne den Rest der Datei zu schieben), ist es ein +hoher Aufwand, von einem fremden Betriebssytem her Textdateien ins EUMEL- +Netz zu senden. Für solche Zwecke muß noch eine einfachere Dateistruktur defi +niert werden und entsprechende Dateikonverter erstellt werden.  +  +  +  +#type("triumb12")#3. Stand der Netzsoftware #type("trium8")#  +  +Das EUMEL-System wickelt die Prozedur #on("bold")#send#off("bold")# über das Netz ab, wenn die +Stationsnummer der Zieltask ungleich der eigenen Stationsnummer ist. Umge +kehrt kann man der von der Prozedur #on("bold")#wait#off("bold")# gelieferten Absendertask die Absen +derstation entnehmen (siehe Prozedur #on("bold")#station#off("bold")# in Abschnitt 3).  +  +Nicht unterstützt wird z.Zt. die Logik der Prozeduren #on("bold")#call#off("bold")# und #on("bold")#pingpong#off("bold")#. Diese +funktionieren nur in der gewohnten Weise, wenn die Zieltask in #on("bold")#wait#off("bold")# steht. Ist +die Zieltask länger als ca. 10 Minuten #on("bold")#busy#off("bold")# oder nicht mehr vorhanden, geht die +Sendung einfach verloren (Gefordert ist: bei #on("bold")#call#off("bold")#: immer wieder versuchen; bei #on("bold")# +pingpong#off("bold")#: Rückmeldung -2).  +  +Wegen dieser Einschränkung kann man z.B. ein sicheres Drucken von Station a +auf einen Drucker der Station b nur durch einen eigenen Spoolmanager auf +Station a verwirklichen. Die Einrichtung eines solchen Managers ist allerdings +sowieso sinnvoll, damit man  +  +- das normale 'print'-Kommando verwenden kann (statt z.B. save ("xxx", +4/printer);) und  +- nicht zu warten braucht, bis die Datei übers Netz gesendet ist.  + + | 
