/* echouser.c
L. Stewart November 28, 1982 6:48 PM
D. Swinehart July 9, 1982 2:15 PM
L. Stewart February 11, 1983 9:55 AM, add routing table print
L. Stewart April 29, 1983 8:22 PM, WDT
L. Stewart July 7, 1983 11:13 AM, routing
L. Stewart July 15, 1983 3:59 PM, change host command
*/
#include <Ec.h>
#include <Env.h>
#include <Queue.h>
#include <Pup.h>
#include <Lark.h>
#include <LarkNet.h>
extern struct Queue ctxQ;
static struct Port echoPort;
static struct Port lclPort;
static int echob;
static int audb;
static int dnet, dhost;
static int speedy;
static int speedytmr;
static int echoPkts;
static int loopCtx;
static int loopSpace;
static int prCtx;
static int prSpace;
static int cpCtx;
static int cpSpace;
static int rcvflag;
static int counter;
static int leftover, any;
extern struct Route routingTable[maxNetworks];
extern /*forward*/Loop();
extern /*forward*/InE();
extern /*forward*/In();
extern /*forward*/cp();
extern /*forward*/pr();
extern int currentHost;
main()
{
InitOS();
InitPupLevel1(&ctxQ, 10, defaultPupDataBytes);
loopSpace = GetFixed(300);
loopCtx = InitNContext("Loop", loopSpace, 300, &Loop);
Enqueue(&ctxQ, loopCtx);
cpSpace = GetFixed(1000);
cpCtx = InitNContext("command", cpSpace, 1000, &cp);
Enqueue(&ctxQ, cpCtx);
prSpace = GetFixed(1000);
prCtx = InitNContext("print", prSpace, 1000, &pr);
Enqueue(&ctxQ, prCtx);
echob = 0;
speedy = 0;
counter = 0;
dnet = 0x007b;
dhost = 0x004a;
echoPort.socket.LS = 0;
echoPort.socket.ms = Swab(5);
echoPort.host = 0;
echoPort.net = 0;
lclPort.socket.LS = 123;
lclPort.socket.ms = 456;
lclPort.host = 0;
lclPort.net = 0;
if (!OpenLevel1Socket(&echoPort, &InE, 0)) CallSwat(ecPup1+10);
if (!OpenLevel1Socket(&lclPort, &In, 0)) CallSwat(ecPup1+10);
ELoad();
for (;;) {
CtxListStart();
CallContext(ctxQ.head);
CtxListEnd();
CheckWDT();
};
};
static cp()
{
char c;
wf("Pup Echo user and server.\r");
for(;;) {
wf("@ ");
while (!Chav()) Block();
c = GetChar();
switch (c) {
case 'a': audb = 1; doaud(); break;
case 'b': audb = 0; doaud(); break;
case 'c': SetHost(); break;
case 'e': echob = 1; break;
case 'f': echob = 0; break;
case 'h': host(); break;
case 'n': net(); break;
case 's':
speedy = 1; counter = 0; SetTmr(1000, &speedytmr); break;
case 'r': PrintRT(); break;
case 't': speedy = 0; break;
default: help(); break;
};
};
};
doaud()
{
if (audb) StartSlave(1, 0);
else PIOOn(0x0020, ipioa);
};
PrintRT()
{
int i;
for (i = 0; i < 256; i += 1) {
Block();
if (Chav()) break;
wf4("net %3d, host %3o, hops %d, age %d\r", i, routingTable[i].host & 0x00ff, routingTable[i].hops & 0x00ff, routingTable[i].age & 0x00ff);
};
};
static AddToTimer(t, i)
int *t, i;
{
*t += i;
};
static pr()
{
for(;;) {
Block();
if (speedy && TmrExp(&speedytmr)) {
AddToTimer(&speedytmr, 1000);
wf2("Pkts/sec: User = %6d, Server = %6d\r", counter, echoPkts);
echoPkts = counter = 0;
};
};
};
static help()
{
wf("a: audio on, b: off\r");
wf("e: echo on, f: off\r");
wf("s: fast on, t: off\r");
wf("h: host, n: net\r");
wf("p: print stuff\r");
};
static net()
{
wf(" net: ");
dnet = gethex();
wf1(" (= %x)\r", dnet);
};
static host()
{
wf(" host: ");
dhost = gethex();
wf1(" (= %x)\r", dhost);
};
static SetHost()
{
int nhost;
wf(" change host to: ");
nhost = gethex();
wf1(" (= %x)\r", nhost);
currentHost = nhost;
NewHost();
};
static Loop()
{
int echotmr;
struct Pup *p;
struct PBI *tPBI;
char foo[8];
foo[0] = 4;
foo[1] = 0;
foo[2] = 4;
foo[3] = 0;
foo[4] = 'A';
foo[5] = 'b';
foo[6] = 'c';
foo[7] = 'd';
for (;;) {
Block();
if (echob) {
rcvflag = 0;
tPBI = GetPBI(5);
p = tPBI->pup;
Zero(p, 10);
p->type = 1;
p->id[0] = Swab(++counter);
p->dPort.net = dnet;
p->dPort.host = dhost;
p->dPort.socket.LS = 0;
p->dPort.socket.ms = Swab(5);
p->sPort.net = 0173;
p->sPort.host = EtherHost();
p->sPort.socket.LS = lclPort.socket.LS;
p->sPort.socket.ms = lclPort.socket.ms;
AppendStringToPup(tPBI, 4, foo);
SendPup(tPBI);
SetTmr(1000, &echotmr);
while (!TmrExp(&echotmr) && (!rcvflag)) {
Block();
};
if (!rcvflag) PutChar('?');
else { if (!speedy) PutChar('!'); };
};
};
};
static int gethex()
{
int v;
v = 0;
any = 0;
for (;;) {
eGetChar();
if (IsDigit(leftover)) {
v = (v<<4);
v += (leftover-'0');
any = 1;
continue;
};
leftover = LC(leftover);
if (leftover>='a' && leftover<='f') {
v = (v<<4);
v += (leftover-'a'+10);
any = 1;
continue;
};
break;
};
return(v);
};
static int eGetChar() /* GetChar with echo */
{
while (!Chav()) Block();
leftover = GetChar() & 0177;
PutCRChar(leftover);
return(leftover);
};
static In(pbi)
struct PBI *pbi;
{
if (!CheckCheckSum(pbi->pup)) PutChar('c');
rcvflag = 1;
ReleasePBI(pbi);
};
static InE(pbi)
struct PBI *pbi;
{
if (!CheckCheckSum(pbi->pup)) PutChar('c');
if (pbi->pup->type == 1) {
pbi->pup->type = 2;
SwapSourceAndDest(pbi);
SendPup(pbi);
echoPkts += 1;
if (!speedy) PutChar('$');
};
else ReleasePBI(pbi);
};
static SwapSourceAndDest(pbi)
struct PBI *pbi;
{
struct Port temp;
MoveBlock(&temp, &pbi->pup->sPort, lenPort);
MoveBlock(&pbi->pup->sPort, &pbi->pup->dPort, lenPort);
MoveBlock(&pbi->pup->dPort, &temp, lenPort);
};