<> <> <> DIRECTORY Atom USING [ GetPropFromList, PutPropOnList ], Commander USING [ CommandProc, Register ], IO, RefID USING [ ID, nullID ], Lark USING [ StatusEvent ], LarkSmartsMonitorImpl, Rope USING [ Equal, ROPE ], RPC USING [ EncryptionKey, ExportFailed ], LarkOpsRpcControl, LarkTTY, LarkTTYRpcControl USING [ ExportInterface ], ThNet USING [ pd ], ThParty USING [ RegisterServiceInterface, ReportAction ], Thrush USING [ ActionID, ActionType, Credentials, InterfaceSpec, NB, noAddress, SHHH, PartyID, SmartsID ], ThSmartsPrivate USING [ ConvDesc, DBInfo, Deb, EnterLarkState, Fail, GetConv, GetSmartsInfo, LarkCallBody, LarkInfo, RegisterServiceProvider, SmartsInfo ], VoiceUtils USING [ CmdOrToken, CurrentPasskey, MakeRName, Problem, ProblemFR, ReportFR ] ; LarkTTYImpl: CEDAR MONITOR LOCKS root IMPORTS Atom, Commander, IO, root: LarkSmartsMonitorImpl, LarkOpsRpcControl, LarkTTYRpcControl, Rope, RPC, ThNet, ThParty, ThSmartsPrivate, VoiceUtils EXPORTS LarkTTY SHARES LarkSmartsMonitorImpl= { OPEN IO; <> <<>> LarkInfo: TYPE = ThSmartsPrivate.LarkInfo; ttyServerSpec: Thrush.InterfaceSpec _ [interfaceName: [type: "LarkTTY"], serviceID: RefID.nullID]; ttyServerUser: Rope.ROPE; ttyServerPassword: RPC.EncryptionKey; <> <<>> LTInfo: TYPE = REF LTInfoBody; LTInfoBody: TYPE = RECORD [ cDesc: ThSmartsPrivate.ConvDesc _ NIL, requestingParty: Thrush.PartyID _ TRASH ]; <<>> <> <<>> LarkTTYInit: Commander.CommandProc = { ttyServerSpec.interfaceName.instance _ NIL; ttyServerSpec.hostHint _ Thrush.noAddress; ttyServerUser _ VoiceUtils.MakeRName[style: rName, name: VoiceUtils.CmdOrToken[cmd: cmd, key: "ThrushServerInstance", default: "Strowger.Lark"]]; ttyServerPassword _ VoiceUtils.CurrentPasskey[VoiceUtils.CmdOrToken[ cmd: cmd, key: "ThrushServerPassword", default: "MFLFLX"]]; ThSmartsPrivate.RegisterServiceProvider[$larktty, LarkTTYRegister]; VoiceUtils.ReportFR["Initialize[LarkTTY.Lark, %s]", $System, NIL, rope[ttyServerUser]]; }; LarkTTYRegister: PROC[ credentials: Thrush.Credentials, smartsInfo: ThSmartsPrivate.SmartsInfo] = { ENABLE { RPC.ExportFailed => { VoiceUtils.Problem["LarkTTY export failed", $System]; GOTO CantExportLarkTTY; }; }; exportRequired: BOOL _ ttyServerSpec.interfaceName.instance = NIL; nb: Thrush.NB; IF ~ThSmartsPrivate.DBInfo[ partyID: credentials.partyID, attribute: $larktty].value.Equal["true", FALSE] THEN RETURN; <> ttyServerSpec.serviceID _ credentials.smartsID; -- identify self. [nb, ttyServerSpec] _ ThParty.RegisterServiceInterface[credentials: credentials, interfaceSpecPattern: ttyServerSpec]; IF nb#$success THEN GOTO CantExportLarkTTY; IF exportRequired THEN LarkTTYRpcControl.ExportInterface[ ttyServerSpec.interfaceName, ttyServerUser, ttyServerPassword! RPC.ExportFailed => GOTO CantExportLarkTTY]; EXITS CantExportLarkTTY => { VoiceUtils.Problem["Couldn't export LarkTTY"]; RETURN; }; }; PutRope: PUBLIC ENTRY PROC -- TAKES -- [ shhh: Thrush.SHHH, credentials: Thrush.Credentials, -- authenticates caller serviceID: RefID.ID, -- identifies particular service rope: Rope.ROPE ] RETURNS [nb: Thrush.NB _ $success] = { ENABLE UNWIND => NULL; larkInfo: LarkInfo; cDesc: ThSmartsPrivate.ConvDesc; smartsInfo: ThSmartsPrivate.SmartsInfo _ ThSmartsPrivate.GetSmartsInfo[serviceID]; ltInfo: LTInfo; IF smartsInfo=NIL OR smartsInfo.failed THEN RETURN[nb: $noSuchSmarts]; larkInfo _ smartsInfo.larkInfo; ltInfo _ GetLTInfo[larkInfo]; cDesc _ ThSmartsPrivate.GetConv[smartsInfo, credentials, FALSE]; IF cDesc=NIL THEN RETURN[nb: $noSuchConv]; ltInfo.cDesc _ cDesc; ltInfo.requestingParty _ credentials.partyID; <> ThSmartsPrivate.EnterLarkState[larkInfo, larkInfo.larkState, LIST[NEW[ThSmartsPrivate.LarkCallBody _ [IssueCommandString, rope]]]]; }; <> <> <> <> <<>> ReportInputEvent: ENTRY PROC [info: LarkInfo, sEvent: Lark.StatusEvent] ~ { <> nb: Thrush.NB; ltInfo: LTInfo _ GetLTInfo[info]; cDesc: ThSmartsPrivate.ConvDesc _ IF ltInfo=NIL THEN NIL ELSE ltInfo.cDesc; i: CARDINAL _ LOOPHOLE[sEvent.event]; c: Thrush.ActionID _ i; IF cDesc=NIL THEN RETURN; nb _ ThParty.ReportAction[ report: [ self: cDesc.situation.self, -- placeholder other: cDesc.situation.self, requestingParty: ltInfo.requestingParty, actionID: c, -- the actual character, for now (actionInfo later) actionClass: $larktty, actionType: $getchar ], reportToAll: FALSE ].nb; IF nb = $success THEN RETURN; IF info#NIL AND ~info.failed THEN ThSmartsPrivate.Fail[info, IO.PutFR["Couldn't report Lark text-input completion -- %g", atom[nb]], TRUE] ELSE VoiceUtils.ProblemFR["Couldn't report Lark text-input completion, probably due to earlier failure -- %g", $System, NIL, atom[nb]]; }; <> <<>> GetLTInfo: INTERNAL PROC[info: LarkInfo] RETURNS [ltInfo: LTInfo_NIL] = { <> IF info=NIL THEN { VoiceUtils.Problem["No larkInfo at GetLTInfo", $System]; RETURN; }; info.keyboardEventHandler _ ReportInputEvent; <> ltInfo _ NARROW[Atom.GetPropFromList[info.props, $ltInfo]]; IF ltInfo#NIL THEN RETURN; ltInfo _ NEW[LTInfoBody_[]]; info.props _ Atom.PutPropOnList[info.props, $ltInfo, ltInfo]; }; IssueCommandString: PROC[info: LarkInfo, clientData: REF] = { textPkt: Rope.ROPE = NARROW[clientData]; IF ThNet.pd.debug THEN ThSmartsPrivate.Deb[info, "Send text to RS232 port", rope[textPkt]]; info.interface.CommandString[shh: info.shh, device: keyboard, commands: textPkt]; }; Commander.Register["LarkTTY", LarkTTYInit, "LarkTTY \nInitialize and Export Lark TTY (char aux input/output) Implementation."]; }. <<>> <> <> <<>> <<>> <<>> <<>> <<>> <<>>