/* Larkaud.c LCS November 1, 1982 9:01 AM, other stuff LCS, November 11, 1982 12:08 PM, CheckFromNet LCS, December 7, 1982 1:24 PM, New relays LCS, December 8, 1982 4:06 PM, dismiss command, LarkSlave refs LCS, January 14, 1983 4:09 PM, Lark.mesa revisions LCS, March 2, 1983 3:31 PM, Larkinitial connections LCS, March 2, 1983 4:30 PM, bonsai LCS, March 6, 1983 3:48 PM, FixedLeft LCS, March 10, 1983 9:12 AM, flush wf LCS, March 10, 1983 2:12 PM, flush xbar init LCS, March 14, 1983 1:27 PM, SPMode LCS, March 16, 1983 9:31 AM, AudioProcess moved to LarkNet LCS, April 18, 1983 10:32 AM, new Lark LCS, April 21, 1983 11:52 AM, correct key parity LCS, May 21, 1983 6:40 PM, WhatIsStatus moved to LarkEventsImpl, WhatAreConnections implemented LCS, May 24, 1983 4:22 PM, PleaseRegister LCS May 27, 1983 4:08 PM, reorganized, echo suppression LCS May 31, 1983 7:29 PM, CmdString bugs LCS June 2, 1983 11:53 AM, net cleanup LCS June 3, 1983 9:51 AM, SetIngain bug, Codec2 wasn't working LCS June 5, 1983 5:37 PM, squelchTail, FirstPacket LCS June 14, 1983 10:45 AM, EchoSuppression LCS July 18, 1983 11:51 AM, SetHostNumber LCS August 17, 1983 12:39 PM, parameterize */ #include "Lark.h" #include "Env.h" #include "RPC.h" #include "LarkSlave.h" #include "Queue.h" #include "Encrypt.h" #include "Pup.h" #include "LarkNet.h" #include "LarkVCB.h" /* context package */ extern Block(); /* Allocate package */ extern FixedLeft(); /* Lark stuff */ extern InitAnalog(); extern SetIngain(); extern SetOutGain(); extern StartSlave(); extern PlayTone(); extern SetBufferTime(); extern SendPup(); extern Encrypt(); extern ReleasePBI(); extern int localHost; extern int currentHost; extern int localNet; extern int wToneCB; extern int totAv; extern int lostTx; extern struct VCB vcb[1]; extern int keyTable[64]; extern int SSilThresh; extern int MaxSquelchTail; extern int ajdelay; extern int tooLate; extern int tooEarly; extern int adjustTooEarly; extern int firstajdelay; int bufferClockBad; int zeroBufferTime; int bufferPointer; int bufferClock; AudioStuff() { InitAnalog(); /* redundant, it is in InitOS, but restarts... */ InitNetStuff(); InitToneStuff(); SetIngain(3, 0) SetOutGain(0) SPMode(false); StartSlave(1, 0); bufferClockBad = 0; }; InitNetStuff() { int i; lostTx = 0; SSilThresh = 576; MaxSquelchTail = 20; ajdelay = 10; tooLate = 3; tooEarly = 40; adjustTooEarly = 10; firstajdelay = 3; for (i = 0; i < 5; i += 1) InitVCB(i); SetBufferTime(); Zero(keyTable, 16 * lenEncryptionKey); for (i = 0; i < 16; i += 1) { CorrectParity(&keyTable[i]); Block(); }; }; InitVCB(i) int i; { int j; struct VCB *p; p = &vcb[i]; Zero(p, lenVCB); switch (i) { case IIn1: { p->bufbase = InBuf1; p->silVal = Sil1Val; break; }; case IIn2: { p->bufbase = InBuf2; p->silVal = Sil2Val; break; }; case IOut1: p->bufbase = OutBuf1; break; case IOut2: p->bufbase = OutBuf2; break; case IOut3: p->bufbase = OutBuf3; break; default: return; }; /* variable initialization, others are zero */ p->firstPacket = true; p->silThresh = SSilThresh; InitQueue(&p->vpq); InitQueue(&p->pq); p->pqlength = 0; p->squelchTail = MaxSquelchTail; /* all but destp and item */ p->loECB.next = 0; p->loECB.srcp = p->bufbase; p->loECB.encrypt = true; p->loECB.count = 160; p->loECB.proc = (int) &SendPup; /* hiECB is just like it except for srcp */ MoveBlock(&p->hiECB, &p->loECB, lenECB); p->hiECB.srcp = &p->bufbase[160]; /* floECB is just like it except . . . */ MoveBlock(&p->floECB, &p->loECB, lenECB); p->floECB.srcp = &p->bufbase[264]; p->floECB.count = 56; p->floECB.proc = (int) &Encrypt; p->floECB.item = (int) &p->loECB; /* fhiECB is just like it except . . . */ MoveBlock(&p->fhiECB, &p->loECB, lenECB); p->fhiECB.srcp = &p->bufbase[104]; p->fhiECB.count = 216; /* needs srcp, dstp, count, proc, item */ p->daECB.next = 0; p->daECB.encrypt = false; /* needs srcp, count, item */ MoveBlock(&p->dbECB, &p->daECB, lenECB); p->dbECB.dstp = p->bufbase; p->dbECB.proc = (int) &ReleasePBI; /* other echo suppression fields set by the call to Zero */ p->decayTime = 5; for (j = 0; j < 5; j += 1) p->gainTable[j] = 32767; }; AudioProcess() { for (;;) { Block(); PokeWDTC(); CheckBufferTime(); TryEcho(); FromNet(); }; }; /* compute the current [zeroBufferTime, bufferPointer] pair */ GetBufferTime() { int newbp; newbp = *BufPtr; /* 0 crossing test */ if (bufferPointer > newbp) zeroBufferTime += 40; bufferPointer = newbp; bufferClock = zeroBufferTime + (bufferPointer >> 3); }; SetBufferTime() { bufferPointer = *BufPtr; zeroBufferTime = ReadTmr() - (bufferPointer >> 3); bufferClock = zeroBufferTime + (bufferPointer >> 3); }; CheckBufferTime() { int diff; GetBufferTime(); /* are bufferClock and ct close? */ diff = bufferClock - ReadTmr(); if ((diff < -2) || (diff > 2)) { SetBufferTime(); bufferClockBad += 1; }; }; AudCmd(p) struct EvSeq *p; { int i; int d, e; if (p->length > 20) return; for (i = 0; i < p->length; i += 1) { Block(); d = p->evs[i].device; e = p->evs[i].event; Each(d, e); }; }; static Each(d, e) int d, e; { int on; d &= 0x00ff; e &= 0x00ff; if (e == 144) on = true; else on = false; switch (d) { case 4: PutC(0, e); break; case 5: PutC(1, e); break; case 8: Revert(on); break; case 9: GoOffHook(on); break; case 10: SideTone(on); break; case 11: RingEnable(on); break; case 12: Led(on); break; case 13: XbarClear(); break; case 14: SetTS(e); break; case 15: SetVoice(e); break; case 16: case 17: case 18: case 19: SetTable(d, e); break; case 22: YXBar(e); break; case 23: XXBar(e); break; case 24: RevertHS(on); break; case 25: ARelay(on); break; case 27: { on = e; Dismiss(on * 10); break; }; case 28: SPMode(on); break; default: break; }; }; static SetTS(c) char c; { if (c == 147) SetCodec(0); if (c == 148) SetCodec(0x0c); }; static YXBar(c) char c; { ClearXbar(((c >> 4) & 0x0f), (c & 0x0f)); }; static XXBar(c) char c; { SetXbar(((c >> 4) & 0x0f), (c & 0x0f)); }; SPMode(on) int on; { int *modep; modep = (int *) ModeFlag; if (on) *modep |= 3; else *modep &= 0xfffc; }; static SetVoice(c) char c; { switch (c) { case 159: StartSlave(1, 0); break; case 160: StartSlave(2, 0); break; default: StartSlave(1, 0); break; }; SetBufferTime(); }; static SetTable(d, e) char d, e; { int table; table = e - 149; switch (d) { case 16: SetIngain(0, table); break; case 17: SetIngain(1, table); break; case 18: SetOutGain(table); break; case 19: SetOutGain(table); break; default: break; }; }; /* Actual calls via RPC */ struct ResetArgs { int procType; int isNil; int length; /* character array */ }; /* ropes are stored with only the length word */ int Reset(sp) int *sp; { struct ShortSTRING *rName; struct ResetArgs *ra; ra = (struct ResetArgs *) sp; if (ra->isNil) return(0); /* no results */ ra->length = Swab(ra->length); ra->isNil = ra->length; /* fake presence of ROPE */ rName = (struct ShortSTRING *) &ra->isNil; AudioStuff(); /* initialize */ totAv = FixedLeft(); return (0); /* no results */ }; struct GTArgs { int procType; int f1, f2, modulation, on, off; int repetitions, waveTable, queueIt, notify; }; int GenerateTones(sp) int *sp; { struct GTArgs *ga; int i; ga = (struct GTArgs *) sp; SwabInPlace(&ga->f1, 9); i = PlayTone(ga->f1, ga->f2, ga->on, ga->off, ga->repetitions, ga->queueIt, ga->waveTable, ga->notify); *sp = (i) ? swapped1: 0; /* boolean */ return (1); /* one result */ }; struct DiscArgs { int procType; int id; }; int Disconnect(sp) int *sp; { struct DiscArgs *da; da = (struct DiscArgs *) sp; StopNet(Swab(da->id)); return (0); /* no results */ }; extern int plsRegister; extern int plsRegTimer; int PleaseRegister(sp) int *sp; { SetTmr(2000, &plsRegTimer); plsRegister = true; return (0); /* no results */ }; /* struct WACArgs { int procType; int which; }; */ int WhatAreConnections(sp) int *sp; { int which, i; struct VCB *p; struct CSpecs *c; which = Swab(sp[1]); sp += 2; c = (struct CSpecs *) sp; sp -= 2; if ((which >= 0) || (which < 5)) { for (i = which; i < 5; i += 1) { p = &vcb[i]; if (p->active) { sp[0] = Swab((i == 4) ? 0: i + 1); sp[1] = 0; /* isNil = false */ c->proto = 0; c->sampleRate = Swab(8000); c->pktSize = Swab(160); c->buffer = Swab(i); c->keyIndex = Swab(p->encIndex); MoveBlock(&c->lsoc[0], &p->lport, lenPort); MoveBlock(&c->rsoc[0], &p->rport, lenPort); return (13); }; }; }; *sp++ = 0; /* next = 0 */ *sp++ = swapped1; /* isNil = true */ return (2); /* two words of results */ }; int WhatAreTones(sp) int *sp { *sp = (wToneCB) ? swapped1: 0; return (1); }; /* argument structure struct KeyArgs { int procType; int isNil; int length[2]; int sequenceTag; int keyArray[64]; }; */ int SetKeyTable(sp) int *sp { int i; if (sp[1]) return(0); /* isnil */ for (i = 0; i < 64; i += 4) { CorrectParity(sp + i + 5); Block(); }; MoveBlock(keyTable, sp+5, 64); return (0); }; /* argument structure */ struct CmdStrArgs { int procType; int device; int isNil; int length; char charArray[1]; }; int CommandString(sp) int *sp { int i; struct CmdStrArgs *ca; struct ShortSTRING *evString; ca = (struct CmdStrArgs *) sp; if (ca->isNil) return(0); /* no results */ ca->length = Swab(ca->length); /* fix length */ ca->isNil = ca->length; /* fake presence of ROPE */ evString = (struct ShortSTRING *) &ca->isNil; for (i = 0; i < evString->length; i += 1) { Block(); Each(Swab(ca->device), evString->text[i]); }; return (0); }; int PleaseLogin(sp) int *sp; { *sp = 0; return(1); }; struct EchoRec { int procType; int isNil; int buffer; int control; int decayTime; int gain[5]; }; int EchoSupression(sp) int *sp; { struct EchoRec *erp; struct VCB *p; if (sp[1]) return(0); /* isnil */ erp = (struct EchoRec *) sp; SwabInPlace(sp + 2, 8); erp->buffer &= 07; erp->control &= 03; erp->decayTime &= 037; if (erp->buffer > 4) return(0); p = &vcb[erp->buffer]; p->gainChannel = erp->control; p->decayTime = erp->decayTime; p->lastEnergy = 0; MoveBlock(&p->gainTable[0], &erp->gain[0], 5); return(0); }; struct SetHostRec { int procType; char net; char host; }; int SetHostNumber(sp) int *sp; { struct SetHostRec *hrp; int lh; hrp = (struct SetHostRec *) sp; lh = hrp->net; lh &= 0x00ff; if (lh == localNet) { lh = hrp->host; lh &= 0x00ff; if (lh == 0) lh = localHost; currentHost = lh; NewHost(); }; return(0); };