<> <> <> <> <> DIRECTORY IO USING [ STREAM ], Lark USING [ CommandEvents, ConnectionSpec, disabled, enabled, Event, KeyTable, LarkModel, o3i1, StatusEvent, ToneSpec, ts0, ts12 ], LarkPlay USING [ ToneList, ToneSpec ], LarkOpsRpcControl USING [ InterfaceRecord ], MBQueue USING [ Queue ], Rope USING [ROPE], BasicTime USING [ GMT ], Thrush USING [ ActionReport, ConversationID, ConvEvent, ConvEventBody, NB, NetAddress, nullID, nullConvID, PartyID, PartyType, ProseSpec, Reason, ROPE, SHHH, SmartsID, StateInConv ], ThParty USING [ PartyInfo ], ThPartyPrivate USING [ SmartsData ], ThSmartsRpcControl USING [ InterfaceRecord ] ; ThSmartsPrivate: CEDAR DEFINITIONS = { <<>> <> <<>> SHHH: TYPE = Thrush.SHHH; SmartsData: TYPE = ThPartyPrivate.SmartsData; <<>> <> <<>> <> <> ParseState: TYPE = { idle, getStr, getSeq, getFeep, getNum, inStr, inSeq, inFeep, inNum, inTossStr }; <<>> <> <> LarkState: TYPE = { none, -- Initial state idle, -- Phone not in use talking, -- Etherphone conversation in progress trunkSignalling, -- "Feeping" trunkTalking, -- Standard telephone conversation in progress trunkForwarding, -- Like trunkTalking, but call is forwarded to some other Lark trunkFlashing, -- Implementing special switchhook flash failed, -- This Lark has died and its brain is dying, too. recovering, -- Lark is presumed not to work, but use attempts don't raise ERRORS ringing, -- Ringing loudly through Lark speaker silence, -- Dial tone has been broken, dialing in progress. dialTone, -- Caller hears dial tone. ringBack, -- Caller hears ringing. busyTone, -- Caller hears busy signal. errorTone -- Caller hears fast busy signal. }; ProgressTones: TYPE = LarkState[dialTone..errorTone]; SwitchState: TYPE = { onhook, telset, speaker, sPEAKER, monitor, mONITOR }; <> < telset (sh on), speaker (sw click), sPEAKER (sw on)>> < onhook (sh off), monitor (sw click), mONITOR (sw on)>> < onhook (sw click), sPEAKER (sw on), telset (sh on)>> < onhook (sw off), mONITOR (sh on)>> < telset (sw click), speaker (sh off), mONITOR (sh on)>> < telset (sw off), sPEAKER (sh off)>> <> RingDetState: TYPE = { idle, maybe, ring, between }; <> Orig: TYPE = { unknown, us, them }; AudioSource: TYPE = ATOM; -- = {$telset (NIL), $lineA, $lineB}; click: Lark.Event = Lark.ts0; -- Momentary closure of speaker box switch. spkrOn: Lark.Event = Lark.ts12; -- Longer-than-momentary closure. LSwitches: TYPE = { xBarAll, hook, aSwitch, sideTone, ringO, revert, revertHook, led, spMode, none }; LState: TYPE = RECORD [ voiceMode: Lark.Event_Lark.o3i1, echoStyle: [0..3]_0, xbar: PACKED ARRAY[0..8) OF [0..256) _ ALL[0], lSw: ARRAY LSwitches OF Lark.Event _ ALL[Lark.disabled] ]; <<>> <> <<>> <> <> SmartsInfo: TYPE = REF SmartsInfoBody; SmartsInfoBody: TYPE = MONITORED RECORD [ smartsID: Thrush.SmartsID, -- back pointer to my smarts. otherSmartsID: Thrush.SmartsID_Thrush.nullID, <> partyType: Thrush.PartyType_NIL, -- type of party this smarts represents. larkInfo: LarkInfo, <> conversations: OpenConversations_NIL, currentConvID: Thrush.ConversationID_Thrush.nullConvID, -- the one we're dealing with. requests: MBQueue.Queue_NIL, -- serialize progress reports, requests for actions <<>> <> ParseEvent: PROC[smartsInfo: SmartsInfo, sEvent: Lark.StatusEvent], <> Command: PROC[info: SmartsInfo, val: INT_0]_NIL, <> NoteNewStateP: PROC[cDesc: ConvDesc, convEvent: Thrush.ConvEvent]_NIL, <> lastTouchpadChar: Lark.Event _ '\000, parseState: ParseState _ $idle, <> arguments: Rope.ROPE_NIL, argLength: NAT_0, offset: NAT_0, -- kludge allowing more than ten touchpad commands haveArguments, cmdOrRecip, haveOne: BOOLEAN_FALSE ]; OpenConversations: TYPE = LIST OF ConvDesc; ConvDesc: TYPE = REF ConvDescBody; ConvDescBody: TYPE = RECORD [ info: SmartsInfo, -- corresponding to credentials.smartsID (or else!) situation: Thrush.ConvEventBody, -- .self describes current state in conv. keyTable: Lark.KeyTable _ NIL ]; <<Temporarily out of service -- please use the circular stairway>> <> <> <> <> <> <> <> <> <> <> <<>> ConvRequest: TYPE = REF ConvRequestBody; ConvRequestBody: TYPE = RECORD [ cDesc: ConvDesc, -- present state, desiredSituation: Thrush.ConvEventBody _ [] ]; <> <<>> LarkInfo: TYPE = REF LarkInfoBody; LarkInfoBody: TYPE = MONITORED RECORD [ interface: LarkOpsRpcControl.InterfaceRecord, -- here's how you make calls to Lark -- shh: SHHH, -- here's what you use to encrypt them -- larkSmartsInfo: SmartsInfo, -- back pointers larkTrunkSmartsInfo: SmartsInfo, -- back pointers netAddress: Thrush.NetAddress, -- <> -- model: Lark.LarkModel, -- what does this Lark look like? -- debugIn: IO.STREAM, debugPrint: IO.STREAM_NIL, larkState: LarkState _ $none, -- tone/crossbar/connect state of actual Lark hardware newActions: LIST OF REF_NIL, -- queue of low-level requests to supervisor process lastAction: LIST OF REF_NIL, -- used in request-queue maintenance, larkProcess: PROCESS_NIL, -- maintains same blinkProcess: PROCESS _ NIL, -- created if LED must flash. stateChange: CONDITION, -- larkProcess should notice change audioSource: AudioSource _ NIL, -- e.g., $telset switchState: SwitchState _ $onhook, -- state of switchhook/speakerphone switch... textToSpeech: BOOL_FALSE, -- Prose 2000 synthesizer is available on this Lark. transmitOnly: BOOL_FALSE, -- w/line(A/B), inhibit spkr, rcvr, line(A/B) out for svcs. <> forwardedCall: BOOL_FALSE, spec: ThParty.PartyInfo_NIL, cSpec: Lark.ConnectionSpec_NIL, keyTable: Lark.KeyTable _ NIL, toneSpec: LarkPlay.ToneSpec_NIL, nextToneList: LIST OF LarkPlay.ToneList_NIL, larkToneSpec: Lark.ToneSpec_NIL, <<>> <> proseResponse: Rope.ROPE_NIL, -- holds incomplete Prose responses flushJustFinished: BOOL_FALSE, -- can expect to have to flush proseQueue next time thru LarkInImpl.HandleProseOutput proseQueue: LarkProseQueue_NIL, -- holds queue of client markers and proseSpecs pTail: LarkProseQueue_NIL, textToSpeak: Rope.ROPE_NIL, clientMarker: INT_maxClientMarker, controlMarker: INT_maxControlMarker, ctrlMarkerQueue: LIST OF REF ANY_NIL, -- holds queue of control markers pktsOutstanding: INT_0, flushInProgress: BOOL_FALSE, -- consider combining w flushJustFinished? <<>> <> swOnTime: CARDINAL_0, <> ringChangeTime: CARDINAL_0, ringDetState: RingDetState _ $idle, ringDetCondition: CONDITION, ringDetInstance: INT_0, -- timeout routine is relevant only if this matches <> <> expectedNotification: Lark.Event _ 'z, receivedNotification: Lark.Event _ 'Y, <> lastSwitchState: SwitchState _ $onhook, lState: LState _ [lSw: ALL[Lark.enabled]], scratchEv: Lark.CommandEvents _ NIL ]; <<>> LarkProseQueue: TYPE = LIST OF LarkProseSpecBody; LarkProseSpecBody: TYPE = RECORD [ proseSpec: Thrush.ProseSpec_NIL, proseMarker: INT_0 ]; ProseCmd: TYPE = Rope.ROPE; indexMarkerEnd: CHAR = 'i; maxClientMarker: INT = 199; maxControlMarker: INT = 250; pReset: ProseCmd; -- = "\022" (ControlR) pResetConfirmEnd: CHAR = 'R; stopAndFlush: ProseCmd; -- = "\033[S" (\033 is ESC) stopAndFlushEnd: CHAR = 'S; flushMarker: INT = 1000; proseFailure: INT = 1001; <> <> EnterLarkState: PROC [ info: LarkInfo, newState: LarkState, data: LIST OF REF ANY_NIL ]; <> <> <> <> <> <> <> <<$audioSource: [$lineA, $lineB, NIL ($telset)]>> <<$transmitOnly: [$TRUE, $FALSE]>> <<$phoneNumber: "number to dial">> <<$textToSpeech: [$TRUE, $FALSE]>> <> <<Making everything a dotted pair would be less efficient but more uniform.>> <> EnterLarkSt: PROC [ info: LarkInfo, newState: LarkState, data: LIST OF REF ANY_NIL ]; <> TonesDone: PROC[ info: LarkInfo, commandEvent: Lark.StatusEvent ]; <> <> QueueFeeps: PROC [ sInfo: SmartsInfo, feeps: Rope.ROPE ]; ProseControlDone: PROC[info: LarkInfo, marker: INT]; <> ReportProseDone: PROC[info: SmartsInfo, proseSpec: Thrush.ProseSpec]; <> InterpretHookState: PROC [ info: LarkInfo, rawEvent: Lark.StatusEvent, sInfo: SmartsInfo ] RETURNS [ processedEvent: Lark.StatusEvent ]; CheckHookState: PROC [ info: LarkInfo] RETURNS [ onHook: BOOL_TRUE ]; <> <> RegisterTrunk: PROC[ <> <> hostSmartsID: Thrush.SmartsID, hostInfo: SmartsInfo, partyRname: Thrush.ROPE ] RETURNS [ nb: Thrush.NB, smartsID: Thrush.SmartsID ]; EnableSmarts: PROC[info: SmartsInfo] RETURNS[enabled: BOOL]; <> Deregister: PROC[smartsID: Thrush.SmartsID]; <> LarkParseEvent: -- INTERNAL -- PROC[smartsInfo: SmartsInfo, sEvent: Lark.StatusEvent]; NoteNewState: PROC[cDesc: ConvDesc, convEvent: Thrush.ConvEvent]; ComputeConnection: PROC[cDesc: ConvDesc] RETURNS [pInfo: ThParty.PartyInfo _ NIL]; LarkProgress: PROC[ <> interface: ThSmartsRpcControl.InterfaceRecord, shh: SHHH, convEvent: Thrush.ConvEvent ]; LarkSubstitution: PROC[ interface: ThSmartsRpcControl.InterfaceRecord, shh: SHHH, convEvent: Thrush.ConvEvent, oldPartyID: Thrush.PartyID, newPartyID: Thrush.PartyID ]; LarkReportAction: PROC[ interface: ThSmartsRpcControl.InterfaceRecord, shh: SHHH, report: Thrush.ActionReport ]; <> <> <> <> <> <> <> <<] RETURNS [ d: Thrush.Disposition, u: Thrush.Tune ];>> LarkFailed: ERROR[sInfo: SmartsInfo]; <> GetSmartsInfo: PROC[smartsID: Thrush.SmartsID] RETURNS [info: SmartsInfo]; GetSIC: PROC[info: SmartsInfo] RETURNS [ state: Thrush.StateInConv ]; ChangeState: PROC[ cDesc: ConvDesc, state: Thrush.StateInConv _ $idle, reason: Thrush.Reason _ NIL, -- $wontSay comment: Thrush.ROPE_NIL ] RETURNS [nb: Thrush.NB]; -- advisory only, by this point AssessDamage: PROC [nb: Thrush.NB, cDesc: ConvDesc, convEvent: Thrush.ConvEvent]; ForgetConv: PROC[cDesc: ConvDesc]; GetConvDesc: PROC[info: SmartsInfo] RETURNS [ cDesc: ConvDesc_NIL ]; GetConv: PROC[info: SmartsInfo, convID: Thrush.ConversationID, createOK: BOOL_FALSE] RETURNS [ cDesc: ConvDesc ]; DBInfo: PROC[partyID: Thrush.PartyID, attribute: ATOM_NIL, prevDbAtom: ATOM_NIL] RETURNS [ dbRname: Rope.ROPE, dbAtom: ATOM, value: Rope.ROPE ]; <> <> }. <> <> <> <> <> <> <> <> <> <> <> <> <> <> < ID>> <> <> < LarkOps>> <> <<>>