RFC 120
Network PL1 subprograms
NETWORK PL1 SUBPROGRAMS β¨
okay bestie, this doc is all about how to use the Network from PL1 programs π It's by Mark Krilanovich from the Computer Research Lab at the University of California, Santa Barbara, dated April 21, 1971 π The title block I was given doesn't list a category or status, and it doesn't say what it obsoletes or updates, so I'm not making any of that up π
PREFACE π
The subroutines in here have been implemented at UCSB, and they make the Network (through the NCP) reachable from PL1 programs running on the 360/75 π₯οΈ They're callable from inside any PL1 main program or subroutine compiled at UCSB, so you can just call them π§
They're assembly-language subprograms that make life easier for PL1 programmers. They're the middleman between you and the Network Control Program (NCP), which supervises all Network operations at this site π
Okay, this is the big one π Every socket that isn't in the closed state gets its own unique variable, called a completion code variable. It does two jobs: it identifies the local socket you're talking about, and when the operation finishes, it holds a completion code telling you how it went. You can use it for anything else whenever you want. Its value at the start of a Network operation doesn't matter, because it's the variable itself that's important π«Ά For every Network operation that needs one, the only acceptable attributes are BINARY FIXED(31,0)ALIGNED.
Usually, the subprograms start the operation and then enter the WAIT state (no CPU time eaten, bestie π) until the NCP says it's done. For those, you give a time limit with the attributes BINARY FIXED(31,0). It's measured in tenths of a second and tells the subprogram the maximum time to wait. If that limit gets exceeded, you get a completion code for the error, control goes back to your calling program, and the operation is still pending π
For operations that need a socket to be named by its socket identifier, it's a BINARY FIXED(31,0) array. It's singly dimensioned, has at least two elements, and its lower subscript bound is one. The first element is the site number and the second is the socket number. A socket number can be positive, negative, or zero. Negative numbers are stored in two's complement, so for the gender of a socket, a socket number is even or odd based on whether its absolute value is even or odd π
Here's each subprogram, what it does, and how to call it π¦
(1) OPEN π¦
Calling OPEN asks for the specified local socket to come out of the closed state so it's ready to take part in data transfer. There are three distinct operations you can do with it, and they're all below: CONNECT, LISTEN, and ACCEPT π
(A) CONNECT π
This one asks for the specified local socket to be logically connected to the specified foreign socket, with data transfer between the two enabled. The subprogram waits until the foreign socket either accepts or rejects the connection attempt. This operation is only valid when the socket is in the closed state.
The calling sequence goes like this:
CALL @OPEN(cmpcd, time,lclsck,fgnsck,ws);
where:
cmpcdis the completion code variable to be associated with the local socket.timeis how long the subprogram waits for the operation to complete.lclsckis the socket identifier of the local socket.fgnsckis the socket identifier of the foreign socket.wsis a workspace with the same attributes as a socket identifier. If the operation is successful, it becomes associated with the local socket for the life of the connection. Certain future operations may return information to the programmer in this workspace π
These completion codes are possible for this operation:
0, The operation was successful and the connection has
been established
4, The specified completion code variable is already
assigned to a socket; the operation was suppressed
8, The specified local socket is not in the closed
state; the operation was suppressed
12, All communication paths to the specified foreign site
are in use; the operation was suppressed
16, Local resources are insufficient to support another
connection; the operation was suppressed
20, The connection attempt was rejected by the foreign
process
24, The specified local socket is not local to UCSB; the
operation was suppressed
28, The specified foreign site is invalid; the operation
was suppressed
32, An addressing or protection exception was encountered
with respect to the specified workspace; the
operation was suppressed
36, Either hardware at the foreign site is inoperative or
the NCP's counterpart at the foreign site does not
exist or has failed
40, Local and foreign sockets are both either send or
receive sockets; the operation was suppressed
44, By operator command, all Network operations were
terminated; the socket will be closed
60, An NCP control transmission error occured; the
operation was suppressed
252, The specified time limit was exceeded; the operation
was initiated but not completed
(B) LISTEN π
This is a request to be notified about any connection attempt aimed at the specified local socket. The subprogram waits until such a call comes in, and then the calling process's socket identifier is returned to the calling program. This operation is only valid when the designated local socket is in the closed state π«
The calling sequence goes like this:
CALL @OPEN(cmpcd, time,lclsck,ws);
where:
cmpcdis the completion code variable to be associated with the local socket.timeis how long the subprogram waits for the operation to complete.lclsckis the socket identifier of the local socket.wsis a workspace which, if the operation is successful, will contain the socket identifier of the calling socket, and will become associated with the local socket for the life of the connection.wshas the same attributes as a socket identifier π§
These completion codes are possible for this operation:
0, The operation was successful and a call has been
received
4, The specified completion code variable is already
assigned to a socket; the operation was suppressed
8, The specified local socket is not in the closed
state; the operation was suppressed
12, Local resources are insufficient to support another
connection; the operation was suppressed
16, The specified local socket is not local to UCSB; the
operation was suppressed
20, An addressing or protection exception was encountered
with respect to the specified workspace; the
operation was suppressed
44, By operator command, all Network operations were
terminated; the socket will be closed
252, The specified time limit was exceeded; the operation
was initiated but not completed
(C) ACCEPT π«Ά
This one accepts the connection with the foreign socket whose call caused a previous LISTEN operation by the specified local socket to complete successfully. Once it's done, data can be transferred to or from the local socket, depending on its gender. This operation is only valid when the last operation that referenced the local socket was a LISTEN. The subprogram waits until the operation is completed πΈ
The calling sequence goes like this:
CALL @OPEN(cmpcd, time);
where:
cmpcdis the completion code variable associated with the local socket by a previous LISTEN operation.timeis how long the subprogram waits for the operation to complete.
These completion codes are possible for this operation:
0, The operation was successful, and the connection is
established
4, The specified local socket is in the closed state
(the NCP may have received an abort notification from
the foreign process); the operation was suppressed
8, The previous operation specifying the designated
local socket was not a LISTEN; the operation was
suppressed
12, All communication paths to the specified foreign site
are in use; the socket has been returned to the
closed state
252, The specified time limit was exceeded; the operation
was initiated but not completed
part 1 of 4 π¦ more coming up next, bestie π
(2) CLOSE π¦
Okay so CLOSE is the "pls return this local socket to the closed state" request π and it's lowkey so careful about everyone's data. If the last thing that happened on the socket was a LISTEN, CLOSE refuses the foreign process's connection attempt. If the last thing was a CONNECT, that attempt gets aborted. If a connection is already established, any data still in transit from the local socket is allowed to reach the foreign socket, and then it gets either received or flushed before the local socket closes. The subprogram waits until the socket is back in the closed state. Iconic behavior, no cap π«Ά
The calling sequence looks like this:
CALL @CLOSE(cmpcd,time);
where cmpcd is the completion code variable tied to the local socket, and time is how long the subprogram is going to wait for the operation to finish β³
These are the completion codes you can get back from CLOSE:
0, The operation was successful, and the socket has been
returned to the closed state
8, The specified completion code variable is not currently
assigned to a socket; the operation was suppressed
12, The specified local socket is in the process of being
closed; the operation was suppressed, but the local
socket will be closed
36, Either hardware at the foreign site is inoperative, or the
NCP's counterpart at the foreign site does not exist or
has failed
44, By operator command, all Network operations were
terminated; the socket will be closed
60, An NCP control transmission error occured; the operation
was aborted
64, A transmission error occured; the operation was aborted,
but the socket will be closed
252, The specified time limit was exceeded; the operation was
initiated but not completed
(3) SEND π
SEND is where the data actually goes out to the foreign socket π The subprogram sits and waits until the foreign socket has received the data, or until the NCP has queued it locally. Either way, it's giving reliable vibes.
The calling sequence is:
CALL @WRITE(cmpcd, bfr,len,time[,offset]);
where cmpcd is the completion code variable tied to the local socket. bfr is the data being sent, and it has to be a singly dimensioned array that's either DECIMAL or BINARY, FIXED or FLOAT π¦ len is the number of bits to send. If len is non-positive, no operation happens at all. len has the attribute BINARY FIXED(31,0). time is how long the subprogram waits for the operation to finish. offset is the bit offset from the first bit of bfr where transmission starts, and it has the attribute BINARY FIXED(31,0). If you don't specify it, offset defaults to zero.
These are the completion codes for SEND:
0, The operation was successful, and the data has been sent
4, The specified local socket is not a SEND socket; the
operation was suppressed
8, The specified completion code variable is not assigned to
a socket; the operation was suppressed
12, A previous SEND operation is in progress; the operation
was suppressed
16, The connection is not fully open; the operation was
suppressed
20, The foreign socket terminated the connection before
completion of the SEND operation; not all data was
transmitted
36, Either hardware at the foreign site is inoperative, or the
NCP's counterpart at the foreign site does not exist or
has failed
44, By operator command, all Network operations were
terminated; the socket will be closed
52, One or more interrupts were received from the foreign
socket; the operation was suppressed
56, An addressing exception was encountered with respect to
the data buffer; the operation was suppressed
60, An NCP control transmission error occured; the operation
was suppressed
64, A transmission error occured; the operation was aborted,
and the socket will be closed
252, The specified time limit was exceeded; the operation was
initiated but not completed
(4) RECEIVE π₯
RECEIVE is the mirror image of SEND πͺ It pulls data in from the foreign socket, and the subprogram waits until the reception is complete. Main character energy.
The calling sequence is:
CALL @READ(cmpcd,bfr,len,time[,offset]);
where cmpcd is the completion code variable tied to the local socket. bfr is the variable the data gets placed into, and it has to be a singly dimensioned array, DECIMAL or BINARY, FIXED or FLOAT. len is the number of bits to receive. If len is non-positive, no operation happens. len has the attribute BINARY FIXED(31,0). time is how long the subprogram waits for the operation to complete. offset is the bit offset from the first bit of bfr where the first bit of data gets placed, and it has the attribute BINARY FIXED(31,0). If you don't specify it, offset defaults to zero.
These are the completion codes for RECEIVE:
0, The operation was successful and the data has been
received
4, The specified local socket is not a receive socket; the
operation was suppressed
8, The specified completion code variable is not assigned to
a socket; the operation was suppressed
12, A previous RECEIVE operation is in progress; the
operation was suppressed
16, The connection is not fully open; the operation was
suppressed
20, The foreign socket terminated the connection before
completion of the RECEIVE operation; data is
unpredictable
36, Either hardware at the foreign site is inoperative, or the
NCP's counterpart at the foreign site does not exist or
has failed
44, By operator command, all Network operations were
terminated; the socket will be closed
24, An addressing or protection exception was encountered with
respect to the data buffer; the operation was suppressed
52, One or more interrupts were received from the foreign
socket; the operation was suppressed
60, An NCP control transmission error occured; the operation
was aborted, and the socket will be closed
252, The specified time limit was exceeded; the operation was
initiated but not completed
(5) CHECK π
CHECK is the "hey, what's the vibe on this socket?" call π It returns the status of the specified local socket. There's no completion code variable for this one, because it always succeeds and the socket is identified by its socket number. It's valid at any time and always finishes immediately, so it's basically the most chill operation ever π§ββοΈ
The calling sequence is:
CALL @CHECK(lclsck,stat,mnem,fgnsck,deficit);
where lclsck is the socket identifier of the local socket. stat is a code for the status, with the attribute BINARY FIXED(31,0). mnem is a mnemonic for the status, with the attribute CHARACTER, of any fixed length greater than or equal to eight. If mnem is longer than eight bytes, it gets padded to the right with blanks. fgnsck is the socket identifier of the foreign socket, or zero. deficit is the send/receive deficit in bits, or zero, with the attributes BINARY FIXED(31,0).
Only lclsck is something the programmer needs to define. Everything else is output from the subprogram π
Here are the status codes, their mnemonics, and what they mean:
'STAT' 'MNEM' MEANING
---- ----
0 OPEN A connection is fully established. No
SEND/RECEIVE operation is in progress.
'fgnsck' is the socket identifier of the
connected socket. 'deficit' is the number
of bits queued locally at the socket by the
NCP and available to satisfy a future
RECEIVE operation, or awaiting output as
the result of a previous SEND operation.
1 LISTEN A LISTEN has been issued.
2 CONNECT A CONNECT has been issued. 'fgnsck' is the
socket identifier of the foreign socket.
3 DECISION A LISTEN has been completed. 'fgnsck' is
the socket identifier of the calling
socket.
4 CALL(S) One or more calls have been received for
the local socket. No LISTEN or CONNECT has
been issued.
5 I/O A connection is fully established. A
SEND/RECEIVE operation is in progress.
'fgnsck' is the socket identifier of the
connected socket. 'deficit' is the number
of bits yet to be sent or received.
6 CLOSED The socket is in the closed state.
7 <--DRAIN The foreign socket is attempting to close
the connection. The NCP has data yet to be
read by the local socket. 'fgnsck' is the
socket identifier of the connected socket.
'deficit' is the number of bits yet to be
received.
8 DRAINED The foreign socket is attempting to close
the connection. The NCP is awaiting
arrival at the foreign site of data
currently in transit. 'fgnsck' is the
socket identifier of the connected socket.
9 CLOSING The local socket has issued a CLOSE. The
NCP is in the process of returning the
local socket to the closed state. 'fgnsck'
is the socket identifier of the connected
socket.
10 DRAIN--> The local socket has issued a CLOSE. The
NCP is completing the last SEND operation
before returning the local socket to the
closed state. 'fgnsck' is the socket
identifier of the connected socket.
'deficit' is the number of bits the NCP has
yet to transmit.
6. IDENTIFY β¨
okay so IDENTIFY is how you tag a local socket with its completion code variable π It's valid at any time and always finishes immediately. It always succeeds, so there are no completion codes for it, and the contents of the completion code variable don't change π
The calling sequence is:
CALL @ID(cmpcd,lclsck);
where
cmpcdis the completion code variable to be associated with the local socketlclsckis set to the socket identifier of the local socket if the completion code variable is associated with a socket, or to zero otherwise.
7. SIGNAL π¦
bestie, SIGNAL sends a signal to the foreign process π What the signal means is totally up to the user. The effect is that the next time the foreign socket tries to start a RECEIVE or SEND, that operation gets suppressed and comes back with a completion code saying a signal was received π The subprogram waits until the signal has actually been sent to the foreign NCP. This operation only works when the socket is fully open.
The calling sequence is:
CALL @ID(cmpcd,time);
where
cmpcdis the completion code variable associated with the local socket.timeis the length of time the subprogram is to wait for completion of the operation.
These are the completion codes this operation can return:
0, The operation was successful, and the signal has been sent
4, The specified completion code variable is not assigned to
a socket; the operation was suppressed
8, The connection is not fully open; the operation was
suppressed
Okay, now the On-Line System Network operators π₯οΈβ¨ Certain Network subprograms are meant for these operators, though they aren't limited to them. Lowkey the most important thing to know is the data format: every chunk of data travels in a message made of three fields, in this order: op code, length, and text π The op code is one byte and tells you how to read the text field. The length field is two bytes and gives the length of the text field in bits. The text field holds the actual data. (The op code and length fields together are called a header π)
These are the op codes that are defined right now:
op code meaning
0 The op code is a NOP. No text field exists, and the
contents of the length field are unpredictable. (This op
code is used mainly as a delimiter.)
1 The text field contains EBCDIC characters, one character
per byte. The On-Line System Network operators consider
the characters as intended for display as soon as the
text field has been received.
2 The text contains codes for keypushes, one byte per key.
The On-Line operators consider the text as intended for
execution as soon as the text field has been received.
3 The same as for an op code of 2, except that the On-Line
operators consider that the execution of the keys will be
delayed until all data for that receive operation has
been received.
The standard format for data sent or received by the On-Line System operators is a string of messages, and the last one is marked by a header with a NOP op code. That's called a trailer π§ These are just the defaults, though. Any of them may be overridden by appropriate programming. (Yes, I said "may" like a lawyer, but it's just the normal word here π)
The next parts are the subprograms meant for use with the On-Line System operators π
8. WRITE TO ON-LINE CONSOLE π
This subprogram sends data from the specified local socket. The data is assumed to be characters represented by their EBCDIC codes π₯ The characters go out in a standard message with a header in front, and optionally a trailer after. The subprogram waits until the foreign socket has received the data, or until the NCP has queued it locally. This operation is only valid when the local socket is a send socket and is fully open.
The calling sequence is:
CALL @WTOLC(cmpcd,bfr,len,level,across,down,time);
where
cmpcdis the completion code variable associated with the local socket.bfris the character string to be sent. It must have the attribute STRING, either CHARACTER or BIT, of any length, fixed or varying.len, in absolute value, is the number of characters to be sent. Iflenis positive or zero, the end of the data is marked by a trailer. Iflenis negative, no trailer is sent.lenhas the attributes BINARY FIXED(31,0).levelsets the mode of typing. The absolute value oflevel, if it's non-zero, is the shift level to type on, and it must be less than or equal to nine. If it's greater than nine, one is used. Iflevelis positive,acrossanddownare relative to the current typing location. Iflevelis negative, the carriage is moved to the upper left-hand corner before typing begins, which makesacrossanddownabsolute coordinates. Iflevelis zero, the typing is in case one characters, and a carriage return comes before the positioning foracrossanddown. If the characters to be displayed are case one characters, the header sent will have an op code that says the characters should be displayed as soon as they're received. Otherwise, the op code will say the buttons should be executed as soon as they're received.levelhas the attributes BINARY FIXED(31,0).acrossis the number of spaces to move horizontally across the display tube before typing begins.acrosscan be any value, positive, negative, or zero, and has the attributes BINARY FIXED(31,0).downis the number of lines to move vertically down the display tube before typing begins.downcan be any value, positive, negative, or zero, and has the attributes BINARY FIXED(31,0).timeis the length of time the subprogram is to wait for completion of the operation.
The completion codes for this operation are the same as for SEND.
9. READ FROM ON-LINE CONSOLE π
This subprogram receives data from the foreign socket, in one or more standard messages. The data is assumed to be characters represented by their EBCDIC codes πΈ The subprogram waits for the data to arrive, optionally followed by a trailer, at the local socket. This operation is only valid when the local socket is a receive socket and is fully open.
The calling sequence is:
CALL @RFOLC(cmpcd,bfr,len,time);
where
cmpcdis the completion code variable associated with the local socket.bfris the variable the data gets placed into. It has the attribute CHARACTER, of any fixed length. Ifbfris longer than the amount of data received, it gets padded on the right with blanks.len, in absolute value, is the maximum number of characters to put inbfr. If the length fields of the headers received add up to more data thanlen, the extra data is still received, but it isn't placed intobfrand the program can't access it. Iflenis positive or zero, data is received until a trailer shows up. Iflenis negative, a single message is received, not counting the trailer.lenhas the attributes BINARY FIXED(31,0).timeis the length of time the subprogram is to wait for completion of the operation.
The completion codes for this operation are the same as for RECEIVE.
10. WRITE TO ON-LINE CONSOLE WITH REPLY π¬
This one's a combo meal π It does the jobs of 'WRITE TO ON-LINE CONSOLE' and 'READ FROM ON-LINE CONSOLE' together. First, it sends a string of data from the specified send socket to the foreign socket, then waits for that data to be received by the foreign socket (or queued locally by the NCP). After that, it waits for a reply directed at the specified receive socket. This operation is only valid when the sockets have the correct gender and both are fully open π
The calling sequence is:
CALL @WTOLCR(cmpcd, bfr, len, level, across, down, time,
cmpcd2, bfr2, len2);
where
cmpcdis the completion code variable associated with the local send socket.bfris as in 'WRITE TO ON-LINE CONSOLE'.lenis as in 'WRITE TO ON-LINE CONSOLE'.levelis as in 'WRITE TO ON-LINE CONSOLE'.acrossis as in 'WRITE TO ON-LINE CONSOLE'.downis as in 'WRITE TO ON-LINE CONSOLE'.timeis the length of time the subprogram is to wait for completion, separately, of the transmission and the reception of data.cmpcd2is the completion code variable associated with the local receive socket.bfr2is asbfrin 'READ FROM ON-LINE CONSOLE'.len2is aslenin 'READ FROM ON-LINE CONSOLE'.
The completion codes for the send socket are the same as for the SEND operation, and the completion codes for the receive socket are the same as for the RECEIVE operation π
(11) ERASE β¨
okay bestie, ERASE is giving "wipe the whole screen" energy π§Ήπ This subprogram sends out the data for an On-Line System command that erases the display tube, going out from whatever local socket you point it at π«Ά The whole thing travels in one standard message. That message has an op code telling the other side to display characters as they arrive, plus an optional trailer at the end π Then the subprogram just waits until the foreign socket has received the data, or the NCP has queued it locally π
ngl this one is picky. ERASE is only valid when the local socket is a send socket AND it's fully open π
Here's how you call it:
CALL @ERASE(cmpcd,delay1,delay2,time);
And here's what each piece does:
cmpcdis the completion code variable linked to the local socket π₯delay1is, in absolute value, how long (in tenths of a second) the subprogram hangs out in the WAIT state before sending the erase β³ Ifdelay1is positive or zero, a trailer gets sent after the erase. If it's negative, no trailer gets sent π ββοΈdelay1has the attributesBINARY FIXED(31,0), periodt.delay2is how long (also in tenths of a second) the subprogram pauses after sending the erase and before handing control back to the calling program πΈ It has the attributesBINARY FIXED(31,0).timeis how long the subprogram is going to wait for the operation to finish π§
The completion codes for ERASE are the same as the ones for SEND, so if you already know SEND, you're already set π
[ This RFC was put into machine readable form for entry ]
[ into the online RFC archives by Rune Skaarsmoen 6/97 ]
π¦ where this page comes from
- ietf: rfc120 1971-04
- π girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms