*DECK NS$NSM
USETEXT COM$NS
USETEXT DEF$NS
USETEXT ERR$NS
USETEXT NAT$NS
USETEXT NCT$NS
USETEXT NPT$NS
USETEXT PFC$NS
USETEXT SMB$NS
USETEXT SMD$NS
  
PROC NS$NSM(ERRCODE);        # PROCESS NETWORK SUPERVISORY MESSAGE     #
  
# TITLE NS$NSM - PROCESS NETWORK SM.                                   #
  
      BEGIN    # NS$NSM # 
# 
**    NS$NSM - PROCESS NETWORK SM.
* 
*     J.C. LEE    1981
* 
*     THIS ROUTINE PROCESSES NETWORK SM.
* 
*     PROC NS$NSM(ERRCODE)
* 
*     ENTRY:  
*       NONE. 
* 
*     EXIT: 
*       ERRCODE.
* 
*     METHOD: 
*       VALIDATE ABH (ABT/ACT/TLC). 
*       IDENTIFY NETWORK SM.
*       CASE ON PFC/SFC OF SM:  
*       1) NPU/IN/R 
*         IF LOAD TYPE VALID: 
*           REQUEST TO LOAD LOCAL/REMOTE NPU. 
*         ELSE, FLAG ERROR AND EXIT.
*       2) NPU/DT/N, NPU/DT/A 
*         IF COMMAND CODE NOT VALID:  
*           FLAG ERROR AND EXIT.
*       ALL NON-ERROR CASES COMES HERE. 
*         ASSIGN STIMULUS-CODE. 
*         LOCATE NPU-TABLE ENTRY. 
*         IF ERRCODE EQ 0:  
*           ACCESS NPU-TABLE ENTRY. 
*           IF NAT-TSBN NQ 0: 
*             IF NETWORK-SM IS A RESPONSE-SM: 
*               CHECK RESPONSE-SM FOR MATCH ON
*               CURRENT ACTIVITY. 
*               IF NOT MATCH: 
*                 DISCARD SM AND EXIT.
*             EXTRACT NPU-STATE FROM NCT. 
*             MAP NPU-STATE INTO STATE-ORDINAL. 
*           ELSE, SET STATE-ORDINAL TO ZERO.
*           IF A VALID STATE ORDINAL: 
*             EXECUTE NETWORK STIMULUS/STATE ACTION.
*           ELSE, DISPATCH MESSAGE AND ABORT. 
*       IF NETWORK-SM INVALID, FLAG ERROR.
* 
# 
  
      ITEM ERRCODE    U;     # ERROR CODE                              #
  
      $BEGIN
      XREF
        BEGIN 
        PROC NS$DBG;
        END 
      $END
  
      XREF
        BEGIN 
        PROC MOVEOK;         # ALLOW TSB TO MOVE                       #
        FUNC NS$FEC U;       # FORMAT ERROR CODE                       #
        PROC NS$MSG;         # DISPATCH MESSAGE                        #
        PROC NS$NSS;         # NPU STATE TABLE PROCESSOR               #
        PROC TSBINFO;        # LOCATE TSB                              #
        END 
  
      ITEM HN         U;     # DESTINATION NODE NUMBER IN ABH          #
      ITEM FOUND      B;     # INDICATES IF NPU TABLE ENTRY IS FOUND   #
      ITEM INDEX      I;     # LOOP INDEX                              #
      ITEM NCTORD     U;     # NODE CONNECTION TABLE ORDINAL           #
      ITEM NODEID     U;     # NEIGHBOR NODE NUMBER OF ADDRESSED NPU   #
      ITEM PN         U;     # PORT NUMBER OF TRUNK                    #
      ITEM SMPFC      U;     # PFC OF SM                               #
      ITEM SMPFCSFC   U;     # PFC/SFC OF SM                           #
      ITEM SN         U;     # SOURCE NODE NUMBER IN ABH               #
      ITEM STATE      U;     # NPU STATE                               #
      ITEM STIMULUS   U;     # STIMULUS TO STATE TABLE                 #
      ITEM TSBFWA     U;     # TSB FWA                                 #
      ITEM TSBSIZE    U;     # TSB SIZE                                #
  
# 
      TABLE OF PFC/SFC CODES FOR LEGAL NETWORK SUPERVISORY MESSAGES 
# 
      DEF ENDNSMT    # 8 #; 
      ARRAY NPFCSFCTAB [0:ENDNSMT] S(1);
        BEGIN 
        ITEM NSM$PFCSFC U(0,0,16) = [  # VALID NETWORK SM PFC/SFC      #
          NPUDTN, 
          NPUDTA, 
          NPUDTN, 
          NPUDTA, 
          NPUDTN, 
          NPUDTA, 
          NPUIN,
          NPUIN,
          0,
                                    ];
        ITEM NSM$NWSTIM S:NWSTIM(0,42,18) = [ # NETWORK STIMULUS CODE  #
          S"NR$NPUDTD",                # NPU/DT/N (DUMP)               #
          S"AR$NPUDTD",                # NPU/DT/A (DUMP)               #
          S"NR$NPUDTL",                # NPU/DT/N (LOAD)               #
          S"AR$NPUDTL",                # NPU/DT/A (LOAD)               #
          S"NR$NPUDTS",                # NPU/DT/N (START)              #
          S"AR$NPUDTS",                # NPU/DT/A (START)              #
          S"RQ$SAMLOAD",               # NPU/IN/C (SAM LOAD)           #
          S"RQ$NPULOAD",               # NPU/IN/R (NPU LOAD)           #
          S"DUMMY",                    # UNRECOGNIZED SM               #
                                            ];
        END 
# 
      TABLE OF VALID NPU STATES ON ACTIVE NPUS
# 
      DEF L$NSTATES  # 13 #;
      ARRAY NPUSTATES [1:L$NSTATES] S(1); 
        BEGIN 
        ITEM ST$NPU     U(0,0,7);                # NPU STATE           #
        ITEM ST$PRIMARY S:PRISTATE(0,0,3) = [    # NPU PRIMARY STATE   #
          S"NPS$DNDCB", 
          S"NPS$LNPU",
          S"NPS$LNPU",
          S"NPS$LNPU",
          S"NPS$LNPU",
          S"NPS$LNPU",
          S"NPS$LNPU",
          S"NPS$DNPU",
          S"NPS$DNPU",
          S"NPS$DNPU",
          S"NPS$LSAM",
          S"NPS$LSAM",
          0,
                                            ];
        ITEM ST$SECOND  S:SECSTATE(0,3,3) = [    # NPU SECONDARY STATE #
          0,
          S"NSS$WLOAD", 
          S"NSS$WSTART",
          S"NSS$WDUMP", 
          S"NSS$WLOAD", 
          S"NSS$WSTART",
          S"NSS$WNDCB", 
          S"NSS$WDUMP", 
          S"NSS$WLOAD", 
          S"NSS$WSTART",
          S"NSS$WLOAD", 
          S"NSS$WSTART",
          0,
                                            ];
        ITEM ST$SUDBIT  B(0,6,1) = [             # SUD BIT SETTING     #
          FALSE,
          TRUE, 
          TRUE, 
          TRUE, 
          FALSE,
          FALSE,
          FALSE,
          FALSE,
          FALSE,
          FALSE,
          FALSE,
          FALSE,
          FALSE,
                                   ]; 
        ITEM ST$ORDINAL S:NPUSTATE(0,42,18) = [  # NPU STATE ORDINAL   #
          S"DUMPNDCB",       # WAITING FOR DUMP NDCB RESPONSE          #
          S"LOADSUD",        # WAIT FOR LOAD SUD RESPONSE              #
          S"STARTSUD",       # WAITING FOR START SUD RESPONSE          #
          S"DUMPSUD",        # WAIT FOR DUMP SUD RESPONSE              #
          S"LOADNPU",        # WAITING FOR LOAD NPU RESPONSE           #
          S"STARTNPU",       # WAITING FOR START NPU RESPONSE          #
          S"LOADNDCB",       # WAITING FOR LOAD NDCB RESPONSE          #
          S"DUMPNPU",        # WAIT FOR DUMP NPU RESPONSE              #
          S"LOADDBS",        # WAITING FOR LOAD DUMP BOOTSTRAP RESPONSE#
          S"STARTDBS",       # WAITING FOR START DUMP BOOTSTRAP RESP   #
          S"LOADSAM",        # WAITING FOR LOAD SAM RESPONSE           #
          S"STARTSAM",       # WAITING FOR START SAM RESPONSE          #
          S"BADSTATE",       # UNRECOGNIZABLE NPU STATE                #
                                              ];
        END 
  
      DEF L$NSMABT   # 2 #; 
      DEF DM$NSMABT  # DM$LOCAL+DM$ABORT #;  # ROUTING OPTIONS         #
      ARRAY MSG$NSMABT [0:0] S(L$NSMABT); 
        BEGIN 
        ITEM NSMA$TEXT C(0,0,18) =               # MESSAGE TEXT        #
          ["INVALID NPU STATE."]; 
        ITEM NSMA$END  U(01,48,12) = [0];        # END OF TEXT         #
        END 
  
      SWITCH NSMCASE         # NETWORK SM PFC/SFC SWITCH               #
        NSMNPUDTN,
        NSMNPUDTA,
        NSMNPUDTN,
        NSMNPUDTA,
        NSMNPUDTN,
        NSMNPUDTA,
        NSMNPUIN, 
        NSMNPUIN, 
        NSMERROR, 
        ; 
CONTROL EJECT;
  
      $BEGIN
      NS$DBG("NSM");         # TRACE CALL                              #
      $END
  
      HN = ABHDN[0];
      SN = ABHSN[0];
      ERRCODE = 0;
# 
      VALIDATE ABH
# 
      IF ABHABT[0] EQ APPPN 
        AND HN NQ 0 
        AND SN NQ 0 
        AND ABHCN[0] EQ 0 
        AND ABHBT[0] EQ NETCMD
        AND ABHACT[0] EQ CT8ASCII 
      THEN                   # VALID APPLICATION BLOCK HEADER          #
        BEGIN 
# 
        IDENTIFY NETWORK SUPERVISORY MESSAGE
# 
        SMPFC = PFC[0]; 
        SMPFCSFC = PFCSFC[0];            # PFC/SFC OF SM               #
        NSM$PFCSFC[ENDNSMT] = SMPFCSFC;  # GURANTEE PFC/SFC MATCH      #
  
        FOR INDEX = 0 WHILE NSM$PFCSFC[INDEX] NQ SMPFCSFC 
        DO                               # SEARCH FOR PFC/SFC MATCH    #
          BEGIN 
          INDEX = INDEX + 1;
          END 
  
        GOTO NSMCASE[INDEX];             # CASE ON PFC/SFC             #
  
NSMNPUIN:                                # NPU/IN/R                    #
        IF NPULT[0] LQ LOADTYPE"LT$REMOT" 
        THEN                             # VALID LOAD TYPE             #
          BEGIN 
          IF NPULT[0] NQ LOADTYPE"LT$SAM" 
          THEN               # REQUEST TO LOAD LOCAL OR REMOTE NPU     #
            INDEX = INDEX + 1;           # ADJUST INDEX VALUE          #
          GOTO NSMP1; 
          END 
  
        ELSE                             # INVALID LOAD TYPE           #
          GOTO NSMERROR;
  
NSMNPUDTN:                               # NPU/DT/N                    #
NSMNPUDTA:                             # NPU/DT/A                      #
        IF NPUCC[0] LQ CMDCODE"CC$STRTR"
        THEN                             # VALID COMMAND CODE          #
          BEGIN 
          INDEX = INDEX + NPUCC[0]*2;    # ADJUST INDEX TO COMMAND CODE#
          GOTO NSMP1; 
          END 
  
        ELSE                             # INVALID COMMAND CODE        #
          GOTO NSMERROR;
  
NSMERROR:                                # NETWORK SM ERROR            #
        ERRCODE = NS$FEC(EC"ERR$SM",SMEC"NSM$FMT"); 
        GOTO NSMEXIT;                    # RETURN                      #
  
# 
        ASSIGN NETWORK STIMULUS CODE
# 
NSMP1:  
        STIMULUS = NSM$NWSTIM[INDEX];    # NETWORK STIMULUS CODE       #
# 
        LOCATE NPU TABLE ENTRY
# 
        NTORD = 0;
        FOUND = FALSE;
        NODEID = SN;         # SOURCE NODE OF SUPERVISORY MESSAGE      #
  
        IF SMPFC EQ NPU 
        THEN                 # NPU/IN/R OR NPU/DT/N OR NPU/DT/A        #
          BEGIN              # SEARCH NODE CONNECTION LIST FOR MATCH   #
  
          IF HN EQ SN 
          THEN               # DUMPING/LOADING LOCAL NPU, LOADING SAM  #
            PN = 0;          # PORT NUMBER NOT APPLICABLE FOR COUPLER  #
  
          ELSE               # DUMPING/LOADING REMOTE NPU              #
            PN = NPUPO[0];   # PORT NUMBER OF TRUNK                    #
  
          NCTORD = NCT$LISTHP[0]; # ORDINAL OF FIRST ENTRY IN NCT LIST #
          FOR INDEX = 0 WHILE NOT FOUND 
                          AND NCTORD NQ 0 
          DO
            BEGIN 
  
            IF NCT$NODE[NCTORD] EQ NODEID        # SOURCE NODE MATCH   #
              AND NCT$PN[NCTORD] EQ PN           # PORT NUMBER MATCH   #
            THEN             # FOUND NPU NODE NEIGHBOR TO SOURCE NODE  #
              BEGIN 
              NTORD = NCT$NTORD[NCTORD]; # NPU TABLE ORDINAL OF NPU    #
              NPT$NCTORD[NTORD] = NCTORD; # SAVE NCT ORDINAL IN NPT    #
              FOUND = TRUE; 
              END 
  
            ELSE                       # TRY NEXT NCT ENTRY IN NCT LIST#
              NCTORD = NCT$LISTFP[NCTORD]; # NCT ORDINAL OF NEXT ENTRY #
  
            END 
          END 
  
        IF NTORD NQ 0 
        THEN                 # NPU TABLE ENTRY FOR THIS SM LOCATED     #
          BEGIN 
          NATTSBN = NPT$NATTSB[NTORD]; # TSB NUMBER OF CURRENT NAT     #
          NPNAM = NPT$NPNAME[NTORD];   # SAVE CURRENT NPU NAME         #
  
          IF NATTSBN NQ 0 
          THEN                         # NAT EXISTS                    #
            BEGIN 
            TSBINFO(TSBSIZE,TSBFWA,NATTSBN); # LOCATE NAT, NON-MOVABLE #
            P<NAT> = TSBFWA; # SET NAT FWA, NAT BECOMES NON-MOVABLE    #
  
            IF EB[0]
              OR RB[0]
            THEN                       # IF A SM RESPONSE              #
              BEGIN          # CHECK FOR MATCH WITH CURRENT ACTIVITY   #
  
              IF HN NQ NAT$HN[0]
                OR SN NQ NAT$SN[0]             # LOAD PATH MISMATCH    #
                OR (SMPFC EQ NPU       # SM IS NPU/DT/N OR NPU/DT/A    #
                AND (NPULS[0] NQ NAT$LSN[0]    # LSN MISMATCH          #
                OR NCTORD NQ NAT$NCTORD[0]))   # TRUNK MISMATCH        #
              THEN           # DISCARD SM                              #
                BEGIN 
                GOTO NSMEXIT;          # RETURN                        #
                END 
  
              END 
  
# 
            ASSIGN ORDINAL FOR CURRENT NPU STATE
# 
            STATE =NAT$STATE[0];                 # CURRENT NPU STATE   #
            ST$NPU[L$NSTATES] = STATE; # GURANTEE STATE MATCH          #
  
            FOR INDEX = 1 WHILE STATE NQ ST$NPU[INDEX]
            DO                                   # VALID STATE         #
              BEGIN 
              INDEX = INDEX + 1;
              END 
  
            STATE = ST$ORDINAL[INDEX];           # NPU STATE ORDINAL   #
            END 
  
          ELSE                         # NAT NOT EXISTS                #
            STATE = NPUSTATE"IDLE";    # SET NPU STATE ORDINAL TO IDLE #
  
          IF STATE NQ NPUSTATE"BADSTATE"
          THEN               # NPU IS IN VALID STATE                   #
            BEGIN            # CALL NPU STATE TABLE PROCESSOR          #
            NS$NSS(STATE,STIMULUS,ERRCODE); 
            END 
  
          ELSE               # ABORT NS, INVALID NPU STATE             #
            BEGIN 
            NS$MSG(MSG$NSMABT,L$NSMABT,DM$NSMABT);
            END 
  
          NATTSBN = NPT$NATTSB[NTORD]; # GET TSB NUMBER OF NAT         #
          IF NATTSBN NQ 0 
          THEN                         # NAT EXISTS                    #
            MOVEOK(NATTSBN);           # ALLOW NAT TO MOVE             #
          END 
  
        ELSE                 # NPU TABLE ENTRY NOT FOUND               #
          BEGIN              # NETWORK SM ERROR - BAD NETWORK ADDRESS  #
          ERRCODE = NS$FEC(EC"ERR$SM",SMEC"NSM$ADDR");
          END 
  
        END 
  
      ELSE                   # INVALID ABH                             #
        BEGIN                # NETWORK SM ERROR - BAD ABH              #
        ERRCODE = NS$FEC(EC"ERR$SM",SMEC"NSM$ABH"); 
        END 
  
NSMEXIT:  
      RETURN; 
      END   # NS$NSM #
      TERM
