-- Copyright (C) 1984, 1985 by Xerox Corporation. All rights reserved. -- DeviceInfo.mesa, HGM, 6-Aug-85 21:02:35 DIRECTORY Format USING [], -- needed by Put.Date and friends Heap USING [systemZone], Menu USING [ItemObject, MCRType, Create, Instantiate], Process USING [Yield], Put USING [ CR, Char, Date, HostNumber, LongDecimal, NetworkNumber, Number, Text], String USING [AppendChar, AppendNumber, AppendString], System USING [HostNumber, localHostNumber, NetworkNumber, nullHostNumber], Time USING [Current], UserInput USING [GetDefaultWindow], Window USING [Handle], Buffer USING [], Driver USING [GetDeviceChain, Network], EthernetDriverFriends USING [EtherStatsInfo], PhoneNetFriends USING [PhoneNetInfo, StatsPtrToStats], PhoneNetExtras USING [ leafBytesSend, leafDupsFiltered, leafPktsSend, nsBytesSend, nsCongestion, nsDupsFiltered, nsTooGreedy, pupBytesSend, pupCongestion, pupDupsFiltered, pupTooGreedy], Protocol1 USING [GetContext], PupRouterDefs USING [NetworkContext], RoutingTable USING [NetworkContext]; DeviceInfo: PROGRAM IMPORTS Heap, Menu, Process, Put, String, System, Time, UserInput, Driver, Protocol1, PhoneNetFriends EXPORTS Buffer = BEGIN Network: PUBLIC TYPE = Driver.Network; z: UNCOUNTED ZONE = Heap.systemZone; DoMenu: Menu.MCRType = BEGIN firstNetwork: Driver.Network ← Driver.GetDeviceChain[]; device: CARDINAL ← 0; FOR network: Driver.Network ← firstNetwork, network.next UNTIL network = NIL DO IF index = device THEN BEGIN SELECT network.device FROM ethernet, ethernetOne => ShowEthernet[NIL, network]; phonenet => ShowPhoneNet[NIL, network]; ENDCASE => ERROR; RETURN; END; device ← device + 1; ENDLOOP; END; ShowEthernet: PROCEDURE [wh: Window.Handle, network: Driver.Network] = BEGIN pup: PupRouterDefs.NetworkContext ← Protocol1.GetContext[network, pup]; ns: RoutingTable.NetworkContext ← Protocol1.GetContext[network, ns]; stats: LONG POINTER TO EthernetDriverFriends.EtherStatsInfo ← network.stats; PrintHeader[wh, "Ethernet"L, FALSE]; IF network.device = ethernetOne THEN Put.Text[wh, "One"L]; Put.Text[wh, " Statistics for "L]; Put.Number[wh, pup.pupNetNumber, [8, FALSE, TRUE, 0]]; Put.Text[wh, "#"L]; Put.Number[wh, pup.pupHostNumber, [8, FALSE, TRUE, 0]]; Put.Text[wh, "#, NS net "L]; PutNetNumbers[wh, ns.netNumber]; Put.CR[wh]; IF stats = NIL THEN RETURN; Put.Text[wh, "Rcv: pkts "L]; Put.LongDecimal[wh, stats.packetsRecv]; Put.Text[wh, ", words "L]; Put.LongDecimal[wh, stats.wordsRecv]; Put.Text[wh, ", bad "L]; Put.LongDecimal[wh, stats.badRecvStatus]; Put.Text[wh, ", missed "L]; Put.LongDecimal[wh, stats.packetsMissed]; Put.CR[wh]; IF stats.badRecvStatus # 0 OR stats.okButDribble # 0 THEN BEGIN Put.Text[wh, " crc "L]; Put.LongDecimal[wh, stats.badCrc]; Put.Text[wh, ", bad alignment but ok crc "L]; Put.LongDecimal[wh, stats.badAlignmentButOkCrc]; Put.Text[wh, ", crc and bad alignment "L]; Put.LongDecimal[wh, stats.crcAndBadAlignment]; Put.CR[wh]; Put.Text[wh, " ok but dribble "L]; Put.LongDecimal[wh, stats.okButDribble]; Put.Text[wh, ", too long "L]; Put.LongDecimal[wh, stats.packetTooLong]; Put.Text[wh, ", overrun "L]; Put.LongDecimal[wh, stats.overrun]; Put.Text[wh, ", idle "L]; Put.LongDecimal[wh, stats.idleInput]; Put.CR[wh]; END; Put.Text[wh, "Xmit: pkts "L]; Put.LongDecimal[wh, stats.packetsSent]; Put.Text[wh, ", words "L]; Put.LongDecimal[wh, stats.wordsSent]; Put.Text[wh, ", bad "L]; Put.LongDecimal[wh, stats.badSendStatus]; Put.CR[wh]; IF stats.badSendStatus # 0 OR stats.tooManyCollisions # 0 THEN BEGIN Put.Text[wh, " underrun "L]; Put.LongDecimal[wh, stats.underrun]; Put.Text[wh, ", stuck "L]; Put.LongDecimal[wh, stats.stuckOutput]; Put.Text[wh, ", too many collisions "L]; Put.LongDecimal[wh, stats.tooManyCollisions]; Put.CR[wh]; END; Put.Text[wh, "Lds:"L]; FOR i: CARDINAL IN [0..16) DO Put.Char[wh, ' ]; Put.LongDecimal[wh, stats.loadTable[i]]; ENDLOOP; Put.CR[wh]; END; ShowPhoneNet: PROCEDURE [wh: Window.Handle, network: Driver.Network] = BEGIN pup: PupRouterDefs.NetworkContext ← Protocol1.GetContext[network, pup]; ns: RoutingTable.NetworkContext ← Protocol1.GetContext[network, ns]; stats: PhoneNetFriends.PhoneNetInfo ← PhoneNetFriends.StatsPtrToStats[network.stats]; PrintHeader[wh, "PhoneNet"L, FALSE]; Put.Text[wh, " Statistics for "L]; Put.Number[wh, pup.pupNetNumber, [8, FALSE, TRUE, 0]]; Put.Text[wh, "#"L]; Put.Number[wh, pup.pupHostNumber, [8, FALSE, TRUE, 0]]; Put.Text[wh, "#, NS net "L]; PutNetNumbers[wh, ns.netNumber]; Put.Text[wh, ", Line "L]; Put.LongDecimal[wh, network.lineNumber]; Put.Text[wh, ", "L]; Put.LongDecimal[wh, network.lineSpeed]; Put.Text[wh, "KB"L]; SELECT TRUE FROM stats.remoteHostNumber = System.nullHostNumber => Put.Text[wh, " Down"L]; stats.remoteHostNumber = System.localHostNumber => Put.Text[wh, " Looped"L]; ENDCASE => BEGIN Put.CR[wh]; Put.Text[wh, "Up to "L]; PutHostNumbers[wh, stats.remoteHostNumber]; END; Put.CR[wh]; Put.Text[wh, "Recv: pkts "L]; Put.LongDecimal[wh, stats.stats[pktsReceived]]; Put.Text[wh, ", bytes "L]; Put.LongDecimal[wh, stats.stats[bytesReceived]]; Put.Text[wh, ", rejected "L]; Put.LongDecimal[wh, stats.stats[pktsRejected]]; Put.Text[wh, ", missed "L]; Put.LongDecimal[wh, stats.stats[rcvErrorNoGet]]; Put.Text[wh, ", idle "L]; Put.LongDecimal[wh, stats.stats[tooLongSinceLastReceive]]; Put.CR[wh]; Put.Text[wh, " Bad crc "L]; Put.LongDecimal[wh, stats.stats[rcvErrorCRC]]; Put.Text[wh, ", data lost "L]; Put.LongDecimal[wh, stats.stats[rcvErrorDataLost]]; Put.Text[wh, ", device error "L]; Put.LongDecimal[wh, stats.stats[rcvDeviceError]]; Put.Text[wh, ", timeout "L]; Put.LongDecimal[wh, stats.stats[rcvErrorFrameTimeout]]; Put.Text[wh, ", other error "L]; Put.LongDecimal[wh, stats.stats[rcvErrorUnknown]]; Put.CR[wh]; Put.Text[wh, "Send: pkts "L]; Put.LongDecimal[wh, stats.stats[pktsSent]]; Put.Text[wh, ", bytes "L]; Put.LongDecimal[wh, stats.stats[bytesSent]]; Put.CR[wh]; Put.Text[wh, " NS "L]; Put.LongDecimal[wh, stats.stats[nsSent]]; Put.Text[wh, " "L]; Put.LongDecimal[wh, stats.stats[PhoneNetExtras.nsBytesSend]]; Put.Text[wh, ", Pups "L]; Put.LongDecimal[wh, stats.stats[pupSent]]; Put.Text[wh, " "L]; Put.LongDecimal[wh, stats.stats[PhoneNetExtras.pupBytesSend]]; Put.Text[wh, ", Leaf "L]; Put.LongDecimal[wh, stats.stats[PhoneNetExtras.leafPktsSend]]; Put.Text[wh, " "L]; Put.LongDecimal[wh, stats.stats[PhoneNetExtras.leafBytesSend]]; Put.CR[wh]; IF stats.stats[sendErrorBadStatus] # 0 OR stats.stats[queueTooOld] # 0 THEN { Put.Text[wh, " Bad "L]; Put.LongDecimal[wh, stats.stats[sendErrorBadStatus]]; Put.Text[wh, ", stuck "L]; Put.LongDecimal[wh, stats.stats[queueTooOld]]; Put.CR[wh]; }; Put.Text[wh, " Queue too long "L]; Put.LongDecimal[wh, stats.stats[congestion]]; Put.Text[wh, ", NS "L]; Put.LongDecimal[wh, stats.stats[PhoneNetExtras.nsCongestion]]; Put.Text[wh, " Pup "L]; Put.LongDecimal[wh, stats.stats[PhoneNetExtras.pupCongestion]]; Put.CR[wh]; Put.Text[wh, " Conn too greedy "L]; Put.LongDecimal[wh, stats.stats[connTooGreedy]]; Put.Text[wh, ", NS "L]; Put.LongDecimal[wh, stats.stats[PhoneNetExtras.nsTooGreedy]]; Put.Text[wh, ", Pup "L]; Put.LongDecimal[wh, stats.stats[PhoneNetExtras.pupTooGreedy]]; Put.CR[wh]; IF stats.stats[PhoneNetExtras.nsDupsFiltered] # 0 THEN { Put.Text[wh, " NS duplicates discarded: "L]; Put.LongDecimal[wh, stats.stats[PhoneNetExtras.nsDupsFiltered]]; Put.CR[wh]; }; IF stats.stats[PhoneNetExtras.pupDupsFiltered] # 0 THEN { Put.Text[wh, " BSP probes/duplicates discarded: "L]; Put.LongDecimal[wh, stats.stats[PhoneNetExtras.pupDupsFiltered]]; Put.CR[wh]; }; IF stats.stats[PhoneNetExtras.leafDupsFiltered] # 0 THEN { Put.Text[wh, " Leaf duplicates discarded: "L]; Put.LongDecimal[wh, stats.stats[PhoneNetExtras.leafDupsFiltered]]; Put.CR[wh]; }; END; PutHostNumbers: PROCEDURE [wh: Window.Handle, net: System.HostNumber] = BEGIN Put.HostNumber[wh, net, productSoftware]; Put.Text[wh, "="L]; Put.HostNumber[wh, net, octal]; END; PutNetNumbers: PROCEDURE [wh: Window.Handle, net: System.NetworkNumber] = BEGIN Put.NetworkNumber[wh, net, productSoftware]; Put.Text[wh, "="L]; Put.NetworkNumber[wh, net, octal]; END; PrintHeader: PROCEDURE [wh: Window.Handle, s: LONG STRING, cr: BOOLEAN ← TRUE] = BEGIN Put.CR[wh]; Put.Date[wh, Time.Current[], dateTime]; Put.Text[wh, " "L]; Put.Text[wh, s]; IF cr THEN Put.CR[wh]; END; DoSomeYields: PROCEDURE = BEGIN THROUGH [0..100) DO Process.Yield[]; ENDLOOP; END; SetupDeviceMenu: PUBLIC PROCEDURE = BEGIN Items: TYPE = RECORD[SEQUENCE COMPUTED CARDINAL OF Menu.ItemObject]; items: LONG POINTER TO Items; firstNetwork: Driver.Network ← Driver.GetDeviceChain[]; devices: CARDINAL ← 0; FOR network: Driver.Network ← firstNetwork, network.next UNTIL network = NIL DO devices ← devices + 1; ENDLOOP; items ← z.NEW[Items[devices]]; devices ← 0; FOR network: Driver.Network ← firstNetwork, network.next UNTIL network = NIL DO context: PupRouterDefs.NetworkContext ← Protocol1.GetContext[network, pup]; tag: STRING = [30]; new: LONG STRING; SELECT network.device FROM ethernetOne => String.AppendString[tag, "Ether1"L]; ethernet => String.AppendString[tag, "Ether"L]; phonenet => String.AppendString[tag, "PhoneNet"L]; ENDCASE => ERROR; String.AppendChar[tag, '-]; String.AppendNumber[tag, context.pupNetNumber, 8]; new ← z.NEW[StringBody[tag.length]]; String.AppendString[new, tag]; items[devices] ← [new, DoMenu]; devices ← devices + 1; ENDLOOP; Menu.Instantiate[ Menu.Create[DESCRIPTOR[items, devices], "DeviceInfo"], UserInput.GetDefaultWindow[]]; END; -- Initialization SetupDeviceMenu[]; END.