-- Copyright (C) 1983, 1985 by Xerox Corporation. All rights reserved. -- Breather.mesa, HGM, 6-Aug-85 21:02:18 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], Protocol1 USING [GetContext], PupRouterDefs USING [NetworkContext], Stats USING [StatIncr]; Breather: MONITOR IMPORTS Inline, Process, Buffer, Driver, BootServerDefs, DiskLessDefs, Protocol1, Stats EXPORTS Buffer, BootServerDefs = BEGIN Network: PUBLIC TYPE = Driver.Network; 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 context: PupRouterDefs.NetworkContext ← Protocol1.GetContext[network, pup]; IF context = NIL THEN LOOP; IF network.device # ethernetOne THEN LOOP; b ← Buffer.GetBuffer[vagrant, 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: context.pupHostNumber, ethernetOneType: breathOfLife]]; network.sendRawBuffer[b]; Stats.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.