*DECK     SSACNI
USETEXT          TEXTSS 
USETEXT          TXTAPSS
PROC SSACNI (SWTESS); 
# TITLE SSACNI - CONTROL NETWORK INTERFACE.                            #
  
      BEGIN # SSACNI #
# 
**    SSACNI - CONTROL NETWORK INTERFACE. 
* 
*     S. H. FISCHER.         81/08/18.
*     C. J. BRION.           82/06/09, 83/06/06.
* 
*     THIS ROUTINE CONTROLS THE NETWORK INTERFACE.
*     NETPUT S AND NETGET S ARE DONE IN PARALLEL MODE TO
*     SEND/RECEIVE DATA/SUPERVISARY BLOCKS TO/FROM
*     NIP AND THE NETWORK.
* 
*     PROC SSACNI (SWTE)
* 
*     ENTRY      SWTE = STATUS WORKLIST MONITOR ARRAY.
* 
*     EXIT       RETURN PARMETERS SET DEPENDING ON WHAT EVENT IS TO 
*                RESTART THIS ROUTINE.
* 
*     NOTES      THIS ROUTINE ASSUMES THAT THE AIP ROUTINE *NETCHEK*
*                IS BEING CALLED BY THE MAIN LOOP.
* 
*     METHOD     THIS ROUTINE GIVES PRECEDENCE TO OUTGOING TRAFFIC. 
*                ALL DATA BLOCKS OR SM S AVAILABLE TO BE SENT ARE 
*                NETPUTED BEFORE ANY NETGETS ARE ATEMPTED.
*                SHOULD ANY TRANSFER NOT BE DONE IMMEDIATELY THIS 
*                ROUTINE WILL EXIT TO BE RESTARTED WHEN THE TRANSFER
*                IS COMPLETE. NETGETS ARE DONE ONLY WHEN THE NSUP 
*                WORD INDICATES THAT INCOMMING TRAFFIC IS AVAILABLE.
*                SM S TAKE PRECEDENCE OVER DATA BLOCKS ON INPUT.
*                NETREL IS CALLED AFTER MC MESSAGES ARE WRITTEN 
*                TO THE TRACE FILE. 
# 
  
  
  
  
# 
****  PROC SSACNI - XREF LIST BEGIN.
# 
  
      XREF
        BEGIN 
        PROC CSNVDSP; 
        PROC NETGETL; 
        PROC NETPUT;
        PROC NETREL;
        PROC SSTRQE;
        PROC RTIME; 
        END 
# 
****
# 
  
  
  
  
  
*CALL SWTESS
  
  
  
  
      ITEM AABH U;           # ABH BUFFER FOR NETWORK I/O              #
      ITEM I U; 
      ITEM FORCERTN B=FALSE; # TRUE WHEN EARLY RETURN NEEDED           #
      ITEM WAITGET B=FALSE;  # TRUE WHEN NETGET INCOMPLETE             #
      ITEM BLK$MSG B;        # BLK OR MSG FLAG                         #
      BASED ARRAY ABHTYPE[00:00] S(1); # BASED ARRAY FOR BLOCK TYPE    #
        BEGIN 
        ITEM ABH$TYPE U(00,00,06); # BLOCK TYPE                        #
        END 
  
  
      ARRAY TXTAREA [00:273] S(1);     # TEXT BUFFER FOR NETWORK I/O   #
        BEGIN 
        ITEM TXTA$WD U(00,00,60); 
        END 
# 
*     THIS ARRAY DEFINES THE LFN USED FOR THE NETREL CALL.
# 
      ARRAY NTRL$LFN [00:00] S(1);
        BEGIN 
        ITEM NRL$NAM    C(00,00,04) = ["NRF1"]; 
        ITEM NRL$ZFIL   U(00,24,36) = [0];
        END 
  
  
  
CONTROL EJECT;
# 
**    AID - ACCEPT INCOMMING DATA.
* 
*     THIS INTERNAL PROC COMPUTES THE 60 BIT WORD COUNT OF THE DATA 
*     RECEIVED AND PASSES THE BLOCK TO A ROUTINE WHICH QUEUES THE 
*     INPUT. THIS ROUTINE HAS THE SAME ENTRY POINT NAME BUT IT IS 
*     DIFFERENT FOR EACH PRODUCT. 
* 
*     PROC AID
* 
*     ENTRY      AABH = RECEIVED APPLICATION BLOCK HEADER.
*                TXTAREA = RECEIVED BLOCK.
* 
*     EXIT       BLOCK PASSED TO PROGRAM. 
*                (IF DATA PRESENT BUT ON A INHIBITED LIST THEN
*                REQUEST SUSPENSION IF NO OUTGOING DATA IS AVAILABLE.)
* 
*     METHOD     CALCULATE WORD COUNT DEPENDING ON CHARACTER TYPE.
*                IF NOT A NULL BLOCK INDICATING DATA PRESENT BUT
*                UNDELIVERABLE CALL PRODUCT OWNCODE ROUTINE TO
*                QUEUE THE BLOCK. OTHERWISE REQUEST SUSPENSION. 
* 
# 
  
  
  
  
      PROC AID;              # ACCEPT INCOMMING DATA                   #
      BEGIN 
      ABHWORD[0] = AABH;     # TRANSFER ABH WORD                       #
  
#     P<ABH> = LOC(ABHBUF)            # 
  
      WCB$WORD[0] = 0;       # CLEAR WORD COUNT WORD                   #
  
  
  
# 
*     COMPUTE SIZE OF INCOMMING BLOCK IN 60 BIT WORDS.
*     ADD TWO TO ACCOUNT FOR ABH AND WORD COUNT WORDS IN
*     RESULTING QUEUE ENTRY.
# 
  
  
      IF ABHACT[0] EQ CT60TRANS 
      THEN                   # 60 BIT TRANSPARENT CHARACTERS           #
        BEGIN 
        WCB$WC[0] = ABHTLC[0];
        END 
      ELSE IF ABHACT[0] EQ CT8ASCII 
      THEN                   # 8-BIT ASCII, 7.5 PER WORD               #
        BEGIN 
        WCB$WC[0] = ((ABHTLC[0] * 10) + 70 ) / 75;
        END 
      ELSE IF ABHACT[0] EQ CT6DISPLAY 
      THEN                   # 6-BIT DISPLAY CODE, 10 PER WORD         #
        BEGIN 
        WCB$WC[0] = (ABHTLC[0] + 9 ) / 10;
        END 
  
      WCB$WC[0] = WCB$WC[0] + 2;
  
  
  
  
# 
*     IF A NULL BLOCK IS RECEIVED AND IT IS FOR A NON-ZERO ACN
*     THEN IT IS QUEUED TO THE PROGRAM NORMALLY.
*     IN THE CASE OF A NULL BLOCK WITH AN ACN OF ZERO 
*     THEN THE DATA BLOCK THAT WAS REQUESTED CANNOT BE DELIVERED
*     TO THE PROGRAM BY NIP AS THE BLOCK WAS ON A CONNECTION THAT 
*     WAS INHIBITED DUE TO THE PROGRAM STILL PROCESSING THE LAST
*     DATA BLOCK AND THE HALF DUPLEX PROCESS ALLOWS ONLY ONE MSG
*     IN THE PROGRAM AT A TIME. 
*     IN THIS CASE THE DATA BLOCK WILL BE REQUESTED AGAIN AFTER 
*     ANY OUTPUT FROM THE PROGRAM OR THE DAYFILE CLOCK CHANGES
*     TO HANDLE THE CASE OF A BLOCK BEING RECEIVED BY NIP FOR 
*     A DIFFERENT ACN WHICH IS NOT INHIBITED. 
*     IN THE EVENT THAT A MAXNULL$ NUMBER OF NETGETLS ATTEMPTED 
*     WITHOUT CONNECTION TRAFFIC (NON ZERO ACN), THE NUMBER OF
*     NULL NETGETS ALLOWED IS DECREMENTED. IF THIS COUNT REACHES
*     ZERO, THE FORCED ROLLOUT PROGRAM FLAG IS SET. THIS ALLOWS THE 
*     CHECK IN SSSWNR TO ISSUE A FORCE ROLLOUT NETWAIT CALL.
*     THIS PROC INDICATES THIS SITUATION BY SETTING FORCERTN
*     TRUE. 
# 
  
  
      IF ABHABT[0] EQ APPNULL 
      THEN
        BEGIN                # NULL BLOCK                              #
        IF ABHADR[0] EQ 0 
        THEN                 # NO DATA OR SM DELIVERABLE               #
          BEGIN 
          FORCERTN = TRUE;
          PGM$NUGETS[0] = PGM$NUGETS[0] - 1;
          IF PGM$NUGETS[0] EQ 0 
          THEN
            BEGIN 
            PGM$FOROLL[0] = TRUE; 
            PGM$NUGETS[0] = MAXNULL$; 
            END 
          ELSE
            PGM$FOROLL[0] = FALSE;
          RETURN; 
          END 
        END 
  
  
  
# 
*     THE BLOCK IS PASSED TO THE PROGRAM TO BE QUEUED.
# 
  
  
      PGM$NUGETS[0] = MAXNULL$; 
      CSNVDSP (WCBUF, ABHBUF, TXTAREA );
  
      RETURN; 
  
      END 
CONTROL EJECT;
# 
*                MAIN LINE CODE.
* 
*     SET THE STATUS WLE PARAMETERS FOR ONLY A SINGLE TYPE CHECK
*     ON THE NSUP WORD. 
# 
      STE$RTN = LOC(SSACNI);
      STE$ADDR1 = LOC(NSUP);
      STE$INIT1 = NSUP$WORD;
      STE$ADDR2 = 0;
  
# 
* 
*     IF PREVIOUS OPERATION STILL NOT COMPLETE
*     (FALSE WAKE UP OR INITIALIZATION CALL)
*     THEN WAIT FOR AIP TRANSFER TO COMPLETE. 
# 
  
  
  
  
      IF NOT NSUP$COMP[0] 
      THEN
        BEGIN                # WAIT FOR NSUP TO COMPLETE               #
        STE$SBIT1 = FALSE;   # INSURE COMPLETE BIT IS CLEAR            #
        RETURN; 
        END 
  
  
  
  
# 
*     IF REQUESTED INCOMMING DATA IS NOW AVAILABLE THEN PROCESS IT. 
*     IF INPUT DATA IS PRESENT BUT CANNOT BE DELIVERED THEN STOP
*     IF OUTGOING DATA IS NOT READY TO BE SENT. 
*     RESTART CONDITIONS ARE EITHER DAYFILE CLOCK CHANGING OR 
*     NSUP WORD CHANGING. 
# 
  
  
      IF WAITGET
      THEN
        BEGIN 
        AID;                 # ACCEPT INCOMMING DATA                   #
        WAITGET = FALSE;
       IF FORCERTN
        THEN
          BEGIN 
          FORCERTN = FALSE; 
          IF SSOTQL[0] EQ 0 
          THEN
            BEGIN              # WAIT FOR NSUP WORD OR DAYFILE
                                 CLOCK TO CHANGE                       #
            STE$ADDR2 = LOC(CTM$CLOCK[0]);
            STE$INIT2 = CTM$CLOCK[0]; 
            RETURN; 
            END 
          END 
        END 
  
  
  
  
# 
*     AS LONG AS OUTGOING DATA REMAINS AND TRANSFERS ARE DONE 
*     IMMEDIATELY LOOP DOING NETPUTS. 
*     IF A TRANSFER DOES NOT COMPLETE IMMEDIATELY STOP WITH 
*     RESTART CONDITIONS BEING THE TRANSFER COMPLETED.
*     NOTE: THE MAIN LOOP CALLING *NETCHEK* IS ASSUMED. 
# 
  
  
      BLK$MSG = FALSE;             # SET BLK$MSG TO FALSE              #
      FOR I = 1 WHILE SSOTQL[0] NQ 0
      DO
        BEGIN 
        SSTRQE (SSIOTQ[0], WCBUF, AABH, TXTAREA); 
        NETPUT (AABH, TXTAREA); 
        P<ABHTYPE> = LOC(AABH);    # GET BLOCK TYPE                    #
        IF ABH$TYPE[0] EQ SWAP$BLK OR ABH$TYPE[0] EQ SWAP$MSG 
        THEN                       # BLK OF MSG BLOCKS                 #
          BEGIN 
          IF SS$TWORD[0] EQ 0      # NEED NEW TIME STAMP               #
          THEN
            BEGIN 
            BLK$MSG = TRUE;  # SET BLK OR MSG FLAG TO TRUE             #
            END 
          END 
        IF NOT NSUP$COMP[0] 
        THEN
          BEGIN              # WAIT FOR NSUP TO COMPLETE               #
          STE$INIT1 = NSUP$WORD;
          STE$SBIT1 = FALSE; # INSURE COMPLETE BIT IS CLEAR            #
          IF BLK$MSG
          THEN               # BLK OR MSG PUT'S EXIST                  #
            BEGIN 
            RTIME(SS$SWAPW); # GET REAL TIME STAMP                     #
            END 
          RETURN; 
          END 
        END 
  
      IF BLK$MSG
      THEN
        BEGIN 
        RTIME(SS$SWAPW);     # GET REAL TIME STAMP                     #
        END 
  
  
  
# 
*     AS LONG AS INCOMING SUPERVISORY MESSAGES ARE INDICATED TO BE
*     AVAILABLE, AND INCOMING DATA BLOCKS ARE INDICATED TO BE 
*     DELIVERABLE, LOOP DOING NETGETS AND PASS THE BLOCKS TO THE
*     PROGRAM.
*     IF A TRANSFER DOES NOT COMPLETE IMMEDIATELY STOP WITH 
*     RESTART CONDITIONS BEING THE TRANSFER COMPLETE. 
*     NOTE: THE MAIN LOOP CALLING *NETCHEK* IS ASSUMED. 
* 
*     IF INPUT DATA IS PRESENT BUT CANNOT BE DELIVERED THEN STOP. 
*     RESTART CONDITIONS ARE EITHER DAYFILE CLOCK CHANGING OR 
*     NSUP WORD CHANGING. 
# 
  
  
      FOR I = 1 WHILE NSUP$SMIN[0]
        OR NSUP$DDEV[0] 
      DO
        BEGIN                # DATA OR SM AVAILABLE                    #
        NETGETL ( 0, AABH, TXTAREA, TXTALEN );
        STE$INIT1 = NSUP$WORD;
        IF NOT NSUP$COMP[0] 
        THEN
          BEGIN              # WAIT FOR NSUP TO COMPLETE               #
          STE$SBIT1 = FALSE; # INSURE COMPLETE BIT IS CLEAR            #
          STE$ADDR2 = 0;     # DISABLE SECOND CHECK                    #
          WAITGET = TRUE; 
          RETURN; 
          END 
        ELSE
          BEGIN 
          AID;               # ACCEPT INCOMMING DATA                   #
          IF FORCERTN 
          THEN
            BEGIN 
            FORCERTN = FALSE; 
            STE$ADDR2 = LOC(CTM$CLOCK[0]);
            STE$INIT2 = CTM$CLOCK[0]; 
            ISSACNI = 0;
            RETURN; 
            END 
          END 
        END 
  
  
  
  
# 
*     IF THE NUMBER OF MESSAGES ON THE TRACE FILE REACHES *MC*
*     THEN CALL *NETREL* IF *MC* NE 0. IF *MC* IS ZERO THEN 
*     THE TRACE FILE IS TO REMAIN ATTACHED TILL END OF RUN
*     SO NETREL CALLS ARE NOT DONE. 
*     NOTE: THE NUMBER OF MESSAGES ON THE TRACE FILE CANNOT BE ASSUMED
*     TO BE EXACTLY *MC* AS THE *NETREL* CALL IS DELAYED DURING 
*     PERIODS OF HIGH ACTIVITY. 
# 
  
  
      IF MC NQ 0
        AND NSUP$MC[0] GR MC
      THEN
        BEGIN 
        NETREL (NTRL$LFN, 0, 0 ); 
        END 
  
  
  
  
# 
*     AIP TRAFFIC IS IDLE.
*     RESTART CONDITIONS ARE EITHER OUTGOING TRAFFIC
*     OR INCOMMING TRAFFIC AVAILABLE. 
# 
  
  
        STE$INIT1 = NSUP$WORD;
        STE$ADDR2 = LOC(ISSACNI);      # OUTGOING TRAFFIC QUEUE        #
        STE$INIT2 = 0;
        ISSACNI = 0;         # ZERO FLAG FOR OUTGOING TRAFFIC          #
        RETURN; 
  
      END # SSACNI #
  
      TERM
