-- Copyright (C) 1982, 1984 by Xerox Corporation. All rights reserved. -- RPCPkt.mesa, HGM, 21-Jan-84 20:39:05 -- Cedar 5, HGM, 21-Jan-84 20:38:14 -- RPC: layout of packets -- [Ivy]RPC>RPCPkt.mesa -- Andrew Birrell 16-Mar-82 11:46:26 DIRECTORY PSB USING [PsbIndex], Buffer USING [PupBuffer], PupTypes USING [PupHostID, PupNetID, PupSocketID], MesaRPCLupine USING [DataLength, Dispatcher, RPCPkt], RPCPrivate USING [rpcSocket]; RPCPkt: DEFINITIONS SHARES MesaRPCLupine = BEGIN -- ******** Layout of stub-packets ******** -- Header: TYPE = MACHINE DEPENDENT RECORD [ length(0:0..14): [0..77777B], oddByte(0:15..15): {no(0), yes(1)}, type(1): PktType, destPSB(2): PSB.PsbIndex, -- field has 6 extra bits srcePSB(3): PSB.PsbIndex, -- field has 6 extra bits destHost(4): Machine, destSoc(5): PupTypes.PupSocketID, srceHost(7): Machine, srceSoc(8): PupTypes.PupSocketID, -- end of standard Pup header -- conv(10): PktConversationID, -- For secure conversations, the remainder of the packet must be encrypted -- pktID(12): PktID, call(16): SELECT OVERLAID * FROM calling => [dispatcher(16): DispatcherDetails], responding => [ outcome(16): Outcome, fill(17): ARRAY [SIZE[Outcome]..SIZE[DispatcherDetails]) OF WORD], ENDCASE]; PktType: TYPE = MACHINE DEPENDENT RECORD [ -- "type" word of a Pup -- transport(0:0..7): [0..255], -- should be zero before sending -- subType(0:8..10): {rpc(3B), (7B)}, eom(0:11..11): {end(0), notEnd(1)}, ack(0:12..12): {dontAck(0), pleaseAck(1)}, class(0:13..15): {call(0), data(1), ack(2), rfa(4), (7)}]; -- Mapping from Pup pkt types to RPC pkt types: -- 140B = [end, dontAck, call ] -- 141B = [end, dontAck, data ] -- 142B = [, dontAck, ack ] (also 162B) -- 143B = unused (also 163B) -- 144B = [, dontAck, rfa ] (also 164B) -- 150B = [end, pleaseAck, call ] -- 151B = [end, pleaseAck, data ] -- 152B = [, pleaseAck, ack ] (also 172B) -- 153B = unused (also 173B) -- 154B = [, pleaseAck, rfa ] (also 174B) -- 160B = [notEnd, dontAck, call ] -- 161B = [notEnd, dontAck, data ] -- 170B = [notEnd, pleaseAck, call ] -- 171B = [notEnd, pleaseAck, data ] pktLengthOverhead: MesaRPCLupine.DataLength = SIZE[Header] + 1 --checksum-- ; -- Difference between MesaRPCLupine.DataLength and transmitted Pup length -- for unencrypted packets -- Machine: TYPE = MACHINE DEPENDENT RECORD [ -- Unambiguous name of a host net: PupTypes.PupNetID, host: PupTypes.PupHostID]; HostConversationID: TYPE = MACHINE DEPENDENT RECORD [ -- Host-relative ID of a conversation; unique for all time -- ls(0): CARDINAL, ms(1): [0..77777B]]; ConversationID: TYPE = RECORD [ -- Absolute ID of a conversation; unique for all hosts and all time -- originator: Machine, count: HostConversationID]; PktConversationID: TYPE = MACHINE DEPENDENT RECORD [ -- Same as ConversationID, but abbreviated for within a packet -- -- Assumes originator is always caller or callee -- ls(0): CARDINAL, originator(1:0..0): {caller, callee}, ms(1:1..15): [0..77777B]]; ConnectionID: TYPE = MACHINE DEPENDENT RECORD [ -- Uniquely identifies an independent sequence of calls -- conv(0): PktConversationID, caller(2): Machine, activity(3): PSB.PsbIndex]; CallCount: TYPE = LONG CARDINAL -- [ConnectionID,CallCount] uniquely identifies call for all hosts and time -- ; PktID: TYPE = MACHINE DEPENDENT RECORD [ -- [ConversationID,PktID] uniquely identifies pkt for all hosts and time -- activity(0): PSB.PsbIndex, -- field has 6 extra bits-- callSeq(1): CallCount, pktSeq(3): CARDINAL]; Outcome: TYPE = MACHINE DEPENDENT{ -- possible responses to call or signal -- result(0), -- normal -- unbound(1), -- dispatcher not known -- signal(2), -- signal propagation -- unwind(3), -- signal is unwinding -- protocol(4), -- stub protocol error detected -- (LAST[CARDINAL]) -- room for expansion? -- }; DispatcherDetails: TYPE = MACHINE DEPENDENT RECORD [ mds: CARDINAL, -- top half of dispatcher's MDS base address -- dispatcherID: DispatcherID, -- exporter-relative UID of interface instance -- dispatcherHint: ExportHandle -- hint to exporter host's export table -- ]; DispatcherID: TYPE = LONG CARDINAL; noDispatcher: DispatcherID = 0; ExportHandle: TYPE = CARDINAL; SetupResponse: PROC [header: LONG POINTER TO Header] = INLINE BEGIN header.destHost ¬ header.srceHost; header.destSoc ¬ RPCPrivate.rpcSocket; header.destPSB ¬ header.srcePSB; header.outcome ¬ result; END; -- ******** Single-packet communication: exported by RPCPktIO ******** -- PktExchangeState: TYPE = {receiving, sending, call, endCall, authReq}; PktExchange: PROC [ inPkt: MesaRPCLupine.RPCPkt, length: MesaRPCLupine.DataLength, maxlength: MesaRPCLupine.DataLength, state: PktExchangeState, signalHandler: MesaRPCLupine.Dispatcher ¬ NIL] RETURNS [newPkt: BOOLEAN, newLength: MesaRPCLupine.DataLength]; -- Reliable transmission of given packet, and receipt of next packet; -- "newLength" is data length of incoming packet, if any. -- IdleReceive: PROC [pkt: MesaRPCLupine.RPCPkt, maxlength: CARDINAL]; -- Returns when new packet arrives; "maxlength" is number of words in the -- pkt buffer starting from pkt.header (total, including all overheads) -- EnqueueAgain: PUBLIC PROC [b: Buffer.PupBuffer]; END.