-- Transport Mechanism - DEFS for communication protocols --

-- [Juniper]<DMS>MS>ProtocolDefs.mesa

-- Andrew Birrell  21-Jan-81 17:27:35 --

DIRECTORY
BodyDefs	USING[ Connect, ItemHeader, maxConnectLength,
		       maxRemarkLength, oldestTime, Password, Remark,
		       RName, Timestamp ],
PupTypes	USING[ PupAddress, PupSocketID ],
Stream		USING[ SubSequenceType, Handle ];

ProtocolDefs:	DEFINITIONS = BEGIN

-- The following are defined for historical compatability.
-- The definitions in BodyDefs should be used in preference.
Connect:	  TYPE =     BodyDefs.Connect;
maxConnectLength: CARDINAL = BodyDefs.maxConnectLength;
Remark:		  TYPE =     BodyDefs.Remark;
maxRemarkLength:  CARDINAL = BodyDefs.maxRemarkLength;
Password:	  TYPE =     BodyDefs.Password;



MakeKey:	PROC[password: STRING] RETURNS[ key: BodyDefs.Password ];
		    -- makes DES encryption key; forces lower case --


Init:		PROC;
		-- initialize exported variables; extra calls ignored --

SetTestingMode:	PROC;
		-- set sockets for test-only mode; called before Init --


RegServerEnquirySocket:	READONLY PupTypes.PupSocketID; -- [0, 50B] --
                         -- for talking to the Registration Server.

RegServerSpareSocket:	READONLY PupTypes.PupSocketID; -- [0, 51B] --

RegServerPollingSocket:	READONLY PupTypes.PupSocketID; -- [0, 52B] --
                         -- for single-packet protocols to RegServer --

spareSocket:		READONLY PupTypes.PupSocketID; -- [0, 53B] --

mailServerPollingSocket: READONLY PupTypes.PupSocketID; -- [0,54B];
		    -- For all single-packet protocols with mail server --

mailServerServerSocket:  READONLY PupTypes.PupSocketID; -- [0,55B] --
		    -- For ServerInput connections to mail server --

mailServerInputSocket:   READONLY PupTypes.PupSocketID; -- [0,56B] --
		    -- For ClientInput connections to mail server --

mailServerOutputSocket:  READONLY PupTypes.PupSocketID; -- [0,57B] --
		    -- For ReadMail connections to mail server --


endSST:		Stream.SubSequenceType = 1;
		    -- used in Server-Server and ReadMail protocols --

IsLocal:	PROC[addr: PupTypes.PupAddress] RETURNS[ BOOLEAN ];
		    -- Whether the address is on this host --

Handle:		TYPE = Stream.Handle;

FailureReason:	TYPE = { communicationError, noData, protocolError };
		    -- communicationError means some error pup arrived
		    -- noData means the stream is still there, but no data
		    -- protocolError means we cant understand him

Failed:		ERROR[ why: FailureReason ];
		    -- may be raised by any of the following procedures,
		    -- except DestroyStream.

CreateStream:	PROC[addr: PupTypes.PupAddress, secs: CARDINAL ← 120 ]
		RETURNS[ Handle ];
		    -- Create stream, with given timeout for data --

DestroyStream:	PROC[str: Handle];
		    -- no signals --

SendNow:	PROC[str:Handle];
		    -- Sends any data that has been buffered on the stream.


-- The following procedures provide type-safe access to the communication
-- protocols --


SendAck:	PROC[str: Handle] = INLINE
   { SendByte[str, 0] };

ReceiveAck:	PROC[str: Handle] = INLINE
   { [] ← ReceiveByte[str] };


SendBoolean:	PROC[str: Handle, bool: BOOLEAN ] = INLINE
   { SendByte[ str, IF bool THEN 1 ELSE 0 ] };

ReceiveBoolean:	PROC[str: Handle] RETURNS[ BOOLEAN ] = INLINE
   { RETURN[ ReceiveByte[str] # 0 ] };


Byte:		TYPE = [0..256);

SendByte:	PROCEDURE[ str: ProtocolDefs.Handle, byte: Byte ];

ReceiveByte:	PROCEDURE[ str: ProtocolDefs.Handle ]
		RETURNS[ byte: Byte ];


SendCount:	PROC[str: Handle, count: CARDINAL];

ReceiveCount:	PROC[str: Handle] RETURNS[ count: CARDINAL ];


SendItemHeader:	PROC[ str: Handle, header: BodyDefs.ItemHeader];
		    -- transmits the header.

ReceiveItemHeader: PROC[ str: Handle ]
		   RETURNS[ header: BodyDefs.ItemHeader ];
		    -- receive header of item from stream.


SendTimestamp:	PROC[str: Handle, stamp: BodyDefs.Timestamp];
		    -- sends a Timestamp value over the stream.

ReceiveTimestamp: PROC[str: Handle] RETURNS [BodyDefs.Timestamp];
		    -- receives a timestamp from the stream.

AppendTimestamp: PROC[s: STRING, stamp: BodyDefs.Timestamp];
		    -- appends a text form of the stamp to the string


SendPassword:	PROC[str: Handle, key, pw: BodyDefs.Password];
		    -- encodes a password with a key, and sends the
		    -- encrypted verion.

ReceivePassword:PROC[str: Handle, key: BodyDefs.Password]
		RETURNS[Password];
		    -- receives an encoded password from the stream, and
		    -- returns the decoded value.


SendRC:		PROC[str: Handle, rc: ReturnCode];
		    -- sends a return code value over the stream.

ReceiveRC:	PROC[str: Handle] RETURNS [ReturnCode];
		    -- receives a return code value from the stream.


SendMSOperation:	PROC[str: Handle, op: MSOperation];

ReceiveMSOperation: PROC[str: Handle] RETURNS[op: MSOperation];


SendRSOperation:	PROC[str: Handle, op: RSOperation];

ReceiveRSOperation: PROC[str: Handle] RETURNS[op: RSOperation];


SendBytes:	PROC[str: ProtocolDefs.Handle,
		     buffer: POINTER, count: CARDINAL];

ReceiveBytes:	PROC[str: ProtocolDefs.Handle,
		     buffer: POINTER, count: CARDINAL];


SendRName:	PROC[str: Handle, name: BodyDefs.RName ] = INLINE
   { SendString[str, name] };
		    -- transmits the contents of the R-Name.

ReceiveRName:	PROC[str: Handle, name: BodyDefs.RName ] = INLINE
   { ReceiveString[str, name] };
		    -- reads from the stream into the R-Name storage.


SendConnect:	PROC[str: Handle, connect: BodyDefs.Connect] = INLINE
   { SendString[str, connect] };
		    -- sends the connect-site name as a Mesa string --
		    -- connect.length should be < maxConnectLength --

ReceiveConnect:	PROC[str: Handle, connect: BodyDefs.Connect] = INLINE
   { ReceiveString[str, connect] };
		    -- receives a connect-site into the given storage --


SendRemark:	PROC[str: Handle, remark: BodyDefs.Remark] = INLINE
   { SendString[str, remark] };
		    -- sends the remakr as a Mesa string --
		    -- remark.length should be < maxRemarkLength --

ReceiveRemark:	PROC[str: Handle, remark: BodyDefs.Remark] = INLINE
   { ReceiveString[str, remark] };
		    -- receives a remark into the given storage --


SendString:	PROC[ str: ProtocolDefs.Handle, string: STRING];

ReceiveString:	PROC[ str: ProtocolDefs.Handle, string: STRING];


Enquire:	PROC[ str: Handle, op: RSOperation, name: BodyDefs.RName,
		      oldStamp: BodyDefs.Timestamp ← BodyDefs.oldestTime ]
		RETURNS[ rc: ReturnCode, stamp: BodyDefs.Timestamp ];
		    -- Sends an enquiry on the stream --

ReceiveRList:	PROCEDURE[ str: Handle,
			   work: PROCEDURE[BodyDefs.RName] ];
		    -- receives a sequence of R-Names from the stream,
		    -- calling "work" for each R-Name.  The sequence should
		    -- have been sent by HeapDefs.SendComponent or its
		    -- equivalent. See also HeapDefs.ReceiveComponent--


MSOperation:	TYPE = MACHINE DEPENDENT {

	openMBX(0),
	nextMessage(1),
	readTOC(2),
	readMessage(3),
	writeTOC(4),
	deleteMessage(5),
	flushMBX(6),
	restartMBX(7),

	startSend(20),
	addRecipient(21),
	checkValidity(22),
	startItem(23),
	addToItem(24),
	send(26),
	expand(27),
	(255)
			};


RNameType:               TYPE = MACHINE DEPENDENT {
	-- status of an RName, given in an R-Server reply.
	group(0),	-- group of names
	individual(1),	-- person or machine
	notFound(2),	-- the R-Name does not exist
	dead(3),	-- the R-Name has been deleted from the database
	(255)		};


Code:                    TYPE = MACHINE DEPENDENT {
	-- result of an R-Server operation.
	done(0),	-- operation succeeded
	noChange(1),	-- enquiry: given stamp was still valid
			-- update:  operation wouldn't change the database
	outOfDate(2),	-- update:  more recent info was in database (!)
	NotAllowed(3),	-- update:  operation prevented by access controls
	BadOperation(4),-- unknown operation number
	BadProtocol(5),	-- protocol violation (e.g. list out of order)
	BadRName(6),	-- R-Name does not exist or has wrong type
	BadPassword(7),	-- what it says
	WrongServer(8),	-- the R-Name's registry is not in this R-Server
	AllDown(9),	-- remote R-Server was down for ACL enquiry
	(255)		};


ReturnCode:              TYPE = MACHINE DEPENDENT RECORD [
					code: Code, type: RNameType];


RSOperation:               TYPE = MACHINE DEPENDENT {

-- an "R-Name", "destn", "member", "owner", or "friend" has type BodyDefs.RName
-- a "Connect" has type BodyDefs.Connect
-- a "site" has type BodyDefs.RName (but may be an NLS name or net address)
-- a "Remark" has type BodyDefs.Remark
-- a "Password" has type BodyDefs.Password
-- a "stamp" has type BodyDefs.Timestamp
-- an "R-List" is a word count (CARDINAL) followed by sequence of R-Names;
--	the R-Names are in alphabetical order.
-- a "component" is a word count (CARDINAL) followed by sequence of words
-- a "Membership" is a boolean ("TRUE" => is a member)


--			arguments		results
--			=========		=======
--
-- ENQUIRY OPERATIONS

NoOp(0),	--	none			none

Expand(1),	--	R-Name,stamp		code=done,stamp,R-List
		--				  group:      R-List=members
		--				  individual: R-List=sites
		--				  forwarded:  R-List=destn's,type=group
		--			or:	code=noChange
		--			or:	code=BadRName(dead,notFound)
		--			or:	code=WrongServer
		-- This also works for names of the form Owners-foo.pa

ReadMembers(2),	--	R-Name,stamp		code=done,stamp,R-List
		--			or:	code=noChange
		--			or:	code=BadRName(#group)
		--			or:	code=WrongServer
		-- This also works for names of the form Owners-foo.pa

ReadOwners(3),	--	R-Name,stamp		code=done,stamp,R-List
		--			or:	code=noChange
		--			or:	code=BadRName(#group)
		--			or:	code=WrongServer

ReadFriends(4),	--	R-Name,stamp		code=done,stamp,R-List
		--			or:	code=noChange
		--			or:	code=BadRName(#group)
		--			or:	code=WrongServer

ReadEntry(5),	--	R-Name,stamp		code=done,stamp,count,components
		--			or:	code=noChange
		--			or:	code=BadRName(notFound)
		--			or:	code=WrongServer

CheckStamp(6),	--	R-Name,stamp		code=done,stamp
		--			or:	code=noChange
		--			or:	code=BadRName(notFound)
		--			or:	code=WrongServer
		-- This also works for names of the form Owners-foo.pa

ReadConnect(7),	--	R-Name			code=done,connect
		--			or:	code=BadRName(#individual)
		--			or:	code=WrongServer

ReadRemark(8),	--	R-Name			code=done,remark
		--			or:	code=BadRName(#group)
		--			or:	code=WrongServer

Authenticate(9),--	R-Name,Password		code=done
		--			or:	code=BadPassword
		--			or:	code=BadRName(#individual)
		--			or:	code=WrongServer

-- more enquiries at 60: the grotty compiler won't let me put them here!

-- UPDATE OPERATIONS

CreateRegistry(10),	-- NOT IMPLEMENTED --

DeleteRegistry(11),	-- NOT IMPLEMENTED --

CreateIndividual(12),--	R-Name,Password		code=done
		--			or:	code=NotAllowed
		--			or:	code=noChange
		--			or:	code=BadRName(group)
		--			or:	code=OutOfDate(!)
		--			or:	code=WrongServer

DeleteIndividual(13),--	R-Name			code=done
		--			or:	code=NotAllowed
		--			or:	code=noChange
		--			or:	code=BadRName(#individual)
		--			or:	code=OutOfDate(!)
		--			or:	code=WrongServer

CreateGroup(14),--	R-Name			code=done
		--			or:	code=NotAllowed
		--			or:	code=noChange
		--			or:	code=BadRName(individual)
		--			or:	code=OutOfDate(!)
		--			or:	code=WrongServer

DeleteGroup(15),--	R-Name			code=done
		--			or:	code=NotAllowed
		--			or:	code=noChange
		--			or:	code=BadRName(#group)
		--			or:	code=OutOfDate(!)
		--			or:	code=WrongServer

ChangePassword(16),--	R-Name,Password		code=done
		--			or:	code=NotAllowed
		--			or:	code=noChange
		--			or:	code=BadRName(#individual)
		--			or:	code=OutOfDate(!)
		--			or:	code=WrongServer

ChangeConnect(17),--	R-Name,Connect		code=done
		--			or:	code=NotAllowed
		--			or:	code=noChange
		--			or:	code=BadRName(#individual)
		--			or:	code=OutOfDate(!)
		--			or:	code=WrongServer

ChangeRemark(18),--	R-Name,Remark		code=done
		--			or:	code=NotAllowed
		--			or:	code=noChange
		--			or:	code=BadRName(#group)
		--			or:	code=OutOfDate(!)
		--			or:	code=WrongServer

AddMember(19),	--	R-Name,member		code=done
		--			or:	code=NotAllowed
		--			or:	code=noChange
		--			or:	code=BadRName(#group)
		--			or:	code=OutOfDate(!)
		--			or:	code=WrongServer

AddMailBox(20),	--	R-Name,site		code=done
		--			or:	code=NotAllowed
		--			or:	code=noChange
		--			or:	code=BadRName(#individual)
		--			or:	code=OutOfDate(!)
		--			or:	code=WrongServer

AddForward(21),	--	R-Name,destn		code=done
		--			or:	code=NotAllowed
		--			or:	code=noChange
		--			or:	code=BadRName(#individual)
		--			or:	code=OutOfDate(!)
		--			or:	code=WrongServer

AddOwner(22),	--	R-Name,owner		code=done
		--			or:	code=NotAllowed
		--			or:	code=noChange
		--			or:	code=BadRName(#group)
		--			or:	code=OutOfDate(!)
		--			or:	code=WrongServer

AddFriend(23),	--	R-Name,friend		code=done
		--			or:	code=NotAllowed
		--			or:	code=noChange
		--			or:	code=BadRName(#group)
		--			or:	code=OutOfDate(!)
		--			or:	code=WrongServer

DeleteMember(24),--	R-Name,member		code=done
		--			or:	code=NotAllowed
		--			or:	code=noChange
		--			or:	code=BadRName(#group)
		--			or:	code=OutOfDate(!)
		--			or:	code=WrongServer

DeleteMailBox(25),--	R-Name,site		code=done
		--			or:	code=NotAllowed
		--			or:	code=noChange
		--			or:	code=BadRName(#individual)
		--			or:	code=OutOfDate(!)
		--			or:	code=WrongServer

DeleteForward(26),--	R-Name,destn		code=done
		--			or:	code=NotAllowed
		--			or:	code=noChange
		--			or:	code=BadRName(#individual)
		--			or:	code=OutOfDate(!)
		--			or:	code=WrongServer

DeleteOwner(27),--	R-Name,owner		code=done
		--			or:	code=NotAllowed
		--			or:	code=noChange
		--			or:	code=BadRName(#group)
		--			or:	code=OutOfDate(!)
		--			or:	code=WrongServer

DeleteFriend(28),--	R-Name,friend		code=done
		--			or:	code=NotAllowed
		--			or:	code=noChange
		--			or:	code=BadRName(#group)
		--			or:	code=OutOfDate(!)
		--			or:	code=WrongServer

AddSelf(29),	--	R-Name			code=done
		--			or:	code=NotAllowed
		--			or:	code=noChange
		--			or:	code=BadRName(#group)
		--			or:	code=OutOfDate(!)
		--			or:	code=WrongServer

DeleteSelf(30),	--	R-Name			code=done
		--			or:	code=NotAllowed
		--			or:	code=noChange
		--			or:	code=BadRName(#group)
		--			or:	code=OutOfDate(!)
		--			or:	code=WrongServer

AddListOfMembers(31),-- adds multiple members; R-List must be alphabetical
		--	R-Name,R-List		code=done
		--			or:	code=NotAllowed
		--			or:	code=noChange
		--			or:	code=BadRName(#group)
		--			or:	code=OutOfDate(!)
		--			or:	code=WrongServer
		--			or:	code=BadProtocol(out of order)

NewName(32),	-- creates a new entry with same content as given one;
		-- R-Names must be in same registry
		--	R-Name(dest),R-Name(srce)
		--				code=done
		--			or:	code=NotAllowed
		--			or:	code=BadRName(srce:notFound)
		--			or:	code=BadRName(dest:#notFound)
		--			or:	code=OutOfDate(!)
		--			or:	code=WrongServer
		--			or:	code=BadProtocol(different registries)

IdentifyCaller(33),	-- must be called to permit updates
		--	R-Name,Password		code=done
		--			or:	code=BadPassword
		--			or:	code=BadRName(#individual)
		--			or:	code=AllDown


-- ACCESS CONTROL ENQUIRIES --

IsMemberDirect(40),--	R-Name,member		code=done,Membership
		--			or:	code=BadRName(#group)
		--			or:	code=WrongServer
		-- This also works for names of the form Owners-foo.pa

IsOwnerDirect(41),--	R-Name,member		code=done,Membership
		--			or:	code=BadRName(#group)
		--			or:	code=WrongServer

IsFriendDirect(42),--	R-Name,member		code=done,Membership
		--			or:	code=BadRName(#group)
		--			or:	code=WrongServer

IsMemberClosure(43),--	R-Name,member		code=done,Membership
		--			or:	code=BadRName(#group)
		--			or:	code=WrongServer
		--			or:	code=AllDown

IsOwnerClosure(44),--	R-Name,member		code=done,Membership
		--			or:	code=BadRName(#group)
		--			or:	code=WrongServer
		--			or:	code=AllDown

IsFriendClosure(45),--	R-Name,member		code=done,Membership
		--			or:	code=BadRName(#group)
		--			or:	code=WrongServer
		--			or:	code=AllDown

IsInList(46),	-- R-Name, member,
		-- {it(0),itsRegistry(1)}: byte,
		-- {member(0),owner(1),friend(2)}: byte,
		-- {direct(0),closure(1)}: byte
		--				code=done,Membership
		--			or:	code=BadRName(#group)
		--			or:	code=WrongServer
		--			or:	code=AllDown(for closure)


-- 60..69 reserved for enquiries: see above

ReadMailboxes(60),--	R-Name,stamp		code=done,stamp,R-List
		--			or:	code=noChange
		--			or:	code=BadRName(#individual)
		--			or:	code=WrongServer



(255)		--	undefined operations:	code=BadOperation

		};


END.