<> <> <> <> <> DIRECTORY IO USING [ STREAM ], Lark USING [ CommandEvents, ConnectionSpec, disabled, enabled, Event, LarkModel, o3i1, StatusEvent, ToneSpec, ts0 ], LarkPlay USING [ ToneList, ToneSpec ], LarkRpcControl USING [ InterfaceRecord ], Rope USING [ROPE], BasicTime USING [ GMT ], Thrush USING [ ConversationHandle, ConvEvent, ConvEventBody, Disposition, IntervalSpecs, IntID, NetAddress, nullHandle, nullConvHandle, nullIntID, PartyHandle, ProseSpec, ProseSpecs, Reason, ROPE, SHHH, SmartsHandle, StateInConv, Tune, VoiceDirection, VoiceInterval ], ThPartyPrivate USING [ SmartsData ], ThSmartsRpcControl USING [ InterfaceRecord ] ; ThSmartsPrivate: CEDAR DEFINITIONS = { <<>> <> <<>> ConversationHandle: TYPE = Thrush.ConversationHandle; nullConvHandle: ConversationHandle = Thrush.nullConvHandle; PartyHandle: TYPE = Thrush.PartyHandle; Reason: TYPE = Thrush.Reason; ROPE: TYPE = Thrush.ROPE; SHHH: TYPE = Thrush.SHHH; SmartsData: TYPE = ThPartyPrivate.SmartsData; SmartsHandle: TYPE = Thrush.SmartsHandle; StatusEvent: TYPE = Lark.StatusEvent; <<>> <> <<>> <> <> 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]; HookState: TYPE = { onhook, telset, spkr, sPkr, spKr, both, bOth, monitor }; TerminalType: TYPE = {std, spkr, monitor, radio}; RingDetState: TYPE = { idle, maybe, ring1, between, ring }; <> <<>> RingMode: TYPE = { -- <> internal, -- standard ringing cadence trunk -- distinctive ringing for incoming back door calls }; Orig: TYPE = { unknown, us, them }; click: Lark.Event = Lark.ts0; -- Momentary closure of speaker box switch. 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 [ smarts: SmartsData, -- back pointer to my smarts. otherSmarts: SmartsData_NIL, -- trunk or station smarts, depending on which this is. larkInfo: LarkInfo, <> conversations: OpenConversations_NIL, currentConvID: ConversationHandle_nullConvHandle, -- the one we're dealing with. thProcess: PROCESS_NIL, -- the process that manages Lark smarts thAction: CONDITION, -- poke this when something has happened. apprise: BOOL_FALSE, -- needs to be true before waking to thAction has any meaning. <<>> <> ParseEvent: PROC[smartsInfo: SmartsInfo, sEvent: StatusEvent], <> Command: PROC[info: SmartsInfo, val: INT_0]_NIL, <> Supervise: PROC[info: SmartsInfo], <> lastTouchpadChar: Lark.Event _ '\000, parseState: ParseState _ idle, <> arguments: ROPE_NIL, argLength: NAT_0, offset: NAT_0, -- kludge allowing more than ten touchpad commands haveArguments, cmdOrRecip, haveOne: BOOLEAN_FALSE, <<>> <> phoneNumber: Rope.ROPE_NIL -- signalling information for TelCo. ]; OpenConversations: TYPE = LIST OF ConvDesc; ConvDesc: TYPE = REF ConvDescBody; ConvDescBody: TYPE = RECORD [ cState: Thrush.ConvEventBody, -- amalgam of useful info from reported events desiredState: Thrush.StateInConv_any, -- what we're aiming for desiredPartyID: PartyHandle_NULL, desiredReason: Reason_wontSay, desiredComment: ROPE_NIL, newIntervals: Thrush.IntervalSpecs _ NIL, iTail: Thrush.IntervalSpecs _ NIL, desiredIntID: Thrush.IntID _ Thrush.nullIntID, newProses: Thrush.ProseSpecs _ NIL, pTail: Thrush.ProseSpecs _ NIL, desiredProseID: Thrush.IntID _ Thrush.nullIntID, originator: Orig _ unknown, newSpec, newKeys, newAddress: BOOL _FALSE, newEvent: BOOL_FALSE, signallingStarted: BOOL_FALSE, descValid: BOOL_FALSE ]; <> <<>> LarkInfo: TYPE = REF LarkInfoBody; LarkInfoBody: TYPE = MONITORED RECORD [ interface: LarkRpcControl.InterfaceRecord, -- here's how you make calls to Lark -- shh: SHHH, -- here's what you use to encrypt them -- 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 stateChange: CONDITION, -- larkProcess should notice change hookState: HookState _ onhook, -- state of switchhook/speakerphone switch... terminalType: TerminalType _ std, -- telset, speakerphone, or monitor switching. <>>> autoAnswer: BOOL_FALSE, -- answers when called. radio: BOOL_FALSE, -- used with hotline; connects line in instead of telset when called. monitor: BOOL_FALSE, -- speaker repeats telset receiver in telset mode. textToSpeech: BOOL_FALSE, -- Prose 2000 synthesizer is available on this Lark. <> forwardedCall: BOOL_FALSE, spec: Lark.ConnectionSpec_NIL, toneSpec: LarkPlay.ToneSpec_NIL, nextToneList: LIST OF LarkPlay.ToneList_NIL, larkToneSpec: Lark.ToneSpec_NIL, <<>> <> proseResponse: 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_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, ringDetWaitState: RingDetState_idle, ringDetCondition: CONDITION, ringDetInstance: CARDINAL_0, -- paranoia <> ringMode: RingMode _ internal, -- what kind of ringing should we do next time? <> ringTune: LarkPlay.ToneSpec, -- Specification of ring tune ringingTune: LarkPlay.ToneSpec, -- Specification of ringback tune <> expectedNotification: Lark.Event _ 'z, receivedNotification: Lark.Event _ 'Y, <> lastTerminalType: TerminalType _ std, lState: LState _ [lSw: ALL[Lark.enabled]], scratchEv: Lark.CommandEvents _ NIL ]; LarkStateSpec: TYPE = RECORD [ state: LarkState, sInfo: SmartsInfo ]; <<>> LarkProseQueue: TYPE = LIST OF LarkProseSpecBody; LarkProseSpecBody: TYPE = RECORD [ proseSpec: Thrush.ProseSpec_NIL, proseMarker: INT_0 ]; ProseCmd: TYPE = Rope.ROPE; indexMarkerEnd: CHAR = 'z; maxClientMarker: INT = 199; maxControlMarker: INT = 250; pReset: ProseCmd; -- = "\022" (ControlR) NO! pResetConfirmEnd: CHAR = 'n; stopAndFlush: ProseCmd; -- = "\033[S" (\033 is ESC) NO! stopAndFlushEnd: CHAR = 'n; -- for confirm, rename to flushConfirmEnd flushMarker: INT = 1000; proseFailure: INT = 1001; <> <> EnterLarkState: PROC [ info: LarkInfo, newState: LarkState, sInfo: SmartsInfo, data: REF_NIL ]; <> EnterLarkSt: PROC [ info: LarkInfo, newState: LarkState, sInfo: SmartsInfo, data: REF_NIL ]; <> TonesDone: PROC[ info: LarkInfo, commandEvent: Lark.StatusEvent, sInfo: SmartsInfo ]; <> <> QueueFeeps: PROC [ sInfo: SmartsInfo, feeps: Thrush.ProseSpecs ]; ProseControlDone: PROC[info: LarkInfo, marker: INT, sInfo: SmartsInfo]; <> 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[ hostPartyID: Thrush.PartyHandle, hostSmarts: ThPartyPrivate.SmartsData, hostInfo: SmartsInfo ] RETURNS [ smartsID: Thrush.SmartsHandle ]; EnableSmarts: PROC[info: SmartsInfo] RETURNS[enabled: BOOL]; Deregister: PROC[info: SmartsInfo ]; LarkParseEvent: -- INTERNAL -- PROC[smartsInfo: SmartsInfo, sEvent: StatusEvent]; LarkProgress: PROC[ interface: ThSmartsRpcControl.InterfaceRecord, shh: SHHH, smartsID: Thrush.SmartsHandle, event: Thrush.ConvEvent, yourParty: BOOL, latestEvent: BOOL, informationOnly: BOOL ] RETURNS [ d: Thrush.Disposition ]; LarkSupervise: PROC[info: SmartsInfo]; LarkSetInterval: PROC[ shh: SHHH, smartsID: SmartsHandle, tune: Thrush.Tune, interval: Thrush.VoiceInterval, direction: Thrush.VoiceDirection, queueIt: BOOLEAN ] RETURNS [ d: Thrush.Disposition, u: Thrush.Tune ]; LarkFailed: ERROR[sInfo: SmartsInfo]; <> GetSmartsInfo: PROC[smartsID: SmartsHandle_Thrush.nullHandle, smarts: ThPartyPrivate.SmartsData_NIL] RETURNS [info: SmartsInfo]; GetSIC: PROC[info: SmartsInfo] RETURNS [ state: Thrush.StateInConv ]; Apprise: PROC[info: SmartsInfo]; ChangeState: PROC[ info: SmartsInfo, cDesc: ConvDesc, state: Thrush.StateInConv _ idle, reason: Reason _ wontSay, comment: ROPE_NIL ]; GetConvDesc: PROC[info: SmartsInfo] RETURNS [ cDesc: ConvDesc_NIL ]; GetConv: PROC[info: SmartsInfo, convID: ConversationHandle, validIfNew: BOOL] RETURNS [ cDesc: ConvDesc_NIL ]; }. <> <> <> <> <> <> <> <> <> <> <> <> <>