-- PacketStreamMgr.mesa (last edited by: Garlick on: January 23, 1981 4:17 PM)
-- Function: The implementation module for the manager of Pilot Packet Streams.

DIRECTORY
CommunicationInternal USING [],
CommFlags USING [doDebug],
DriverDefs USING [Glitch],
NetworkStream USING [],
OISCP USING [uniqueAddress, unknownConnID],
OISCPTypes USING [ConnectionID, WaitTime],
PacketStream USING [
FailureReason, Handle, SuspendReason, ClassOfService, WaitTime, defaultWaitTime],
PacketStreamInstance USING [Delete],
PrincOpsUtils USING [GlobalFrame],
Router USING [AssignDestinationRelativeOisAddress],
NSAddress USING [NetworkAddress];

PacketStreamMgr: MONITOR
IMPORTS PrincOpsUtils, DriverDefs, pktStrmInst: PacketStreamInstance, Router
EXPORTS CommunicationInternal, NetworkStream, PacketStream =
BEGIN OPEN Router, PacketStream;

-- These variables must eventually live in outerspace so that multiple MDSs
-- access the same packet stream variables. The module in the primary MDS will
-- perform the initialization of the "globals", while the others will not.

-- This module is a monitor in order to protect the value of spareConnectionID and the
-- ConnectionTable. Some day the connection IDs in use will be remembered across wrap
-- around.

primaryMDS: PUBLIC BOOLEAN ← TRUE; -- we are in the primary MDS.
infiniteWaitTime: PUBLIC WaitTime ← LAST[WaitTime];
initialSpareConnectionID: OISCPTypes.ConnectionID = [500];
-- monitor data
-- connectionID parameters
spareConnectionID: OISCPTypes.ConnectionID;
-- connectionTable parameters and types
ConnectionTable: ARRAY (0..maxConnectionNumber] OF ConnectionTableEntry;
maxConnectionNumber: CARDINAL = 20;
index: CARDINAL ← 0;
ConnectionTableEntry: TYPE = RECORD [
rAddr: NSAddress.NetworkAddress, rConnID: OISCPTypes.ConnectionID];

-- various Glitches.
ConnectionTableFull: ERROR = CODE;
NotInConnectionTable: ERROR = CODE;

ConnectionSuspended: PUBLIC ERROR [why: SuspendReason] = CODE;
ConnectionFailed: PUBLIC SIGNAL [why: FailureReason] = CODE;
AttentionTimeout: PUBLIC ERROR = CODE;

-- Cool Procedures

-- This procedure creates a packet stream instance. The local and remote addresses
-- must be correctly specified, or else we pick defaults when possible.
Make: PUBLIC PROCEDURE [
local, remote: NSAddress.NetworkAddress, localConnID, remoteConnID:
OISCPTypes.ConnectionID, establishConnection: BOOLEAN, timeout:
OISCPTypes.WaitTime ← defaultWaitTime, classOfService: ClassOfService ← bulk]
RETURNS [psH: PacketStream.Handle] =
BEGIN
estdRemoteAddr: NSAddress.NetworkAddress;
estdRemoteConnID: OISCPTypes.ConnectionID;
newPktStrmInst: POINTER TO FRAME[PacketStreamInstance] ← NEW pktStrmInst;
BEGIN
ENABLE UNWIND => newPktStrmInst.Delete[];
-- If we do not have a local address we pick one with a network number that is a
-- good way to get to the destinationand therefore a good way to get back to us!
IF local = OISCP.uniqueAddress THEN
local ← Router.AssignDestinationRelativeOisAddress[remote.net];
IF localConnID = OISCP.unknownConnID THEN localConnID ← GetUniqueConnectionID[];
[psH, estdRemoteAddr, estdRemoteConnID] ← START newPktStrmInst[
local, remote, localConnID, remoteConnID, establishConnection, timeout,
classOfService];
InsertIntoConnectionTable[estdRemoteAddr, estdRemoteConnID];
END;
END; -- Create

-- This procedure deletes the specified packet stream instance.

Destroy: PUBLIC PROCEDURE [psH: PacketStream.Handle] =
BEGIN
oldPktStrmInst: POINTER TO FRAME[PacketStreamInstance] ←
LOOPHOLE[PrincOpsUtils.GlobalFrame[psH.get], POINTER];
remote: NSAddress.NetworkAddress ← oldPktStrmInst.remoteAddr;
remoteConnID: OISCPTypes.ConnectionID ← oldPktStrmInst.remoteConnectionID;
oldPktStrmInst.Delete[];
RemoveFromConnectionTable[remote, remoteConnID];
END; -- Delete

-- This procedure returns a unique connection ID. Some day the active connection IDs
-- in use will be kept around, so that on wrap around an unused ID will be assigned.

GetUniqueConnectionID: ENTRY PROCEDURE RETURNS [iD: OISCPTypes.ConnectionID] =
BEGIN
iD ← spareConnectionID;
IF (spareConnectionID ← [spareConnectionID + 1]) = OISCPTypes.ConnectionID[0] THEN
spareConnectionID ← initialSpareConnectionID;
END; -- GetUniqueConnectionID

-- This procedure inserts a connection into the connectionTable.

InsertIntoConnectionTable: PUBLIC ENTRY PROCEDURE [
remote: NSAddress.NetworkAddress, remoteConnID: OISCPTypes.ConnectionID] =
BEGIN
IF (index ← index + 1) > maxConnectionNumber THEN
IF CommFlags.doDebug THEN DriverDefs.Glitch[ConnectionTableFull];
ConnectionTable[index] ← ConnectionTableEntry[remote, remoteConnID];
END; -- InsertIntoConnectionTable

-- This procedure removes a connection from the connectionTable.

RemoveFromConnectionTable: PUBLIC ENTRY PROCEDURE [
remote: NSAddress.NetworkAddress, remoteConnID: OISCPTypes.ConnectionID] =
BEGIN
i: CARDINAL;
FOR i IN (0..index] DO
IF ConnectionTable[i].rAddr.host = remote.host AND ConnectionTable[
 i].rAddr.socket = remote.socket AND ConnectionTable[i].rConnID =
 remoteConnID THEN
 BEGIN
 ConnectionTable[i] ← ConnectionTable[index];
 index ← index - 1;
 RETURN;
 END;
ENDLOOP;
IF CommFlags.doDebug THEN DriverDefs.Glitch[NotInConnectionTable];
END; -- RemoveFromConnectionTable

-- This procedure checks if there is a similar connection in the connectionTable.

ConnectionAlreadyThere: PUBLIC ENTRY PROCEDURE [
remote: NSAddress.NetworkAddress, remoteConnID: OISCPTypes.ConnectionID] RETURNS [BOOLEAN] =
BEGIN
i: CARDINAL;
FOR i IN (0..index] DO
IF ConnectionTable[i].rAddr.host = remote.host AND ConnectionTable[
 i].rAddr.socket = remote.socket AND ConnectionTable[i].rConnID =
 remoteConnID THEN RETURN[TRUE];
ENDLOOP;
RETURN[FALSE];
END; -- ConnectionAlreadyThere

-- initialization

IF primaryMDS THEN spareConnectionID ← initialSpareConnectionID;

END. -- of PacketStreamMgr module

LOG
Time: January 23, 1981 4:17 PM By: Garlick Action: added classOfService to Make.