/* LarkImpl.c
Dan Swinehart October 11, 1982 2:16 pm
L. Stewart October 13, 1982 1:09 PM
L. Stewart January 1, 1983 4:12 PM, flush AllocZero
L. Stewart January 3, 1983 1:16 PM, flush CStringToString
*/
#include <Alloc.h>
#include <Queue.h>
#include <Ec.h>
#include <Env.h>
#include <Signal.h>
#include <rpc.h>
#include <rpcinternal.h>
#include <rpclupine.h>
#include <encrypt.h>
/* runtime */
extern CallSwat();
extern InitOS();
extern Move2();
extern MoveBlock();
extern Swab();
extern Zero();
/* RPC package */
extern AddToDispatcherSpecs();
extern AddType();
extern int CallFormatted();
extern struct ShortSTRING *CStringToString();
extern int diagnoseBinding;
extern int ExportFailed;
extern ExportInterface();
extern int ImportFailed;
extern int ImportInterface();
extern struct VersionRange *matchAllVersions;
extern RPCInitialize();
extern RPCInitializeCtx();
extern int *StartDispatcherSpecs();
extern StartNProcess();
extern int StdDispatcher();
/* Alloc package */
extern int *Allocate();
extern Free();
/* Lark package */
/* in LarkEventsImpl.c */
extern InitEventReport();
extern EventReport();
extern EventProcess();
/* context package */
extern Block();
extern CallContext();
extern Dismiss();
/* signaller package */
extern int CONT();
/* chario package */
extern wf();
extern wf3();
/* pup package */
extern GetPupHost();
/* unknown */
extern int mySoc;
/* (Forward) Interface procedures to which Server, below, dispatches */
extern Reset();
extern GenerateTones();
extern Feep();
extern Commands();
extern Connect();
extern Disconnect();
extern PleaseRegister();
extern WhatIsStatus();
extern WhatAreConnections();
extern WhatAreTones();
/* End of interface procedures */
extern struct ZN *sysZone;
extern struct EncryptionKey nullKeyB;
static struct Queue ctxQ;
struct ShortSTRING *spNl, *spDT;
static struct ShortSTRING *sp1, *sp2, *sp6;
static struct ShortSTRING *sp8, *spSt, *sp3St, *sp4Sq, *spSt3, *spX;
static struct ShortSTRING *spD1, *spRegister;
static struct ShortSTRING *spSq, *sp1Sq, *sp1X;
struct Conversation *shhhh; /* Place holder for later
encrypted conversations */
int *smartsHandle;
/* RPC Procedure indices, Lark interface */
#define iReset 4
#define iGenerateTones 5
#define iFeep 6
#define iCommands 7
#define iConnect 8
#define iDisconnect 9
#define iPleaseRegister 10
#define iWhatIsStatus 11
#define iWhatAreConnections 12
#define iWhatAreTones 13
/* RPC Procedure indices, LarkSmarts interface */
#define iIdentify 4
#define iRegister 5
#define iRecordEvent 6
Main() {
shhhh = unencrypted;
InitOS(); /* Sets up sysZone */
Zero(&ctxQ, 2);
RPCInitialize(&ctxQ);
spNl = (struct ShortSTRING *) Allocate(sysZone, 2);
sp1 = CStringToString("W");
sp2 = CStringToString("WW");
sp6 = CStringToString("WWWWWW");
sp8 = CStringToString("WWWWWWWW");
spSt = CStringToString("S");
sp1Sq = CStringToString("WT");
spSq = CStringToString("K");
sp3St = CStringToString("WWWS");
sp4Sq = CStringToString("WWWWK");
spSt3 = CStringToString("SSS");
spRegister = CStringToString("DWDSS");
spX = CStringToString("X"); /* Connection spec */
sp1X = CStringToString("WX"); /* INTEGER, ConnectionSpec */
spD1 = CStringToString("D");
spDT = CStringToString("DT");
InitEventReport();
/* EventProcess is temporary until the interrupt procedures get fixed up */
StartNProcess("EventProcess", &ctxQ, &EventProcess, 200, 10);
StartNProcess("EventReport", &ctxQ, &EventReport, 350, 90);
for (;;) {
CallContext(ctxQ.head);
};
};
int handle;
static struct Seal sl;
static struct InterfaceName clientInterface;
static int args[10]; /* prob not needed */
struct Events {
int length; /* must be 1 */
char device;
char event;
};
struct Model {
char hardwareVersion; /* Swabbed from Mesa version, since */
char genre; /* marshaller will re-Swab */
int softwareVersion;
};
#define lenModel (sizeof (struct Model)/2)
int pNil[2];
struct ShortSTRING *instance, *serverRname, *myRname;
struct Model *myModel;
Initialize() {
RPCInitializeCtx(true);
diagnoseBinding = true;
AddType('Z', 0); /* Get things started */
AddType('X', dBlock( /* Connection specification */
11*16, /* eltSize: 11 word elements
(VoiceStreams in trailing sequence) */
6, /* overhead: 5 words + sequence length field */
5, /* length: Sequence length field */
true, /* atLen: length is in record at word 5 */
true)); /* eltWd: all Swabbed, have to reverse some of them */
AddType('K', dBlock( /* LarkModel specification */
16, /* one word elements */
1, /* sequence only */
0,
true, /* length is in record at word 2 */
false)); /* deviceStates: sequence of pairs of bytes */
AddType('T', dBlock( /* events: int time; char device, event; */
32,
1,
0,
true,
false));
handle = 0;
Zero(&clientInterface, lenInterfaceName);
clientInterface.type = CStringToString("LySmarts.Lark");
clientInterface.instance = 0; /* Use broadcast binding methods. */
Move2(&clientInterface.version, matchAllVersions);
{ /* Implicit loop until ENABLE succeeds */
if (ENABLE(ImportFailed, &CONT, &sl))
CallSwat(ecPup1+100);
handle = ImportInterface(&clientInterface);
DISABLE(&sl);
wf("Identify[...] = ");
args[0] = (int) Swab(GetPupHost()); /* netAddress */
serverRname = CallFormatted(handle, iIdentify, sp1, spSt3, args);
myRname = args[2];
instance = args[3];
wf3("[serverRname: %r, myRname: %r, instance: %r]\r", serverRname, myRname, instance);
shhhh = StartConversation(myRname, &nullKeyB, serverRname, slECB);
wf1("StartConversation[...] = %xH\r", shhhh);
AttachConversation(&clientInterface, shhhh);
Server(instance);
myModel = (struct Model *) Allocate(sysZone, lenModel);
myModel->genre = 1; /* Lark1 */
myModel->hardwareVersion = 5; /* or something */
myModel->softwareVersion = 6; /* or something */
/* Now register in (once, for now) */
args[0] = (int) pNil; /* oldHandle: none yet */
args[1] = (int) Swab(GetPupHost()); /* netAddress: */
args[2] = (int) myModel; /* model: */
args[3] = (int) instance
args[4] = (int) myRname; /* <<not sure this still belongs here.>> */
wf("Register[...] = ");
smartsHandle = CallFormatted(handle, iRegister, spRegister, spD1, args);
wf2("%xH, %xH]\r", smartsHandle[0], smartsHandle[1]);
}; /* endloop */
};
static Server(instance)
struct ShortSTRING *instance;
{
struct InterfaceName *interface;
int *specs;
interface = (struct InterfaceName *) Allocate(sysZone, lenInterfaceName);
interface->type = CStringToString("Lark.Lark");
interface->instance = instance;
Move2(&interface->version, matchAllVersions);
specs = StartDispatcherSpecs(10);
AddToDispatcherSpecs(specs, iReset, &Reset, spSt, spNl);
AddToDispatcherSpecs(specs, iGenerateTones, &GenerateTones, sp8, sp1);
AddToDispatcherSpecs(specs, iFeep, &Feep, sp4Sq, sp1);
AddToDispatcherSpecs(specs, iCommands, &Commands, spSq, spNl);
AddToDispatcherSpecs(specs, iConnect, &Connect, spX, spNl);
AddToDispatcherSpecs(specs, iDisconnect, &Disconnect, spD1, spNl);
AddToDispatcherSpecs(specs, iPleaseRegister, &PleaseRegister, spNl, spNl);
AddToDispatcherSpecs(specs, iWhatIsStatus, &WhatIsStatus, sp1, sp1Sq);
AddToDispatcherSpecs(specs, iWhatAreConnections, &WhatAreConnections, sp1, sp1X);
AddToDispatcherSpecs(specs, iWhatAreTones, &WhatAreTones, spNl, sp1);
ExportInterface(interface, &StdDispatcher, specs);
};
Reset(rName)
struct ShortSTRING *rName;
{
wf1("Reset[%r]\r", rName);
Free(sysZone, rName);
};
GenerateTones(f1, f2, modulation, on, off, repetitions, waveTable, queueIt)
int f1, f2, modulation, on, off, repetitions, waveTable, queueIt;
{
wf4("GenerateTones[f1: %d, f2: %d, mod: %d, on: %d, ",
f1, f2, modulation, on);
wf4("off: %d, repetitions: %d, waveTable: %d, queueIt: %s]\r",
off, repetitions, waveTable, Bool(queueIt));
};
static char *Bool(x)
int x;
{
return x?"true":"false";
};
struct Event {
char device;
char event;
};
struct EvSeq {
int length;
struct Event evs[2];
};
int Feep(on, off, waveTable, queueIt, events)
int on, off, waveTable, queueIt;
struct EvSeq *events;
{
int i; char *evStr;
wf4("Feep[on: %d, off: %d, waveTable: %d, queueIt: %s, \r events: ",
on, off, waveTable, Bool(queueIt));
DisplayEvents(events);
wf(" ]\r");
Free(sysZone, events);
return (true);
};
Commands(events)
struct EvSeq *events;
{
wf("Commands[ ");
DisplayEvents(events);
wf(" ]\r");
Free(sysZone, events);
};
static int evArray[20];
static char *DisplayEvents(events)
struct EvSeq *events;
{
int i, d, e;
for (i=0; i<events->length; ++i) {
e=events->evs[i].event;
d=events->evs[i].device;
if (e<128) {
wf2("(%d,%c)", d, e);
};
else {
wf2("(%d,%d)", d, e);
};
};
return (" ");
};
struct VStream {
int buffer;
int key[4];
int lsoc[3];
int rsoc[3];
};
struct CSpecs {
int id[2];
int proto;
int sampleRate;
int pktSize;
int length;
struct VStream stream[8];
};
Connect(specs)
struct CSpecs *specs;
{
int i;
wf("Connect[");
wf2("id0: %04x, id1: %04x,\r", specs->id[0], specs->id[1]);
wf3("proto: %04x, sampleRate: %d, pktSize: %d,\r", specs->proto, specs->sampleRate, specs->pktSize);
wf1("nStreams: %d,\r", specs->length);
for (i = 0; i<specs->length; i += 1) PStream(&specs->stream[i]);
wf(" ]\r");
Free(sysZone, specs);
};
PStream(s)
struct VStream *s;
{
wf1(" buffer: %d,\r", s->buffer);
wf4(" key: %04x %04x %04x %04x\r", s->key[0], s->key[1], s->key[2], s->key[3]);
wf3(" lsoc: %04x %04x %04x\r", s->lsoc[0], s->lsoc[1], s->lsoc[2]);
wf3(" rsoc: %04x %04x %04x\r", s->rsoc[0], s->rsoc[1], s->rsoc[2]);
};
Disconnect(id)
int *id;
{
wf2("Disconnect[id: [%xH, %xH]]\r", id[0], id[1]);
Free(sysZone, id);
};
PleaseRegister()
{
wf("PleaseRegister[]\r");
};
int WhatIsStatus(which)
int which;
{
int res;
wf1("WhatIsStatus[which: %d] = [0, NIL]\r", which);
/* args[2] = 0; */ /* FIR can't really handle multiple returns */
if (which >= 3) res = 0;
else res = which + 1;
return (res);
};
int WhatAreConnections(which)
int which;
{
int res;
wf1("WhatAreConnections[which: %d] = [0, NIL]\r", which);
/* args[2] = 0; */ /* FIR can't really handle multiple returns */
if (which >= 3) res = 0;
else res = which + 1;
return (res);
};
int WhatAreTones()
{
wf("WhatAreTones[] = [FALSE]\r");
return (0);
};