DIRECTORY Atom, BasicTime USING [Now], Booting USING [switches], Buttons USING [ButtonProc], Commander USING [CommandProc, Handle, Register], Containers USING [ChildXBound, ChildYBound], DebuggerSwap USING [CallDebugger], FS USING [Error, SetKeep], IO, Labels USING [Create], Loader USING [BCDBuildTime, MakeGlobalFrameResident, MakeProcedureResident], Menus USING [Menu, MenuProc, AppendMenuEntry, CreateEntry, CreateMenu], ProcessorFace USING [processorID], Rope USING [ROPE, Length], Rules USING [Create], TypeScript USING [Create], SystemVersion USING [machineType], VFonts, ViewerIO USING [CreateViewerStreams], ViewerOps, Unformat USING [HostNumberToRope], NSPilotSystem USING [HostNumber], NewEthernetFace USING [Status, GetPacketLength, GetStatus, GetRetries, TurnOn], EtherTesterOps USING [ StartTest, StopTheWorld, DontBeAHog, InitializeCSBs, CleanThingsUp, Buffer, Pattern, activeProcesses, HWTestMode], EtherTesterViewer; EtherTesterControlImpl: MONITOR IMPORTS BasicTime, Booting, Commander, Containers, DebuggerSwap, FS, IO, Labels, Loader, Menus, ProcessorFace, Rope, Rules, SystemVersion, TypeScript, Unformat, ViewerIO, ViewerOps, NewEthernetFace, EtherTesterOps, EtherTesterViewer EXPORTS EtherTesterOps, EtherTesterViewer = BEGIN OPEN IO, EtherTesterViewer; ROPE: TYPE = Rope.ROPE; counter: PUBLIC ARRAY [0..8) OF INT; tsOut: PUBLIC STREAM_ NIL; me, source, dest: PUBLIC NSPilotSystem.HostNumber_ LOOPHOLE[ProcessorFace.processorID]; recvSize: PUBLIC CARDINAL_ defaultRecvSize; sendSize: PUBLIC CARDINAL_ defaultSendSize; ticksBeforeSend: PUBLIC CARDINAL_ defaultTicksBeforeSend; promiscuous: PUBLIC BOOLEAN _ FALSE; broadcasting: PUBLIC BOOLEAN _ FALSE; check: PUBLIC BOOLEAN _ FALSE; flipem: PUBLIC BOOLEAN _ FALSE; doChecksum: PUBLIC BOOLEAN _ TRUE; doStats: PUBLIC BOOLEAN _ TRUE; showRunts, showGarbage, dallyBeforeOutput: PUBLIC BOOLEAN _ FALSE; defaultNumberOfRecvBuffers: CARDINAL = 6; numberOfRecvBuffers: PUBLIC CARDINAL _ defaultNumberOfRecvBuffers; defaultNumberOfSendBuffers: CARDINAL = 1; numberOfSendBuffers: PUBLIC CARDINAL _ defaultNumberOfSendBuffers; showStrangeStatus, showWrongLength: PUBLIC BOOLEAN _ TRUE; showWrongData, showOnlyBadAlign: PUBLIC BOOLEAN _ TRUE; bumpPacketNumber, dallyIfBehind: PUBLIC BOOLEAN _ TRUE; hwMode: PUBLIC EtherTesterOps.HWTestMode_ normal; defNumOfRecvBuffers: ROPE = "6"; defNumOfSendBuffers: ROPE = "1"; etherNetBoard: CARDINAL _ defaultEtherNetBoard; herald: ROPE; etherTesterLogName: ROPE = "EtherTester.log"; okToRun: BOOL_ FALSE; etherTesterController: Viewer_ NIL; testerTS: Viewer_ NIL; boardNum, sourceHost, destHost, myHost: PUBLIC ButtonItem_ NIL; numRecvBuffers, inputBuffLen, numSendBuffers, outputBuffLen: PUBLIC ButtonItem_ NIL; ticksBefore: PUBLIC ButtonItem_ NIL; statsDisplayer: PUBLIC StatsItem; defaultEtherNetBoard: CARDINAL = 1; defaultRecvSize: CARDINAL = 2020; defaultSendSize: CARDINAL = 2000; defaultTicksBeforeSend: CARDINAL = 0; defEtherNetBoard: ROPE = "1"; defRecvSize: ROPE = "2020"; defSendSize: ROPE = "2000"; defTicksBeforeSend: ROPE = "0"; myHostNumber: ROPE; sourceHostNumber: ROPE; destHostNumber: ROPE; ParseError: PUBLIC SIGNAL = CODE; pattern: PUBLIC EtherTesterOps.Pattern _ ignore; patternButton, hwModeButton: PUBLIC Viewer; noE2Board: ROPE = "**************** Can't find specified Ethernet(2) board."; Stop: ENTRY Menus.MenuProc = TRUSTED BEGIN EtherTesterOps.StopTheWorld[]; ViewerOps.SetMenu[etherTesterController, readyMenu]; END; Send: ENTRY Buttons.ButtonProc = TRUSTED BEGIN IF ComplainIfRunningAndSuch["\nSending..."] THEN RETURN; PrintDest[]; IF ~EtherTesterOps.StartTest[SendOnly, etherNetBoard] THEN Trouble[noE2Board]; END; Recv: ENTRY Buttons.ButtonProc = TRUSTED BEGIN IF ComplainIfRunningAndSuch["\nReceiving..."] THEN RETURN; PrintSource[]; IF ~EtherTesterOps.StartTest[ReceiveOnly, etherNetBoard] THEN Trouble[noE2Board]; END; SendAndRecv: ENTRY Buttons.ButtonProc = TRUSTED BEGIN IF ComplainIfRunningAndSuch["\nSending and Receiving..."] THEN RETURN; PrintSource[]; PrintDest[]; IF ~EtherTesterOps.StartTest[SendAndReceive, etherNetBoard] THEN Trouble[noE2Board]; END; EchoServer: ENTRY Buttons.ButtonProc = TRUSTED BEGIN IF ComplainIfRunningAndSuch["\nEcho Server..."] THEN RETURN; PrintSource[]; PrintDest[]; IF ~EtherTesterOps.StartTest[EchoServer, etherNetBoard] THEN Trouble[noE2Board]; END; EchoUser: ENTRY Buttons.ButtonProc = TRUSTED BEGIN IF ComplainIfRunningAndSuch["\nEcho User..."] THEN RETURN; PrintSource[]; PrintDest[]; IF ~EtherTesterOps.StartTest[EchoUser, etherNetBoard] THEN Trouble[noE2Board]; END; Quit: ENTRY Buttons.ButtonProc = TRUSTED BEGIN xx: Viewer_ etherTesterController; IF ComplainIfRunningAndSuch["\nQuit...", TRUE] THEN RETURN; tsOut.Close[]; EtherTesterOps.CleanThingsUp[]; etherTesterController_ NIL; xx.inhibitDestroy_ FALSE; ViewerOps.DestroyViewer[xx]; END; syntaxError: ROPE = "Syntax error in "; ComplainIfRunningAndSuch: INTERNAL PROC[header: ROPE, stopping: BOOL _ FALSE] RETURNS[notOK: BOOL] = BEGIN ENABLE UNWIND => NULL; BEGIN IF EtherTesterOps.activeProcesses # 0 THEN { tsOut.PutRope["A test is already running. Please Stop it first."]; RETURN[TRUE]}; IF stopping THEN { tsOut.PutRope[header]; RETURN[FALSE] }; ViewerOps.SetMenu[etherTesterController, stopMenu]; source_ ReadHostNum[sourceHost.text ! ParseError => {Trouble[syntaxError, "Source."]; GOTO quitThis}]; dest_ ReadHostNum[destHost.text ! ParseError => {Trouble[syntaxError, "Dest."]; GOTO quitThis}]; me_ ReadHostNum[myHost.text ! ParseError => {Trouble[syntaxError, "MyHostNmber."]; GOTO quitThis}]; etherNetBoard_ ReadCard[boardNum ! ParseError => {Trouble[syntaxError, "etherNet board number."]; GOTO quitThis}]; ticksBeforeSend_ ReadCard[ticksBefore ! ParseError => {Trouble[syntaxError, "ticksBeforeSend."]; GOTO quitThis}]; numberOfRecvBuffers_ ReadCard[numRecvBuffers ! ParseError => {Trouble[syntaxError, "number of Receive buffers."]; GOTO quitThis}]; recvSize_ ReadCard[inputBuffLen ! ParseError => {Trouble[syntaxError, "input buffer length."]; GOTO quitThis}]; numberOfSendBuffers_ ReadCard[numSendBuffers ! ParseError => {Trouble[syntaxError, "number of send buffers."]; GOTO quitThis}]; sendSize_ ReadCard[outputBuffLen ! ParseError => {Trouble[syntaxError, "output buffer length."]; GOTO quitThis}]; IF recvSize < 6 THEN {Trouble[PutFR["Input buffer too small (%g < 6).", int[recvSize]]]; RETURN[TRUE]}; IF recvSize > 3100 THEN {Trouble[PutFR["Input buffer too big ( %g > 3100).", int[recvSize]]]; RETURN[TRUE]}; IF sendSize > 3000 THEN {Trouble[PutFR["Output buffer too big (%g > 3000).", int[sendSize]]]; RETURN[TRUE]}; IF sendSize < 7 THEN {Trouble[PutFR["Output buffer too small (%g < 7).", int[sendSize]]]; RETURN[TRUE]}; tsOut.PutRope[header]; tsOut.PutRope[PutFR["\n%g Running.....\n", IO.time[]]]; IF sendSize < 30 THEN tsOut.PutRope[ "\n***** Warning: Sending packets shorter than allowed by Ethernet Spec. (30 words)"]; IF sendSize > 757 THEN tsOut.PutRope[ "\n***** Warning: Sending packets longer than allowed by Ethernet Spec. (757 words)"]; RETURN[FALSE] EXITS quitThis => RETURN[TRUE]; END; END; PrintDest: PROC = BEGIN SELECT TRUE FROM broadcasting => tsOut.PutRope["\nOutput packets will be BROADCAST!\n"]; dest = me => tsOut.PutRope["\nOutput packets will be sent to me.\n"]; ENDCASE => tsOut.PutF["\nOutput packets will be sent to %g.\n", rope[Unformat.HostNumberToRope[dest]]]; IF check THEN tsOut.PutRope["Output data will be formatted.\n"]; tsOut.PutF["Output packet length is %d words.\n", int[sendSize]]; END; PrintSource: PROC = BEGIN IF promiscuous THEN tsOut.PutRope["\nReading everything.\n"] ELSE tsOut.PutRope["\nReading just packets for me.\n"]; IF check THEN tsOut.PutRope["Input data will be checked.\n"]; tsOut.PutF["Input buffer length is %d words.\n", int[recvSize]]; END; blankMenu: Menus.Menu_ Menus.CreateMenu[]; stopMenu: Menus.Menu_ Menus.CreateMenu[]; readyMenu: Menus.Menu_ Menus.CreateMenu[]; BuildController: INTERNAL PROC = BEGIN xx, zz: Viewer; IF etherTesterController # NIL THEN RETURN; xx_ ViewerOps.CreateViewer[ flavor: $Container, info: [name: "Ether Tester", iconic: FALSE, column: left, scrollable: FALSE]]; xx.inhibitDestroy_ TRUE; ViewerOps.SetMenu[xx, blankMenu]; zz_ Labels.Create[ info: [name: " Black background means TRUE; White background means FALSE", parent: xx, wx: 5, wy: 3, wh: entryHeight, border: FALSE]]; zz_ Rules.Create[info: [parent: xx, wy: zz.wy+zz.wh+4, ww: xx.ww, wh: 1]]; Containers.ChildXBound[xx, zz]; zz_ MakeBoolItem[name: "ShowRunts", proc: ShowRunts, sib: zz, init: showRunts, newLine: TRUE]; zz_ MakeBoolItem[name: "ShowGarbage", proc: ShowGarbage, sib: zz, init: showGarbage]; zz_ MakeBoolItem[name: "ShowStrange", proc: ShowStrange, sib: zz, init: showStrangeStatus]; zz_ MakeBoolItem[name: "ShowWrongLength", proc: ShowWrongLength, sib: zz, init: showWrongLength]; zz_ MakeBoolItem[name: "ShowWrongData", proc: ShowWrongData, sib: zz, init: showWrongData]; zz_ MakeBoolItem[name: "ShowOnlyBadAlign", proc: ShowOnlyBadAlign, sib: zz, init: showOnlyBadAlign, newLine: TRUE]; zz_ MakeBoolItem[name: "DoChecksum", proc: DoChecksum, sib: zz, init: doChecksum]; zz_ MakeBoolItem[name: "DoStats", proc: DoStats, sib: zz, init: doStats]; zz_ MakeBoolItem[name: "CheckInput", proc: CheckInput, sib: zz, init: check]; zz_ MakeBoolItem[name: "BumpPacketNumber", proc: BumpPacketNumber, sib: zz, init: bumpPacketNumber]; zz_ MakeBoolItem[name: "DallyIfBehind", proc: DallyIfBehind, sib: zz, init: dallyIfBehind, newLine: TRUE]; zz_ MakeBoolItem[name: "DallyBeforeOutput", proc: DallyBeforeOutput, sib: zz, init: dallyBeforeOutput]; zz_ MakeBoolItem[name: "Promiscuous", proc: Promiscuous, sib: zz, init: promiscuous]; zz_ MakeBoolItem[name: "Broadcasting", proc: Broadcasting, sib: zz, init: broadcasting]; boardNum_ ButtonAndText[name: "Board #:", sib: zz, width: 40, default: defEtherNetBoard, valType: cardinal, newLine: TRUE]; ticksBefore_ ButtonAndText[name: "TicksBeforeSend ", sib: boardNum.text, width: 60, default: defTicksBeforeSend, valType: cardinal]; PatternButton[sib: ticksBefore.text]; HWModeButton[sib: patternButton]; sourceHost_ ButtonAndText[name: "Source: ", sib: ticksBefore.text, width: 100, default: sourceHostNumber, valType: hostNum, newLine: TRUE]; destHost_ ButtonAndText[name: "Dest: ", sib: sourceHost.text, width: 100, default: destHostNumber, valType: hostNum]; myHost_ ButtonAndText[name: "Me: ", sib: destHost.text, width: 100, default: myHostNumber, valType: hostNum]; numRecvBuffers_ ButtonAndText[name: "NumberOfRecvBuffers: ", sib: myHost.text, width: 40, newLine: TRUE, default: defNumOfRecvBuffers, valType: cardinal]; inputBuffLen_ ButtonAndText[name: "InputBufferLength: ", sib: numRecvBuffers.text, width: 100, default: defRecvSize, valType: cardinal]; numSendBuffers_ ButtonAndText[name: "NumberOfSendBuffers: ", sib: inputBuffLen.text, width: 40, newLine: TRUE, default: defNumOfSendBuffers, valType: cardinal]; outputBuffLen_ ButtonAndText[name: "OutputBufferLength: ", sib: numSendBuffers.text, width: 100, default: defRecvSize, valType: cardinal]; zz_ outputBuffLen.text; zz_ Rules.Create[ info: [parent: xx, wy: zz.wy+zz.wh+3, ww: xx.ww, wh: 1]]; Containers.ChildXBound[xx, zz]; MakeStatsDisplayers[zz.wy + zz.wh + xFudge, xx]; zz_ statsDisplayer.label; zz_ Rules.Create[ info: [parent: xx, wy: zz.wy+zz.wh+3, ww: xx.ww, wh: 1]]; Containers.ChildXBound[xx, zz]; BEGIN y: INTEGER_ zz.wy + zz.wh + xFudge; testerTS_ TypeScript.Create[ info: [parent: xx, ww: xx.cw, wy: y, wh: xx.ch - y, border: FALSE]]; Containers.ChildYBound[xx, testerTS]; Containers.ChildXBound[xx, testerTS]; FS.SetKeep[etherTesterLogName, 2 ! FS.Error => CONTINUE]; tsOut_ ViewerIO.CreateViewerStreams[NIL, testerTS, etherTesterLogName].out; END; etherTesterController_ xx; ViewerOps.SetMenu[etherTesterController, readyMenu]; tsOut.PutRope[herald]; END; ShowPacket: PUBLIC PROC[why: ROPE, this: EtherTesterOps.Buffer] = BEGIN limit: CARDINAL = 30; length: CARDINAL = NewEthernetFace.GetPacketLength[this.iocb] + 2; -- CRC p: LONG POINTER _ @this.header; val: WORD; IF this = NIL THEN Debugger["AttemptToPrintNilBuffer"L]; tsOut.PutRope[why]; tsOut.PutF[".\nStatus: %g, Length: %d, Used: %d, Retries: %bB.\n", rope[StatusToRope[NewEthernetFace.GetStatus[this.iocb]]], int[this.length], int[NewEthernetFace.GetPacketLength[this.iocb]], int[NewEthernetFace.GetRetries[this.iocb]] ]; tsOut.PutF["Dest: %g, Source: %g, Type: %bB.\n", rope[Unformat.HostNumberToRope[this.header.dest]], rope[Unformat.HostNumberToRope[this.header.source]], int[this.header.packetType]]; tsOut.PutRope["IOCB: "]; FOR i: CARDINAL IN [0..8) DO { val_ (this.iocb + i)^; tsOut.PutF["%07b ", card[val]]}; ENDLOOP; FOR i: CARDINAL IN [0..IF TRUE THEN length ELSE MIN[limit, length]) DO IF (i MOD 8) = 0 THEN BEGIN tsOut.PutChar['\n]; IF EtherTesterOps.DontBeAHog[] THEN EXIT; tsOut.PutF["%4b/ ", card[i]]; END; val_ (p + i)^; tsOut.PutF["%07b ", card[val]]; ENDLOOP; tsOut.PutChar['\n]; IF FALSE AND length > limit THEN tsOut.PutRope["....\n"]; END; Debugger: PROC[e: STRING] = { DebuggerSwap.CallDebugger[e] }; Trouble: PROC[txt, txt2: ROPE_ NIL] = BEGIN tsOut.PutRope[txt]; IF txt2.Length[] # 0 THEN tsOut.PutRope[txt2]; tsOut.PutChar['\n]; ViewerOps.SetMenu[etherTesterController, readyMenu]; END; ShowRunts: BoolItemProc = { showRunts_ value}; ShowGarbage: BoolItemProc = { showGarbage_ value}; ShowStrange: BoolItemProc = { showStrangeStatus_ value}; ShowWrongLength: BoolItemProc = { showWrongLength_ value}; ShowWrongData: BoolItemProc = { showWrongData_ value}; ShowOnlyBadAlign: BoolItemProc = { showOnlyBadAlign_ value}; DoChecksum: BoolItemProc = { doChecksum_ value}; DoStats: BoolItemProc = { doStats_ value}; CheckInput: BoolItemProc = { check_ value}; BumpPacketNumber: BoolItemProc = { bumpPacketNumber_ value}; DallyIfBehind: BoolItemProc = { dallyIfBehind_ value}; DallyBeforeOutput: BoolItemProc = { dallyBeforeOutput_ value}; Promiscuous: BoolItemProc = { promiscuous_ value}; Broadcasting: BoolItemProc = { broadcasting_ value}; UpdateNumbers: PUBLIC PROC = {EtherTesterViewer.UpdateStatsBoxes[]}; EtherTesterProc: ENTRY Commander.CommandProc = TRUSTED BEGIN IF etherTesterController # NIL THEN { cmd.out.PutRope["EtherTester control window already exists\n"]; RETURN }; cmd.out.PutRope[herald]; myHostNumber_ Unformat.HostNumberToRope[me]; sourceHostNumber_ Unformat.HostNumberToRope[source]; destHostNumber_ Unformat.HostNumberToRope[dest]; BuildController[]; END; InitializeThings: PROC = BEGIN SELECT SystemVersion.machineType FROM dorado => okToRun_ TRUE; dandelion => okToRun_ Booting.switches[b]; ENDCASE; Loader.MakeGlobalFrameResident[NewEthernetFace.TurnOn]; Loader.MakeProcedureResident[NewEthernetFace.TurnOn]; herald_ PutFR["Ethernet Tester of %g running on host number: %g.\n", time[Loader.BCDBuildTime[NewEthernetFace.TurnOn]], rope[Unformat.HostNumberToRope[me]]]; EtherTesterOps.InitializeCSBs[]; Menus.AppendMenuEntry[stopMenu, Menus.CreateEntry["Stop", Stop]]; Menus.AppendMenuEntry[readyMenu, Menus.CreateEntry["Send", Send]]; Menus.AppendMenuEntry[readyMenu, Menus.CreateEntry["Receive", Recv]]; Menus.AppendMenuEntry[readyMenu, Menus.CreateEntry["SendAndRecv", SendAndRecv]]; Menus.AppendMenuEntry[readyMenu, Menus.CreateEntry["EchoServer", EchoServer]]; Menus.AppendMenuEntry[readyMenu, Menus.CreateEntry["EchoUser", EchoUser]]; Menus.AppendMenuEntry[readyMenu, Menus.CreateEntry["Quit", Quit]]; END; Commander.Register["EtherTester", EtherTesterProc, "Builds an EtherTester control window"]; InitializeThings[]; END. €EtherTesterControlImpl.mesa Copyright Σ 1988 by Xerox Corporation. All rights reserved. last edited by Willie-Sue, April 7, 1988 2:30:29 pm PDT taken from: EtherTesterTajo.mesa, AOF, 26-Sep-83 17:13:41 Global Data variables used for testing Private Data Button Commands building controller and initializing it ************************ initial line ********** first line ********** second line ********** third line ********** fourth line ********** fifth line ********** sixth line ********** seventh line ********** line of stats which get updated if desired typescript area at end Miscellaneous routines ShowPacket is called at interrupt level so we must call DontBeAHog to let other guys get a chance to run. Also checks for Stop key. Initialization ********************************* IF ~okToRun THEN { cmd.out.PutRope[ "The 'b switch needs to be down before EtherTester will run."]; RETURN }; IF ~okToRun THEN RETURN; Κί˜šœ™Icode™˜MJ˜J˜Jšœ™J˜šžœœ˜$š˜Jšœ˜Jšœ4˜4—Jšœ˜—J˜šžœœ˜(š˜Jšœ*œœ˜8Jšœ ˜ Jšœ4œ˜N—Jšœ˜—J˜šžœœ˜(š˜Jšœ,œœ˜:Jšœ˜Jšœ7œ˜Q—Jšœ˜—J˜šž œœ˜/š˜Jšœ8œœ˜FJšœ˜Jšœ ˜ Jšœ:œ˜T—Jšœ˜—J˜šž œœ˜.š˜Jšœ.œœ˜˜>J˜Jšœ2˜2J˜Jšœ4˜4J˜Jšž œœœ*˜DJ™Jšœ0™0J˜šžœœ˜6š˜šœœ˜#JšœBœ˜K—J˜šœ ™™J™?Jš™—Jšœ™—J˜,J˜4J˜0J˜—Jšœ˜—J˜šžœœ˜š˜šœ˜%Jšœœ˜Jšœ*˜*Jšœ˜—Jšœ œœ™J˜Jšœ7˜7Jšœ5˜5˜DJšœ2˜2J˜%—J˜ J˜JšœA˜AJšœB˜BJšœE˜EJšœP˜PJšœN˜NJšœJ˜JJšœB˜BJ˜—Jšœ˜—J˜Jšœ[˜[J˜J˜Jšœ˜—…—=P“