/* LarkEventsImpl.c
L. Stewart October 29, 1982 3:16 PM
L. Stewart December 7, 1982 1:52 PM, tone event
L. Stewart December 7, 1982 1:52 PM, smaller
L. Stewart January 14, 1983 4:23 PM, Lark.mesa revisions
*/
#include <Alloc.h>
#include <Queue.h>
#include <Env.h>
#include <Signal.h>
#include <rpc.h>
#include <rpcinternal.h>
#include <rpclupine.h>
#include <Lark.h>
#include <ec.h>
#include <LarkNet.h>
/* local definitions */
struct SEvent {
int time;
char device;
char event;
};
struct SEvents {
int length;
struct SEvent eventseq[16];
};
struct SEventCB {
struct SEventCB *next;
int time;
char device;
char event;
};
/* queue package */
extern InitQueue();
extern struct SEventCB *Dequeue();
extern Enqueue();
/* context package */
extern Block();
/* TTY IO package */
extern int AvC();
extern int GetC();
extern wf3();
/* 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 CallFormatted();
extern struct ShortSTRING *spNl;
extern struct ShortSTRING *spDT;
extern int *smartsHandle;
extern struct Conversation *shhhh; /* Place holder for later
encrypted conversations */
extern int handle;
static struct Queue evQ, evFreeQ;
static struct SEventCB evcb[20];
static int *clockPtr;
static int oldAS;
int toneDone;
InitEventReport()
{
int i;
InitQueue(&evQ);
InitQueue(&evFreeQ);
for (i = 0; i < 20; i += 1) Enqueue(&evFreeQ, &evcb[i]);
clockPtr = clklo;
};
EventProcess()
{
for (;;) {
Block();
CheckTTY(0);
Block();
CheckTTY(1);
Block();
CheckAnalogEvents();
Block();
CheckTones();
};
};
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 args[5];
int i;
/* Before entering the loop, do all the initialization stuff
that must be done with contexts running */
Initialize();
for (;;) {
Block();
i = 0;
for (;;) {
Block();
p = Dequeue(&evQ);
if (p) {
if (DEBUG) wf3("ev time: %04x, dev: %02x, ev %02x\r", p->time, p->device, p->event);
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;
};
else break;
};
Block();
if (i > 0) {
e.length = i;
args[0] = (int) smartsHandle;
args[1] = (int) &e;
/* need a signal catcher here for callfailed */
CallFormatted(handle, iRecordEvent, spDT, spNl, args);
};
};
};