-- File: GateStats.mesa, Last Edit: HGM March 17, 1981 7:27 PM DIRECTORY InlineDefs USING [MesaToBcplLongNumber], Process USING [Detach], AltoEthernetDefs USING [ EtherStatsEntry, EtherStatsInfo, ethernetStatsReply, etherVersion], GateControlDefs USING [pupStatsAck, pupStatsNak, pupStatsSend], PupDefs USING [ PupBuffer, ReturnFreePupBuffer, GetPupContentsBytes, PupRouterSendThis, SwapPupSourceAndDest, ReturnPup, PupSocket, PupSocketMake, veryLongWait], DriverDefs USING [Network, GetDeviceChain], PupTypes USING [statSoc, fillInPupAddress]; GateStats: PROGRAM IMPORTS InlineDefs, Process, PupDefs, DriverDefs EXPORTS DriverDefs, GateControlDefs = BEGIN OPEN PupDefs; soc: PupSocket; GateStatsOn: PUBLIC PROCEDURE = BEGIN Process.Detach[FORK Stats[]]; END; Stats: PROCEDURE = BEGIN b: PupBuffer; firstNetwork: DriverDefs.Network = DriverDefs.GetDeviceChain[]; SetupStatsEntries[]; soc ← PupSocketMake[ PupTypes.statSoc, PupTypes.fillInPupAddress, veryLongWait]; DO -- forever IF (b ← soc.get[]) # NIL THEN BEGIN SELECT b.pupType FROM GateControlDefs.pupStatsSend => BEGIN target: CARDINAL = b.pupWords[0]; network: DriverDefs.Network; IF GetPupContentsBytes[b] # 2 THEN GOTO Ignore; FOR network ← firstNetwork, network.next UNTIL network = NIL DO IF network.netNumber.b # target THEN LOOP; IF network.pupStats = NIL OR network.stats = NIL THEN GOTO Reject; IF network.pupStats[b, network] THEN GOTO Send; GOTO Reject; ENDLOOP; GOTO Reject; END; ENDCASE => GOTO Reject; EXITS Send => BEGIN -- pupLength setup already b.pupType ← GateControlDefs.pupStatsAck; SwapPupSourceAndDest[b]; PupRouterSendThis[b]; END; Reject => BEGIN ReturnPup[b, GateControlDefs.pupStatsNak, 0]; END; Ignore => BEGIN ReturnFreePupBuffer[b]; END; END; ENDLOOP; END; SetupStatsEntries: PUBLIC PROCEDURE = BEGIN network: DriverDefs.Network; FOR network ← DriverDefs.GetDeviceChain[], network.next UNTIL network = NIL DO SELECT network.device FROM ethernet, ethernetOne => network.pupStats ← EthernetStats; ENDCASE; ENDLOOP; END; EthernetStats: PUBLIC PROCEDURE [b: PupBuffer, network: DriverDefs.Network] RETURNS [BOOLEAN] = BEGIN OPEN AltoEthernetDefs; ese: LONG POINTER TO EtherStatsEntry; esi: LONG POINTER TO EtherStatsInfo ← network.stats; b.pupWords[0] ← ethernetStatsReply; ese ← LOOPHOLE[@b.pupWords[1]]; ese↑ ← [version: etherVersion, packetsSent: InlineDefs.MesaToBcplLongNumber[esi.packetsSent], badSendSatus: InlineDefs.MesaToBcplLongNumber[esi.badSendSatus], overruns: InlineDefs.MesaToBcplLongNumber[esi.overruns], packetsRecv: InlineDefs.MesaToBcplLongNumber[esi.packetsRecv], badRecvStatus: InlineDefs.MesaToBcplLongNumber[esi.badRecvStatus], inputOff: InlineDefs.MesaToBcplLongNumber[esi.inputOff], loadTable:]; FOR i: CARDINAL IN [0..16] DO ese.loadTable[i] ← InlineDefs.MesaToBcplLongNumber[esi.loadTable[i]]; ENDLOOP; b.pupLength ← 22 + 2 + 2*SIZE[EtherStatsEntry]; RETURN[TRUE]; END; GateStatsOn[]; END.