PacketStreamMgr.mesa - implementation module for the manager of Pilot Packet Streams
Copyright © 1985 by Xerox Corporation. All rights reserved.
Garlick on: January 23, 1981 4:17 PM
Russ Atkinson (RRA) October 17, 1985 5:11:18 pm PDT
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 =
{ 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 BOOLTRUE; -- 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: REF ConnectionTableType ← NEW[ConnectionTableType];
ConnectionTableType: TYPE = 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 PROC [local, remote: NSAddress.NetworkAddress, localConnID, remoteConnID: OISCPTypes.ConnectionID, establishConnection: BOOL, timeout: OISCPTypes.WaitTime ← defaultWaitTime, classOfService: ClassOfService ← bulk] RETURNS [psH: PacketStream.Handle] = {
estdRemoteAddr: NSAddress.NetworkAddress;
estdRemoteConnID: OISCPTypes.ConnectionID;
newPktStrmInst: POINTER TO FRAME[PacketStreamInstance] ← NEW pktStrmInst;
{
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];
};
};
This procedure deletes the specified packet stream instance.
Destroy: PUBLIC PROC [psH: PacketStream.Handle] = {
oldPktStrmInst: POINTER TO FRAME[PacketStreamInstance] ←
LOOPHOLE[PrincOpsUtils.GlobalFrame[LOOPHOLE[psH.get]], POINTER];
remote: NSAddress.NetworkAddress ← oldPktStrmInst.remoteAddr;
remoteConnID: OISCPTypes.ConnectionID ← oldPktStrmInst.remoteConnectionID;
oldPktStrmInst.Delete[];
RemoveFromConnectionTable[remote, remoteConnID];
};
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 PROC RETURNS [iD: OISCPTypes.ConnectionID] = {
iD ← spareConnectionID;
IF (spareConnectionID ← [spareConnectionID + 1]) = OISCPTypes.ConnectionID[0] THEN
spareConnectionID ← initialSpareConnectionID;
};
This procedure inserts a connection into the connectionTable.
InsertIntoConnectionTable: PUBLIC ENTRY PROC [remote: NSAddress.NetworkAddress, remoteConnID: OISCPTypes.ConnectionID] = {
IF (index ← index + 1) > maxConnectionNumber THEN
IF CommFlags.doDebug THEN DriverDefs.Glitch[ConnectionTableFull];
ConnectionTable[index] ← ConnectionTableEntry[remote, remoteConnID];
};
This procedure removes a connection from the connectionTable.
RemoveFromConnectionTable: PUBLIC ENTRY PROC [remote: NSAddress.NetworkAddress, remoteConnID: OISCPTypes.ConnectionID] = {
FOR i: CARDINAL IN (0..index] DO
IF ConnectionTable[i].rAddr.host = remote.host AND ConnectionTable[i].rAddr.socket = remote.socket AND ConnectionTable[i].rConnID = remoteConnID THEN {
ConnectionTable[i] ← ConnectionTable[index];
index ← index - 1;
RETURN;
};
ENDLOOP;
IF CommFlags.doDebug THEN DriverDefs.Glitch[NotInConnectionTable];
};
This procedure checks if there is a similar connection in the connectionTable.
ConnectionAlreadyThere: PUBLIC ENTRY PROC [remote: NSAddress.NetworkAddress, remoteConnID: OISCPTypes.ConnectionID] RETURNS [BOOL] = {
FOR i: CARDINAL 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];
};
initialization
IF primaryMDS THEN spareConnectionID ← initialSpareConnectionID;
}.
LOG
Time: January 23, 1981 4:17 PM By: Garlick Action: added classOfService to Make.