<> <> <> <> <> DIRECTORY BufferDefs USING[ PupBuffer ], PrincOps USING[ PsbIndex ], PupTypes USING[ PupHostID, PupNetID, PupSocketID ], RPCLupine USING[ DataLength, Dispatcher, RPCPkt ], RPCPrivate USING[ rpcSocket ]; RPCPkt: DEFINITIONS SHARES RPCLupine = 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): PrincOps.PsbIndex,-- field has 6 extra bits srcePSB (3): PrincOps.PsbIndex,-- field has 6 extra bits destHost (4): Machine, destSoc (5): PupTypes.PupSocketID, srceHost (7): Machine, srceSoc (8): PupTypes.PupSocketID, <> conv (10): PktConversationID, <> 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) } ]; <> <<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: RPCLupine.DataLength = SIZE[Header] + 1--checksum--; <> Machine: TYPE = MACHINE DEPENDENT RECORD[ <> net: PupTypes.PupNetID, host: PupTypes.PupHostID ]; HostConversationID: TYPE = MACHINE DEPENDENT RECORD[ <> ls(0): CARDINAL, ms(1): [0..77777B] ]; ConversationID: TYPE = RECORD[ <> originator: Machine, count: HostConversationID]; PktConversationID: TYPE = MACHINE DEPENDENT RECORD[ <> ls(0): CARDINAL, originator(1:0..0): { caller, callee }, ms(1:1..15): [0..77777B] ]; ConnectionID: TYPE = MACHINE DEPENDENT RECORD[ <> conv(0): PktConversationID, caller(2): Machine, activity(3): PrincOps.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): PrincOps.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: RPCLupine.RPCPkt, length: RPCLupine.DataLength, maxlength: RPCLupine.DataLength, state: PktExchangeState, signalHandler: RPCLupine.Dispatcher _ NIL] RETURNS[newPkt: BOOLEAN, newLength: RPCLupine.DataLength]; <> IdleReceive: PROC[pkt: RPCLupine.RPCPkt, maxlength: CARDINAL]; <> EnqueueAgain: PROC[b: BufferDefs.PupBuffer]; <> END.