/* LarkEventsImpl.c
LCS October 29, 1982 3:16 PM
LCS December 7, 1982 1:52 PM, tone event
LCS December 7, 1982 1:52 PM, smaller
LCS January 14, 1983 4:23 PM, Lark.mesa revisions
LCS January 17, 1983 3:47 PM, LarkSmarts.mesa bonsai
LCS March 6, 1983 3:47 PM, remove Alloc
LCS March 22, 1983 8:58 AM, WDT, more eventcbs
LCS April 18, 1983 12:04 PM, new LarkSmarts
LCS May 23, 1983 12:32 PM, PleaseRegister
LCS June 3, 1983 12:58 PM, success in RecordEvent
LCS June 12, 1983 2:46 PM, 10 sec timeout in RecordEvent
*/
#include <Queue.h>
#include <Env.h>
#include <Signal.h>
#include <rpc.h>
#include <rpcinternal.h>
#include <rpclupine.h>
#include <RPCBind.h>
#include <Lark.h>
#include <ec.h>
#include <LarkSlave.h>
#include <LarkNet.h>
/* queue package */
extern InitQueue();
extern struct SEventCB *Dequeue();
extern Enqueue();
/* context package */
extern Block();
/* TTY IO package */
extern int AvC();
extern int GetC();
/* runtime package */
extern CallSwat();
extern Swab();
/* analog package */
extern ScanIn();
extern GetPIO(); /* really runtime() */
/* Rest of Lark */
extern int DEBUG;
extern Initialize();
/* RPC package */
extern int *StartBonsai();
extern CallBonsai();
extern CleanupCall();
extern int smartsHandle[1];
extern struct Conversation *shhhh; /* Place holder for later
encrypted conversations */
extern struct ImportInstance handle[1];
/* PleaseRegister implementation */
extern int plsRegister;
extern int plsRegTimer;
extern RegisterSelf();
static struct Queue evQ, evFreeQ;
static struct SEventCB evcb[80];
static int *clockPtr;
static int oldAS;
int toneDone;
static int eventInProgress;
static int eventTimer;
InitEventReport()
{
int i;
InitQueue(&evQ);
InitQueue(&evFreeQ);
for (i = 0; i < 80; i += 1) Enqueue(&evFreeQ, &evcb[i]);
clockPtr = clklo;
};
EventProcess()
{
eventInProgress = false;
for (;;) {
Block();
CheckTTY(0);
CheckTTY(1);
Block();
CheckAnalogEvents();
Block();
CheckTones();
PokeWDTB();
if (eventInProgress && TmrExp(&eventTimer)) {
CallDebugger(ecLarkImpl + 27);
plsRegister = false;
};
};
};
static CheckTTY(ch)
int ch;
{
if (AvC(ch)) {
Enqueue(&evQ, GetSEventCB(4 + ch, GetC(ch)));
};
};
static struct SEventCB *GetSEventCB(dev, ev)
int dev, ev;
{
struct SEventCB *p;
p = Dequeue(&evFreeQ);
if (p == 0) CallSwat(ecLarkImpl+ 1);
p->device = dev;
p->event = ev;
p->time = Swab(*clockPtr);
return(p);
};
static CheckAnalogEvents()
{
int i, diff, newAS, ev;
newAS = ScanIn();
if (oldAS != newAS) {
newAS = ScanIn();
diff = oldAS ↑ newAS;
if (diff & AIDTMF) {
if (newAS & AIDTMF) {
i = (GetPIO(iapioc) >> 4) & 0x0f;
if ((i > 0) && (i < 10)) ev = i + 128;
else switch (i) {
case 0: ev = 141; break;
case 10: ev = 128; break;
case 11: ev = 142; break;
case 12: ev = 143; break;
case 13: ev = 138; break;
case 14: ev = 139; break;
case 15: ev = 140; break;
default: ev = 145;
};
};
else ev = 145;
Enqueue(&evQ, GetSEventCB(3 /* DTMF decoder */, ev));
};
Block();
if (diff & AISwitch) {
Enqueue(&evQ, GetSEventCB(2, (newAS & AISwitch) ? 144: 145));
};
if (diff & AIRing) {
Enqueue(&evQ, GetSEventCB(7, (newAS & AIRing) ? 144: 145));
};
if (diff & AIHookSwitch) {
Enqueue(&evQ, GetSEventCB(1, (newAS & AIHookSwitch) ? 144: 145));
};
oldAS = newAS;
};
};
static CheckTones()
{
if (toneDone != 0) {
Enqueue(&evQ, GetSEventCB(toneDone >> 8, toneDone & 0377));
toneDone = 0;
};
};
/* This process is the key user of LarkSmarts.Lark" */
EventReport() {
struct SEvents *e;
struct SEventCB *p;
int i;
/* bonsai variables */
struct Seal1 csr;
int *ap;
int success;
/* Before entering the loop, do all the initialization stuff
that must be done with contexts running */
Initialize();
for (;;) {
if (plsRegister && TmrExp(&plsRegTimer)) {
RegisterSelf();
plsRegister = false;
};
Block();
p = Dequeue(&evQ);
if (p == 0) continue;
/* new bonsai code, variables are above */
/* someday
struct Seal sl;
if (ENABLE(CallFailed, &CONT, &sl)) return (0);
*/
ap = StartBonsai(handle, &csr);
e = (struct SEvents *) ap;
e->procType = Swab(iRecordEvent); /* procedure index */
e->smartsLo = smartsHandle[0]; /* Lark.SmartsHandle */
e->smartsHi = smartsHandle[1];
/* fill it in */
i = 0;
for (;;) {
Block();
e->eventseq[i].time = p->time;
e->eventseq[i].device = p->device;
e->eventseq[i].event = p->event;
i += 1;
Enqueue(&evFreeQ, p);
if (i == 14) break;
p = Dequeue(&evQ);
if (p == 0) break;
};
Block();
e->lenLo = e->length = Swab(i);
e->isNil = e->lenHi = 0;
SetTmr(10000, &eventTimer);
eventInProgress = true;
CallBonsai(&csr, 7 + (i << 1));
success = *ap;
CleanupCall(&csr);
eventInProgress = false;
/* end of new bonsai code */
if (success == 0) CallSwat(ecLarkImpl + 26)
};
};