*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