*DECK NVFCUFS USETEXT TEXTSS USETEXT TXTSUSS USETEXT TXTAPSS USETEXT TXTANVF USETEXT TEXTNVF USETEXT TXINNVF PROC NVFCUFS; # TITLE NVFCUFS - UPDATE FLOW STATUS. # BEGIN # NVFCUFS # # ** NVFCUFS - UPDATE FLOW STATUS. * * S. H. FISCHER. 81/11/06. * D. G. DEPEW. 81/12/22. * * THIS PROCEDURE PERFORMS ALL THE CONNECTION(C) LAYER PROCESSING * REQUIRED FOR ALL INBOUND, FLOW CONTROL SUPERVISORY MESSAGES. * * PROC NVFCUFS * * ENTRY WCBUF[0] = WORD COUNT WORD FROM ORIGINAL CONNECTION * TRAFFIC QUEUE (*CTQ*) 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: FC/INIT/R, FC/ACK, FC/NAK, * FC/BRK, INTR/USR, AND FC/INACT. * * EXIT ANY OF THE FOLLOWING IN VARIOUS COMBINATIONS ACCORDING TO * THE SM RECEIVED AND THE STATE OF THE ACN LIST ENTRY FOR * THE USER IN QUESTION. * - THE STATE OF THE ACN LIST ENTRY HAS BEEN UPDATED. * - AN FC/INIT/N SM HAS BEEN PLACED IN THE OUTGOING TRAFFIC * QUEUE (*OTQ*). * - AN FS/RST SM HAS BEEN PLACED IN THE OUTGOING TRAFFIC * QUEUE (*OTQ*). * - ONE OR MORE ENTRIES IN THE WAITING BLOCK QUEUE (*WBQ*) * FOR THE USER IN QUESTION HAVE BEEN TRANSFERRED TO THE * OUTGOING TRAFFIC QUEUE (*OTQ*) * - A CR/SWH/R OR CR/TRM/R SM ENQUEUED (IN THE *WBQ*) FOR * THE USER IN QUESTION HAS BEEN TRANSFERRED TO THE * OUTGOING TRAFFIC QUEUE (*OTQ*). * - ALL OUTPUT ENQUEUED (IN THE *WBQ*) FOR THE USER IN * QUESTION HAS BEEN DISCARDED. * - AN INTR/USR ENTRY HAS BEEN PLACED IN THE TERMINAL-TO- * APPLICATION CONNECTION INPUT QUEUE (*TAINPQ*). * - THE SM HAS BEEN DISCARDED. * * NOTE THE PROCESSING IS DEFINED BY THE NVF/USER C-LAYER STATE * DIAGRAM. # # **** PROC NVFCUFS - XREF LIST. # XREF BEGIN PROC ABORT; # ABORT PROGRAM # PROC NVFCFCE; # FIND CONNECTION ENTRY # PROC MOVE; # MOVE BLOCK OF MEMORY # PROC SSCCTR; # CANCEL TIMER REQUEST # PROC SSSAWR; # ACCEPT WORKLIST REQUEST # PROC SSTAQE; # ACCEPT QUEUE ENTRY # PROC SSTATS; # ALLOCATE TABLE SPACE # PROC SSTRTS; # REMOVE TABLE SPACE # END # **** # ITEM I I; # LOOP VARIABLE AND SCRATCH # ITEM NEWACN B; # TRUE IF ACN NOT FOUND IN ACN LIST # ITEM AE I; # ORD OF MATCHED (OR NEW) ACN LIST ENTRY # ITEM ACNN I; # ACN FROM ENTRY WE ARE LOOKING FOR # ITEM RORD I; # ORDINAL OF ENTRY LOCATED IN *WBQ*/*IWBQ*# ITEM OORD I; # ORDINAL OF ENTRY POSITION IN *OTQ* # ITEM SIZ I; # SIZE OF ENTRY BEING MOVED TO *OTQ* # ITEM SMID I; # INTERNAL SM IDENTIFIER # SWITCH FSSWT:CTQSTAT LLFCACK: SACK, # FC/ACK # LLFCBRK: SBRK, # FC/BRK # LLIUSR: SIUSR, # INTR/USR # LLFCINA: SINA, # FC/INACT # LLFCINI: SINIT, # FC/INIT # LLFCNAK: SNAK, # FC/NAK # LLBIMRK: SBMRK; # BI/MARK # PROC DELDAT; BEGIN # DELDAT # # * DELDAT - DELETE SYNCHRONOUS BLOCKS. * * THIS EMBEDDED PROC FINDS BLOCKS QUEUED FOR THE ACN IN QUESTION IN * THE WAITING BLOCK QUEUE AND DELETES THEM FROM THE QUEUE. * * PROC DELDAT # FOR I = 0 WHILE ACN$WBCNT[AE] NQ 0 DO BEGIN FOR RORD = RORD STEP WBQ$ESIZE[RORD] WHILE WBQ$ABHACN[RORD] NQ ACNN DO BEGIN END SIZ = WBQ$ESIZE[RORD]; # SIZE OF ENTRY TO DELETE # SSTRTS( P, RORD, SIZ ); # DELETE ENTRY # ACN$WBCNT[AE] = ACN$WBCNT[AE] - 1; END END # DELDAT # PROC XMITDAT; BEGIN # XMITDAT # # * XMITDAT - TRANSMIT SYNCHRONOUS BLOCKS. * * THIS EMBEDDED PROC FINDS BLOCKS QUEUED FOR THE ACN IN QUESTION IN * THE WAITING BLOCK QUEUE AND MOVES THEM TO THE OUTGOING TRAFFIC * QUEUE UNTIL THE NUMBER OF UNACKNOWLEDGED SYNCHRONOUS BLOCKS IS * EQUAL TO THE APPLICATION BLOCK LIMIT. * * PROC XMITDAT # FOR I=0 WHILE ACN$WBCNT[AE] NQ 0 AND ACN$BLCNT[AE] LS ACN$ABL[AE] DO BEGIN FOR RORD = RORD STEP WBQ$ESIZE[RORD] WHILE WBQ$ABHACN[RORD] NQ ACNN DO BEGIN END OORD = OTQLNGTH; SIZ = WBQ$ESIZE[RORD]; # SIZE OF ENTRY TO BE MOVED # WBQ$ABN[RORD] = ACN$ABN[AE]; # TRANSFER NEXT ABN # SSTATS( P, SIZ ); MOVE( SIZ, WBQ[RORD], OTQ[OORD] ); SSTRTS( P, RORD, SIZ ); IF OORD EQ 0 THEN SSSAWR( WWDF"SACNI"); ACN$ABN[AE] = ACN$ABN[AE] + 1; ACN$BLCNT[AE] = ACN$BLCNT[AE] + 1; ACN$WBCNT[AE] = ACN$WBCNT[AE] - 1; END END # XMITDAT # PROC XMITSM; BEGIN # XMITSM # # * XMITSM - TRANSMIT ASYNCHRONOUS SUPERVISORY MESSAGE. * * THIS EMBEDDED PROC FINDS AN ASYNCHRONOUS SM (EITHER CR/SWH/R OR * CR/TRM/R) QUEUED FOR THE ACN IN QUESTION IN THE WAITING BLOCK * QUEUE AND MOVES IT TO THE OUTGOING TRAFFIC QUEUE. * * PROC XMITSM # IF (ACN$STATE[AE] EQ ACNST"SWTPEND" OR ACN$STATE[AE] EQ ACNST"TRMPEND") AND ACN$BLCNT[AE] EQ 0 THEN BEGIN FOR RORD = RORD STEP WBQ$ESIZE[RORD] WHILE WBQ$ABHACN[RORD] NQ 0 OR WBQ$CRSACN[RORD] NQ ACNN DO BEGIN END OORD = OTQLNGTH; SIZ = WBQ$ESIZE[RORD]; # SIZE OF ENTRY TO BE MOVED # SSTATS( P, SIZ ); MOVE( SIZ, WBQ[RORD], OTQ[OORD] ); SSTRTS( P, RORD, SIZ ); IF OORD EQ 0 THEN SSSAWR( WWDF"SACNI" ); IF ACN$STATE[AE] EQ ACNST"SWTPEND" THEN ACN$STATE[AE] = ACNST"SWSTART"; ELSE ACN$STATE[AE] = ACNST"ENDED"; END END # XMITSM # # MAIN PROCEDURE CODE BEGINS HERE # IF WCB$SMID[0] EQ CTQSTAT"SBMRK" THEN BEGIN ACNN = ABHADR[0]; END ELSE BEGIN ACNN = FCACN[0]; END NVFCFCE( ACNN, AE, NEWACN ); SMID = WCB$SMID[0]; # GET INTERNAL SM IDENTIFIER # IF NEWACN THEN BEGIN IF SMID NQ CTQSTAT"SINA" THEN ABORT; ELSE GOTO ENDTAS; END RORD = 0; GOTO FSSWT[SMID]; LLFCINI: IF ACN$STATE[AE] NQ ACNST"ENDED" THEN BEGIN ACN$INIT[AE] = TRUE; PFCSFC[0] = FCINITN; SSTAQE( P, WCBUF, ABHBUF, MSGBUF ); XMITDAT; # SEND DATA IF ANY # XMITSM; # SEND SM IF ALL BLOCKS ACKED # END GOTO ENDTAS; LLFCINA: # * IF THE CURRENT STATE OF THE CONNECTION IS TERMINATE PENDING, THEN * THE CONNECTION IS HUNG. GO AHEAD AND TERMINATE IT. # IF ACN$STATE[AE] EQ ACNST"TRMPEND" AND ACN$CNUM[AE] EQ ABHABN[0] THEN BEGIN ACN$BLCNT[AE] = 0; # CLEAR OUTSTANDING BLOCK COUNT # DELDAT; # DELETE SYNCHRONOUS DATA # XMITSM; # SEND CR/TRM/R # END GOTO ENDTAS; LLIUSR: IF INTRCHR[0] GR RIR"UB2" THEN # IF THIS IS A USER INTERRUPT # BEGIN IF ACN$STATE[AE] NQ ACNST"SWSTART" AND ACN$STATE[AE] NQ ACNST"ENDED" THEN # IF A SWITCH OR TERM IS NOT IN PROGRESS, # BEGIN # SEND AN INTR/RSP SM # WCB$WORD[1] = LINTR + 2; ABHWORD[1] = LINTR; ABHABT[1] = APPCMD; ABHACT[1] = ACINTR; SPMSG0[1] = 0; PFCSFC[1] = INTRRSP; INTRACN[1] = ACNN; SSTAQE(P,WCBUF[1],ABH[1],APSM[1]); END END ELSE # MUST BE A USER BREAK # BEGIN ACN$BKCNT[AE] = 1; DELDAT; # DELETE SYNCHRONOUS DATA # IF ACN$STATE[AE] EQ ACNST"ACTIVE" OR ACN$STATE[AE] EQ ACNST"BRKCMD" THEN BEGIN ACN$STATE[AE] = ACNST"BRKOUT"; SSTAQE( P, WCBUF, ABHBUF, MSGBUF ); IF ACN$BLKF[AE] THEN BEGIN ACN$BLKF[AE] = FALSE; FOR RORD=0 STEP IWQ$WC[RORD] WHILE ACNN NQ IWQ$ACN[RORD+1] DO BEGIN END SSTRTS(P,RORD,IWQ$WC[RORD]); END END ELSE XMITSM; # SEND SM IF ONE # END GOTO ENDTAS; LLBIMRK: IF ACN$STATE[AE] EQ ACNST"CLEARI" THEN # IF THE CURRENT ACN STATE IS CLEAR INPUT # BEGIN WCB$WORD[1] = LINTR + 2; ABHWORD[1] = LINTR; ABHABT[1] = APPCMD; ABHACT[1] = ACINTR; SPMSG0[1] = 0; PFCSFC[1] = INTRRSP; INTRACN[1] = ACNN; SSTAQE(P,WCBUF[1],ABH[1],APSM[1]); # SET CURRENT ACN STATE BACK TO ACTIVE # ACN$STATE[AE] = ACNST"ACTIVE"; ACN$BKCNT[AE] = 0; END ELSE IF ACN$STATE[AE] EQ ACNST"BRKOUT" THEN BEGIN ACN$BKCNT[AE] = 0; END GOTO ENDTAS; LLFCACK: LLFCNAK: IF ACN$STATE[AE] EQ ACNST"ENDED" OR ACN$STATE[AE] EQ ACNST"SWSTART" THEN GOTO ENDTAS; ACN$BLCNT[AE] = ACN$BLCNT[AE] - 1; XMITDAT; # SEND DATA IF ANY # # * IF TERMINATION IS PENDING AND THE CR/TRM/R WILL NOW BE SENT OUT * THEN CANCEL THE TIMER REQUEST THAT WAS STARTED UP BECAUSE OF BEING * IN THE PENDING STATE. # IF ACN$STATE[AE] EQ ACNST"TRMPEND" AND ACN$BLCNT[AE] EQ 0 THEN SSCCTR(ACN$CNUM[AE],I); XMITSM; # SEND SM IF ALL BLOCKS ACKED # GOTO ENDTAS; LLFCBRK: IF ACN$STATE[AE] NQ ACNST"SWSTART" AND ACN$STATE[AE] NQ ACNST"ENDED" THEN # IF A SWITCH OR TERM IS NOT IN PROGRESS # BEGIN # SEND AN FC/RST SM # WCB$WORD[1] = LFCRST + 2; ABHWORD[1] = LFCRST; ABHABT[1] = APPCMD; ABHACT[1] = ACFC; SPMSG0[1] = 0; PFCSFC[1] = FCRST; FCACN[1] = ACNN; SSTAQE(P,WCBUF[1],ABH[1],APSM[1]); END GOTO ENDTAS; ENDTAS: END # NVFCUFS # TERM