/* LarkImpl.c
Dan Swinehart October 14, 1982 1:25 PM
L. Stewart October 27, 1982 11:15 PM
L. Stewart November 9, 1982 9:58 AM, use ctxQ
L. Stewart December 8, 1982 3:57 PM, silent DTMF events
L. Stewart December 20, 1982 10:04 AM, more space for EventReport
L. Stewart December 27, 1982 11:07 PM, ELoad, less space for E.R.
L. Stewart January 1, 1983 4:11 PM, remove AllocZero
L. Stewart January 17, 1983 3:47 PM, Lark.mesa revisions
L. Stewart March 2, 1983, LarkSmarts.mesa bonsai
L. Stewart March 3, 1983 10:04 AM, Lark.mesa bonsai
L. Stewart March 6, 1983 3:46 PM, getfixed
L. Stewart March 10, 1983 11:55 AM, no wf calls
L. Stewart March 22, 1983 8:57 AM, WDT
L. Stewart April 18, 1983 10:35 AM, new Lark, LarkSmarts
LCS May 4, 1983 1:10 PM, New ImportInterface args, retry
LCS May 24, 1983 4:27 PM, PleaseRegister
LCS June 13, 1983 4:36 PM, EchoSupression
LCS July 15, 1983 3:38 PM, SetHostNumber
*/
#include <Queue.h>
#include <Ec.h>
#include <Env.h>
#include <Signal.h>
#include <rpc.h>
#include <rpcinternal.h>
#include <rpclupine.h>
#include <RPCBind.h>
#include <encrypt.h>
#include <LarkNet.h>
#include <RpcBonsai.h>
/* runtime */
extern CallSwat();
extern InitOS();
extern Move2();
extern Swab();
extern Zero();
/* RPC package */
extern int *StartBonsai();
extern CallBonsai();
extern CleanupCall();
extern int diagnoseBinding;
extern int ExportFailed;
extern ExportInterface();
extern int ImportFailed;
extern ImportInterface();
extern struct VersionRange *matchAllVersions;
extern RPCInitialize();
extern RPCInitializeCtx();
extern StartNProcess();
extern int BonsaiDispatcher();
extern struct ShortSTRING *CStringToString();
/* Alloc package */
extern int *GetFixed();
/* Lark package */
/* in LarkEventsImpl.c */
extern InitEventReport();
extern EventReport();
extern EventProcess();
extern AudioStuff();
extern AudioProcess();
extern AudCmd();
extern StartNet();
extern StopNet();
/* context package */
extern Block();
extern CallContext();
extern Dismiss();
/* signaller package */
extern int CONT();
/* pup package */
extern GetPupHost();
extern ELoad();
/* unknown */
extern int mySoc;
/* (Forward) Interface procedures to which Server, below, dispatches */
extern Reset(); /* in LarkAud.c */
extern GenerateTones(); /* in LarkAud.c */
extern Feep();
extern Commands();
extern Connect();
extern Disconnect();
extern PleaseRegister();
extern WhatIsStatus();
extern WhatAreConnections();
extern WhatAreTones();
extern SetKeyTable();
extern CommandString();
extern PleaseLogin();
extern EchoSupression();
extern SetHostNumber();
/* End of interface procedures */
extern struct EncryptionKey nullKeyB;
extern struct Queue ctxQ;
struct Conversation *shhhh;
/* Place holder for later encrypted conversations */
int smartsHandle[2];
int smartsEpoch[2];
int DEBUG;
struct ImportInstance handle[1];
static struct Seal sl;
static struct InterfaceName larkSmartsInterface; /* LarkSmarts */
struct ShortSTRING *clientInstance;
struct ShortSTRING *serverInstance;
struct ShortSTRING *clientRname;
static struct ShortSTRING *larkRope;
static struct ShortSTRING *larkSmartsRope;
/* Lark.mesa dispatcher data
*/
static int larkdispspace[20];
struct SSpecsTable *larkSpecs;
int plsRegister;
int plsRegTimer;
Main() {
CheckWDT();
InitOS(); /* Sets up sysZone */
DEBUG = false;
plsRegister = false;
shhhh = unencrypted;
larkRope = CStringToString("Lark.Lark");
larkSmartsRope = CStringToString("LarkSmarts.Lark");
CheckWDT();
RPCInitialize(&ctxQ);
CheckWDT();
InitEventReport();
/* EventProcess is temporary until the interrupt procedures get fixed up */
StartNProcess("EventProcess", &ctxQ, &EventProcess, 200, 10);
StartNProcess("EventReport", &ctxQ, &EventReport, 350, 90);
StartNProcess("AudioProcess", &ctxQ, &AudioProcess, 350, 90);
CheckWDT();
InitCtxStats();
AudioStuff();
for (;;) {
CtxListStart();
PokeWDTA();
CallContext(ctxQ.head);
CtxListEnd();
};
};
Initialize()
{
int serverMachine;
int bindTries;
bindTries = 0;
RPCInitializeCtx(false);
ELoad();
diagnoseBinding = true;
Zero(handle, lenImportInstance);
Zero(&larkSmartsInterface, lenInterfaceName);
larkSmartsInterface.type = larkSmartsRope;
Move2(&larkSmartsInterface.version, matchAllVersions);
{ /* Implicit loop until ENABLE succeeds */
if (ENABLE(ImportFailed, &CONT, &sl)) {
bindTries += 1;
if (bindTries > 10) { CallSwat(ecPup1+100); bindTries = 0; };
Dismiss(20000);
};
while (!AgentInitialize()) {
bindTries += 1;
if (bindTries > 10) { CallSwat(ecLarkImpl+23); bindTries = 0; };
Dismiss(20000);
};
/* call Vitae */
serverMachine = Vitae(GetPupHost(), matchAllVersions, larkSmartsInterface.type, &clientRname, &clientInstance, &serverInstance);
larkSmartsInterface.instance = serverInstance;
ImportInterface(serverMachine, &larkSmartsInterface, handle);
DISABLE(&sl);
shhhh = StartConversation(clientRname, &nullKeyB, serverInstance, slCBCCheck);
AttachConversation(handle, shhhh);
Server(clientInstance);
Zero(smartsHandle, 2); /* nil smartsHandle, first time */
Zero(smartsEpoch, 2); /* nil smartsEpoch, first time */
RegisterSelf();
}; /* endloop */
};
RegisterSelf() {
/* bonsai variables */
struct Seal1 csr;
int *ap, *sp;
struct Model *myModel;
/* new bonsai code for register */
/* arguments are
LONG CARDINAL (Lark.SmartsHandle )
LONG CARDINAL (Epoch (use 0) )
net,,host (Lark.Machine)
Lark.LarkModel:
genre,,hardwareversion
software version
BOOL (authenticated (use false))
Rope (instance from Identify (use clientInstance))
return values are
LONG CARDINAL (Lark.SmartsHandle)
*/
sp = ap = StartBonsai(handle, &csr);
*ap++ = Swab(iRegister); /* procedure index */
*ap++ = smartsHandle[0]; /* zero first time through */
*ap++ = smartsHandle[1];
*ap++ = smartsEpoch[0]; /* zero first time through */
*ap++ = smartsEpoch[1];
*ap++ = GetPupHost(); /* Lark.Machine */
myModel = (struct Model *) ap;
myModel->genre = 1;
myModel->hardwareVersion = 5;
myModel->softwareVersion = Swab(6);
myModel += 1;
ap = (int *) myModel;
*ap++ = 0; /* not authenticated */
ap = StringToPkt(ap, clientInstance);
Block();
CallBonsai(&csr, ap-sp);
Block();
ap = sp;
smartsHandle[0] = *ap++;
smartsHandle[1] = *ap++;
smartsEpoch[0] = *ap++;
smartsEpoch[1] = *ap++;
CleanupCall(&csr);
};
static Server(larkInstance)
struct ShortSTRING *larkInstance;
{
struct InterfaceName *larkInterface;
int *specs;
/* set up Bonsai dispatcher */
larkSpecs = (struct SSpecsTable *) larkdispspace;
Zero(larkdispspace, 20);
larkSpecs->maxProcs = iSetHostNumber
larkSpecs->procs[iReset] = (int) &Reset;
larkSpecs->procs[iGenerateTones] = (int) &GenerateTones;
larkSpecs->procs[iFeep] = (int) &Feep;
larkSpecs->procs[iCommands] = (int) &Commands;
larkSpecs->procs[iConnect] = (int) &Connect;
larkSpecs->procs[iDisconnect] = (int) &Disconnect;
larkSpecs->procs[iPleaseRegister] = (int) &PleaseRegister;
Block();
larkSpecs->procs[iWhatIsStatus] = (int) &WhatIsStatus;
larkSpecs->procs[iWhatAreConnections] = (int) &WhatAreConnections;
larkSpecs->procs[iWhatAreTones] = (int) &WhatAreTones;
larkSpecs->procs[iSetKeyTable] = (int) &SetKeyTable;
larkSpecs->procs[iCommandString] = (int) &CommandString;
larkSpecs->procs[iPleaseLogin] = (int) &PleaseLogin;
larkSpecs->procs[iEchoSupression] = (int) &EchoSupression;
larkSpecs->procs[iSetHostNumber] = (int) &SetHostNumber;
larkInterface = (struct InterfaceName *) GetFixed(lenInterfaceName);
larkInterface->type = larkRope;
larkInterface->instance = larkInstance;
Move2(&larkInterface->version, matchAllVersions);
Block();
ExportInterface(larkInterface, &BonsaiDispatcher, larkSpecs);
};
/* Actual calls via RPC */
struct FeepArgs {
int procType;
int on, off, waveTable, queueIt, notify;
int isNil;
int lenLo, lenHi;
struct EvSeq events;
};
int Feep(sp)
int *sp;
{
int i, thisNotify;
char d, e, c;
int tot;
struct FeepArgs *fa;
fa = (struct FeepArgs *) sp;
if (fa->isNil) goto retTrue;
SwabInPlace(&fa->on, 9); /* through length field of events */
thisNotify = 0;
for (i = 0; i < fa->events.length; i += 1) {
if ((i + 1) == fa->events.length) thisNotify = fa->notify;
Block();
d = fa->events.evs[i].device;
e = fa->events.evs[i].event;
if ((e >= 128) && (e <= 137)) c = e - 128 + '0';
else switch (e) {
case 138: c = 'A'; break;
case 139: c = 'B'; break;
case 140: c = 'C'; break;
case 141: c = 'D'; break;
case 142: c = '*'; break;
case 143: c = '#'; break;
default: {
tot = e;
PlayTone(0, 0, 0, (tot & 0x00ff) * 10, 1, fa->queueIt, fa->waveTable, thisNotify);
fa->queueIt = true;
continue;
};
};
LocPlayDTMF(c, fa->on, fa->off, fa->queueIt, fa->waveTable, thisNotify);
fa->queueIt = true;
};
retTrue:
*sp = swapped1; /* a Mesa TRUE */
return(1);
};
struct CArgs {
int procType;
int isNil;
int lenLo, lenHi;
struct EvSeq e;
};
Commands(sp)
int *sp;
{
struct CArgs *ca;
ca = (struct CArgs *) sp;
ca->e.length = Swab(ca->e.length);
if (ca->isNil) return(0); /* no return values */
AudCmd(&ca->e);
return(0); /* no return values */
};
struct ConnArgs {
int procType;
int isNil;
struct CSpecs specs;
};
Connect(sp)
int *sp;
{
struct ConnArgs *ca;
ca = (struct ConnArgs *) sp;
if (ca->isNil) return(0); /* no return values */
SwabInPlace(&ca->specs, 5);
StartNet(&ca->specs);
return (0); /* no return values */
};