-- File: PupRouterDefs.Mesa,  Last Edit: HGM  February 25, 1981  1:59 PM

DIRECTORY
  DriverDefs USING [Network],
  BufferDefs USING [PupBuffer, Byte, PupNetID, PupHostID, QueueObject],
  PupTypes USING [Pair, PupAddress, PupErrorCode];

PupRouterDefs: DEFINITIONS =
  BEGIN OPEN DriverDefs, BufferDefs;

  wordsPerPupHeader: CARDINAL = 11;
  bytesPerPupHeader: CARDINAL = wordsPerPupHeader*2;

  BeSurePupIsOn: PROCEDURE;

  NextPupConnectionID: PROCEDURE RETURNS [PupTypes.Pair];
  PupRouterKnowAboutSocket: PROCEDURE [PupRouterSocket];
  PupRouterForgetAboutSocket: PROCEDURE [PupRouterSocket];
  GetFirstPupSocket: PROCEDURE RETURNS [PupRouterSocket];
  PupRouterSocket: TYPE = LONG POINTER TO PupRouterSocketObject;
  PupRouterSocketObject: TYPE = RECORD [
    next: PupRouterSocket,
    local: PupTypes.PupAddress,
    remote: PupTypes.PupAddress, -- this lives here only for debugging
    ready: CONDITION,
    input: QueueObject,
    checkit: BOOLEAN,
    id: PupTypes.Pair]; -- only used by listeners

  SetPupChecksum: PROCEDURE [PupBuffer];
  TestPupChecksum: PROCEDURE [PupBuffer] RETURNS [BOOLEAN];
  SetBadPupProc: PROCEDURE [PROCEDURE [PupBuffer]];

  GetRoutingTableEntry: PROCEDURE [PupNetID] RETURNS [RoutingTableEntry];
  EnumerateRoutingTable: PROCEDURE [PROCEDURE [RoutingTableEntry]];
  GetRoutingTable: PROCEDURE RETURNS [RoutingTable];
  PupGatewaySee: PROCEDURE [PupBuffer] RETURNS [BOOLEAN];

  RoutingTable: TYPE = DESCRIPTOR FOR ARRAY OF RoutingTableObject;
  RoutingTableEntry: TYPE = POINTER TO RoutingTableObject;
  RoutingTableObject: TYPE = RECORD [
    net: PupNetID,
    hop: Byte,
    time: Byte,
    route: PupHostID,
    network: DriverDefs.Network];
  maxHop: CARDINAL = 15;

  -- Format of one slot of routing info from gateways, in routing info pups.
  -- Note: the middle half of this info isn't really needed for routing,
  --    but it is handy for debugging
  PupGateInfo: TYPE = MACHINE DEPENDENT RECORD [
    net: PupNetID, viaNet: PupNetID, viaHost: PupHostID, hop: Byte];

  -- Dispatcher interface
  PupInputer: PROCEDURE [PupBuffer];
  PupBroadcaster: PROCEDURE [PupBuffer];
  DontForwardPupBuffer: PROCEDURE [PupBuffer];
  DoForwardPupBuffer: PROCEDURE [PupBuffer];
  SetPupForwarder: PROCEDURE [PROCEDURE [PupBuffer]];
  SneakySendUnlocked: PROCEDURE [PupBuffer];
  RejectPupWithBadChecksum: PROCEDURE [PupBuffer];
  Reject: PROCEDURE [PupBuffer, PupErrorCode];
  Timeout: PROCEDURE;

  -- misc routines
  PupErrorCode: TYPE = PupTypes.PupErrorCode;
  BuildErrorPup: PROCEDURE [PupBuffer, PupErrorCode, STRING]
    RETURNS [ok: BOOLEAN];


  -- SemiPublic things from PupRouter
  routerLock: MONITORLOCK;
  routingTableUpdateTimeout: CONDITION;
  probeResponse: CONDITION;
  numberOfNetworks: CARDINAL;
  dataWordsPerPup: CARDINAL;
  routerIsActive: BOOLEAN;
  routingTable: RoutingTable;
  firstSocket: PupRouterSocket;

  outThings: OutThings;
  OutThings: TYPE = RECORD [
    outStormy: BOOLEAN,
    showOut: BOOLEAN,
    outShower: PROCEDURE [CARDINAL, PupBuffer]];

  inThings: InThings;
  InThings: TYPE = RECORD [
    inStormy: BOOLEAN,
    watcherIsWatching: BOOLEAN,
    watcherSeesBroadcast: BOOLEAN,
    watcherCallsThis: PROCEDURE [PupBuffer] RETURNS [BOOLEAN],
    badChecksumProc: PROCEDURE [PupBuffer],
    showIn: BOOLEAN,
    inShower: PROCEDURE [CARDINAL, PupBuffer]];

  Checksum: TYPE = {none, software, alto, princOps};
  checksum: Checksum;

  PupRouterCold, PupRouterOut, PupRouterIn, PupChecksums: PROGRAM;
  PupSockets, PupErrors: PROGRAM;

  END.