*DECK NP$SEND
USETEXT AIPDEF
USETEXT NP$GMB
USETEXT NP$MODE
USETEXT NP$NWL
USETEXT NP$STAT
PROC NP$SEND;
*IF DEF,IMS
#
*1DC NP$SEND
* 1. PROC NAME AUTHOR DATE
* NP$SEND S.KRULEVITCH 77/05/23
*
* 2. FUNCTIONAL DESCRIPTION
* SENDS A WORKLIST,POSSIBLY WITH A GETSM REQUEST, TO NIP.
*
* 3. METHOD USED
* IF THE UPLINE DATA QUEUE FEATURE IS IN USE, AND IF THE
* SENDGETMM AND ID$FLAG ARE SET TRUE, BUILD A
* -GET MULTIPLE MESSAGES- ENTRY AT THE END OF THE WORKLIST.
*
* BUILD A -GET SUPERVISORY MESSAGE- ENTRY AT THE END OF THE WL
* IF SENDGETSM AND SD$FLAG ARE SET TRUE.
*
* IF THE DOWNLINE MESSAGE BUFFERING FEATURE IS IN USE, AND IF
* THE DOWNLINE BUFFER IS LESS THAN THE LENGTH OF THE (FIXED-SIZE)
* NETWORK WORKLIST, COPY THE MESSAGES INTO THE WORKLIST.
* OTHERWISE, BUILD A PUTQ ENTRY IN THE NETWORK WORKLIST,
* CONTAINING THE ADDRESS OF THE DOWNLINE MESSAGE BUFFER.
*
* CALL NP$XFER TO TRANSFER THE NETWORK WORKLIST TO NIP. IF THE
* WORKLIST RESPONSE IS RETURNED TO AIP THEN NP$RESP IS CALLED
* TO PROCESS THE RESPONSE.
*
* 4. ENTRY CONDITIONS
* NEXT - INDEX OF NEXT AVAILABLE WORKLIST CELL
* SD$FLAG - TRUE IF SM DATA QUEUED IN NIP
* SPACE$LEFT - NUMBER OF AVAILABLE WORKLIST CELLS
*
* 5. EXIT CONDITONS
* IF A NETGET OR NETGETL WAS JUST ISSUED, THE DATA BLOCK (OR NULL
* BLOCK) WILL BE FOUND (OR POINTED TO) IN THE WORKLIST. IF A
* -GETSM- WAS INCLUDED IN THE WORKLIST, SUPERVISORY MESSAGES
* (IF ANY) WILL BE FOUND IN THE SUPERVISORY MESSAGE BUFFER.
*
* 6. COMDECKS CALLED AND SYMPL TEXTS USED.
* AIPDEF NP$CRT NP$MODE NP$NWL
* NP$STAT
*
* 7. ROUTINES CALLED
* NP$RESP - PROCESSES WORKLIST RESPONSE
* NP$XFER - TRANSFER NWL TO NIP
* NP$UCV - UPDATE CONTROL VARIABLES
*
* 8. DAYFILE MESSAGES
* NONE
*
#
*ENDIF
BEGIN
*CALL NP$CRT
# #
# ROUTINES CALLED #
# #
XREF BEGIN
PROC NP$RESP; # PROCESSES NIP RESPONSE #
PROC NP$SN; # UPDATE AIP STATISTICS #
PROC NP$UCV; # UPDATE CONTROL VARIABLES #
PROC NP$XFER; # TRANSFER NWL TO NIP #
END #XREFS#
# #
# LOCAL DECLARATIONS #
# #
DEF TIL #STEP 1 UNTIL#;
ITEM
I I,
LEN I; #TEMPORARY VARIABLE #
BASED ARRAY MEM[0];
BEGIN
ITEM MEMWORD I; # FULL WORD ACCESS #
END
#**********************************************************************#
# #
# NP$SEND EXECUTION BEGINS HERE #
# #
#
ONLY CREATE GETMM WORKLIST ENTRY IF THE AIP MULTIPLE UPLINE DATA
MESSAGE QUEUING FEATURE IS IN USE AND NIP HAS DATA MESSAGES AND
EITHER THE WORKLIST BUFFER IS NOT EMPTY OR A WORKLIST REQUEST
WILL BE SENT ANYWAY TO GET SUPERVISORY MESSAGES.
#
IF (GMBUSE ) AND
(SENDGETMM ) AND
(ID$FLAG NQ 0 ) AND
( (HDR$N[NHDR] NQ 0) OR
(DEFER$GSM ) )
THEN
BEGIN
# #
# THE SHORTEST DATA MESSAGE IS TWO WORDS LONG. A GETMM #
# REQUEST IS BUILT ONLY IF THERE IS AT LEAST TWO WORDS IN #
# THE AIP UPLINE DATA BUFFER. #
# #
# STEP 1: CALCULATE LEN = EMPTY SPACE IN AIP DATA BUFFER #
IF (GMBHEAD LS GMBFOOT) AND
(GMBLAST LQ GMBFOOT)
THEN
BEGIN
IF GMBHEAD GQ 4
THEN
GMBFOOT = 1;
END #BOUNDARY CONDITION#
IF GMBHEAD GR GMBFOOT
THEN
BEGIN
LEN = GMBHEAD - GMBFOOT - 1;
END
ELSE
LEN = GMBLAST - GMBFOOT + 1;
# #
# STEP 2: BUILD GETMM ENTRY IF LEN IS LARGE ENOUGH #
IF LEN GQ 2
THEN # UPLINE DATA BUF LARGE ENOUGH #
BEGIN
*IF,DEF,STAT
NP$SN(TYPE"GMM"); # INCREMENT NO OF GMM WKLST BLT#
*ENDIF
N$GMMAWL[0] = 1; # FLAG GMM AWL TO PROCESS #
NWL[NEXT]=0; # CLEAR AND BUILD OP WORD #
NWL$ID[NEXT]=AWLID;
BS = OPABHSIZ; # NWL ENTRY SIZE #
NWL$TA[NEXT]=LOC(GMBWRD[GMBFOOT]);
NWL$OP[NEXT]=OP$GMM; # GETMM OPCODE #
GMM$NFW[NEXT+1] = LEN; # SIZE OF AIP DATA BUFFER #
GMM$ACN[NEXT+1] = GMBCN; # CON NO FOR AIP DATA BUFFER #
GMM$ALN[NEXT+1] = GMBLN; # LIST NO FOR AIP DATA BUFFER #
NP$UCV; # UPDATE NWL CONTROL VARIABLES #
END
END #SENDGETMM#
IF SENDGETSM AND (SD$FLAG NQ 0) # IF SM QUEUED IN NIP #
THEN
BEGIN
# #
# THE SHORTEST SUPERVISORY MESSAGE IS TWO WORDS LONG. A GETSM #
# REQUEST IS BUILT ONLY IF THERE IS AT LEAST TWO WORDS IN THE #
# SMB (SUPERVISORY MESSAGE BUFFER). #
# #
# STEP 1: CALCULATE LEN = EMPTY SPACE IN SMB #
IF HEAD LS FOOT AND (LAST-FOOT+1) LS NEXTSMLEN
THEN
BEGIN
IF (HEAD-FIRST) GQ NEXTSMLEN
THEN
FOOT = FIRST;
END #BOUNDARY CONDITION#
IF HEAD GR FOOT
THEN
LEN = HEAD - FOOT;
ELSE
LEN = LAST - FOOT + 1;
# #
# STEP 3: BUILD NP$GSM ENTRY IF LEN IS LARGE ENOUGH #
IF LEN GQ NEXTSMLEN
AND LEN GQ OPABHSIZ
THEN
BEGIN
*IF,DEF,STAT
NP$SN(TYPE"GSM"); # INCREMENT NO OF GSM WKLST BLT#
*ENDIF
N$GSMAWL[0] = 1; # FLAG GSM AWL TO PROCESS #
NWL[NEXT]=0; # CLEAR AND BUILD OP WORD #
NWL$ID[NEXT]=AWLID;
BS = OPABHSIZ; # NWL ENTRY SIZE #
NWL$TA[NEXT]=LOC(GSM[FOOT]);
NWL$OP[NEXT]=OP$GSM;
NWL[NEXT+1]=LEN; # CLEAR AND SEND SMB SPACE SIZE#
NP$UCV; # UPDATE NWL CONTROL VARIABLES #
END
END #SENDGETSM#
# #
# ISSUE NWL WORKLIST TO NIP IF NWL ENTRY EXISTS #
# #
IF HDR$N[NHDR] NQ 0
THEN
BEGIN
IF DOWNUSE # DOWNLINE BUFFERING IN USE #
THEN
BEGIN
P<WORKLIST> = LOC(NWLBUF); # ADDR OF FIXED WORKLIST #
IF NOT RESEND # NOT RESENDING SAME WORKLIST #
THEN
BEGIN
P<MEM> = LOC$APBUF; # SAVE LOC OF APP BUFFER #
LEN = HDR$W[NHDR] - 1; # LENGTH (WORDS) OF TEXT IN BUF#
NEXT = NNTR; # INITIALIZE POINTERS FOR WL #
SPACE$LEFT = LWL;
IF LEN LQ SPACE$LEFT
THEN # TEXT IN BUFFER CAN FIT IN WL #
BEGIN
FOR I = 0 STEP 1 UNTIL (LEN - 1)
DO # COPY TEXT FROM APP BUFF INTO #
BEGIN # FIXED-SIZE NETWORK WORKLIST #
NWL[NEXT + I] = MEMWORD[I];
END
END
ELSE # TEXT IN BUF TOO LONG FOR WL #
BEGIN # BUILD PUTQ ENTRY #
NP$SN(TYPE"PUTQ"); # INCREMENT NO OF PUTQ WL BUILT#
PUTQ[NEXT] = 0; # CLEAR AND BUILD OP WORD #
PQ$ID[NEXT] = AWLID;
PQ$OP[NEXT] = OP$PUTQ; # PUTQ OPCODE #
PQ$TA[NEXT] = LOC$APBUF; # ADDR OF TEXT AREA BUFFER #
PQ$N[NEXT+1] = HDR$N[NHDR]; # NO. OF WL ENTRIES IN BUF #
PQ$W[NEXT+1] = LEN; # NO. OF WORDS IN TEXT AREA BUF#
#
THE HEADER FIELDS CONTAIN THE LENGTH AND NUMBER OF WORDS
OF THE DOWNLINE BUFFER. CLEAR THESE FIELDS, AS THEY
SHOULD NOW REFLECT THE LENGTH/NO. OF ENTRIES OF THE FIXED
WORKLIST. THE FIXED WORKLIST ONLY CONTAINS ONE 2-WORD
PUTQ ENTRY. THE HEADER FIELDS WILL BE RESET IN NP$UCV.
#
HDR$N[NHDR] = 0;
HDR$W[NHDR] = 1;
BS = OPABHSIZ;
NP$UCV; # UPDATE NWL CONTROL VARIABLES #
END
END
END
NP$XFER(LOC(NWL[NCTL]));
IF NOT DEFER$PRO
THEN # IF NOT IN PARALLEL MODE #
NP$RESP; # PROCESS RESPONSE AWL #
END
RETURN;
END #NP$SEND#
TERM