/* 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); };