-- Copyright (C) 1984  by Xerox Corporation. All rights reserved. 
-- RPCEchoUserTajo.mesa, HGM, 21-Jan-84 20:37:52

DIRECTORY
  FormSW USING [
    AllocateItemDescriptor, ClientItemsProcType, CommandItem, newLine, ProcType, StringItem],
  Put USING [Line, LongDecimal, Text],
  Runtime USING [GetBcdTime],
  String USING [AppendString],
  System USING [GetClockPulses, Microseconds, Pulses, PulsesToMicroseconds],
  Time USING [Append, Unpack],
  Tool USING [Create, MakeSWsProc, MakeFormSW, MakeFileSW, UnusedLogName],
  ToolWindow USING [TransitionProcType],
  Window USING [Handle],

  MesaRPC USING [ImportFailed, unencrypted],
  MesaRPCLupine USING [
    Call, DataLength, GetStubPkt, ImportHandle, ImportInterface,
    maxDataLength, pktOverhead, StartCall, StubPkt, UnimportInterface];

RPCEchoUserTajo: MONITOR
  IMPORTS
    FormSW, Put, Runtime, String, System, Time, Tool,
    MesaRPC, MesaRPCLupine =
  BEGIN

  target: LONG STRING ← NIL;

  pktSpace: ARRAY [0..MesaRPCLupine.pktOverhead + MesaRPCLupine.maxDataLength) OF WORD;
  pkt: MesaRPCLupine.StubPkt = MesaRPCLupine.GetStubPkt[@pktSpace];
  

  -- Test version of stub code --

  MultiPacket: ERROR = CODE;
  WrongLengthAnswer: ERROR = CODE;

  SendRecv: ENTRY PROCEDURE [import: MesaRPCLupine.ImportHandle, words: CARDINAL] =
    BEGIN
    length: MesaRPCLupine.DataLength;
    last: BOOLEAN;
    [] ← MesaRPCLupine.StartCall[pkt, import, MesaRPC.unencrypted];
    [length, last] ← MesaRPCLupine.Call[pkt, words, MesaRPCLupine.maxDataLength];
    IF ~last THEN ERROR MultiPacket[];
    IF length # words THEN ERROR WrongLengthAnswer[];
    END;

  Echo: FormSW.ProcType =
    BEGIN
    type: STRING = "RPC-Echo"L;
    import: MesaRPCLupine.ImportHandle ← NIL;
    start, end: System.Pulses;
    packets: LONG CARDINAL ← 0;
    ms: LONG CARDINAL;
    start ← System.GetClockPulses[];
    import ← MesaRPCLupine.ImportInterface[[type, target], [0, 0] !
      MesaRPC.ImportFailed =>
        BEGIN
	Put.Text[log, "Import of "L];
	Put.Text[log, type];
	Put.Text[log, " from "L];
	Put.Text[log, target];
	Put.Text[log, " failed: "L];
	SELECT why FROM
	  communications => Put.Text[log, "communications"L];
	  badInstance => Put.Text[log, "badInstance"L];
	  badVersion => Put.Text[log, "badVersion"L];
	  wrongVersion => Put.Text[log, "wrongVersion"L];
	  unbound => Put.Text[log, "unbound"L];
	  stubProtocol => Put.Text[log, "stubProtocol"L];
	  ENDCASE => Put.Text[log, "??"L];
	Put.Line[log, "."L];
	CONTINUE;
	END];
    IF import = NIL THEN RETURN;
    end ← System.GetClockPulses[];
    ms ← System.PulsesToMicroseconds[[end-start]]/1000;
    Put.Text[log, "It took "L];
    Put.LongDecimal[log, ms];
    Put.Line[log, " ms to Import RPC-Echo."L];
    start ← System.GetClockPulses[];
    FOR i: CARDINAL IN [0..10) DO
      FOR k: CARDINAL IN [0..100) DO
        SendRecv[import, k];
        packets ← packets + 1;
        ENDLOOP;
      ENDLOOP;
    end ← System.GetClockPulses[];
    ms ← System.PulsesToMicroseconds[[end-start]]/1000;
    Put.Text[log, "It took "L];
    Put.LongDecimal[log, ms];
    Put.Text[log, " ms to to Echo "L];
    Put.LongDecimal[log, packets];
    Put.Line[log, " packets."L];
    import ← MesaRPCLupine.UnimportInterface[import];
    END;

  form, log: PUBLIC Window.Handle ← NIL;

  Init: PROCEDURE =
    BEGIN
    herald: STRING = [100];
    String.AppendString[herald, "RPCEchoUser of  "L];
    Time.Append[herald, Time.Unpack[Runtime.GetBcdTime[]]];
    [] ← Tool.Create[
      name: herald, makeSWsProc: MakeSWs,
      clientTransition: ClientTransition];
    END;

  MakeSWs: Tool.MakeSWsProc =
    BEGIN
    logFileName: STRING = [40];
    Tool.UnusedLogName[logFileName, "RPCEchoUser.log$"L];
    form ← Tool.MakeFormSW[window: window, formProc: MakeForm];
    log ← Tool.MakeFileSW[window: window, name: logFileName];
    END;

  MakeForm: FormSW.ClientItemsProcType =
    BEGIN
    nParams: CARDINAL = 2;
    items ← FormSW.AllocateItemDescriptor[nParams];
    items[0] ← FormSW.CommandItem[tag: "Echo"L, proc: Echo, place: FormSW.newLine];
    items[1] ← FormSW.StringItem[tag: "Target"L, string: @target, inHeap: TRUE];
    RETURN[items, TRUE];
    END;

  ClientTransition: ToolWindow.TransitionProcType =
    BEGIN IF new = inactive THEN form ← log ← NIL; END;

  Init[];

  END.