-- PilotCommUtilPup.mesa -- BLyon on March 17, 1981 4:29 PM -- HGM on March 14, 1981 10:07 PM 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], OISCPConstantsAdditions USING [pupAddressTranslation], OISCPTypesAdditions USING [pupAddrTransPacket], 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 ← OISCPTypesAdditions.pupAddrTransPacket; b.ois.destination.socket ← OISCPConstantsAdditions.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..