*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