*DECK IPPRECV USETEXT TEXTIPL USETEXT TEXTXDR PROC IPPRECV (SOCKID, BUFFER, BUFLEN, ADDRESS, SOCKSTATUS); *CALL COPYRITE CDCNET - COPYRIGHT CONTROL DATA. 1992. # TITLE IPPRECV - RECEIVE DATA FOR SOCKET # BEGIN # IPPRECV # # **** IPPRECV RECEIVE DATA FOR SOCKET * * THIS PROCEDURE OBTAINS A BLOCK OF DATA FOR THE SOCKET. * * PROC IPPRECV * * ENTRY SOCKID = INTEGER VALUE OF SOCKET * BUFFER = BUFFER TO PLACE THE DATA * * EXIT BUFFER = BUFFER WITH RECEIVED DATA * BUFLEN = INTEGER VALUE OF NUMBER BYTES IN BUFFER * ADDRESS = 4 WORD SOURCE IP ADDRESS ARRAY * SOCKSTATUS = COMPLETION STATUS * * METHOD IF THE SOCKET HAS BEEN ABORTED BY NAM, RETURN AN ABORT * STATUS TO INFORM THE CALLER. IF THE SOCKET * IS NOT CONNECTED, RETURN AN ERROR STATUS. IF DATA * IS NOT QUEUED TO THE CONNECTION AND THE SOCKET BLOCKS, * LOOP CALLING THE NAM INPUT HANDLER UNTIL DATA IS * RECEIVED OR THE SPECIFIED BLOCKING TIMER HAS EXPIRED. * IF DATA IS RECEIVED, EXTRACT THE HEADER AND VERIFY THE * REQUEST AND UDP VERSION. PLACE THE SOURCE ADDRESS FROM * THE HEADER INTO *ADDRESS*, AND THE REMAINDER DATA INTO * *BUFFER*. ISSUE A LST/ON SM TO NAM SO MORE DATA CAN * BE SENT TO THE APPLICATION. # # **** PROC IPPRECV - XREF LIST # XREF BEGIN PROC IMNS; # MOVE NON-OVERLAPPING STRING # PROC IPIAIPA; # ABORT IP APPLICATION # PROC IPIDOSM; # DISPATCH OUTPUT SUPERVISORY MESSAGE # PROC IPINITH; # NAM INPUT TRAFFIC HANDLER # PROC MESSAGE; # ISSUE DAYFILE MESSAGE # PROC RTIME; # REAL TIME CLOCK # PROC XDRBYTE; # CONVERT BYTES TO XDR FORMAT # PROC XDRINT; # CONVERT INTEGERS TO XDR FORMAT # PROC XWHD; # CONVERT HEXIDECIMAL TO DISPLAY # END # ** # ITEM SOCKID I; # SOCKET IDENTIFIER # ARRAY BUFFER [00:00] S(1);; # BUFFER TO RECEIVE DATA # ARRAY ADDRESS [00:00] S(1);; # SOURCE ADDRESS FOR DATA # ITEM BUFLEN U; # LENGTH OF DATA IN BUFFER # ITEM SOCKSTATUS S:SOCKSTAT; # RETURNED SOCKET STATUS # # **** THIS ARRAY DEFINES THE DAYFILE MESSAGE FOR DISPLAYING AN INVALID * MESSAGE RECEIVED. # ARRAY DATAMSG [00:00] S(3); BEGIN ITEM DATA$TEXT C(00,00,20); ITEM DATA$ZBYTE U(02,00,60) = [0]; END # **** BASED ARRAY WHICH POINTS TO THE BLOCK OF DATA THAT WAS RECEIVED BY * NAM. # BASED ARRAY INP$BUF [00:INPSIZE$] S(1); BEGIN ITEM INP$WRD U(00,00,60); # FULL WORD REFERENCE # END ITEM DESTBUF I; # CURRENT WRD LOCATION IN BUFFER# ITEM DESTPOS U; # BIT OFFSET IN BUFFER WORD # ITEM INDEX I; # LOOP COUNTER # ITEM INPPOS U; # OFFSET IN INP$BUF BYTE # ITEM LOOP I; # LOOP COUNTER # ITEM MOVEBITS U; # BITS TO MOVE TO *BUFFER* # ITEM SCRBUF U; # CURRENT LOCATION INP$BUF # ITEM SCRPOS U; # BIT OFFSET IN INP$BUF WORD # ITEM WAITLOOP I; # NUMBER OF WAIT CYCLES # BASED ARRAY IPADDR [00:00] S(1);;# SOURCE ADDRESS FOR XDR CALL # CONTROL EJECT; # **** START MAIN PROCEDURE # IF (ACN$ABORT [SOCKID]) THEN BEGIN # CONNECTION ABORTED # SOCKSTATUS = S"ABORT"; RETURN; END IF NOT ACN$CONNECT [SOCKID] THEN BEGIN SOCKSTATUS = SOCKSTAT"INVALIDST"; RETURN; END BLOCK = ACN$BLOCK [SOCKID]; # SET GLOBAL BLOCKING FLAG # IF NOT ACN$DATAV [SOCKID] THEN BEGIN # DATA NOT AVAILABLE # IF BLOCK THEN BEGIN # IF BLOCKING # WAITLOOP = ACN$WAITIME [SOCKID] / 2 + 1; RTIME (BWT$TIME); # CURRENT TIME # BWT$EXPIRE [0] = BWT$SECONDS [0] + ACN$WAITIME [SOCKID]; # **** CONTINUE POLLING THE NETWORK FOR DATA UNTIL EITHER DATA IS * IS RECEIVED ON THE CONNECTION OR UNTIL THE WAIT TIMER HAS EXPIRED. * THE LOOP COUNTER IS SET TO THE TIME/2 DUE TO THE NETWAIT TIME OF * 2 SECONDS WHILE BLOCKING. # FOR LOOP = 0 WHILE (NOT ACN$DATAV [SOCKID]) DO BEGIN # WAIT FOR DATA OR EXPIRED TIME # FOR INDEX = 1 STEP 1 WHILE (NOT ACN$DATAV [SOCKID]) AND (NOT ACN$ABORT [SOCKID]) AND (INDEX LQ WAITLOOP) DO BEGIN IPINITH; # NAM INPUT TRAFFIC HANDLER # END IF (ACN$ABORT [SOCKID]) THEN BEGIN # CONNECTION ABORTED # SOCKSTATUS = S"ABORT"; RETURN; END IF NOT ACN$DATAV [SOCKID] THEN BEGIN # CHECK IF TIMED OUT # RTIME (BWT$TIME); IF (BWT$SECONDS [0] GQ BWT$EXPIRE [0]) THEN BEGIN # TIMER EXPIRED # SOCKSTATUS = S"NODATA"; RETURN; END ELSE BEGIN # TIME STILL TO WAIT # WAITLOOP = (BWT$EXPIRE [0] - BWT$SECONDS [0]) / 2 + 1; END END # CHECK IF TIMED OUT # END # WAIT FOR DATA OR EXPIRED TIME # END # IF BLOCKING # ELSE BEGIN # NO DATA/NOT BLOCKING RETURN # IPINITH; # NAM INPUT TRAFFIC HANDLER # IF (ACN$ABORT [SOCKID]) THEN BEGIN # CONNECTION ABORTED # SOCKSTATUS = S"ABORT"; RETURN; END IF (NOT ACN$DATAV [SOCKID]) THEN BEGIN SOCKSTATUS = S"NODATA"; RETURN; END END END # DATA NOT AVAILABLE # P = ACN$BUFFER [SOCKID];# INITIALIZE SOURCE POINTER # MOVEBITS = (ACN$DATALNTH [SOCKID] - UDPHEADSZ$) * 8; # **** DATA IS AVAILABLE. VERIFY THE FIRST TWO BYTES OF DATA INDICATE * A VALID UDP REQUEST AND VERSION. IF IT DOES, THEN EXTRACT THE * SOURCE ADDRESS FROM BUFFER AND PLACE IN *ADDRESS*. MOVE THE * REMAINDER OF THE SOURCE BUFFER TO *BUFFER* WITH *IMNS*. # INPPOS = 0; # STARTING OFFSET IN INP$BUF # XDRBYTE (INP$BUF, INPPOS, REC$UDP, 2, XDROPER"READ"); IF ((REC$REQ [0] NQ CALLRES$) AND (REC$REQ [0] NQ DATAIND$)) OR (REC$VER [0] NQ UDPVERS$) OR (MOVEBITS LS 0) THEN BEGIN # INVALID DATA, ABORT APPLICATIO# XWHD (INP$WRD [0], DATAMSG); MESSAGE (DATAMSG, 0); XWHD (REC$REQ, DATAMSG); MESSAGE (DATAMSG, 0); XWHD (REC$VER, DATAMSG); MESSAGE (DATAMSG, 0); IPIAIPA (NINVALID$); RETURN; END P = LOC (ADDRESS) + 1; INPPOS = 3; # BEGIN EXTRACT SOURCE ADDRESS # XDRBYTE (INP$BUF, INPPOS, ADDRESS, 1, XDROPER"READ"); XDRINT (INP$BUF, INPPOS, IPADDR, 3, XDROPER"READ"); BUFLEN = MOVEBITS / 8; # NUMBER OF BYTES IN BUFFER # IF MOVEBITS NQ 0 THEN BEGIN SCRBUF = LOC (INP$BUF) + (INPPOS * 2) / 15; DESTBUF = LOC (BUFFER); SCRPOS = XDRMODU ((INPPOS * 8), 60);# WORD BIT OFFSET # DESTPOS = 0; IMNS (MOVEBITS, SCRBUF, SCRPOS, DESTBUF, DESTPOS); END # **** CLEAR FLOW CONTROL ON THIS CONNECTION NOW THAT THE DATA HAS * BEEN PROCESSED. * # IF ACN$DATAV [SOCKID] THEN BEGIN ACN$DATAV [SOCKID] = FALSE; P = LOC(OUTBUF); SPMSG0 [0] = 0; LSTACN [0] = SOCKID; IPIDOSM (LSTON, LLST); # ISSUE LST/ON/R SM # END SOCKSTATUS = S"OK"; RETURN; # RETURN TO CALLER # END # IPPRECV # TERM