-- File: PupPktOps.mesa
-- Last Edit: HGM  February 10, 1981  6:39 PM
-- Last Edit: BLyon  June 30, 1980  5:22 PM

DIRECTORY
  Mopcodes USING [zEXCH],
  System USING [Pulses],
  PupStream USING [PupOpenMode, CloseReason],
  PupPktDefs USING [PupPktStreamObject],
  PupDefs USING [Pair, PupBuffer, PupSocket],
  BufferDefs USING [QueueObject],
  PupTypes USING [Pair, PupAddress, PupSocketID];

PupPktOps: DEFINITIONS =
  BEGIN

  bytesPerPupHeader: CARDINAL = 22;
  bytesPerAck: CARDINAL = bytesPerPupHeader + 6;
  dataBytesPerRFC: CARDINAL = 6;
  byteAllocate: CARDINAL = 32000; -- lots and lots

  retransmitionsBeforeAbort: CARDINAL = probesBeforePanic + 3*60/5; -- about 3 min
  initialRetransmissions: CARDINAL = 2*retransmitionsBeforeAbort/3; -- 1 min
  pingRetransmissions: CARDINAL = retransmitionsBeforeAbort/3; -- 2 (more) min
  probesBeforePanic: CARDINAL = 10;
  maxRetransmitTime: CARDINAL = 5000;
  maxRetransmitPulses: System.Pulses; -- 5 sec
  minRetransmitPulses: System.Pulses; -- 100 ms
  initialRetransmitPulses: System.Pulses; -- 5 sec
  ctlRetransmitPulses: System.Pulses; -- 2 sec
  pingPulses: System.Pulses; -- 1 min

  duplicateWindow: CARDINAL = 10000;

  clumpsBeforeBump: CARDINAL = 10;

  Flip: PROCEDURE [PupDefs.Pair] RETURNS [LONG INTEGER] = MACHINE CODE
    BEGIN Mopcodes.zEXCH; END;

  Flop: PROCEDURE [LONG INTEGER] RETURNS [PupDefs.Pair] = MACHINE CODE
    BEGIN Mopcodes.zEXCH; END;



  Instance: TYPE = POINTER TO InstanceData;
  InstanceData: TYPE = RECORD [


    state: {idle, halfOpen, open, talking, finishing, end, closed},
    -- halfOpen is when we have an unanswered RFC outstanding
    -- talking is like open except that we have unAcked packets out
    -- end is when we have an unanswered End outstanding
    -- finishing is when we get an end, but we have unAcked packets out

    c: PupDefs.PupBuffer, -- this is a kludge

    socket: PupDefs.PupSocket,

    dontWait: BOOLEAN,

    local: PupTypes.PupAddress,
    remote: PupTypes.PupAddress,
    mode: PupStream.PupOpenMode,
    dataBytesPerPup: CARDINAL,


    stateChange: CONDITION,
    inputReady: CONDITION,
    retransmitterReady: CONDITION,
    inputQueue: BufferDefs.QueueObject,
    sentQueue: BufferDefs.QueueObject,
    retransmitterFork: PROCESS,
    slurpFork: PROCESS,

    waitingForInterrupt: CONDITION,
    outIntSeq, inIntSeq, seenIntSeq: LONG INTEGER,
    outIntPending: BOOLEAN,
    outIntTime: System.Pulses,

    outEnd: CARDINAL,
    probeCounter: CARDINAL,
    ping: BOOLEAN,
    myMaxAllocate: CARDINAL,
    pathMaxAllocate: CARDINAL,
    hisMaxAllocate: CARDINAL,
    throttle: CARDINAL,
    unackedPups, allocatedPups: CARDINAL,
    clumpsSinceBump: CARDINAL,
    sentBuffer: PupDefs.PupBuffer,
    pleaseDie, sameNet, sendAck, aDataOut: BOOLEAN,
    timer: System.Pulses,
    -- mostly used by send side, but used for pinging if state=open
    retransmitPulses: System.Pulses,
    connectionID: PupDefs.Pair,
    nextInputID, nextOutputID, maxOutputID, ackedID: LONG INTEGER,
    allocationID, allocatedID: LONG INTEGER,
    whyClosed: PupStream.CloseReason,
    text: STRING,
    lock: MONITORLOCK,
    slurp: PROCEDURE,
    retransmitter: PROCEDURE,
    me: PupPktDefs.PupPktStreamObject,
    next: Instance];

  PupPktHot: PROGRAM RETURNS [Instance];
  MakeLocal: PROCEDURE [
    him: Instance, l: PupTypes.PupSocketID, r: PupTypes.PupAddress,
    m: PupStream.PupOpenMode, id: PupTypes.Pair];
  DestroyLocalLocked: PROCEDURE [him: Instance];

  GetSenderSizeLimit: PROCEDURE [Instance] RETURNS [CARDINAL];
  GetLocalAddress: PROCEDURE [Instance] RETURNS [PupTypes.PupAddress];

  GotOther: PROCEDURE [Instance, PupDefs.PupBuffer];
  SmashClosed: PROCEDURE [Instance, PupStream.CloseReason];
  SendRfc: PROCEDURE [Instance];
  SendEnd: PROCEDURE [Instance];
  SendInt: PROCEDURE [Instance];
  SendAbort: PROCEDURE [Instance];
  StreamDied: PROCEDURE [Instance, PupDefs.PupBuffer];

  -- Kludge to make things work if the Dispatcher runs at Priority 2 in an Alto Gateway
  SetLockRequeueProcedureFlag: PROCEDURE [lockit: BOOLEAN];

  END.