*DECK     NP$GETQ 
USETEXT AIPDEF
USETEXT HEADER
USETEXT NP$DB 
USETEXT NP$GETS 
USETEXT NP$GMB
USETEXT NP$MODE 
USETEXT NP$NWNC 
USETEXT NP$NWL
USETEXT NP$STAT 
USETEXT NP$TAA
      PROC NP$GETQ(GMMSC);
 #
*1DC  NP$GETQ 
* 
*     1. PROC NAME           AUTHOR              DATE 
*        NP$GETQ             E. GEE              01/30/85 
* 
*     2. FUNCTIONAL DESCRIPTION.
*          EXTRACT OR UPDATE DATA MESSAGES IN THE AIP UPLINE DATA 
*            BUFFER.
* 
*     3. METHOD USED. 
*          IF PREVIOUS AIP REQUEST HAS NOT COMPLETED, 
*            CALL NP$ERR TO ISSUE DAYFILE MSG AND ABORT APP.
*          PROCESS ACCORDING TO THE SEARCH CODE THAT WAS PROVIDED.
*            SC = 0  SEARCH BUFFER FOR MSG FOR SPECIFIED CONNECTION NUM.
*                    IF FOUND,
*                      UPDATE DATA BUFFER POINTERS. 
*                    CALL NP$EXTQ TO RETURN DATA MSG OR NULL BLK TO APP.
*            SC = 1  SEARCH BUFFER FOR MSG FOR SPECIFIED LIST NUMBER. 
*                    IF FOUND,
*                      UPDATE DATA BUFFER POINTERS. 
*                    CALL NP$EXTQ TO RETURN DATA MSG OR NULL BLK TO APP.
*            SC = 2  SEARCH BUFFER FOR ALL MSGS FOR SPECIFIED CON NUM.
*                      ADJUST DATA BUFFER POINTERS TO ELIMINATE MSG 
*                        MOVING MSGS FOR OTHER CONNECTIONS AS NECESSARY.
*          CALL NP$USI TO UPDATE THE NSUP WORD. 
* 
*     4. ENTRY CONDITIONS.
*          GMMSC             SEARCH CODE TO DETERMINE TYPE OF PROCESSING
*                            = 0  GET DATA FOR SPECIFIED ACN
*                            = 1  GET DATA FOR SPECIFIED LIST NUMBER
*                            = 2  DISCARD ALL DATA FOR SPECIFIED ACN
* 
* 
*     5. EXIT CONDITIONS. 
*          HA                CONTAIN NULL BLOCK IF NOT DATA MSG WAS 
*                            AVAILABLE.  OTHERWISE, IT WILL CONTAIN THE 
*                            APP BLOCK HEADER OF THE TEXT.
*          ATA               CONTAINS TEXT OF DATA MSG IF ONE WAS 
*                            DELIVERED. 
* 
*     6. COMDECKS AND SYMPL TEXT USED.
*          AIPDEF            CONSTANT DEFINITIONS 
*          HEADER            APP BLOCK HEADER TEMPLATE
*          NP$DB             UPLINE DATA BUFFER TEMPLATE
*          NP$GETS           GLOBAL VARIABLES 
*          NP$GMB            APP SUPPLIED DATA BUFFER TEMPLATE
*          NP$MODE           GLOBAL VARIABLES 
*          NP$NWL            NETWORK WORKLIST TABLE 
*          NP$NWNC           GLOBAL VARIABLES 
*          NP$STAT           STATISTICS TABLE 
* 
*     7. PROCEDURES/FUNCTIONS CALLED. 
*          NP$DBG            LOG DATA MESSAGE IN DEBUG LOG FILE 
*          NP$ERR            ISSUE ERROR MSG AND ABORT APP
*          NP$ITMG           INTERCEPT DATA MSG TO FILE TRANSFER MSGS 
*          NP$SN             INCREMENT AIP STATISTICS 
*          NP$USI            UPDATE NSUP WORD 
* 
*     8. DAYFILE MESSAGES OR OTHER IMPORTANT INFORMATION. 
*          NONE.
 #
      BEGIN 
# 
      EXTERNAL ROUTINES CALLED
# 
      XREF
        BEGIN 
        PROC NP$DBG;                   # LOG AIP TRAFFIC IN TRACE FILE #
        PROC NP$ERR;                   # ISSUE DAYFILE MSG AND ABT APP #
        PROC NP$SN;                    # INCREMENT STATISTICS COUNTERS #
        PROC NP$USI;                   # UPDATE S AND I BIT IN NSUP    #
        END 
# 
      INPUT VARIABLES 
# 
      ITEM GMMSC;                      # SEARCH CODE TO PROCESS        #
# 
      OUTPUT VARIABLES
# 
      ITEM GMMRC;                      # RETURN CODE                   #
# 
      LOCAL VARIABLES 
# 
      ITEM DACT;                       # CHARACTER TYPE OF DATA        #
      ITEM I;                          # LOOP CONTROL VARIABLE         #
      ITEM I1;                         # LOOP CONTROL VARIABLE         #
      ITEM I2;                         # TEMPORARY INDEX               #
      ITEM J;                          # TEMPORARY INDEX               #
      ITEM K;                          # TEMPORARY INDEX               #
      ITEM N;                          # WORDS OF SM TRANSFERRED - 1   #
      ITEM NEXTHEAD;                   # 1ST WD AFTER RETURNED ENTRY   #
      ITEM NOWHEAD;                    # 1ST WD OF RETURNED ENTRY      #
  
      ITEM TLW;                        # ACTUAL SIZE OF SM             #
      ITEM TLWDIF;                     # TLW - SUM OF TAASIZE[K]       #
  
      BASED ARRAY MEM S(1); 
        ITEM
          HA            I (0),         # HEADER AREA                   #
          WORD          I (0);         # TEXT ARRAY                    #
  
      SWITCH SWTCH$SC  SC$0,SC$1,SC$2,SC$3,SC$4,SC$5,SC$6,SC$7; 
  
#**********************************************************************#
      CONTROL EJECT;
# 
      EXECUTABLE CODE BEGINS HERE 
# 
*IF,DEF,STAT
      NP$SN(IAM);                      # INCREMENT STATISTICS COUNTER  #
*ENDIF
  
      GMMRC = 1;                       # INIT RETURN CODE TO NOT FOUND #
      IF DEFER$PRO
      THEN                             # PREVIOUS REQUEST IS INCOMPLETE#
        BEGIN 
        NP$ERR("42");                  # ISSUE DAYFILE MSG AND ABT APP #
        END 
  
  
# 
      PROCESS ACCORDING TO SEARCH CODE
# 
      GOTO SWTCH$SC[GMMSC]; 
  
SC$0:                                  # GET DATA FOR CONNECTION       #
        BEGIN 
        IF (GMBHEAD NQ GMBFOOT) AND 
           ( ( (GMBCN NQ 0) AND 
             (GMBCN EQ ACLN) ) OR 
             (GMBCN EQ 0) ) 
        THEN                           # AIP BUF MAY CONTAIN MSG FOR CN#
          BEGIN 
          NOWHEAD = GMBHEAD;           # START SEARCH AT 1ST MSG       #
          FOR I1=I1 WHILE (NOWHEAD NQ GMBFOOT) AND (GMMRC EQ 1) 
          DO                           # CHECK ALL MSGS IN AIP BUFFER  #
            BEGIN 
            P<HEADER> = LOC(GMBWRD[NOWHEAD]);  # ABH WORD OF MSG       #
            DACT = GMBACT[NOWHEAD];    # CHARACTER TYPE OF QUEUED DATA #
            TLW = (2 * GMBTLC[NOWHEAD] + NW$ROUND[DACT])/ NW$FACT[DACT];
            IF ACLN EQ ABHADR[0]
            THEN                       # WE HAVE FOUND AN ENTRY        #
              BEGIN 
              GMMRC = 0;
              END 
            ELSE                       # BUFFER ENTRY FOR DIFFERENT CN #
              BEGIN 
              NOWHEAD = NOWHEAD + TLW +1;  # SKIP TO CHECK NEXT ENTRY  #
              IF (GMBLAST LQ NOWHEAD) AND  # REACHED END OF BUFFER     #
                 (NOWHEAD NQ GMBFOOT)      # NOT REACHED END OF DATA   #
              THEN                     # WE HAVE REACHED THE END OF BUF#
                BEGIN 
                NOWHEAD = 1;           # RESTART SEARCH AT BEGIN OF BUF#
                END 
              END 
            END 
          END 
        NP$EXTQ;                       # RETURN DATA MSG OR NULL MSG   #
        GOTO SC$END;
        END 
SC$1:                                  # GET DATA FOR LIST NUMBER      #
        BEGIN 
        IF (GMBHEAD NQ GMBFOOT) AND 
           (ACLN EQ GMBLN)
        THEN                           # AIP HAS DATA AVAILABLE        #
          BEGIN 
          GMMRC = 0;                   # FLAG THAT ENTRY WAS FOUND     #
          NOWHEAD = GMBHEAD;           # SAVE PTR OF CURRENT HEAD      #
          DACT = GMBACT[NOWHEAD];      # CHARACTER TYPE OF QUEUED DATA #
          TLW = (2 * GMBTLC[NOWHEAD] + NW$ROUND[DACT])/ NW$FACT[DACT];
          END 
        NP$EXTQ;
        GOTO SC$END;
        END 
SC$2:                                  # DISCARD ALL DATA ON CONNECTION#
        BEGIN 
        IF (GMBHEAD NQ GMBFOOT) AND 
           ( ( (GMBCN NQ 0) AND 
             (GMBCN EQ ACLN) ) OR 
             (GMBCN EQ 0) ) 
        THEN                           # AIP BUF MAY CONTAIN MSG FOR CN#
          BEGIN 
          NOWHEAD = GMBHEAD;           # START SEARCH AT 1ST MSG       #
          FOR I1=I1 WHILE NOWHEAD NQ GMBFOOT
          DO                           # CHECK ALL MSGS IN AIP BUFFER  #
            BEGIN 
            P<HEADER> = LOC(GMBWRD[NOWHEAD]);  # ABH WORD OF MSG       #
            DACT = GMBACT[NOWHEAD];    # CHARACTER TYPE OF QUEUED DATA #
            TLW = (2*GMBTLC[NOWHEAD] + NW$ROUND[DACT])/NW$FACT[DACT]; 
            NEXTHEAD = NOWHEAD + TLW + 1;  # INDEX FOR NEXT MSG IN BUF #
            IF ACLN EQ ABHADR[0]
            THEN                       # WE HAVE FOUND AN ENTRY        #
              BEGIN 
              GMMRC = 0;
  
*IF,DEF,STAT
              NP$SN(TYPE"GDM");        # INCREMENT AIP STATISTICS      #
*ENDIF
  
              IF GMBHEAD EQ NOWHEAD 
              THEN                     # RETURNED FIRST MSG IN BUFFER  #
                BEGIN 
                GMBHEAD = NEXTHEAD;    # UPDATE PTR TO NEXT MSG        #
                IF (GMBLAST LQ GMBHEAD) AND 
                   (GMBHEAD NQ GMBFOOT) 
                THEN                   # REACHED END OF BUFFER         #
                  BEGIN 
                  GMBHEAD = 1;
                  END 
                NOWHEAD = GMBHEAD;     # ADDR OF NEXT ENTRY TO CHECK   #
                END                    # END DATA MESSAGE DELIVERED    #
              ELSE                     # DID NOT RETURN 1ST MSG IN BF  #
                BEGIN 
                IF GMBFOOT EQ NEXTHEAD
                THEN                   # RETURNED LAST MSG IN BUFFER   #
                  BEGIN 
                  GMBFOOT = GMBFOOT - TLW - 1;  # UPDATE PTR FOR NXT   #
                  END 
                ELSE                   # NOT LAST MSG IN BUFFER        #
                  BEGIN 
                  IF NOWHEAD LS GMBFOOT 
                  THEN                 # RETURNED MSG IS IN 1ST PART   #
                    BEGIN 
# 
                    MOVE UP ALL DATA ENTRIES BELOW ONE RETURNED TO APP
# 
                    FOR I = 0 STEP 1 UNTIL GMBFOOT-NEXTHEAD-1 
                    DO
                      BEGIN 
                      GMBWRD[NOWHEAD+I] = GMBWRD[NEXTHEAD+I]; 
                      END 
                    GMBFOOT = GMBFOOT - TLW - 1;  # NEW INDEX FOR LAST #
                    END 
                  ELSE                   # RETURNED MSG IS IN LAST PART#
                    BEGIN 
# 
                    MOVE DOWN ALL DATA ENTRIES BEFORE ONE RETURNED TO 
                    APP 
# 
                    FOR I = 1 STEP 1 UNTIL NOWHEAD - GMBHEAD
                    DO
                      BEGIN 
                      GMBWRD[NEXTHEAD-I] = GMBWRD[NOWHEAD-I]; 
                      END 
                    GMBHEAD = GMBHEAD + TLW + 1;  # NEW INDX FOR 1ST   #
                    NOWHEAD = NEXTHEAD;# ADDR OF NEXT ENTRY TO CHECK   #
                    END 
                  END 
                END 
              END 
            ELSE                       # BUFFER ENTRY FOR DIFFERENT CN #
              BEGIN 
              NOWHEAD = NEXTHEAD;      # SKIP TO CHECK NEXT ENTRY      #
              IF (GMBLAST LQ NOWHEAD) AND  # REACHED END OF BUFFER     #
                 (NOWHEAD NQ GMBFOOT)      # NOT REACHED END OF DATA   #
              THEN                     # WE HAVE REACHED THE END OF BUF#
                BEGIN 
                NOWHEAD = 1;           # RESTART SEARCH AT BEGIN OF BUF#
                END 
              END 
            END 
          IF GMBFOOT EQ GMBHEAD 
          THEN                         # BUFFER IS NOW EMPTY           #
            BEGIN 
            GMBFOOT = 1;               # INITIAL PTR FOR NEXT FREE WORD#
            GMBHEAD = 1;               # INITIAL PTR FOR NEXT DATA MSG #
            END 
          END 
  
        GOTO SC$END;
        END 
SC$3:                                  # DISCARD ALL DATA ON LIST NO   #
        BEGIN 
# 
        THIS FEATURE HAS NOT BEEN IMPLEMENTED 
# 
        GOTO SC$END;
        END 
SC$4:                                  # SET LIST OFF FLAG FOR ALL MSGS#
                                       # IN BUFFER WITH SPECIFIED LIST #
                                       # NUMBER.                       #
        BEGIN 
# 
        THIS FEATURE HAS NOT BEEN IMPLEMENTED 
# 
        GOTO SC$END;
        END 
SC$5:                                  # CLEAR LIST OFF FLAG FOR ALL   #
                                       # MSGS IN BUFFER WITH SPECIFIED #
                                       # LIST NUMBER.                  #
        BEGIN 
# 
        THIS FEATURE HAS NOT BEEN IMPLEMENTED 
# 
        GOTO SC$END;
        END 
SC$6:                                  # SET TEMP LIST OFF FLAG FOR ALL#
                                       # MSGS IN BUFFER WITH SPECIFIED #
                                       # LIST NUMBER.                  #
        BEGIN 
# 
        THIS FEATURE HAS NOT BEEN IMPLEMENTED 
# 
        GOTO SC$END;
        END 
SC$7:                                  # CLEAR TEMP LIST OFF FLAG FOR  #
                                       # ALL MSGS IN BUFFER WITH       #
                                       # SPECIFIED LIST NUMBER.        #
# 
        THIS FEATURE HAS NOT BEEN IMPLEMENTED 
# 
        BEGIN 
        GOTO SC$END;
        END 
  
 SC$END:                               # END OF CASE STATEMENT         #
  
      NP$USI;                          # UPDATE NSUP WORD              #
  
      LTAA = 0;                        # CLEAR FRAGMENT CALL FLAG      #
  
      RETURN; 
  
  
      CONTROL EJECT;
        PROC NP$EXTQ; 
 #
*1DC  NP$EXTQ 
* 
*     1. PROC NAME           AUTHOR              DATE 
*        NP$EXTQ             E. GEE              01/30/85 
* 
*     2. FUNCTIONAL DESCRIPTION.
*          EXTRACT DATA MSG FROM UPLINE DATA BUFFER AND DELIVER TO
*            THE APPLICATION. 
* 
*     3. METHOD USED. 
*          IF NO MESSAGE FOUND, 
*            RETURN NULL BLOCK TO APPLICATION.
*          ELSE (DATA MESSAGE FOUND IN DATA BUFFER),
*            IF APP BUFFER IS NOT BIG ENOUGH AND TRUNCATION NOT ALLOWED,
*              SET IBU BIT IN ABH WORD. 
*            ELSE ( DATA MSG CAN BE DELIVERED), 
*              SET TRUNCATION BIT IF DATA MSG IS TRUNCATED. 
*              IF FRAGMENTED GET REQUEST, 
*                COPY TEXT INTO FRAGMENTED BUFFERS. 
*              ELSE (DELIVER MSG INTO ONE BUFFER),
*                COPY TEXT INTO APPLICATION BUFFER. 
*              ADJUST AIP POINTERS FOR UPLINE DATA BUFFER.
* 
*     4. ENTRY CONDITIONS.
*          GMMRC             MESSAGE FOUND FLAG.
*                            = 0  MESSAGE FOUND TO DELIVER. 
*                            = 1  RETURN NULL BLOCK TO APPLICATION. 
* 
*     5. EXIT CONDITIONS. 
*          HA                CONTAIN NULL BLOCK IF NOT DATA MSG WAS 
*                            AVAILABLE.  OTHERWISE, IT WILL CONTAIN THE 
*                            APP BLOCK HEADER OF THE TEXT.
*          ATA               CONTAINS TEXT OF DATA MSG IF ONE WAS 
*                            DELIVERED. 
* 
*     7. PROCEDURES/FUNCTIONS CALLED. 
*          NONE.
* 
*     8. DAYFILE MESSAGES OR OTHER IMPORTANT INFORMATION. 
*          NONE.
 #
  
#**********************************************************************#
        CONTROL EJECT;
  
        BEGIN 
        IF GMMRC EQ 1 
        THEN                           # NO MATCHING ENTRY FOUND       #
          BEGIN                        # RETURN NULL BLOCK             #
          I = NEXT + 1;                # CURRENT INDEX INTO NWL BUF    #
          ABH[I] = 0;                  # ZERO ABH WORD IN NWL BUFFER   #
          ABH$ADR[0] = ACLN;           # CONNECTION/LIST NUMBER        #
          P<HEADER> = LOC$HA;          # ADDRESS TO WRITE ABH WORD     #
          ABHWORD[0] = ABH[I];         # WRITE NULL ABH TO ABH WORD    #
  
*IF,DEF,STAT
          NP$SN(TYPE"INB"); 
*ENDIF
  
          END 
        ELSE                           # MATCHING ENTRY FOUND          #
          BEGIN 
          NEXTHEAD = NOWHEAD + TLW + 1; 
          P<HEADER> = LOC$HA;          # ADDRESS TO WRITE ABH WORD     #
          ABHWORD[0] = GMBWRD[NOWHEAD]; 
          IF (TLW GR TLMX) AND
             (NOT GMBTRUNC) 
          THEN                         # BLOCK IS TOO LARGE TO DELIVER #
            BEGIN 
            GMBIBU[NOWHEAD] = TRUE;    # SET IBU BIT IN BLOCK HEADER   #
            END 
          ELSE                         # BLOCK CAN BE DELIVERED        #
            BEGIN 
            IF TLW GR TLMX
            THEN                       # BLOCK MUST BE TRUNCATED       #
              BEGIN 
              TLW = TLMX;              # NO OF WORDS OF TEXT TO DELIVER#
              ABHTLC[0] = (TLMX * NW$FACT[DACT]) / 2;  # NO OF CHARS   #
              ABHTRU[0] = 1;           # SET TRUNCATION FLAG IN ABH    #
              END 
            N = TLW - 1;
            P<MEM> = LOC$TA;
            P<TAA> = LOC$TA;
            J = NOWHEAD + 1;
            TLWDIF = TLW; 
  
            CONTROL FASTLOOP; 
            FOR K = 1 STEP 1 UNTIL LTAA DO
              BEGIN 
              IF LTAA NQ 0
              THEN
                BEGIN 
                P<MEM> = TAADDR[K]; 
                N = TAASIZE[K] - 1; 
                IF N GR TLWDIF         # MAKE SURE THAT AIP IS ONLY    #
                THEN                   # COPYING THE DATA              #
                  N = TLWDIF - 1;      # MESSAGE TO THE FRAGMENTED     #
                                       # BUFFERS - NO MATTER WHAT SIZE #
                                        #HAS BEEN SPECIFIED IN THE     #
                                        #TEXT AREA ARRAY.              #
                TLWDIF = TLWDIF - TAASIZE[K]; 
                END 
  
              CONTROL SLOWLOOP; 
              FOR I = 0 STEP 1 UNTIL N DO 
                BEGIN 
                WORD[I] = GMBWRD[I+J];
                END 
  
              J = J + TAASIZE[K]; 
              END 
  
*IF,DEF,STAT
            I = GMBABT[NOWHEAD] + TYPE"INB";
            NP$SN(I); 
*ENDIF
*IF,DEF,DEBUG 
            NP$DBG;                    # WRITE MSG TO AIP DEBUG FILE   #
*ENDIF
            IF GMBHEAD EQ NOWHEAD 
            THEN                       # RETURNED FIRST MSG IN BUFFER  #
              BEGIN 
              GMBHEAD = NEXTHEAD;      # UPDATE PTR TO NEXT MSG        #
              IF (GMBLAST LQ GMBHEAD) AND 
                 (GMBFOOT NQ GMBHEAD) 
              THEN                     # REACHED END OF BUFFER         #
                BEGIN 
                GMBHEAD = 1;
                END 
              END                      # END DATA MESSAGE DELIVERED    #
            ELSE                       # DID NOT RETURN 1ST MSG IN BUF #
              BEGIN 
              IF GMBFOOT EQ NEXTHEAD
              THEN                     # RETURNED LAST MSG IN BUFFER   #
                BEGIN 
                GMBFOOT = GMBFOOT - TLW - 1;  # UPDATE PTR FOR NXT FREE#
                END 
              ELSE                     # NOT LAST MSG IN BUFFER        #
                BEGIN 
                IF NOWHEAD LS GMBFOOT 
                THEN                   # RETURNED MSG IS IN 1ST PART   #
                  BEGIN 
# 
                  MOVE UP ALL DATA ENTRIES BELOW ONE RETURNED TO APP
# 
                  FOR I = 0 STEP 1 UNTIL GMBFOOT-NEXTHEAD - 1 
                  DO
                    BEGIN 
                    GMBWRD[NOWHEAD+I] = GMBWRD[NEXTHEAD+I]; 
                    END 
                  GMBFOOT = GMBFOOT - TLW - 1;  # NEW INDEX FOR LAST MS#
                  END 
                ELSE                   # RETURNED MSG IS IN LAST PART  #
                  BEGIN 
# 
                  MOVE DOWN ALL DATA ENTRIES BEFORE ONE RETURNED TO APP 
# 
                  FOR I = 1 STEP 1 UNTIL NOWHEAD - GMBHEAD
                  DO
                    BEGIN 
                    GMBWRD[NEXTHEAD-I] = GMBWRD[NOWHEAD-I]; 
                    END 
                  GMBHEAD = GMBHEAD + TLW + 1;  # NEW INDEX FOR 1ST MSG#
                  END 
                END 
              END 
            IF GMBHEAD EQ GMBFOOT 
            THEN                       # EMPTY UPLINE DATA BUFFER      #
              BEGIN 
              GMBHEAD = 1;
              GMBFOOT = 1;
              END 
            END 
          END 
        RETURN; 
        END 
      END 
TERM
