*DECK NMSG                         26MAY81
USETEXT COMCBEG 
USETEXT COMCAPR 
USETEXT COMCCAE 
USETEXT COMQDEF 
USETEXT COMQFIL 
USETEXT COMQKDS 
USETEXT COMQNET 
    PROC NMSG;
      BEGIN    # NMSG # 
# 
**    NMSG       PROCESS ALL NETWORK MESSAGES.
* 
*     NMSG VALIDATES EACH NETWORK MESSAGE AND THEN CALLS THE APPROPRIATE
*     PROCESSOR:  AREQ, SREQ, SRES, OR ILLMSG.
* 
*     PROC NMSG 
* 
*     ENTRY      NHA/NTA = NETWORK MESSAGE HEADER/TEXT. 
* 
*     EXIT       ACN = APPLICATION CONNECTION NUMBER. 
*                EB  = ERROR BIT. (EB IN NTA CLEARED.)
*                FC  = FUNCTION CODE. 
*                IDLE = TRUE IF NETWORK IDLE DOWN 
*                NOMSGCNT =0, IF MESSAGE RECEIVED.
*                RB  = RESPONSE BIT. (RB IN NTA CLEARED.) 
*                SHUTDOWN = TRUE IF NETWORK SHUT DOWN.
*                TY  = MESSAGE TYPE.
* 
*     PROCESS    TY = MESSAGE TYPE
*                IF TY NE 0:  
*                  IF BLOCK LENGTH ERROR: 
*                    SEND MESSAGE (NETWORK MESSAGE BLOCK SIZE ERROR). 
*                    CALL ABORT.
*                  IF SUPERVISORY MESSAGE:  
*                    SAVE ERROR AND RESPONSE BITS 
*                    CLEAR ERROR AND RESPONSE BITS IN MESSAGE AREA
*                    GET FUNCTION CODE
*                    IF HOST OPERATOR SUPERVISORY MESSAGE:  
*                      EXIT.
*                    GET CONNECTION NUMBER (ACN)
*                    IF QTFI NEW CONNECTION BUT DIFFERENT PID CONNECTED:  
*                      CALL SWAPAFT (SO AFT ENTRY AGREES WITH PID). 
*                  ELSE:  (NOT SUPERVISORY MESSAGE) 
*                    GET CONNECTION NUMBER (ACN). 
*                  IF ACN INVALID:  
*                    IF SUPERVISORY MESSAGE:  
*                    SEND MESSAGE (SUP MSG FOR INACTIVE ACN). 
*                    EXIT.
*                  ELSE: (ACN VALID)
*                    IF NON-SUPERVISORY MESSAGE (TYPE 1/2/6/7): 
*                      IF NOT LAST BLOCK (TYPE 1 OR 6): 
*                        SAVE TEXT IN FILE BUFFER 
*                        EXIT.
*                      IF ANY TEXT SAVED PREVIOUSLY:  
*                        MERGE NEW WITH SAVED TEXT. 
*                      IF NOT CONNECTION BREAK: 
*                        CALL AREQ. 
*                      EXIT.
*                    IF SUPERVISORY MESSAGE:  
*                      IF SHUT-DOWN FUNCTION: 
*                        IF IMMEDIATE SHUTDOWN: 
*                          CALL CONENDM (SERVICER) OR DROP INITIATOR. 
*                        ELSE: (NOT IMMEDIATE SHUTDOWN) 
*                          IDLE = TRUE. (IDLE DOWN FLAG)
*                      ELSE: (NOT SHUT-DOWN)
*                        IF SUPERVISORY REQUEST: (EB + RB = 0)
*                          CALL SREQ. 
*                        ELSE: (RESPONSE, EB + RB NE 0) 
*                          CALL SRES. 
# 
  
# 
****  XREF
# 
      XREF
        BEGIN 
        PROC ABORTQ;
        PROC AREQ;
        FUNC CHKCMM     U;         # REQUEST MEMORY # 
        PROC CONENDM; 
        PROC DROP;
        FUNC FREECMM    U;         # FREE CMM BUFFER #
        PROC FTUGETL;              # GET NETWORK DATA # 
        PROC ILLMSG;
        PROC MNS;                  # MOVE ASCII TEXT #
        PROC MOVEI; 
        PROC MSGLOG;
        PROC NAME;                 # DEBUG CODE # 
        FUNC NFETCH     U;
        PROC NSTORE;
        PROC SREQ;
        PROC SRES;
        PROC SWAPAFT; 
        PROC XWOD;                 # CONVERT BINARY TO OCTAL DISPLAY #
        END 
# 
****  XREF END
# 
  
      SWITCH   MSGTY   MTY1,
                       MTY2,
                       MTY3,
                       MTY4,
                       MTY5,
                       MTY6,
                       MTY7;
  
  
      ITEM I;                      # SCRATCH INDEX #
      ITEM J;                      # SCRATCH INDEX #
  
      DEF LEMSGBSE   #41#;
      ITEM EMSGBSE    C(LEMSGBSE) = 
                 " QTF, NETWORK MESSAGE BLOCK SIZE ERROR.  "; 
  
      DEF LEMSGIDL   #35#;
      ITEM EMSGIDL    C(LEMSGIDL) = 
                 " QTF, NETWORK IDLEDOWN IN PROGRESS."; 
  
      DEF LEMSGSHU   #23#;
      ITEM EMSGSHU    C(LEMSGSHU) = 
                 " QTF, NETWORK SHUTDOWN."; 
  
      DEF LEMSGNAP   #52#;
      ARRAY EMSGNAP S(6); 
        BEGIN 
        ITEM $DEMSGNAPA C(00,00,40) = 
          [" QTF, SUPERVISORY MESSAGE RECEIVED FOR I"]; 
        ITEM $DEMSGNAPB C(04,00,12) = 
          ["NACTIVE ACN."]; 
        ITEM EMSGNAPZB  U(05,12,48) = [0];
        END 
  
      DEF LEMSGHDR   #51#;
      ARRAY EMSGHDR S(6); 
        BEGIN 
        ITEM $DEMSGHDRA C(00,00,10) = 
          [" QTF, HDR="]; 
        ITEM $DEMSGHDRC C(01,00,41) = 
          ["XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX."];
        ITEM EMSGHDRW1  U(01,00,60);
        ITEM EMSGHDRW2  U(03,00,60);
        ITEM EMSGHDRZB  U(05,06,54) = [0];
        END 
  
    CONTROL IFEQ OS$NOS;
      DEF HOP        #X"D0"#;      # HOST OPERATOR MESSAGE (PFC) #
    CONTROL ENDIF;
  
  
        $BEGIN
        NAME("NMSG");                # DEBUG CODE # 
        $END
  
      FTUGETL (0, NHA, NTA, NTLMAX);  # GET MESSAGE # 
      TY=NFETCH(NHA,$ABHABT);      # GET MESSAGE TYPE # 
      IF TY NQ 0                   # IF MESSAGE OBTAINED #
      THEN                         # MESSAGE RECEIVED # 
        BEGIN 
        NOMSGCNT = 0;              # RESET NO MESSAGE COUNT # 
        IF NFETCH(NHA,$ABHIBU) NQ 0  # IF BLOCK UNDELIVERABLE # 
        THEN
          BEGIN 
          MSGLOG(LOC(EMSGBSE),LEMSGBSE);
          ABORTQ("NMSG/BSIZE");    # END JOB #
          END 
  
        ELSE                       # IF MESSAGE VALID # 
          BEGIN 
          IF TY EQ SUPMSG 
          THEN
            BEGIN 
            EB = NFETCH(NTA,$EB);  # SAVE ERROR BIT # 
            RB = NFETCH(NTA,$RB);  # SAVE RESPONSE BIT #
            NSTORE (NTA,$EB,0);    # CLEAR ERROR BIT #
            NSTORE (NTA,$RB,0);    # CLEAR RESPONSE BIT # 
  
            FC = NFETCH(NTA,$PFCSFC);  # GET FUNCTION CODE #
  
            IF FC EQ CONACRQ
            THEN
              BEGIN 
              ACN = 0;             # CLEAR INDEX #
              SLOWFOR I = 1 STEP 1 WHILE
                (ACN EQ 0 
                 AND I LE LACNMAX 
                 AND CONABN[1] NE 0)
              DO
                BEGIN              # FIND REQUESTING AFT ENTRY #
                P<FILETAB> = AFT[I];
                IF FILERCN EQ CONABN[1] 
                THEN
                  BEGIN 
                  FILERCN = 0;     # CLEAR REQUESTED CONN NUMBER #
                  ACN = I;         # SET INDEX #
                  END 
  
                END 
  
              END 
  
            ELSE
              BEGIN 
  
            CONTROL IFEQ OS$NOS;
              IF  (FC/256) EQ HOP  # IF PFC = HOST OPERATOR MESSAGE # 
              THEN
                BEGIN 
                GOTO EMTY;
                END 
            CONTROL ENDIF;
  
              ACN = NFETCH(NTA,$CONACN);  # GET CONNECTION NUMBER # 
              P<FILETAB> = AFT[ACN];
              IF FC EQ CONREQ      # CON/REQ #
                AND NOT QRCV       # AND QTF (INITIATOR) #
              THEN
                BEGIN 
                I = ACN;
                ACN = 0;           # CLEAR INDEX #
                SLOWFOR J = 1 STEP 1 WHILE
                  (J LE LACNMAX 
                  AND ACN EQ 0
                  AND CONRABN[1] NE 0 
                  AND I NE 0) 
                DO
                  BEGIN            # FIND REQUESTING AFT ENTRY #
                  P<FILETAB> = AFT[J];
                  IF FILERCN EQ CONRABN[1]
                  THEN
                    BEGIN 
                    FILERCN = 0;   # CLEAR REQUESTED CONN NUMBER #
                    ACN = J;       # SET INDEX #
                    IF I NE ACN    # IF REQUESTED NE ASSIGNED CONN #
                    THEN
                      BEGIN 
                      SWAPAFT(I);  # EXCHANGE AFT ENTRIES # 
                      END 
  
                    END 
  
                  END 
  
                END 
  
              ELSE
                BEGIN 
                IF FC EQ SHUTINS   # SHUT/INS # 
                THEN
                  BEGIN 
                  ACN = 1;         # SET ACN FOR QTFS # 
                  P<FILETAB> = AFT[ACN];
                  END 
  
                END 
  
              END 
  
            END 
  
          ELSE    # NOT SUPERVISORY MESSAGE # 
            BEGIN 
            ACN = NFETCH(NHA,$ABHADR);    # GET CONNECTION NUMBER # 
            P<FILETAB> = AFT[ACN];
            END 
  
          IF (ACN LE 0) 
            OR (ACN GT LACNMAX)    # BAD CONNECTION NUMBER #
            OR (AFT[ACN] EQ 0)     # AFT NOT ASSIGNED # 
          THEN
            BEGIN 
            IF TY EQ SUPMSG 
            THEN
              BEGIN 
              MSGLOG(LOC(EMSGNAP),LEMSGNAP);
              P<FET>=LOC(EMSGHDRW1);
              XWOD(NTAWD[0],FET); 
              P<FET>=LOC(EMSGHDRW2);
              XWOD(NTAWD[1],FET); 
              MSGLOG(LOC(EMSGHDR),LEMSGHDR);
              GOTO EMTY;
              END 
  
            END 
  
  
          IF (TY GE 1)             # IF BLOCK TYPE IN-RANGE # 
            AND (TY LE 7) 
          THEN
            BEGIN 
            GOTO MSGTY[TY-1];                # PROCESS MESSAGE #
            END 
  
MTY4: 
MTY5: 
MTYERR: 
          ILLMSG;                  # INVALID BLOCK TYPE # 
          GOTO EMTY;               # END OF CASE #
  
MTY1:                              # BLOCK TYPE BLOCK MESSAGES #
MTY6:                              # Q-BLOCK BLK #
          IF FILEBUF EQ 0          # IF FIRST BLOCK # 
          THEN
            BEGIN 
            FILEBUF=CHKCMM(0,NTLMAX);  # RESERVE MEMORY # 
            FILECHR=0;
            END 
  
          I=NFETCH(NHA,$ABHTLC);   # GET TEXT LENGTH IN CHARACTERS #
          MNS(NTA,I,FILEBUF,FILECHR);  # MOVE TEXTS # 
          FILECHR=FILECHR+I;       # UPDATE TEXT LENGTH # 
  
          GOTO EMTY;               # END OF CASE #
  
MTY2:                              # NON-SUPERVISORY MESSAGE #
MTY7:                              # Q-BLOCK MSG #
          IF FILEBUF NE 0          # IF NOT FIRST BLOCK # 
          THEN
            BEGIN 
            I=NFETCH(NHA,$ABHTLC);    # GET TEXT LENGTH IN CHARACTERS # 
            MNS(NTA,I,FILEBUF,FILECHR);  # MOVE TEXTS # 
            FILECHR=FILECHR+I;     # UPDATE TEXT LENGTH # 
            MOVEI(((FILECHR*8)+59)/60,FILEBUF,LOC(NTA));
            I=FREECMM(FILEBUF);    # RELEASE BUFFER # 
            FILEBUF=0;
            END 
  
          ELSE
            BEGIN 
            FILECHR=NFETCH(NHA,$ABHTLC);  # GET TEXT LENGTH # 
            END 
  
          FC = NFETCH(NTA,$PFCSFC);  # GET FUNCTION CODE #
  
          IF NOT FILEBRK           # IF CONNECTION NOT BROKEN # 
            OR FC NE CONCB         # OR CON/CB COMMAND #
          THEN
            BEGIN 
            AREQ;                  # PROCESS COMMAND #
            END 
  
          GOTO EMTY;               # END OF CASE #
  
MTY3:                              # SUPERVISORY MESSAGE #
          IF FC EQ SHUTINS         # IF SHUT-DOWN REQUEST # 
          THEN
            BEGIN 
            IF(NTAWD[1] LAN 1) NQ 0  # IF IMMEDIATE SHUT-DOWN # 
            THEN
              BEGIN 
              SHUTDOWN = TRUE;
              IDLE = TRUE;
              MSGLOG(LOC(EMSGSHU),LEMSGSHU);
              KL$IDLE = "*SHUTDOWN*"; 
              END 
  
            ELSE                   # IF NOT IMMEDIATE SHUT-DOWN # 
              BEGIN 
              IDLE=TRUE;           # SET IDLE-DOWN FLAG # 
              SHUTDOWN = SHUTDOWN OR (ACNNO EQ 0);
              MSGLOG(LOC(EMSGIDL),LEMSGIDL);
              KL$IDLE = "*IDLEDOWN*"; 
              MSGWFAIDLE = "*IDLEDOWN*";
              END 
  
            END 
  
          ELSE                     # NOT SHUT-DOWN #
            BEGIN 
            IF (RB + EB) EQ 0      # IF SUP REQUEST # 
            THEN
              BEGIN 
              SREQ;                # PROCESS REQUEST #
              END 
  
            ELSE                   # SUP RESPONSE # 
              BEGIN 
              SRES;                # PROCESS RESPONSE # 
              END 
            END 
          END                      # END OF CASE #
  
EMTY: 
        END 
      END      # NMSG # 
    TERM
