<> <> <> DIRECTORY IO USING [ STREAM ], Lark USING [ CommandEvents, disabled, enabled, Event, LarkModel, o3i1, StatusEvent, ts0 ], LarkPlay USING [ ToneSpec ], LarkRpcControl USING [ InterfaceRecord ], Rope USING [ROPE], BasicTime USING [ GMT ], Thrush USING [ ConversationHandle, ConvEvent, ConvEventBody, Disposition, IntervalSpecs, IntID, NetAddress, nullHandle, nullConvHandle, nullIntID, PartyHandle, Reason, ROPE, SHHH, SmartsHandle, StateInConv, Tune, VoiceDirection, VoiceInterval ], ThPartyPrivate USING [ SmartsData ]; 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: CHAR_'4, -- nonsense value to force initialization first time. 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, 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. <>>> hotLine: 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. <> 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 ]; <<>> <> <> EnterLarkState: PROC [ info: LarkInfo, newState: LarkState, sInfo: SmartsInfo ]; <> EnterLarkSt: PROC [ info: LarkInfo, newState: LarkState, sInfo: SmartsInfo ]; <> TonesDone: PROC[ info: LarkInfo, commandEvent: Lark.StatusEvent, sInfo: SmartsInfo ]; <> <> InterpretHookState: PROC [ info: LarkInfo, rawEvent: Lark.StatusEvent ] 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[ 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 ]; }.