{$DOUBLE} Program NEWLNK; {$nomain} { Description: Module for AMI Message Router to process net Link Request File: [AMIRTR]NEWLNK.PAS Author: Jim Bostwick Last Edit: 20-DEC-1989 23:51:02 History: 10-OCT-1989 - JMB - major happy munging... 3-AUG-1989 - JMB - Add $DOUBLE compiler switch } {$Nolist} {[a+,b+,l-,k+,r+] Pasmat } %INCLUDE 'AMIRTR.PKG'; %INCLUDE 'Signal.ext'; {$List } {*CALL*} PROCEDURE NEWLNK; EXTERNAL; {*USER* This procedure processes net link requests. Called from DoMail, it determines if a slot is available, and either accepts (and initializes) the link for that slot, or rejects the link if none is available. A future version will employ least-recently-used techniques to always accept a (non-duplicating) link by dropping a 'stale' link when necessary. This version simply rejects the request. Note that one link per remote node/router pair is required for all message traffic. This procedure will reject a link request for which an active link exists. } {*WIZARD* The link request lives in the mailbox structures - Links[0]. } PROCEDURE NEWLNK; LABEL 999; { error exit shortcut } VAR Lnk: Integer; { slot number } Slot: Integer; { number of open slot (which we'll use for new link)} new_node: CH6; { the node asking for service } new_task: CH16; { task asking for service } NetDat: CH16; { net mbx data } found: Boolean; { a flag } IOSB: Io_Status_Block; { For internal net IO } Function Find_empty_link:Integer; { Return first inactive link number, or zero if none available } VAR L: Integer; BEGIN L := 1; WHILE (Link[L].Active) AND (L <= Max_links) DO L := L + 1; If L > Max_links THEN L := 0; Find_empty_link := L END; BEGIN { Check for duplicate link and open slot } New_Node := Conb.Src_Desc.Src_Node; New_Task := Conb.Src_desc.Src_task; { Check for active link. } Found := false; For Lnk := 1 to Max_links DO if Link[Lnk].Active THEN found := ( SEqual(Link[Lnk].node, New_Node) AND SEqual(link[Lnk].Task, Conb.Src_desc.Src_task)); IF found THEN BEGIN { Reject the link as a duplicate } SAssign(NetDat, 'DUPLNK - Duplicate Link'); Signal(Sig_DUPLNK, 0, Null_IOSB, 'NEWLNK - link already exists. '); NTREJ(Mbx_Lun, Aux_Efn, NetDat, Conb, IOSB); IF (IOSB.int[1] < 1) THEN Signal(Sig_NtRejF, 0, IOSB, 'NEWLNK'); GOTO 999 { exit procedure } END; { Find an open slot } Slot := Find_Empty_link; IF (Slot = 0) THEN BEGIN { nope - reject with no-slots error } SAssign(NetDat, 'NOSLOT - No Slots Open'); NTREJ(Mbx_Lun, Aux_Efn, NetDat, Conb, IOSB); Signal(Sig_NOSLOT, 0, IOSB, 'NEWLNK '); NTREJ(Mbx_Lun, Aux_Efn, NetDat, Conb, IOSB); IF (IOSB.int[1] < 1) THEN Signal(Sig_NtRejF, 0, IOSB, 'NEWLNK'); GOTO 999 { exit procedure } END; { Accept the link request } Lnk := Slot; SClear(NetDat); NTACC(Link[Lnk].Lun, Aux_Efn, Conb, NetDat, IOSB); IF (IOSB.int[1] = 1) AND ($DSW = 1) THEN BEGIN Signal(Sig_NTAcc, Link[Lnk].Lun, IOSB, 'NEWLNK'); { Post first (nowait) net read } NTREC(Link[Lnk].Lun, Net_EFN, Loophole(address, ref(Link[Lnk].Msg)), size(Message_rec), Link[Lnk].Read_IOSB); IF ($DSW <> 1) THEN Signal(Sig_NTRECF, Link[Lnk].Lun, IOSB, 'NEWLNK') ELSE WITH Link[Lnk] DO BEGIN Active := TRUE; node := new_node; Task := New_task; WITH Stats DO BEGIN Connects := Connects + 1; Reads := 0; Writes := 0 END { with stats } END { with link } END ELSE Signal(Sig_NTAccF, Link[Lnk].Lun, IOSB, 'NEWLNK'); 999: ; END; { newlnk }