<> <> <> <> <> <> <<>> DIRECTORY PrincOpsUtils--Inline-- USING[ BITOR, HighHalf, LowHalf, MakeLongPointer ], MesaRPC USING[ Conversation, EncryptionKey, InterfaceName, maxPrincipalLength, maxShortStringLength, Principal, unencrypted, VersionRange ]; MesaRPCLupine: DEFINITIONS IMPORTS PrincOpsUtils = BEGIN OPEN RPC: MesaRPC, Inline: PrincOpsUtils; -- Definitions copied across from RPC.mesa for Lupine's benefit maxPrincipalLength: CARDINAL = RPC.maxPrincipalLength; maxShortStringLength: CARDINAL = RPC.maxShortStringLength; <> <<>> <> <> <<>> <> <<>> <> <> Encapsulation: PRIVATE TYPE[7]; -- large enough for all current networks Header: PRIVATE TYPE[10+6+4]; <> maxPupWords: PRIVATE CARDINAL = <PupSpec.press -->> 266 -- Pup data -- + 10 -- Pup header -- + 1 -- Pup checksum --; encryptionBlockSize: PRIVATE CARDINAL = 4; SecurityChecksum: PRIVATE TYPE[2]; maxDataLength: CARDINAL = <> ( ( maxPupWords - 1 -- Pup checksum -- - SIZE[Header] ) / encryptionBlockSize --round down--) * encryptionBlockSize - SIZE[SecurityChecksum]; DataLength: TYPE = [0..maxDataLength]; pktOverhead: CARDINAL = pktAlign -- wastage for aligning the buffer -- + SIZE[StubPktData[0]] + encryptionBlockSize-1 -- rounding -- + SIZE[SecurityChecksum] + 1 -- Pup checksum --; pktAlign: PRIVATE WORD = 3B; -- maximum wastage for quad-word alignment StubPkt: TYPE = POINTER TO StubPktData; RPCPkt: TYPE = LONG StubPkt; StubPktData: TYPE = MACHINE DEPENDENT RECORD[ -- must be suitably aligned convHandle: PRIVATE RPC.Conversation, encapsulation: PRIVATE Encapsulation, header: PRIVATE Header, -- Pup/OIS header -- data: SEQUENCE COMPUTED DataLength OF UNSPECIFIED]; GetStubPkt: PROC[ space: POINTER TO UNSPECIFIED] RETURNS[--pkt:-- StubPkt ] = INLINE <> < result=1,>> < result=1,>> < result=5,>> < result=5.>> { RETURN[ LOOPHOLE[Inline.BITOR[LOOPHOLE[space, WORD]+2, pktAlign],POINTER]-2 ] }; GetRPCPkt: PROC[ space: LONG POINTER TO UNSPECIFIED] RETURNS[--pkt:-- RPCPkt ] = INLINE <> < result=1,>> < result=1,>> < result=5,>> < result=5.>> <> { RETURN[ Inline.MakeLongPointer[ low: LOOPHOLE[Inline.BITOR[LOOPHOLE[Inline.LowHalf[space+2], WORD], pktAlign] - 2], high: Inline.HighHalf[space+2] ]] }; -- Binding primitives for use by stubs -- <> <> <> ExportHandle: TYPE[SIZE[CARDINAL]]; -- index to table of dispatcher procedures ExportInterface: PROC[user: RPC.Principal, password: RPC.EncryptionKey, interface: RPC.InterfaceName, dispatcher: Dispatcher, stubProtocol: RPC.VersionRange, localOnly: BOOLEAN _ FALSE] RETURNS[ interfaceInstance: ExportHandle ]; <> UnexportInterface: PROC[ interfaceInstance: ExportHandle ] RETURNS[ExportHandle]; <> ImportHandle: TYPE = REF ImportInstance; ImportInstance: TYPE; ImportInterface: PROC[interface: RPC.InterfaceName, stubProtocol: RPC.VersionRange, localOnly: BOOLEAN _ FALSE] RETURNS[ interfaceInstance: ImportHandle ]; <> UnimportInterface: PROC[ interfaceInstance: ImportHandle ] RETURNS[ ImportHandle ]; <> <> <> <> <> <> <> <> StartCall: PROC[callPkt: RPCPkt, interface: ImportHandle, localConversation: RPC.Conversation _ RPC.unencrypted]; <> Call: PROC[pkt: RPCPkt, callLength: DataLength, maxReturnLength: DataLength, signalHandler: Dispatcher _ NIL] RETURNS[ returnLength: DataLength, lastPkt: BOOLEAN]; <> <> SendPrelimPkt: PROC[pkt: RPCPkt, length: DataLength]; <> ReceiveExtraPkt: PROC[prevPkt: RPCPkt] RETURNS[ length: DataLength, lastPkt: BOOLEAN]; <> Dispatcher: TYPE = PROC[pkt: RPCPkt, callLength: DataLength, lastPkt: BOOLEAN, localConversation: RPC.Conversation ] RETURNS[ returnLength: DataLength ]; <<"pkt" is the first argument packet. This must be passed to any calls of ReceiveExtraPkt or SendPrelimPkt; the stub leaves the last return pkt data in "pkt". "pkt" has maxlength = maxDataLength. The caller of the dispatcher will catch RPC.CallFailed -->> StartSignal: PROC[signalPkt: RPCPkt]; <> <> <> RejectUnbound: ERROR; <> RejectProtocol: ERROR; <> END. <> <> <<>>