system/net/1.7.5/src/net manager-M

Raw file
Back to index

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 )