From 04e68443040c7abad84d66477e98f93bed701760 Mon Sep 17 00:00:00 2001 From: Lars-Dominik Braun Date: Mon, 4 Feb 2019 13:09:03 +0100 Subject: Initial import --- system/net/1.7.5/doc/EUMEL Netz | 832 ++++++++++++++++++++++++++++++++++++ system/net/1.7.5/src/basic net | 840 +++++++++++++++++++++++++++++++++++++ system/net/1.7.5/src/callee | 14 + system/net/1.7.5/src/net inserter | 50 +++ system/net/1.7.5/src/net manager-M | 302 +++++++++++++ system/net/1.7.5/src/net report-M | 29 ++ 6 files changed, 2067 insertions(+) create mode 100644 system/net/1.7.5/doc/EUMEL Netz create mode 100644 system/net/1.7.5/src/basic net create mode 100644 system/net/1.7.5/src/callee create mode 100644 system/net/1.7.5/src/net inserter create mode 100644 system/net/1.7.5/src/net manager-M create mode 100644 system/net/1.7.5/src/net report-M (limited to 'system/net/1.7.5') 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. 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 + 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. + + 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 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 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 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 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, fhren zu feh- + lerhaften Verhalten. Dies liegt daran, daá durch #on("bold")#define station#off("bold")# alle + Task-Id's ge„ndert werden mssen, 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 fr 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 fr 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")# 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. 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 berprfen. 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) berprfen 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. + š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" verf„lscht. + + - 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 ge„ndert werden, daá sie +beliebige andere Netzhardware untersttzt. 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 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, m”glichst wenig Unter- +sttzung 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-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 F„lle 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 n”tig (siehe Systemhandbuch 173, Teil 4, +Punkt 5). Fr 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 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 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 zurckschickt. 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 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 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”tbrcken) + + 2.2.2 Box <--> Box + + SDLC + 400 KBaud + +2.3 Netzebene + + 2.3.1 Station <--> Box + + Telegrammformat: STX, , , , <(n-4) byte> + + ist L„ngenangabe ( 8 <= n <= 160) + , sind Stationsnummern. Diese mssen an den je- + weiligen Boxen ber L”tbrcken eingestellt sein. + + Box --> Station: + + Ein Telegramm kommt nur bei der Station an, bei deren Box die + Nummer 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 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, , , , + + + 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 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 groáe Stcke zerlegt wird. Es werden nur echt allokierte Seiten + bermittelt. Um nicht jedes Telegramm voll qualifizieren zu mssen, 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, , , , , , + , , + + , siehe 2.3.1 + + Die Stromnummer identifiziert die virtuelle Verbindung. + Sie muá in den QUIT-Telegrammen angegeben wer- + den. + + -1 (Kennzeichen fr OPEN) + + Nummer der ersten echt allokierten Seite des Datenra- + ums (=-1, falls Nilspace) + + Taskid der sendenden Task + + Taskid der empfangenden Task + + Wert des im 'send' angegebenen Codes. + + 2.4.2 DATA-Telegramm + + STX, 74, , , , , <64 byte> + + wird von Telegramm zu Telegramm hochgez„hlt. Dient + der šberwachung gegen verlorengegangene Telegramme + bzw. durch Zeitberwachung verdoppelter Telegramme. + + Nummer der x.ten echt allokierten Seite des Datenra- + ums. (x = (+16) DIV 8). + + <64 byte> Nutzinformation. Diese geh”rt zur Adresse a des Daten- + raums. + + a = N ( DIV 8 + 1) * 512 + + ( 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 ). + + 2.4.3 QUIT-Telegramm + + STX, 8, , , , + + muá die Stromnummer sein, die in dem OPEN/DATA- + Telegramm stand, das quittiert wird. + + 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 zurcksetzen. + + -3: šbertragung abbrechen. + + +2.5 Vermittlungsebene + + Diese Ebene ist dafr 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 + 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 Verfgung steht, ist eine +Fenstertechnik (wie bei HDLC) nicht n”tig. 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-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. 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 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")#: Rckmeldung -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. + + + + + 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..41c8402 --- /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..8cccedd --- /dev/null +++ b/system/net/1.7.5/src/net inserter @@ -0,0 +1,50 @@ + +{ Inserter fr EUMEL - Netz - Software; 04.12.83 + bercksichtigt 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..0383211 --- /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; -- cgit v1.2.3