-- File: PupRouterCool.Mesa, Last Edit: HGM July 15, 1979 9:35 PM
-- This section of code is mostly used when creating/destroying sockets

-- Copyright Xerox Corporation 1979, 1980

DIRECTORY
CommUtilDefs: FROM "CommUtilDefs" USING [InitializeCondition, GetTicks],
PupRouterDefs: FROM "PupRouterDefs" USING [
routerLock, BeSurePupIsOn,
pupRoutingTable, PupRoutingTableEntry,
firstSocket, PupRouterSocket],
DriverDefs: FROM "DriverDefs" USING [doDebug, Network, GetDeviceChain],
PupDefs: FROM "PupDefs", -- EXPORTS
BufferDefs: FROM "BufferDefs" USING [QueueInitialize, QueueCleanup],
PupTypes: FROM "PupTypes" USING [
fillInNetID, fillInHostID, fillInSocketID,
PupAddress, PupNetID, PupSocketID, Pair];

PupRouterCool: MONITOR LOCKS PupRouterDefs.routerLock
IMPORTS CommUtilDefs, DriverDefs, PupRouterDefs, BufferDefs
EXPORTS PupDefs, PupRouterDefs =
PUBLIC BEGIN OPEN PupTypes, PupRouterDefs;

spareSocket: CARDINAL ←
1000B;
nextConnection
ID: CARDINAL ← 1000;

UniqueLocalPupSocketID: PUBLIC ENTRY PROCEDURE RETURNS [socket: PupSocketID] =
BEGIN
IF (spareSocket←spareSocket+1)=0 THEN spareSocket←1000B;
socket ← [Co
mmUtilDefs.GetTicks[],spareSocket];
E
ND;

UniqueLocalPupAddress: PU
BLIC PROCEDURE [him: POINTER TO PupAddress] RETURNS [me: PupAddress] =
BEGIN
RETURN[GetLocalPupAdd
ress[PupTypes.fillInSocketID,him]];
END;

NextPupConnectionID: PUBLIC ENTRY PROCEDURE RETURNS [p: PupTypes.Pair] =
BEGIN
p.a ← CommUtilDefs.GetTicks[];
p.b ← nex
tConnectionID ← nextConnectionID+1;
END;

GetLocalPupAddress: PUBLIC PROCEDURE [local:
PupSocketID, remote: POINTER TO PupAddress] RETURNS [me: PupAddress] =
BEGIN
destNet: CARDINAL ← 0;
routing: DES
CRIPTOR FOR ARRAY OF PupRoutingTableEntry ← GetPupRoutingTable[];
network: DriverDefs.Network ← NIL;
IF remote#NIL THEN
BEGIN OPEN PupTypes;
destNet ← remote.net;
-- Maybe we should scan for the right net if he specifies a host?
IF remote.net=fillInNetID OR remote.host=fillInHostID THEN destNet ← 0;
END;
IF destNet<LENGTH[routing] THEN network ← routing[destNet].network;
IF network=NIL THEN network ← DriverDefs.GetDeviceChain[];
me.net ← [network.netNumber];
me.ho
st ← [network.hostNumber];
me.soc
ket ← IF local#PupTypes.fillInSocketID THEN local ELSE UniqueLocalPupSocketID[];
IF remote#NIL THEN
BEGIN OPEN PupTypes;
IF remote.net=fillInNetID THEN
remote.net ← IF
network#NIL THEN [network.netNumber] ELSE me.net;
IF remote.host=fillInHostID THEN
remote.host ← IF n
etwork#NIL THEN [network.hostNumber] ELSE me.host;
IF remote.socket=fillInSocketID THEN r
emote.socket ← me.socket;
END;
END;

PupRouterKnowAboutSocket: PUBLIC ENTRY PROCEDURE [so: PupRouterSoc
ket] =
BEGI
N
IF DriverDefs.doDebug THEN BeSurePupIsOn[];
CommUtilDefs.InitializeCondition[@so.ready,0];
BufferDefs.QueueInitialize[@so.input];
so.next
← firstSocket;
firstSoc
ket ← so;
END;

PupRouterForgetAboutSocket: PUBLIC ENTRY PROCEDURE [so: PupRouterSocket] =
BEGIN
previous: Pu
pRouterSocket;
IF DriverDefs.doDebug THEN BeSurePupIsOn[];
IF firstSocket=so THEN firstSocket ← so.next
ELSE FOR previous←firstSocket,previous.next UNTIL previous=NIL DO
IF previous.next=so THEN
BEGIN previous.next ← so.next; EXIT; END;
ENDLOOP;
BufferDefs.QueueCleanup[@so.input];
END;

GetPupRoutingTable: PROC
EDURE RETURNS [
DESCRIPTOR FOR ARRAY OF PupRoutingTableEntry ] =
BEGIN
BeSurePu
pIsOn[];
RETURN
[pupRoutingTable];
END;

GetFirstPupSocket: PROC
EDURE RETURNS [PupRouterSocket] =
BEGIN
BeSu
rePupIsOn[];
R
ETURN[firstSocket];
END;

GetHopsToNetwork: PROCEDURE [net: PupTypes.PupNetID] RETURNS [CARDINAL] =
BEGIN
routing: DES
CRIPTOR FOR ARRAY OF PupRoutingTableEntry ← GetPupRoutingTable[];
BeSurePupIsOn[];
IF net ~IN [0..LENGTH[routing]) THEN RETURN [LAST[CARDINAL]];
RETURN[routing[net].hop];
END;

END.