-- File: Breather.mesa - last edit: -- AOF 3-Feb-88 13:12:06 -- HGM 6-Aug-85 21:02:18 -- Copyright (C) 1983, 1985, 1988 by Xerox Corporation. All rights reserved. DIRECTORY Inline USING [LongCOPY], Process USING [Detach, SetTimeout, MsecToTicks], Buffer USING [AccessHandle, Buffer, DestroyPool, GetBuffer, MakePool], BootServerDefs USING [statLife], DiskLessDefs USING [GetPointerToBootLoader], Driver USING [Device, GetDeviceChain], EthernetOneDriverTypes USING [Encapsulation, ethernetOneBootLoaderHost], Protocol1 USING [GetContext], PupRouterDefs USING [NetworkContext], Stats USING [StatIncr]; Breather: MONITOR IMPORTS Inline, Process, Buffer, Driver, BootServerDefs, DiskLessDefs, Protocol1, Stats EXPORTS BootServerDefs, Buffer = BEGIN Device: PUBLIC <<Buffer>> TYPE = Driver.Device; breatherRunning, breatherStop: BOOLEAN ← FALSE; delay: CONDITION; bytesInBOLPacket: NATURAL = 512; -- 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; firstDevice: Device = Driver.GetDeviceChain[]; bootLoader: POINTER ← DiskLessDefs.GetPointerToBootLoader[]; FOR network: Device ← firstDevice, 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: Device ← firstDevice, 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, TRUE, bytesInBOLPacket]; b.fo.driver.length ← bytesInBOLPacket; -- the boot loader has the encapsulation in it already Inline.LongCOPY[ from: bootLoader, nwords: bytesInBOLPacket / 2, to: @b.linkLayer.blockPointer]; LOOPHOLE[ b.linkLayer.blockPointer, LONG POINTER TO EthernetOneDriverTypes.Encapsulation]↑ ← [ ethernetOne[ ethernetOneDest: EthernetOneDriverTypes.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.