/* audnet.c
L. Stewart November 13, 1982 4:32 PM
*/
#include "Ec.h"
#include "Env.h"
#include "Alloc.h"
#include "Queue.h"
#include "Pup.h"
#include "Encrypt.h"
#include "LarkNet.h"
#define VoiceLowSocket 111
#define VoiceHighSocket 222
/* comm */
extern SendPup();
extern int EtherHost();
extern struct PBI *GetPBI();
extern int OpenLevel1Socket();
extern CloseLevel1Socket();
extern ReleasePBI();
/* runtime */
extern int Swab();
extern MoveBlock();
extern CallSwat();
/* encryption */
extern Encrypt();
struct Port source, dest;
struct PBI *mikePBI;
struct Pup *mikePup;
struct ECB loECB, hiECB, daECB, dbECB;
static int bytesDecrypted; /* num finished in first pass of wraparound case */
extern int *silval1; /* silence value for buffer 1 */
extern char *inbuf1; /* input buffer 1 */
extern char *obuf1; /* output buffer 1 */
extern int *bufptr; /* ring buffer pointer */
extern int audioMode; /* control program */
static int lsoc; /* saved for CloseSocket */
static int nextIndex; /* next spot in ringbuffer */
static int silCount; /* packets since silence started */
static int silLimit; /* number of silent packets to transmit */
static int silThresh; /* definition of silence */
static int stayAliveLimit; /* interval to send empty packets */
static int numSample; /* number of packets total */
static int numPackets; /* number of packets transmitted */
static int expSample; /* expected sample number */
static int expPacket; /* expected packet number */
static int pktsMissed; /* number of runs of packets missed */
static int pktsDuped; /* number of duplicate packets */
static char myKey[8];
extern /* FORWARD */ FromNet();
InitNetStuff()
{
SetConstants(5, 16, 4096);
};
SetConstants(sL, sAL, sT)
int sL, sAL, sT;
{
int i;
silLimit = sL;
stayAliveLimit = sAL;
silThresh = sT;
for (i=0; i<8; i+=1) myKey[i] = 01;
};
PrintNetStuff()
{
wf2("numSample: %u, numPackets: %u\r", numSample, numPackets);
wf2("expSample: %u, expPacket: %u\r", expSample, expPacket);
wf2("pktsMissed: %u, pktsDuped: %u\r", pktsMissed, pktsDuped);
wf2("silLimit: %u, stayAliveLimit: %u\r", silLimit, stayAliveLimit);
wf1("silThresh: %u\r", silThresh);
};
StartNet(dnet, dhost, encb)
char dnet, dhost;
int encb;
{
char *ek;
if (encb) ek = myKey;
else ek = 0;
nextIndex = 0;
silCount = 0;
numSample = 0;
numPackets = 0;
expSample = 0;
expPacket = 0;
pktsMissed = 0;
pktsDuped = 0;
source.net = 0; /* will be filled in by Open socket */
source.host = 0;
source.socket.LS = Swab(VoiceLowSocket);
source.socket.ms = Swab(VoiceHighSocket);
dest.net = dnet;
dest.host = dhost;
dest.socket.LS = Swab(VoiceLowSocket);
dest.socket.ms = Swab(VoiceHighSocket);
loECB.next = 0;
loECB.kp = ek;
loECB.srcp = inbuf1;
loECB.encrypt = true;
loECB.count = 160;
loECB.proc = (int) &SendPup;
hiECB.next = 0;
hiECB.kp = ek;
hiECB.srcp = &inbuf1[160];
hiECB.encrypt = true;
hiECB.count = 160;
hiECB.proc = (int) &SendPup;
daECB.next = 0;
daECB.kp = ek;
daECB.encrypt = false;
dbECB.next = 0;
dbECB.kp = ek;
dbECB.dstp = obuf1;
dbECB.encrypt = false;
dbECB.proc = (int) &ReleasePBI;
if (!(lsoc = OpenLevel1Socket(&source, &FromNet, 0))) CallSwat(ecPup1+10);
SetupPBI();
};
StopNet()
{
if (audioMode == AMNet) {
CloseLevel1Socket(lsoc);
audioMode = AMOff;
if (mikePBI != 0) ReleasePBI(mikePBI);
mikePBI = 0;
mikePup = 0;
wf("talk off\r");
};
};
/* other aud net components */
ToNet(h)
int h;
{
if ((silCount < silLimit) || (*silval1 > silThresh)) {
mikePup->id[0] = Swab(numSample);
mikePup->id[1] = Swab(numPackets);
if (h) {
hiECB.dstp = &mikePup->data;
hiECB.item = (int) mikePBI;
Encrypt(&hiECB);
};
else {
loECB.dstp = &mikePup->data;
loECB.item = (int) mikePBI;
Encrypt(&loECB);
};
numPackets += 1;
silCount = (*silval1 > silThresh) ? 0 : silCount+1;
SetupPBI();
};
else {
if (silCount > stayAliveLimit) {
silCount = silLimit;
mikePup->id[0] = Swab(numSample);
mikePup->id[1] = Swab(numPackets);
mikePup->type = VoiceAliveType;
mikePup->length = Swab(pupOvBytes);
SendPup(mikePBI);
SetupPBI();
numPackets += 1;
};
else silCount += 1;
};
numSample += 1;
};
SetupPBI()
{
mikePBI = GetPBI();
mikePup = mikePBI->pup;
mikePup->length = Swab(160+pupOvBytes);
mikePup->transport = 0;
mikePup->type = VoiceType
MoveBlock(&mikePup->dPort, &dest, lenPort);
MoveBlock(&mikePup->sPort, &source, lenPort);
};
/* with encryption */
FromNet(p)
struct PBI *p;
{
struct Pup *iPup;
int diff, thisIndex;
iPup = p->pup;
diff = Swab(iPup->id[1]) - expPacket;
if (diff < 0) pktsDuped += 1;
if (diff > 0) pktsMissed += 1;
expPacket = Swab(iPup->id[1]) + 1;
if ((iPup->type == VoiceType) && (diff >= 0) && (diff < 50)) {
diff = Swab(iPup->id[0]) - expSample;
expSample = Swab(iPup->id[0]) + 1;
thisIndex = (diff == 0) ? nextIndex : *bufptr+80;
thisIndex &= 0xfff8;
if (thisIndex >= 320) thisIndex -= 320;
DecryptFromTo(p, thisIndex);
nextIndex = thisIndex + 160;
if (nextIndex >= 320) nextIndex -= 320;
};
else ReleasePBI(p);
};
DecryptFromTo(p, toIndex)
struct PBI *p;
int toIndex;
{
daECB.srcp = &p->pup->data;
daECB.dstp = &obuf1[toIndex];
if (toIndex > 160) {
daECB.proc = (int) &Encrypt;
daECB.item = (int) &dbECB;
daECB.count = bytesDecrypted = 320 - toIndex;
dbECB.srcp = &p->pup->data.bytes[bytesDecrypted];
dbECB.count = 160 - bytesDecrypted;
dbECB.item = (int) p;
};
else {
daECB.proc = (int) &ReleasePBI;
daECB.count = 160;
daECB.item = (int) p;
};
Encrypt(&daECB);
};