{$DOUBLE}
Program NetIn;
 {$nomain}

{ 
  Description: Process inbound DECNET messages for AMIRTR 
         File: [AMIRTR]NETIN.PAS
       Author: Jim Bostwick 
    Last Edit: 5-DEC-1989 23:21:31 
      History:
         27-NOV-1989 -JMB - Improve debug code
         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 'DoCtl.ext';
 %INCLUDE 'pas$ext:CR56TA.ext';
 %INCLUDE 'Signal.ext';
 %INCLUDE 'dbghdr.ext';
 %INCLUDE 'debug.ext';
 %INCLUDE 'dbgio.ext';

 {$List }
 {*CALL*}


  PROCEDURE NetIn(L: Integer);
    EXTERNAL;

{*USER*

  This procedure processes inbound messages from a DECNET link other
than the network mailbox. For AMIRTR, this means net messages comming
from other message routers on the net.
  Parameter L is the index into the Link array. 
  The design of the message system dictates that messages which cannot
be processed (e.g., unknown addressee) be simply dropped. This makes
error handling easy, at least at this level. 

    Messages are either: 
      1. Sent to destination task (via SMSG), possibly with additional
          action specified in message flags. 
      2. Router control messages for this router - passed to DoCtrl for
          processing. 
      3. Can't be handled and dropped on the floor. 


  This routine is also involved in link shutdown. Once the program is
notified (via net mailbox) that a link is shutting down, we stop sending
to it. However, pending inbound traffic will complete. Eventually, 
we arrive here with an IOSB of NT_ABT or NT_ABO, telling us that
the net data queue has been flushed. At that time, we go ahead and 
zap the link structures and declare the link inactive. 

 }

{*WIZARD*

 }



  PROCEDURE NetIn;

    VAR
      Tnam: Ch6; { ASCII task name for error reporting }
      Errtxt: STR40; { String for error reporting }
      shtdwn: Boolean; { flags that link shutdown complete }


    BEGIN

      { Check to see if this is the last read of a dying link }

      WITH Link[L] DO
        BEGIN
        shtdwn := ((Read_IOSB.int[1] = Nt_NT_ABT) OR
                  (Read_IOSB.int[1] = Nt_NT_ABO));
        DBGIO('NETIN - Read_IOSB = ', Read_IOSB)
        END;

      IF shtdwn THEN
        BEGIN
        END
      ELSE
        BEGIN { Normal processing }

        { update link statistics }
        WITH Link[L].Stats DO
          BEGIN
          Last_Activity := 0;
          Reads := Reads + 1
          END;

        { Process message }
        dbghdr(Link[L].msg);
        WITH Link[L].msg DO
          BEGIN
    { 
      What we're looking at here is (better be!) a standard message: header  
      followed by text. 
        }
          IF ((MyName[1] = Dest_Task[1]) AND (MyName[2] = Dest_Task[2]) AND
             Sequal(MyNode, Dest_Node)) THEN
            DoCtl(Link[L].msg) { It's a control message }
          ELSE
            BEGIN { forward on to real destination }
            router := Dest_Task;
            MsSend(Link[L].msg, Aux_EFN);
            IF ($DSW <> 1) THEN
              BEGIN
              CR56TA(Dest_Task, Tnam);
              SASSIGN(Errtxt, 'NetIn - Can not Route to <');
              SConcat(Errtxt, Tnam);
              SConcat(Errtxt, '> (Link)');
              Signal(Sig_MSSEND, L, Null_IOSB, Errtxt);
              END { If DSW }
            END { Else }
            {*** Insert ELSE clause here to deal with WAKE, RUN actions ***}
          END; { with }
        { In any case, re-post the network read. }
        NTREC(Link[L].LUN, Net_EFN, Loophole(address, ref(Link[L].msg)),
              size(Message_rec), Link[L].Read_IOSB);
        IF ($DSW <> 1) THEN
          Signal(Sig_NTRECF, Link[L].LUN, Link[L].Read_IOSB, 'NetIn (Lun)')
        END { not shutdwn }
    END; { NetIn }
