-- Copyright (C) 1983 by Xerox Corporation. All rights reserved. -- Breather.mesa, HGM, 5-Oct-83 20:26:19 DIRECTORY Inline USING [LongCOPY], Process USING [Detach, SetTimeout, MsecToTicks], Buffer USING [AccessHandle, Buffer, DestroyPool, GetBuffer, MakePool], BootServerDefs USING [statLife], DiskLessDefs USING [GetPointerToBootLoader], Driver USING [Network, GetDeviceChain], DriverTypes USING [ethernetOneBootLoaderHost, ethernetOneEncapsulationOffset], Stats USING [StatIncr]; Breather: MONITOR IMPORTS Inline, Process, Buffer, Driver, BootServerDefs, DiskLessDefs, Stats EXPORTS BootServerDefs = BEGIN OPEN Stats; breatherRunning, breatherStop: BOOLEAN ← FALSE; delay: CONDITION; -- Send BreathOfLife RAW Packet every 5 seconds or so EthernetBreather: ENTRY PROCEDURE = BEGIN pool: Buffer.AccessHandle ← Buffer.MakePool[send: 1, receive: 0]; b: Buffer.Buffer; firstNetwork: Driver.Network = Driver.GetDeviceChain[]; bootLoader: POINTER ← DiskLessDefs.GetPointerToBootLoader[]; FOR network: Driver.Network ← firstNetwork, network.next UNTIL network = NIL DO IF network.device = ethernetOne THEN EXIT; REPEAT FINISHED => BEGIN breatherRunning ← FALSE; RETURN; END; ENDLOOP; UNTIL breatherStop DO WAIT delay; FOR network: Driver.Network ← firstNetwork, network.next UNTIL network = NIL DO IF network.device # ethernetOne THEN LOOP; b ← Buffer.GetBuffer[raw, pool, send]; b.driver.length ← 256; -- the boot loader has the encapsulation in it already Inline.LongCOPY[ from: bootLoader, nwords: 256, to: @b.encapsulation + DriverTypes.ethernetOneEncapsulationOffset]; b.encapsulation ← [ ethernetOne[ etherSpare1:, etherSpare2:, etherSpare3:, etherSpare4:, etherSpare5:, translationWorked: TRUE, ethernetOneDest: DriverTypes.ethernetOneBootLoaderHost, ethernetOneSource: network.pupHostNumber, ethernetOneType: breathOfLife]]; network.sendRawBuffer[b]; StatIncr[BootServerDefs.statLife]; ENDLOOP; ENDLOOP; breatherRunning ← FALSE; Buffer.DestroyPool[pool]; END; BreatherOn: PUBLIC PROCEDURE = BEGIN breatherStop ← FALSE; breatherRunning ← TRUE; Process.Detach[FORK EthernetBreather[]]; END; BreatherOff: PUBLIC ENTRY PROCEDURE = BEGIN pause: CONDITION; breatherStop ← TRUE; Process.SetTimeout[@pause, Process.MsecToTicks[100]]; NOTIFY delay; WHILE breatherRunning DO WAIT pause; ENDLOOP; END; -- initialization Process.SetTimeout[@delay, Process.MsecToTicks[5000]]; END.