-- File: Breather.mesa, Last Edit: HGM February 10, 1981 5:28 PM DIRECTORY Process USING [Detach, SetTimeout, MsecToTicks], CommUtilDefs USING [CopyLong], BootServerDefs USING [statLife], DiskLessDefs USING [GetPointerToBootLoader], StatsDefs USING [StatIncr], DriverDefs USING [Network, GetDeviceChain], BufferDefs USING [Buffer, GetFreeBuffer], DriverTypes USING [ethernetOneBootLoaderHost, ethernetEncapsulationOffset]; Breather: MONITOR IMPORTS Process, CommUtilDefs, BootServerDefs, DiskLessDefs, StatsDefs, DriverDefs, BufferDefs EXPORTS BootServerDefs SHARES BufferDefs = -- length and encapsulation BEGIN OPEN StatsDefs; dropDead: BOOLEAN ← FALSE; delay: CONDITION; -- This won't work with small buffers -- Send BreathOfLife RAW Packet every 5 seconds or so EthernetBreather: ENTRY PROCEDURE = BEGIN b: BufferDefs.Buffer; network, firstNetwork: DriverDefs.Network; bootLoader: POINTER ← DiskLessDefs.GetPointerToBootLoader[]; firstNetwork ← DriverDefs.GetDeviceChain[]; UNTIL dropDead DO WAIT delay; FOR network ← firstNetwork, network.next UNTIL network = NIL DO IF network.device # ethernetOne THEN LOOP; b ← BufferDefs.GetFreeBuffer[]; b.length ← 256; -- the boot loader has the encapsulation in it already CommUtilDefs.CopyLong[ from: bootLoader, nwords: 256, to: @b.encapsulation + DriverTypes.ethernetEncapsulationOffset]; b.encapsulation ← [ethernetOne[ etherSpare1:, etherSpare2:, etherSpare3:, etherSpare4:, etherSpare5:, translationWorked: TRUE, ethernetOneDest: DriverTypes.ethernetOneBootLoaderHost, ethernetOneSource: network.hostNumber, ethernetOneType: breathOfLife]]; network.sendBuffer[b]; StatIncr[BootServerDefs.statLife]; ENDLOOP; ENDLOOP; dropDead ← FALSE; END; BreatherOn: PUBLIC PROCEDURE = BEGIN Process.Detach[FORK EthernetBreather[]]; END; BreatherOff: PUBLIC ENTRY PROCEDURE = BEGIN pause: CONDITION; dropDead ← TRUE; Process.SetTimeout[@pause, Process.MsecToTicks[100]]; NOTIFY delay; WHILE dropDead DO WAIT pause; ENDLOOP; END; -- initialization Process.SetTimeout[@delay, Process.MsecToTicks[5000]]; END.