*DECK     CSCBPA
USETEXT TEXTCS
USETEXT TEXTSS
USETEXT TXTAPSS 
PROC CSCBPA;
# TITLE CSCBPA - BEGIN PROTOCOL ACTION.   # 
  
      BEGIN  # CSCBPA # 
# 
**    CSCBPA - BEGIN PROTOCOL ACTION. 
* 
*     D. G. DEPEW.           82/06/01.
* 
*     THIS PROCEDURE PERFORMS ALL THE CONNECTION(C) LAYER PROCESSING
*     REQUIRED FOR ALL INBOUND, CONNECTION/NOP RELATED SUPERVISORY
*     MESSAGES. 
* 
*     PROC CSCBPA 
* 
*     ENTRY    WCBUF[0] = WORD COUNT WORD FROM ORIGINAL CONNECTION
*                         TRAFFIC QUEUE (*CNQ*) ENTRY 
*             ABHBUF[0] = APPLICATION BLOCK HEADER FOR THE SM (BASED
*                         ARRAY *ABH* IN *TXTAPSS* POINTS HERE).
*             MSGBUF[0] = BODY OF THE SM (BASED ARRAY *APSM* IN 
*                         *TXTAPSS* POINTS HERE).  THE POSSIBLE PFC/SFC 
*                         VALUES ARE:  CON/REQ/R, CON/CB, CON/END/N,
*                         TCH/TCHAR, AND SHUT/INSD. 
* 
*     EXIT    ANY OF THE FOLLOWING IN VARIOUS COMBINATIONS ACCORDING TO 
*             THE SM RECEIVED AND THE STATE OF THE ACN LIST ENTRY FOR 
*             THE NOP IN QUESTION.
*             - THE STATE OF THE ACN LIST ENTRY HAS BEEN UPDATED. 
*             - AN ENTRY HAS BEEN PLACED IN THE OUTGOING TRAFFIC QUEUE
*               (*OTQ*).
*             - AN ENTRY HAS BEEN PLACED IN THE PROTOCOL EVENT QUEUE
*               (*PEQ*).
*             - ALL OUTPUT ENQUEUED (IN THE *WBQ*) FOR THE NOP IN 
*               QUESTION HAS BEEN DISCARDED.
* 
*     NOTE    THE PROCESSING IS DEFINED BY THE CS/NOP C-LAYER STATE 
*             DIAGRAM.
# 
  
# 
****  PROC CSCBPA - XREF LIST.
# 
      XREF
        BEGIN 
        PROC CSCPNQ;         # PURGE NOP QUEUE                         #
        PROC SSTAQE;         # ACCEPT QUEUE ENTRY                      #
        END 
# 
****
# 
  
  
      ITEM NACN;             # NOP ACN = ORDINAL OF ACN LIST ENTRY     #
      ITEM DUM; 
  
  
  
  
  
CONTROL EJECT;
  
FUNC CSIDLE  B; 
  
      BEGIN  # CSIDLE # 
# 
*     CSIDLE - DETERMINE IF CS IS IDLE. 
* 
*     THIS EMBEDDED FUNCTION DETERMINES WHETHER CS CURRENTLY HAS ANY
*     CONNECTED NPU OPERATORS.  THE PROGRAM IS CONSIDERED TO BE IDLE
*     (FOR SHUTDOWN PURPOSES ONLY) IF THERE ARE NONE. 
* 
*     FUNC CSIDLE  B
* 
*     ENTRY   NONE. 
* 
*     EXIT    CSIDLE = TRUE, IF CS HAS NO NOP (TERMINAL) CONNECTIONS. 
*             CSIDLE = FALSE, IF CS HAS NOP (TERMINAL) CONNECTIONS. 
# 
  
      ITEM I;                # LOOP INDUCTION VARIABLE                 #
  
  
  
# 
*     SEARCH ACN LIST FOR AN ACTIVE NOP (STATE OF ACN NOT EQUAL ZERO).
*     IF THERE IS AT LEAST ONE NOP PRESENT, CS IS STILL BUSY. 
# 
      FOR I=MINACN$  STEP 1 
        WHILE ACN$NOPST[I] EQ S"INACT"
          AND I LQ MAXACN$
      DO                     # FIND FIRST ACTIVE NOP                   #
        BEGIN  END
  
      IF I GR MAXACN$ 
      THEN                   # NO NOP"S                                #
        CSIDLE = TRUE;
      ELSE                   # AT LEAST ONE NOP                        #
        CSIDLE = FALSE; 
  
      END  # CSIDLE # 
  
  
  
  
  
CONTROL EJECT;
  
# 
*     MAIN ROUTINE BEGINS HERE. 
* 
*     SAVE ACN NUMBER AND REFORMAT THE ABH FOR THE I-LAYER.  EXECUTE A
*     CASE CONSTRUCT TO PROCESS THE FIVE TYPES OF INCOMING SM"S.
# 
      ABHWORD[1] = 0; 
      ABHADR[1]  = CONACN[0]; 
      NACN = CONACN[0]; 
  
  
  
      IF WCB$SMID[0] EQ SMID"CONREQ"
      THEN                             # TERM USER WANTS TO BE A NOP   #
        BEGIN 
  
  
# 
*       REJECT THE CON/REQ/R IF IT IS NOT FOR A CONSOLE DEVICE. 
*       OTHERWISE SEND THE CON/REQ/R TO THE I-LAYER (AS PROTOCOL EVENT),
*       UPDATE THE STATE AND INITIALIZE THE ACN LIST ENTRY. 
# 
        IF COND[0] NQ 0 
        THEN                           # UNACCEPTABLE DEVICE FOR CS    #
          BEGIN                        # ISSUE CON/REQ/A               #
          WCB$WORD[0] = LCORQR + 2;         # ENTRY SIZE               #
          ABHTLC[0]   = LCORQR;             # TEXT LENGTH, ABH DONE    #
          SPMSG0[0]   = 0;
          PFCSFC[0]   = CONREQA;            # PFC/SFC                  #
          CONACN[0]   = NACN;               # SM BODY COMPLETE         #
          SSTAQE (P<OTQ>, WCBUF[0], ABHBUF[0], MSGBUF[0]);
          END 
  
        ELSE                           # CONSOLE                       #
          BEGIN 
          ACN$NOPST[NACN] = S"CREATE";      # STATE                    #
          ACN$ABN[NACN]   = 1;              # FIRST BLOCK NUMBER       #
          ACN$DBZ[NACN]   = CONDBZ[0];      # RECOMMENDED BLOCK SIZE   #
          ACN$ABL[NACN]   = CONABL[0];      # BLOCK LIMIT - *ACN* DONE #
          SSTAQE (P<PEQ>, WCBUF[0], ABHBUF[1], MSGBUF[0]);  # TO I-LAY #
          END 
  
        END                  # CON/REQ/R                               #
  
  
  
      ELSE IF WCB$SMID[0] EQ SMID"CONCB"
      THEN                             # NOP'S CONNECTION IS BROKEN    #
        BEGIN 
  
  
# 
*       RELEASE ALL OUTPUT QUEUED (IN THE *WBQ*) FOR THIS NOP (IF ANY). 
*       IF THE NOP'S ACN IS IN THE *ACTIVE* STATE, SEND A CON/CB
*       PROTOCOL EVENT TO THE I-LAYER.  IF THERE IS A COMMAND IN
*       PROGRESS, SEND A CON/CB-WARNING PROTOCOL EVENT TO THE I-LAYER 
*       (CON/CB WILL BE SENT WHEN THE COMMAND IS CLEANED UP).  IGNORE 
*       THE CON/CB IF CONNECTION TERMINATION HAS ALREADY BEGUN.  UPDATE 
*       THE ACN STATE.
# 
        CSCPNQ (NACN, DUM);            # DELETE NOP'S OUTPUT (IF ANY)  #
  
        IF ACN$NOPST[NACN] EQ S"ACTIVE" 
          OR ACN$NOPST[NACN] EQ S"COMMAND"
          OR ACN$NOPST[NACN] EQ S"CLEARI" 
        THEN                           # MUST SEND P.E. TO I-LAYER     #
          BEGIN 
          IF ACN$NOPST[NACN] EQ S"COMMAND"
          THEN
            WCB$SMID[0] = SMID"CONCBW"; 
          SSTAQE (P<PEQ>, WCBUF[0], ABHBUF[1], MSGBUF[0]);  # TO I-LAY #
          END 
  
        IF ACN$NOPST[NACN] NQ S"ENDED"
        THEN
          ACN$NOPST[NACN] = S"BROKEN";
  
        END                  # CON/CB                                  #
  
  
  
      ELSE IF WCB$SMID[0] EQ SMID"CONENDN"
      THEN                             # CONNECTION TERMINATION DONE   #
        BEGIN 
  
  
# 
*       CLEAR THE ACN LIST ENTRY.  IF SHUTDOWN IS IN PROGRESS AND THERE 
*       ARE NO LONGER ANY CONNECTED NOPS, SEND A FORCED SHUTDOWN
*       PROTOCOL EVENT TO THE I-LAYER.
# 
        ACN$WORD0[NACN] = 0;
        ACN$WORD1[NACN] = 0;
        ACN$ACN[NACN]   = NACN;        # LV AS AFTER CS INITIALIZATION #
  
        IF CSSTATE AND CSIDLE 
        THEN                           # IDLE DOWN AND NO NOPS         #
          BEGIN                        # FORMAT SHUT/INSD              #
          WCB$WORD[0] = LSHUT + 2;          # ENTRY SIZE               #
          WCB$SMID[0] = SMID"SHUINS"; 
          ABHWORD[1]  = 0;                  # NO REAL ABH NEEDED       #
          SPMSG0[0]   = 1;                  # IMI SHUT FLG, P.E. DONE  #
          SSTAQE (P<PEQ>, WCBUF[0], ABHBUF[1], MSGBUF[0]);  # TO I-LAY #
          END 
  
        END                  # CON/END/N                               #
  
  
  
      ELSE IF WCB$SMID[0] EQ SMID"TCHTCH" 
      THEN                             # NOP CHANGED TERM'S TC,PW,PL   #
        BEGIN 
  
  
# 
*       SEND TERMINAL CHARACTERISTICS TO I-LAYER ONLY IF WE HAVE NOT
*       INITIATED CONNECTION TERMINATION. 
# 
        IF ACN$NOPST[NACN] NQ S"ENDED"
        THEN
          SSTAQE (P<PEQ>, WCBUF[0], ABHBUF[1], MSGBUF[0]);
  
        END                  # TCH/TCHAR                               #
  
  
  
      ELSE IF WCB$SMID[0] EQ SMID"SHUINS" 
      THEN                             # CS SHOULD SHUT DOWN           #
        BEGIN 
  
  
# 
*       SET THE STATE OF CS TO SHUTDOWN IN PROGRESS.  IF THERE ARE
*       CURRENTLY NO NOPS CONNECTED, CS WILL ACT AS IF THIS IS AN 
*       IMMEDIATE SHUTDOWN REQUEST REGARDLESS OF WHICH TYPE OF SHUTDOWN 
*       WAS ACTUALLY ENTERED. 
# 
        CSSTATE = TRUE;                # EQUALS SHUTDOWN IN PROGRESS   #
        IF CSIDLE 
        THEN
          SPMSG0[0] = 1;               # SET IMMEDIATE SHUTDOWN        #
        SSTAQE (P<PEQ>, WCBUF[0], ABHBUF[1], MSGBUF[0]);   # TO I-LAYR #
  
        END                  # SHUT/INSD                               #
  
      END  # CSCBPA # 
  
      TERM
