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 = { -- <<obsolete??>> 
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,	-- <<needed when creating socket numbers?>> --
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? <<Obsolete??>>
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 ];

}.

���ü��ThSmartsPrivate.mesa
Copyright c 1985 by Xerox Corporation.  All rights reserved.
Last modified by D. Swinehart, August 6, 1985 3:50:34 pm PDT
Polle Zellweger (PTZ) December 11, 1985 11:50:41 pm PST
Last Edited by: Pier, May 3, 1984 1:04:49 pm PDT

Copies


Types

States (enumerated types) and other scalars
Parser is controlled by state sequence that's largely independent of the state of the smarts in any conversation.  Parser represents the user's wishes.  After parsing is complete, other processing determines whether these wishes can be granted.

This state is essentially a superset of Thrush.StateInConv.  It is used to express the user's wishes; when wish and reality coincide, it is set to the corresponding StateInConv, and quiescence follows, at least temporarily.
Control of the Lark hardware state (remaining types)
no ring, glitch interval, first (partial?) ring, break, nth ring


Structures

Information used by LarkSmarts and LarkTrunkSmarts implementations
They require similar information, although the trunk does not use all of it.
State of Lark hardware, shared between Lark and Trunk

Parsing control fields
Allows Lark, Lark trunk, Radio, ... smarts to parse different command languages
Command procedure to act on results of completely parsed command
Command procedure to act on results of completely parsed command
Independent of any notion of what's going on in eventInfo; desire of local user

LarkTrunkSmarts fields; something feels pretty wrong here.
Access to the Lark hardware via the Lark interface.  This monitored record is shared by the Smarts info for both the LarkSmarts and LarkTrunkSmarts.  There are also some random shared fields kept here.

Special attributes.  << Not clear how set >>
Some values that have to be preserved from one larkState to another

Prose control values

Click and ring detect timings
Ringing control information
When a Note in a tune specifies "notify", expectedNotification is incremented (mod the lower-case letters) and sent along to the Lark.  When the Lark finishes that note, it notifies the smarts, and eventually LarkOut, using that value.  It's possible (though not desired) for this notification to precede the "WAIT" that pends notification.  In this case, we mustn't wait.  See LarkOutImpl.DoTones and ditto.WaitQ. receivedNotification is set to a value outside the range just after each WAIT opportunity terminates.
LarkSupervisor Variables

Procedures
ENTRY version
INTERNAL version
INTERNAL version
A way to feed back tone completions, initiated by LarkOut, back to LarkOut.
Feep tones don't go through this path, since higher-levels need to know about the situation.
Reports low-level control marker completion from Prose (thru LarkInImpl) to LarkOutImpl, to trigger sending more text if there is any.  For Prose metering only (to avoid filling Lark and Prose buffers).
Reports client-level marker completion from Prose (thru LarkInImpl) to party level, for conversation mgmt and client completion reports.  Corresponds to the end of a Finch client SpeakText command.
Determines if user terminal appears to be offhook.  May not be able to tell if there's
a "click-mode" speakerphone call in progress.
Registration of Lark trunks (back doors)
Return current state 
Swinehart, May 21, 1985 4:39:39 pm PDT
Cedar 6.0, adding Text-to-speech service
changes to: LarkInfoBody
Polle Zellweger (PTZ) August 8, 1985 8:11:29 pm PDT
changes to: pResetConfirmEnd, stopAndFlushEnd, incorrectClientMarker, flushMarker
Polle Zellweger (PTZ) August 19, 1985 2:52:15 pm PDT
Handle Prose flushing.
changes to: pResetConfirmEnd, stopAndFlushEnd, incorrectClientMarker, flushMarker, LarkInfoBody (added flushJustFinished)
Polle Zellweger (PTZ) August 20, 1985 7:50:19 pm PDT
changes to: ResetProse, ProseControlDone, ReportProseDone
Polle Zellweger (PTZ) August 29, 1985 5:31:56 pm PDT
Place local variables from LarkOutImpl.LarkSupervisor into LarkInfo record.
changes to: LarkInfoBody, maxClientMarker, indexMarkerEnd, maxControlMarker, pReset, pResetConfirmEnd, stopAndFlush, stopAndFlushEnd, flushMarker, proseFailure
�Ê›��˜�šœ™Icodešœ
Ïmœ1™<Jšœ<™<K™7J™0—J˜�šÏk	˜	Jšžœžœžœ˜šœžœ˜Jšœg˜g—Jšœ	žœ˜&Jšœžœ˜)Jšœžœžœ˜Jšœ
žœžœ˜šœžœ˜Jšœ°žœžœC˜ý—Jšœžœ˜$J˜,J˜J˜�—šœžœžœ˜&J™�—šÏc™J™�šœžœ˜5J˜;—Jšœ
žœ˜'Jšœžœ˜Jšžœžœ
žœ˜Jšžœžœ
žœ˜Jšœžœ˜-Jšœžœ˜)Jšœ
žœ˜%J™�—šŸ™J™�™+J˜�J™ôšœžœ˜J˜Y—J™�J™ßJ˜�Jšœ4™4šœžœ˜Jšœ
Ÿ˜Jšœ
Ÿ˜JšœŸ&˜2JšœŸ˜JšœŸ.˜=JšœŸ>˜OJšœŸ(˜8JšœŸ2˜=JšœŸD˜RJšœŸ&˜2JšœŸ2˜>Jšœ
Ÿ˜'Jšœ
Ÿ˜%JšœŸ˜(Jšœ
Ÿ!˜.J˜—Jšœžœ"˜5J˜�Jšœžœ=˜LJ˜�Jšœžœ˜1J˜�šœžœ)˜;J™@—J™�šœ
žœ˜%JšœŸ˜'Jšœ	Ÿ3˜<J˜J˜�—J˜�Jšœžœ˜#J˜�JšœŸ+˜IJ˜�šœžœ˜JšœQ˜Q—šœžœžœ˜J˜ Jšœ˜Jš	œžœžœžœžœ˜.Jšœžœžœžœ˜7J˜—J™�—™
J™�JšœB™BJšœL™LJ˜�Jšœžœžœ˜&šœžœž	œž˜'J˜JšœŸ˜1JšœžœŸ7˜T˜J™5—Jšœ!žœ˜%Jšœ2Ÿ˜PJšœžœžœŸ'˜?Jšœ
ž	œŸ)˜>Jšœ	žœžœŸ>˜SJ™�J™šÏn
œžœ.˜>J™O—š œžœžœžœ˜0J™@—š 	œžœ˜"J™@—J˜%˜J™O—Jšœžœžœ˜Jšœžœ˜JšœžœŸ2˜AJšœ$žœžœ˜2J™�Jšœ:™:JšœžœžœŸ$˜?J˜�J˜—J˜�Jšœžœžœžœ
˜+Jšœ
žœžœ˜"šœžœžœ˜JšœŸ.˜MJšœ&Ÿ˜>Jšœžœ˜!J˜Jšœžœžœ˜Jšœ%žœ˜)Jšœžœ˜"J˜.Jšœžœ˜#Jšœžœ˜J˜0J˜Jšœžœž˜*Jšœ
žœžœ˜Jšœžœžœ˜Jšœžœž˜J˜J˜�——šœÉ™ÉJ™�Jšœ
žœžœ˜"šœžœž	œž˜%J˜Jšœ+Ÿ'˜RJšœžœŸ)˜4JšœŸ.˜MJšœŸ$˜;Jšœ	žœžœžœžœžœ˜/J˜�JšœŸ6˜TJš
œžœžœžœžœŸ4˜QJš
œžœžœžœžœŸ%˜BJšœ
žœžœŸ˜+Jšœ
ž	œŸ#˜<JšœŸ-˜LJšœ"Ÿ.˜PJ™,JšœžœžœŸ˜/JšœžœžœŸE˜XJšœ	žœžœŸ2˜GJšœžœžœŸ4˜NJ˜�J™CJšœžœžœ˜Jšœžœ˜Jšœžœ˜ Jšœžœžœžœ˜,Jšœžœ˜ J™�J™JšœžœžœŸ#˜=JšœžœžœŸU˜uJšœžœŸ/˜PJšœžœ˜Jšœ
žœžœ˜Jšœ
žœ˜"Jšœžœ˜$JšœžœžœžœžœžœŸ!˜HJšœžœ˜JšœžœžœŸ*˜HJ™�J™Jšœ
žœ˜J˜�Jšœžœ˜J˜"J˜$Jšœž	œ˜JšœžœŸ˜(J˜�J™JšœŸ>˜]JšœŸ˜:Jšœ Ÿ!˜AJ™„J˜&J˜'J˜�J™J˜%J˜*Jšœ!ž˜$J˜—J˜�šœžœžœ˜J˜J˜—J™�Jšœžœžœžœ˜1šœžœžœ˜"Jšœžœ˜ Jšœ
žœ˜J˜J˜�—Jšœ
žœžœ˜Jšœžœ˜Jšœžœ˜Jšœžœ˜JšœŸ˜,Jšœžœ˜JšœŸ˜8JšœžœŸ)˜FJšœ
žœ˜Jšœžœ˜J˜�——šœ
™
J˜�J™
š œž˜Jšœ@žœžœ˜JJ˜�—J™š œž˜Jšœ@žœžœ˜JJ˜�—J™š 	œžœF˜UJ™KJ™\J˜�—š 
œž˜Jšœ0˜0J˜�—š œžœžœ˜GJ™ÊJ˜�—š œžœ0˜EJ™ÅJ˜�—š œž˜šœA˜AJšžœ&˜-J˜�——š œž˜˜Jšžœžœžœ˜—J™V™-J˜�——Jšœ(™(š 
œžœ"˜5Jšœ=˜=Jšžœ#˜*—J˜�Jš œžœžœ
žœ˜<J˜�Jš 
œžœ˜$J˜�Jš œŸÐckŸœžœ.˜QJ˜�š œžœ˜J˜.Jšœžœ˜
J˜Jšœ˜Jšœž˜Jšœ
žœ˜Jšœž˜Jšœžœ˜$—J˜�š 
œžœ˜&J˜�—š œžœ˜Jšœžœ˜
Jšœ˜J˜J˜Jšœ!˜!Jšœ	ž˜Jšœžœ+˜4—J˜�Jšœžœ˜%J˜�Jšœ™š 
œžœ*˜=Jšœ"žœ˜&Jšžœ˜J˜�—Jš œžœžœ˜EJ˜�š œžœ˜ J˜�—š œžœ˜J˜J˜J˜!J˜Jšœ	žœž˜J˜J˜�—Jš œžœžœžœ˜DJ˜�š œžœ;žœ˜MJšžœžœ˜ —J˜�—J˜J˜�™&K™(KšœÏr™—™3Kšœ¢E™Q—™4K™Kšœ¢Eœ¢&™y—™4Kšœ¢-™9—™4K™KKšœ¢“™Ÿ——�…—����%Î��Ae��