-- 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.