<<>> <> <> <> <> DIRECTORY Atom USING [ GetPName ], IO, PhSmarts USING [ ConvDesc, ConvDescBody, OpenConversations, PhoenixInfo ], PhSwitch USING [ StartSession ], RefID USING [ ID, Reseal ], Thrush USING [ ConversationID, ConvEvent, ConvEventBody, Credentials, NB, nullID, nullConvID, PartyID, PartyType, Reason, ROPE, SHHH, SmartsID, StateInConv], ThParty USING [ AddAttributes, Attributes, DescribeParty, RegisterConversation ], VoiceUtils USING [ MakeAtom, ProblemFR], NameDB USING [ GetAttribute ]; PhPrivateImpl: CEDAR PROGRAM IMPORTS Atom, IO, PhSwitch, RefID, ThParty, VoiceUtils, NameDB EXPORTS PhSmarts ~ BEGIN <> <<>> ConversationID: TYPE = Thrush.ConversationID; nullConvID: ConversationID=Thrush.nullConvID; ConvDesc: TYPE = PhSmarts.ConvDesc; ConvEvent: TYPE = Thrush.ConvEvent; Reseal: PROC[r: REF] RETURNS[RefID.ID] = INLINE {RETURN[RefID.Reseal[r]]; }; NB: TYPE = Thrush.NB; OpenConversations: TYPE = PhSmarts.OpenConversations; PartyID: TYPE = Thrush.PartyID; nullID: RefID.ID = Thrush.nullID; ROPE: TYPE = Thrush.ROPE; SmartsID: TYPE = Thrush.SmartsID; PhoenixInfo: TYPE = PhSmarts.PhoenixInfo; StateInConv: TYPE = Thrush.StateInConv; <> ForgetConv: PUBLIC PROC[cDesc: ConvDesc] = { <> info: PhoenixInfo = cDesc.info; convs: OpenConversations ¬ info.conversations; IF convs=NIL THEN RETURN ELSE IF convs.first=cDesc THEN info.conversations ¬ convs.rest ELSE FOR cS: OpenConversations ¬ convs, cS.rest WHILE cS.rest#NIL DO IF cS.rest.first=cDesc THEN { cS.rest ¬ cS.rest.rest; EXIT; }; ENDLOOP; }; GetConv: PUBLIC PROC[ info: PhoenixInfo, credentials: Thrush.Credentials, createOK: BOOL¬FALSE ] RETURNS [ cDesc: ConvDesc¬NIL ] = { partyID: PartyID¬credentials.partyID; convID: ConversationID ¬ credentials.convID; convName: ROPE; vtClass, vtAddress: ROPE; nb: NB; SELECT credentials.smartsID FROM nullID => credentials.smartsID ¬ info.smartsID; info.smartsID => NULL; ENDCASE=>ERROR; FOR convs: OpenConversations ¬ info.conversations, convs.rest WHILE convs#NIL DO IF convs.first.situation.self.convID = convID THEN RETURN[convs.first]; ENDLOOP; IF ~createOK THEN { VoiceUtils.ProblemFR["Couldn't find referenced conversation, id= %g", $System, NIL, IO.time[convID]]; RETURN; }; IF partyID=nullID THEN partyID ¬ info.partyID; cDesc ¬ NEW[PhSmarts.ConvDescBody¬[]]; cDesc.situation.self ¬ credentials; cDesc.situation.self.state ¬ $neverWas; cDesc.info ¬ info; info.conversations ¬ CONS[cDesc, info.conversations]; convName ¬ DBInfo[partyID, $conversationname].value; IF convName#NIL THEN []¬ThParty.RegisterConversation[shhh: info.shh, credentials: credentials, name: convName, convAttributes: LIST[[$subject, convName]], accessList: LIST["*"]]; <> [vtClass, vtAddress] ¬ PhSwitch.StartSession[cDesc]; IF ThParty.AddAttributes[credentials: credentials, convAttributes: NIL, partyAttributes: LIST [[$VTClass, vtClass], [$VTAddress, vtAddress]]]#$success THEN ERROR; }; DBInfo: PUBLIC PROC[partyID: Thrush.PartyID, attribute: ATOM¬NIL, prevRNAtom: ATOM¬NIL] RETURNS [rName: ROPE¬NIL, rNAtom: ATOM¬NIL, value: ROPE¬NIL] = { nb: NB ¬ $success; rNAtom ¬ prevRNAtom; IF rNAtom#NIL THEN rName ¬ Atom.GetPName[rNAtom] ELSE IF partyID#nullID THEN [nb, rName] ¬ ThParty.DescribeParty[partyID: partyID, nameReq: $current]; IF nb # $success OR rName=NIL THEN RETURN; IF rNAtom=NIL THEN rNAtom ¬ VoiceUtils.MakeAtom[rName: rName, case: FALSE]; IF attribute#NIL THEN value ¬ NameDB.GetAttribute[rName, attribute]; }; END. <> <<>> <> FindActiveConv: PUBLIC PROC [info: PhoenixInfo] RETURNS [cDesc: ConvDesc¬NIL] ~ { FOR convs: OpenConversations ¬ info.conversations, convs.rest WHILE convs#NIL DO IF convs.first.situation.self.state = $active THEN RETURN[convs.first]; ENDLOOP; }; MoreThanOneConversation: PUBLIC PROC [info: PhoenixInfo] RETURNS [BOOL] ~ { openConvs: OpenConversations ¬ info.conversations; IF openConvs.rest # NIL THEN RETURN[TRUE] ELSE RETURN[FALSE]; }; MoreThanOneAudioConversation: PUBLIC PROC [info: PhoenixInfo] RETURNS [BOOL] ~ { totalAudioConversations: INT ¬ 0; openConvs: OpenConversations ¬ info.conversations; IF openConvs # NIL THEN { WHILE openConvs # NIL DO cDesc: ConvDesc ¬ openConvs.first; IF cDesc.cInfo.media # $Video--only-- THEN { totalAudioConversations ¬ totalAudioConversations + 1; }; openConvs ¬ openConvs.rest; ENDLOOP; }; IF totalAudioConversations > 1 THEN RETURN[TRUE] ELSE RETURN[FALSE]; }; VideoHardwareInUse: PUBLIC PROC [cDesc: ConvDesc] RETURNS [inUse: BOOL] ~ { <> convID: ConversationID ¬ cDesc.situation.self.convID; info: PhoenixInfo ¬ cDesc.info; IF info=NIL OR convID = nullConvID THEN RETURN[FALSE]; <> FOR convs: OpenConversations ¬ info.conversations, convs.rest WHILE convs#NIL DO IF (convs.first.situation.self.convID # convID) THEN { IF convs.first.cInfo.media # $Audio--only-- THEN { IF convs.first.situation.self.state = $active THEN RETURN[TRUE]; }; }; ENDLOOP; RETURN[FALSE]; }; requiresHardware: ARRAY StateInConv OF BOOL ¬ [ <> FALSE, FALSE,TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE ]; <> FetchAttribute: PROC[ attributes: ThParty.Attributes, attribute: ATOM, default: ROPE¬NIL] RETURNS [value: ROPE, valueLoc: ThParty.Attributes¬NIL] = { value ¬ default; FOR aL: ThParty.Attributes ¬ attributes, aL.rest WHILE aL#NIL DO IF aL.first.type = attribute THEN RETURN[aL.first.value, aL]; ENDLOOP; };