PilotCommUtilPup.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
BLyon on March 17, 1981 4:29 PM
HGM on March 14, 1981 10:07 PM
Russ Atkinson (RRA) February 2, 1985 4:21:08 pm PST
DIRECTORY
BufferDefs USING [BufferAccessHandle, OisBuffer],
CommUtilDefs USING [],
EthernetOneFace USING [DeviceHandle, GetEthernet1Address, GetNextDevice, nullDeviceHandle],
MPCodes USING [findPupAddress, emptyMP],
OISCP USING [GetFreeSendOisBufferFromPool, GetOisPacketTextLength, OiscpPackageMake, OiscpPackageDestroy, ReturnFreeOisBuffer, SetOisPacketTextLength],
OISCPConstants USING [pupAddressTranslation],
ProcessorFace USING [SetMP],
PupDefs USING [PupAddress],
Socket USING [Abort, AssignNetworkAddress, Create, Delete, GetPacket, PutPacketToAllConnectedNets, SetWaitTime, TimeOut, TransferStatus],
SocketInternal USING [GetBufferPool, SocketObject],
NSAddress USING [GetProcessorID, ProcessorID];
PilotCommUtilPup: MONITOR
IMPORTS BufferDefs, EthernetOneFace, NSAddress, OISCP, ProcessorFace, Socket, SocketInternal
EXPORTS CommUtilDefs, PupDefs, Socket
SHARES BufferDefs =
BEGIN
EXPORTED TYPEs
ChannelHandle: TYPE = REF ChannelObject;
ChannelObject: PUBLIC TYPE = SocketInternal.SocketObject;
translationRequest: CARDINAL = 1;
translationResponse: CARDINAL = 2;
translationError: CARDINAL = 3;
myHostNumber: CARDINAL ← 0;
SmashMyHostNumber: PUBLIC ENTRY PROCEDURE [new: CARDINAL] =
BEGIN
myHostNumber ← new;
END; -- SmashMyhostNumber
GetEthernetHostNumber: PUBLIC ENTRY PROCEDURE RETURNS [CARDINAL] =
BEGIN
i: CARDINAL;
cH: ChannelHandle;
myBufferAccessHandle: BufferDefs.BufferAccessHandle;
hit: BOOLEAN;
b: BufferDefs.OisBuffer;
status: Socket.TransferStatus;
where: LONG POINTER TO NSAddress.ProcessorID;
myID: NSAddress.ProcessorID;
ether: EthernetOneFace.DeviceHandle;
IF myHostNumber#0 THEN RETURN[myHostNumber]; -- easy known case
if the machine has a real ethernetOne then get the address from the device
ether ← EthernetOneFace.GetNextDevice[EthernetOneFace.nullDeviceHandle];
IF ether#EthernetOneFace.nullDeviceHandle THEN
BEGIN
net, host: [0..256);
[net, host] ← EthernetOneFace.GetEthernet1Address[ether];
RETURN[myHostNumber ← host];
END;
hard case: there is no ethernetOne, so probe for it.
ProcessorFace.SetMP[MPCodes.findPupAddress];
OISCP.OiscpPackageMake[];
cH ← Socket.Create[Socket.AssignNetworkAddress[]];
Socket.SetWaitTime[cH, 3000];
myBufferAccessHandle ← SocketInternal.GetBufferPool[cH];
myID ← NSAddress.GetProcessorID[];
logically, translate ProcessFace.ProcessorID into EthernetFace.ProcessorID
hit ← FALSE;
UNTIL hit DO
i ← i + 1;
b ← OISCP.GetFreeSendOisBufferFromPool[myBufferAccessHandle];
OISCP.SetOisPacketTextLength[b, 2*(3+SIZE[NSAddress.ProcessorID])];
b.ois.transCntlAndPktTp.packetType ← pupAddrTransPacket;
b.ois.destination.socket ← OISCPConstants.pupAddressTranslation;
b.ois.oisWords[0] ← b.ois.oisWords[1] ← i;
b.ois.oisWords[2] ← translationRequest;
where ← LOOPHOLE[@b.ois.oisWords[3]];
where^ ← myID;
Socket.PutPacketToAllConnectedNets[cH, b];
UNTIL hit DO
b ← Socket.GetPacket[cH ! Socket.TimeOut => EXIT];
status ← LOOPHOLE[b.status];
IF (status = goodCompletion)
AND (OISCP.GetOisPacketTextLength[b] >= 2*(3 + SIZE[PupDefs.PupAddress]))
AND (b.ois.oisWords[2] = translationResponse) THEN
BEGIN -- the response we were looking for
myLoc: LONG POINTER TO PupDefs.PupAddress = LOOPHOLE[@b.ois.oisWords[3]];
me: PupDefs.PupAddress ← myLoc^;
myHostNumber ← me.host;
hit ← TRUE;
END;
OISCP.ReturnFreeOisBuffer[b];
ENDLOOP;
ENDLOOP;
Socket.Abort[cH];
Socket.Delete[cH];
OISCP.OiscpPackageDestroy[];
ProcessorFace.SetMP[MPCodes.emptyMP];
RETURN[myHostNumber];
END; -- GetEthernetHostNumber
END..