*DECK NVFCUHS
USETEXT TEXTNVF
USETEXT TEXTSS
USETEXT TXTAPSS
USETEXT TXTANVF
USETEXT TXINNVF
PROC NVFCUHS;
# TITLE NVFCUHS - UPDATE HOP STATUS. #
BEGIN # NVFCUHS #
#
** NVFCUHS - UPDATE HOP STATUS.
*
* D. G. DEPEW. 82/03/04.
*
* THIS PROCEDURE PERFORMS ALL THE CONNECTION(C) LAYER PROCESSING
* REQUIRED FOR THE INBOUND, SPECIAL HOP SUPERVISORY MESSAGES.
*
* PROC NVFCUHS
*
* 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: HOP/START, HOP/CMD, HOP/BRK,
* HOP/PAGE, HOP/END, HOP/IG.
*
* EXIT ANY OF THE FOLLOWING IN VARIOUS COMBINATIONS ACCORDING TO
* THE SM RECEIVED AND THE STATE OF THE HOP PSEUDO ACN:
* - THE HOP PSEUDO ACN STATE HAS BEEN UPDATED.
* - AN ENTRY HAS BEEN PLACED IN THE PROTOCOL EVENT QUEUE
* (*PEQ*).
* - ONE OR MORE HOP ENTRIES IN THE WAITING BLOCK QUEUE
* (*WBQ*) HAVE BEEN TRANSFERRED TO THE OUTGOING TRAFFIC
* QUEUE (*OTQ*).
* - ALL OUTPUT ENQUEUED FOR THE HOP (IN THE *WBQ*) HAS BEEN
* DISCARDED.
* - AN ENTRY HAS BEEN PLACED IN THE OPERATOR TYPEIN QUEUE
* (*OPTQ*).
* - HOP PAGING STATUS HAS BEEN UPDATED.
* - HOP IGNORE STATUS HAS BEEN UPDATED.
*
* NOTE THE PROCESSING IS DEFINED BY THE NVF/HOP C-LAYER STATE
* DIAGRAM.
#
#
**** PROC NVFCUHS - XREF LIST.
#
XREF
BEGIN
PROC MOVE; # MOVE STORAGE DIRECT ADDRESSING (MACREL) #
PROC SSSAWR; # ACCEPT WORKLIST REQUEST #
PROC SSTAQE; # ACCEPT QUEUE ENTRY #
PROC SSTATS; # ALLOCATE TABLE SPACE AT END OF TABLE #
PROC SSTRTS; # REMOVE TABLE SPACE ANYWHERE IN TABLE #
END
*CALL HMSGNVF
#
****
#
ITEM STATE S:HCNST; # TEMP CELL FOR STATE OF HOP PSEUDO ACN #
#
* FOLLOWING ITEMS ARE USED ONLY BY EMBEDDED PROCS (SOME ARE
* SHARED).
#
ITEM I; # LOOP INDUCTION VARIABLE #
ITEM COUNT; # NUMBER OF HOP *WBQ* ENTRIES TO BE MOVED #
ITEM LICNT; # COUNT OF DISPLAY LINES IN *WBQ* ENTRY #
ITEM OORD; # OUTGOING TRAFFIC QUEUE ORDINAL #
ITEM SIZ; # *OTQ* ENTRY SIZE #
ITEM WBC; # *WBQ* ENTRY COUNT OR ENTRY SIZE #
ITEM WORD; # WAITING BLOCK QUEUE ORDINAL #
BASED ARRAY TEXTLOC [00:00] S(1); ;
ARRAY OUTDISC [00:00] S(5);
BEGIN
ITEM OD$PSFC U(00,00,16) = [HOPDIS];
ITEM OD$ZERO1 U(00,16,43) = [0];
ITEM OD$IAF B(00,59,01) = [TRUE]; # INPUT OK #
ITEM OD$TEXT1 C(01,00,16) = ["OUTPUT DISCARDED"];
ITEM OD$ZERO2 U(02,36,24) = [0];
ITEM OD$TEXT2 C(03,00,07) = ["READY.."];
ITEM OD$ZERO3 U(03,42,18) = [0];
ITEM OD$ZERO4 U(04,00,60) = [0];
END
ARRAY PAGEMSG [00:00] S(4);
BEGIN
ITEM PG$PSFC U(00,00,16) = [HOPDIS];
ITEM PG$ZERO1 U(00,16,44) = [0]; # NO INPUT #
ITEM PG$TEXT C(01,00,15) = ["PAGE ACCEPTED.."];
ITEM PG$ZERO2 U(02,30,30) = [0];
ITEM PG$ZERO3 U(03,00,60) = [0];
END
DEF ODTLW$ #5#; # *OUTPUT DISCARDED* TEXT LENGTH IN WORDS #
DEF ODQES$ #7#; # *OUTPUT DISCARDED* QUEUE ENTRY SIZE #
DEF PGTLW$ #4#; # *PAGE ACCEPTED..* TEXT LENGTH IN WORDS #
DEF PGQES$ #6#; # *PAGE ACCEPTED..* QUEUE ENTRY SIZE #
CONTROL EJECT;
PROC XMITHQ;
BEGIN # XMITHQ #
#
* XMITHQ - TRANSMIT HOP QUEUE.
*
* THIS EMBEDDED PROC MOVES HOP ENTRIES IN THE WAITING BLOCK QUEUE
* (*WBQ*) TO THE OUTGOING TRAFFIC QUEUE (*OTQ*). THE NUMBER OF
* ENTRIES MOVED DEPENDS UPON PAGING STATUS AND WHETHER THERE
* ACTUALLY IS DATA QUEUED (IN THE *WBQ*) FOR THE HOP.
*
* PROC XMITHQ
*
* ENTRY 1. THE *WBQ* CONTAINS ZERO OR MORE HOP ENTRIES.
* 2. THE ACN LIST ENTRY FOR THE HOP CONTAINS ALL REQUIRED
* INFORMATION - NAMELY, THE COUNT OF HOP ENTRIES IN THE
* *WBQ* AND THE PAGING STATUS FLAG.
*
* EXIT 1. ZERO OR MORE HOP ENTRIES HAVE BEEN REMOVED FROM THE
* *WBQ* AND PLACED IN THE *OTQ*.
* 2. THE COUNT OF LINES CURRENTLY BEING DISPLAYED HAS BEEN
* SET TO THE LINE COUNT OF THE LAST *WBQ* ENTRY MOVED
* (ZERO IF NO ENTRIES MOVED).
* 3. THE HOP WAITING BLOCK COUNT HAS BEEN UPDATED
* APPROPRIATELY.
*
* NOTE HOP ENTRIES IN THE *WBQ* ARE ALREADY IN CORRECT HOP/DIS
* FORMAT EXCEPT FOR THE EXTRA WORD AT THE END, WHICH IS
* REQUIRED BY NIP AND MUST BE ADDED.
#
#
* THE FIRST TASK IS TO DETERMINE HOW MANY BLOCKS (HOP *WBQ* ENTRIES)
* TO MOVE. IF PAGING IS ON, MOVE ONE BLOCK (AT MOST A SCREENFULL).
* IF PAGING IS OFF, MOVE ALL ENQUEUED BLOCKS. OF COURSE, IF THERE
* ARE CURRENTLY NO HOP ENTRIES IN THE *WBQ*, NOTHING HAPPENS.
#
WBC = ACN$WBCNT[HOPORD$];
IF ACN$PWAIT[HOPORD$]
AND WBC NQ 0
THEN
COUNT = 1;
ELSE
COUNT = WBC; # CAN BE ZERO #
ACN$WBCNT[HOPORD$] = WBC - COUNT; # UPDATED #
#
* NOW MOVE THE BLOCKS. SET THE COUNT OF TEXT LINES CURRENTLY BEING
* DISPLAYED TO THE LINE COUNT OF THE LAST BLOCK MOVED (IF ONE).
* PROVIDE FOR THE EXTRA WORD REQUIRED IN THE HOP/DIS SM. IN ORDER
* TO MOVE A BLOCK, WE MUST FIRST FIND IT.
#
LICNT = 0; # INITIALIZE #
WORD = 0;
FOR I=1 STEP 1 UNTIL COUNT
DO # MOVE *COUNT* BLOCKS, ZERO OK #
BEGIN
FOR WORD = WORD STEP WBQ$ESIZE[WORD]
WHILE WBQ$ABHACN[WORD] NQ 0
OR WBQ$CRSACN[WORD] NQ 0
DO # FIND HOP ENTRY (HOP/DIS SM) #
BEGIN END
OORD = OTQLNGTH; # WHERE *OTQ* ENTRY WILL BE #
WBC = WBQ$ESIZE[WORD]; # SIZE OF ENTRY TO BE MOVED #
SIZ = WBC + 1; # SIZE OF HOP/DIS NTRY IN *OTQ* #
LICNT = WBQ$LICNT[WORD]; # TEXT LINES IN *WBQ* ENTRY #
WBQ$ESIZE[WORD] = SIZ; # UPDATE PRIOR TO MOVE #
WBQ$TLC[WORD] = WBQ$TLC[WORD] + 1;
SSTATS (P<OTQ>, SIZ); # MAKE ROOM #
MOVE (WBC, WBQ[WORD], OTQ[OORD]);
SSTRTS (P<WBQ>, WORD, WBC); # DELETE WAITING BLOCK #
OTQ$WORD[OTQLNGTH-1] = 0; # EXTRA WORD #
IF OORD EQ 0
THEN # FIRST ENTRY IN *OTQ* #
SSSAWR (WWDF"SACNI");
END
ACN$BLCNT[HOPORD$] = LICNT; # NUMBER LINES ON SCREEN #
END # XMITHQ #
PROC PURGEHQ;
BEGIN # PURGEHQ #
#
* PURGEHQ - PURGE HOP QUEUE.
*
* THIS EMBEDDED PROC REMOVES ALL HOP ENTRIES FROM THE WAITING BLOCK
* QUEUE (*WBQ*).
*
* PROC PURGEHQ
*
* ENTRY 1. THE *WBQ* CONTAINS ZERO OR MORE HOP ENTRIES.
* 2. THE ACN LIST ENTRY FOR THE HOP CONTAINS ALL REQUIRED
* INFORMATION - NAMELY, THE COUNT OF HOP *WBQ* ENTRIES.
*
* EXIT 1. ALL HOP ENTRIES IN THE *WBQ* HAVE BEEN DELETED.
* 2. THE COUNTS OF *WBQ* ENTRIES AND LINES CURRENTLY BEING
* DISPLAYED (BOTH IN THE ACN LIST ENTRY FOR THE HOP)
* HAVE BEEN CLEARED.
#
#
* INITIALIZE AND UPDATE THE ACN LIST ENTRY FOR THE HOP.
#
COUNT = ACN$WBCNT[HOPORD$]; # NUMBER OF BLOCKS TO DELETE #
ACN$WBCNT[HOPORD$] = 0;
ACN$BLCNT[HOPORD$] = 0; # START NEW PAGE #
#
* NOW DELETE THE ENTRIES. IN ORDER TO DELETE AN ENTRY, WE MUST
* FIRST FIND IT.
#
WORD = 0;
FOR I=1 STEP 1 UNTIL COUNT
DO # DEL *COUNT* ENTRIES, ZERO OK #
BEGIN
FOR WORD = WORD STEP WBQ$ESIZE[WORD]
WHILE WBQ$ABHACN[WORD] NQ 0
OR WBQ$CRSACN[WORD] NQ 0
DO # FIND HOP ENTRY (HOP/DIS SM) #
BEGIN END
WBC = WBQ$ESIZE[WORD]; # SIZE OF ENTRY TO BE DELETED #
SSTRTS (P<WBQ>, WORD, WBC); # DELETE WAITING BLOCK #
END
END # PURGEHQ #
CONTROL EJECT;
#
* MAIN ROUTINE BEGINS HERE.
*
* WE EXECUTE WHAT AMOUNTS TO A CASE CONSTRUCT TO PROCESS THE SIX
* TYPES OF INCOMING HOP SM-S.
#
IF WCB$SMID[0] EQ CTQSTAT"SHSTART"
THEN # K-DISPLAY ASSIGNED TO NVF #
BEGIN
#
* INITIALIZE THE HOP ACN LIST ENTRY. SEND THE HOP/START TO THE
* I-LAYER (AS PROTOCOL EVENT), IF APPROPRIATE. UPDATE THE STATE.
#
STATE = ACN$HOPST[HOPORD$];
ACN$WORD0[HOPORD$] = 0;
ACN$WORD1[HOPORD$] = 0;
ACN$ACN[HOPORD$] = 1; # INSURE NON-MATCH W/REAL ACN'S #
IF STATE EQ S"INACT"
THEN # SEND HOP/START TO I-LAYER #
BEGIN
WCB$SMID[0] = HPESTAT"HOPSRT"; # HOP/START ID FOR I-LAYER #
SSTAQE (P<PEQ>, WCBUF[0], ABH[0], APSM[0]); # TO I-LAYER #
END
IF STATE EQ S"ENDED"
THEN
ACN$HOPST[HOPORD$] = S"RESTART";
ELSE
BEGIN
ACN$HOPST[HOPORD$] = S"CREATE";
ACN$PL[HOPORD$] = HOPLPL[0] - 1;
END
END
ELSE IF WCB$SMID[0] EQ CTQSTAT"SHCMD"
THEN # HOP ENTERED A COMMAND #
BEGIN
#
* FORWARD THE COMMAND TO THE I-LAYER (AS OPERATOR TYPEIN) FOR
* SYNTAX CRACKING AND COMMAND PROCESSING. ECHO THE COMMAND BACK
* TO THE K-DISPLAY VIA HOP/DIS SM. UPDATE THE STATE AND SEND HIM
* THE NEXT PAGE OF QUEUED OUTPUT (IF ANY). NOTE THAT *OPTQ*
* ENTRIES DO NOT CONTAIN A PFC/SFC WORD.
#
WCB$WORD[1] = WCB$WC[0] - 1; # DEDUCT FOR PFC/SFC WORD #
ABHWORD[1] = 0;
ABHTLC[1] = HOPDTL[0]; # ACTUAL CHAR COUNT #
P<TEXTLOC> = LOC(SPMSG1[0]); # LOCATION OF COMMAND TEXT #
SSTAQE (P<OPTQ>, WCBUF[1], ABH[1], TEXTLOC[0]); # TO I-LAYER #
WCB$WORD[0] = WCB$WC[0] + 1; # EXTRA WORD FOR HOP/DIS SM #
ABHTLC[0] = ABHTLC[0] + 1;
SPMSG0[0] = 0; # NO INPUT ALLOWED #
PFCSFC[0] = HOPDIS;
SSTAQE (P<OTQ>, WCBUF[0], ABH[0], APSM[0]); # ECHO COMMAND #
OTQ$WORD[OTQLNGTH-1] = 0; # EXTRA WORD #
ACN$HOPST[HOPORD$] = S"COMMAND";
XMITHQ; # XMIT QUEUED HOP DATA (IF ANY) #
END
ELSE IF WCB$SMID[0] EQ CTQSTAT"SHBRK"
THEN # HOP ENTERED A BREAK #
BEGIN
#
* RELEASE ALL QUEUED (IN THE *WBQ*) OUTPUT. IF THE HOP PSEUDO
* ACN IS IN THE *ACTIVE* STATE, SEND THE *OUTPUT DISCARDED*
* MESSAGE FOLLOWED BY *READY..*. IF A COMMAND IS IN PROGRESS,
* FORWARD THE BREAK TO THE I-LAYER AS AN OPERATOR TYPEIN (*OPTQ*).
* UPDATE THE STATE.
#
PURGEHQ; # PURGE QUEUED HOP DATA(IF ANY) #
IF ACN$HOPST[HOPORD$] EQ S"CREATE"
THEN # BREAK HISTORY BUFFER OUTPUT #
ACN$HOPST[HOPORD$] = S"STARTBRK";
ELSE IF ACN$HOPST[HOPORD$] EQ S"ACTIVE"
THEN # BREAK UNSOLICITED STATUS RPTS #
BEGIN
WCB$WORD[0] = ODQES$;
ABHTLC[0] = ODTLW$;
SSTAQE (P<OTQ>, WCBUF[0], ABH[0], OUTDISC);
ACN$BLCNT[HOPORD$] = 2; # START NEW PAGE W/ 2 LINES #
END
ELSE IF ACN$HOPST[HOPORD$] EQ S"COMMAND"
THEN # BREAK COMMAND IN PROGRESS #
BEGIN
WCB$WORD[1] = 2; # MIN QUEUE ENTRY LENGTH #
ABHWORD[1] = 0; # TLC = 0 #
ABHBRK[1] = 1;
SSTAQE (P<OPTQ>, WCBUF[1], ABH[1], TEXTLOC[0]); #TO I-LAYER #
ACN$HOPST[HOPORD$] = S"BREAK";
END
ELSE # MUST BE BRK HIST AFT RESTART #
ACN$HOPST[HOPORD$] = S"RESBREAK";
END
ELSE IF WCB$SMID[0] EQ CTQSTAT"SHIG"
THEN # HOP WANTS TO IGNORE NVF REPTS #
#
* ALL THAT IS REQUIRED IS TO SET THE APPROPRIATE FLAG IN THE HOP
* ENTRY OF THE ACN LIST.
#
ACN$IGNOR[HOPORD$] = TRUE;
ELSE IF WCB$SMID[0] EQ CTQSTAT"SHEND"
THEN # K-DIS NO LONGER ASS'D TO NVF #
BEGIN
#
* RELEASE ALL QUEUED (IN THE *WBQ*) OUTPUT. IF THE HOP PSEUDO
* ACN IS IN THE *ACTIVE* STATE, SEND A HOP/END PROTOCOL EVENT TO
* THE I-LAYER. IF A COMMAND IS IN PROGRESS, SEND A HOP/END-
* WARNING PROTOCOL EVENT TO THE I-LAYER (HOP/END WILL BE SENT
* WHEN COMMAND IS CLEANED UP). UPDATE THE HOP PSEUDO ACN STATE.
#
PURGEHQ; # PURGE QUEUED HOP DATA(IF ANY) #
IF ACN$HOPST[HOPORD$] EQ S"ACTIVE"
OR ACN$HOPST[HOPORD$] EQ S"COMMAND"
THEN # MUST SEND P.E. TO I-LAYER #
BEGIN
WCB$WORD[0] = 2; # MIN QUEUE ENTRY SIZE #
ABHTLC[0] = 0;
IF ACN$HOPST[HOPORD$] EQ S"ACTIVE"
THEN
WCB$SMID[0] = HPESTAT"HOPEND";
ELSE
WCB$SMID[0] = HPESTAT"HOPENDW";
SSTAQE(P<PEQ>, WCBUF[0], ABH[0], APSM[0]); # TO I-LAYER #
END
IF ACN$HOPST[HOPORD$] EQ S"CREATE"
OR ACN$HOPST[HOPORD$] EQ S"STARTBRK"
THEN
ACN$HOPST[HOPORD$] = S"STARTEND";
ELSE
ACN$HOPST[HOPORD$] = S"ENDED";
END
ELSE # MUST BE A PAGING COMMAND SM #
BEGIN
#
* IF THE COMMAND IS A PAGING COMMAND FOR THE RIGHT K-DISPLAY, SEND
* A NEW PAGE OF HELP TEXT TO THE RIGHT K-DISPLAY.
#
IF (HOPPC[0] EQ "(" ) OR
(HOPPC[0] EQ ")" )
THEN
BEGIN
WCB$SMID[1] = HOPDIS;
WCB$WC[1] = RKPAGESZ$ + 1;
ABHWORD[1] = 0;
ABHABT[1] = APPCMD;
ABHACT[1] = CT60TRANS;
ABHTLC[1] = RKPAGESZ$;
#
* IF THE COMMAND IS A PAGE FORWARD COMMAND, SEND THE NEXT PAGE
* OF HELP TEXT.
#
IF HOPPC[0] EQ "("
THEN
BEGIN
IF CURPAGE EQ LASTPAGE$
THEN
BEGIN
CURPAGE = PAGE1$;
END
ELSE
BEGIN
CURPAGE = CURPAGE + 1;
END
END
#
* IF THE COMMAND IS A PAGE BACKWARD COMMAND, SEND THE PREVIOUS
* PAGE OF HELP TEXT.
#
ELSE # HOPPC = ")" #
BEGIN
IF CURPAGE EQ PAGE1$
THEN
BEGIN
CURPAGE = LASTPAGE$;
END
ELSE
BEGIN
CURPAGE = CURPAGE - 1;
END
END
SSTAQE(P<OTQ>,WCBUF[1],ABH[1],RKPAGE[CURPAGE]);
END
#
* IF THE COMMAND INDICATES A CHANGE IN PAGING STATUS IS DESIRED,
* SEND THE *PAGE ACCEPTED..* MESSAGE AND REMEMBER THE NEW PAGING
* STATUS. THEN SEND THE HOP AS MUCH QUEUED (IN THE *WBQ*) DATA
* (IF ANY) AS IS CONSISTENT WITH THE UPDATED PAGING STATUS.
#
ELSE
BEGIN
IF HOPPC[0] NQ ACN$PCHAR[HOPORD$]
THEN # PAGING STATUS CHANGE #
BEGIN
WCB$WORD[0] = PGQES$;
ABHTLC[0] = PGTLW$;
SSTAQE (P<OTQ>, WCBUF[0], ABH[0], PAGEMSG);
ACN$PCHAR[HOPORD$] = HOPPC[0];
END
XMITHQ; # XMIT QUEUED HOP DATA (IF ANY) #
END
END
END # NVFCUHS #
TERM