DIRECTORY Basics USING [ LongNumber, BITAND ], Lark, Thrush USING [ AlertKind, CallUrgency, ConversationHandle, ConvEventBody, Credentials, EncryptionKey, IntervalSpec, IntervalSpecBody, NB, nullHandle, PartyHandle, PartyType, Reason, Rname, ROPE, SHHH, SmartsHandle, StateID, StateInConv, ThHandle, unencrypted ], ThSmarts USING [ SmartsInterface, SmartsProperties ] ; ThParty: CEDAR DEFINITIONS IMPORTS Basics = { PartyHandle: TYPE = Thrush.PartyHandle; ConversationHandle: TYPE = Thrush.ConversationHandle; SmartsHandle: TYPE = Thrush.SmartsHandle; nullHandle: Thrush.ThHandle = Thrush.nullHandle; AlertKind: TYPE = Thrush.AlertKind; CallUrgency: TYPE = Thrush.CallUrgency; ConvEventBody: TYPE = Thrush.ConvEventBody; Credentials: TYPE = Thrush.Credentials; IntervalSpecBody: TYPE = Thrush.IntervalSpecBody; NB: TYPE = Thrush.NB; Reason: TYPE = Thrush.Reason; Rname: TYPE = Thrush.Rname; ROPE: TYPE = Thrush.ROPE; SHHH: TYPE = Thrush.SHHH; none: SHHH = Thrush.unencrypted; SmartsInterface: TYPE = ThSmarts.SmartsInterface; StateID: TYPE = Thrush.StateID; StateInConv: TYPE = Thrush.StateInConv; convClassMask: CARDINAL = 377B; Alert: PROC[ shhh: SHHH _ none, credentials: Credentials, state: StateInConv_initiating, -- IF reserved, reason specifies reason for cancelling prev. reason: Reason_wontSay, calledPartyID: PartyHandle_nullHandle, urgency: CallUrgency_normal, alertKind: AlertKind_standard, newConv: BOOL_FALSE, comment: ROPE_NIL ] RETURNS [nb: NB, convID: ConversationHandle ]; Advance: PROC[ shhh: SHHH _ none, credentials: Credentials, state: StateInConv, reason: Reason_wontSay, comment: ROPE_NIL ] RETURNS [nb: NB]; Disconnect: PROC[ shhh: SHHH _ none, credentials: Credentials, comment: ROPE_NIL ] RETURNS [nb: NB] = INLINE { RETURN[Advance[shhh, credentials, idle, terminating, comment]]}; CreateConversation: PROC[ shhh: SHHH _ none, credentials: Credentials, urgency: CallUrgency_normal, alertKind: AlertKind_standard ] RETURNS [ nb: NB, convID: ConversationHandle ]; SameConvClass: PROC[convID1: ConversationHandle, convID2: ConversationHandle] RETURNS [sameClass: BOOL] = INLINE { ln1: Basics.LongNumber=LOOPHOLE[convID1]; ln2: Basics.LongNumber=LOOPHOLE[convID2]; IF ln1.lowbits#ln2.lowbits THEN RETURN[FALSE]; RETURN[ Basics.BITAND[ln1.highbits,convClassMask]=Basics.BITAND[ln2.highbits,convClassMask]]; }; MergeConversations: PROC[ shhh: SHHH _ none, credentials: Credentials, -- of surviving conversation otherStateID: StateID, -- of dissolving conversation otherConvID: ConversationHandle ] RETURNS [ nb: NB ]; SetSubject: PROC[ shh: SHHH_none, convID: ConversationHandle, subject: ROPE ]; GetSubject: PROC[ shh: SHHH_none, convID: ConversationHandle ] RETURNS [subject: ROPE]; OtherParty: PROC[ shhh: SHHH_none, credentials: Credentials ] RETURNS[ nb: NB, partyID: PartyHandle, description: Thrush.ROPE, conference: BOOL ]; DescribeParty: PROC[ shh: SHHH_none, partyID: PartyHandle] RETURNS[ description: Thrush.ROPE ]; ConversationsForParty: PROC [ shh: SHHH_none, partyID: PartyHandle ]; SetInterval: PROC[ shhh: SHHH _ none, credentials: Credentials, intervalSpec: Thrush.IntervalSpec ] RETURNS [ nb: NB ]; RegisterKey: PROC[ shh: SHHH _ none, credentials: Credentials, key: Thrush.EncryptionKey ] RETURNS [ nb: NB, keyIndex: [0..17B] ]; CreateParty: PROC[ shh: SHHH_none, rName: Rname_NIL, type: Thrush.PartyType ] RETURNS [partyID: PartyHandle]; GetParty: PROC[ shh: SHHH_none, partyID: PartyHandle, rName: Rname_NIL ] RETURNS [newPartyID: PartyHandle]; GetJayParty: PROC[ shh: SHHH_none, partyID: PartyHandle ] RETURNS [newPartyID: PartyHandle]; GetPartyFromNumber: PROC[ shh: SHHH_none, partyID: PartyHandle, phoneNumber: Thrush.ROPE_NIL, description: ROPE_NIL, trunkOK: BOOL_TRUE ] RETURNS [newPartyID: PartyHandle]; GetPartyFromFeepNum: PROC[ shh: SHHH_none, partyID: PartyHandle, feepNum: Thrush.ROPE_NIL ] RETURNS [newPartyID: PartyHandle]; ReleaseTrunkParty: PROC[shh: SHHH_none, partyID: PartyHandle]; GetRname: PROC[shh: SHHH_none, partyID: PartyHandle] RETURNS [Rname: Thrush.Rname]; Register: PROC[shh: SHHH_none, partyID: PartyHandle, interface: SmartsInterface, properties: ThSmarts.SmartsProperties, oldSmartsID: SmartsHandle_nullHandle] RETURNS [smartsID: SmartsHandle]; RegisterClone: PROC[shh: SHHH_none, partyID: PartyHandle, clonePartyID: PartyHandle, oldSmartsID: SmartsHandle_nullHandle] RETURNS [smartsID: SmartsHandle]; Deregister: PROC[shh: SHHH_none, smartsID: SmartsHandle]; Enable: PROC[shh: SHHH_none, smartsID: SmartsHandle] RETURNS [nb: Thrush.NB]; Disable: PROC[shh: SHHH_none, smartsID: SmartsHandle] RETURNS [nb: Thrush.NB]; GetNumbersForRName: PROC[shh: SHHH_none, rName: ROPE] RETURNS [fullRName: ROPE, number: ROPE, homeNumber: ROPE]; }. 2ThParty.mesa Last modified by Swinehart, December 28, 1983 9:15 pm Parties and Conversations Redefinitions, Obligatory Concrete, simple types Conversation Management A Smarts must relay all call-placement requests through a Party it is associated with. This is because we don't trust all Smarts as much as we trust all Parties; the Parties should validate the requests. Alert can either perform a feasibility study, or an actual attempt to connect. In either case, it provokes an answer indicating how likely it is that the connection would (will) be made. To perform the feasibility study, the alertKind parameter should be queryOnly (the conversation argument need not be supplied for this call.) This allows the calling client to determine whether the callee is busy, filtered out, missing in action, etc., before attempting to make the call. It also allows the calling client to obtain this information for some reason other than to place the call. If the call fails, perhaps it will succeed if the priority is increased. When the call has been accepted or rejected, the result will be reported back to the caller of Alert via a call to ThSmarts.Progress. Alert the end client or user associated with EACH "PENDING" PARTY of the attempted connection. Alert[..., calledPartyID: nullHandle, ... state: reserved, ...] reserves presence in conv. without attempting a connection (state reserved). Called by Smarts to progress through a call; answer, indicate "ringing", reject, "hold", . . . The Party-owning Smarts calls Disconnect to terminate the Party's participation in this conversation, voluntarily. On return, the Party is probably no longer in the conversation. The comments may be useful to indicate why one is calling things off. <> Disconnect is really "Advance[terminating]". Conversations Create a conversation with nobody in it, state empty or something. Scavengers may reclaim it after a time if no Party joins it. conv, stateID fields of Credentials are ignored. GetHistory: PROC[ -- No room, no room; for now shhh: SHHH _ none, credentials: Credentials, firstState: StateID_1, lastState: StateID _ 0 -- default: get latest ] RETURNS [ nb: NB, events: Thrush.EventSequence ]; -- if successful, will trigger new Progress reports for this range. Produces ID of one other party, + description. If # parties > 2, description is best efforts description of who's in it with credentials.partyID, conference is TRUE. Like GetRName.... but produces best available user-oriented description. Enumerations, queries Caller should expect to be informed of all conversations currently in progress for this party. So should all of the other Smartses connected to the party. Thus, a Smarts must be prepared to hear about the same event twice. <> Recorded voice management. Party Initialization The PartyHandle is used by local or remote Smarts and other Parties to invoke the Party's functions. The Party is the dynamic representative of its Rname; most of the system functions traffic in PartyHandles. Clients should convert from Rname to Party as early as possible. Returns NIL if no valid name found. Owning Smarts identify (and authenticate) themselves to Parties using Register*[]. That's where the password action is. GetParty assumes that a Party for the specified party already exists, returning NIL if none can be found. The self argument is the caller's own Party; it's used to obtain the corresponding trunk, or "back door", Party when the callee must be reached via the public network. CreateParty also returns an existing Party if there is one. If there isn't, it creates one instead, as long as the Rname is valid. This is for use by the Smarts registration procedures. Raises Thrush.ServerError if fatal confusion arises. For other troubles ~~ no such name, no network response ~~ returns NIL << Can change this if clients could use additional information. >> Obtains an idle Jay Party, assigns it to self. << It is not at all clear how this will be set back to idle again, using current implementation. >> phoneNumber is a valid extension or outside telephone number. Description is probably a name, but may not be an RName; we can use it to help the user, but not to look up anything. Unless trunkOK, number must be an internal extension representing an Etherphone user. FeepNum is a string of the form "*nnnnn", where "nnnnn" is a prefix of some rName, mapped with information loss into the corresponding DTMF buttons. The prefix should be long enough to be guaranteed unique within the system. This isn't at all good yet. If party is a trunk party, with number and descriptive identification, get rid of same. No-op if party is involved in ANY conversations. Return the Rname for a given fone A Smarts uses one of these Register* functions to identify itself as the owner (implementor) of the specified Party, and to supply the Party with necessary attribute information. If a password is provided (and is OK), the smarts will be an authenticated smarts. This will carry additional privileges. At present, the attributes comprise a role that will determine the order in which multiple Smarts for a Party will be polled, when polling is necessary. The idea is that first workstations, then Larks, will get the oportunity to deal with each action. When the role is "voiceTerminal", the attributes also include a Thrush.Machine value identifying the machine that can carry out a voice conversation. Since there can be more than one Smarts implementation per Party, the Smarts must also supply its interface as an RPC-style interface record. A Thrush-based Smarts uses RegisterLocal to supply the interface record directly (type LocalSmartsInterface). A remote Smarts uses Register to supply an RPC InterfaceName that can be used to import the proper implementation (type SmartsInterface). A Smarts re-registers when it wants to supply a new/different password, when the Lark or workstation it represents is reinitialized, or at any other time it chooses to. When re-registering, a Smarts should include its current handle, but be willing to believe the returned one if it's different. This is the Party-level analog of the LarkSmarts.Register[] approach to resiliency. Raises Thrush.NetError, with nearly any of its failure codes. nb=success unless something went wrong. Any parties connected to this smarts will now be available to GetParty; this smarts is an active voice smarts. This smarts can no longer supply a voice connection to its parties. fullRName is NIL if nothing found. Êê˜Jšœ ™ Jšœ5™5J˜Jšœ™J˜šÏk ˜ Jšœœœ˜$J˜šœœ˜Jšœwœ5œœ>˜ö—˜J˜#—Jšœ˜J˜—Jšœ œœ ˜-J˜™0J˜Jšœ œ˜'Jšœœ˜5J˜Jšœœ˜)J˜0J˜Jšœ œ˜#Jšœ œ˜'Jšœœ˜+Jšœ œ˜'Jšœœ˜1Jšœœ œ˜J˜Jšœœ˜Jšœœ œ˜šœœ œ˜Jšœœ˜ —Jšœœ˜1Jšœ œ˜Jšœ œ˜'J˜Jšœœ˜J˜—™J˜JšœË™ËJšœâÏb œž œŠ™“Jšœ_žœžœa™åJ™ŒJ˜šÏnœœ˜ Jšœœ˜J˜Jšœ Ïc<˜\Jšœ˜J˜&J˜Jšœ˜Jšœ œœ˜Jšœ œ˜Jšœœœ˜0J˜—Jšœa™ašŸœœ˜Jšœœ˜J˜J˜Jšœ˜Jšœ œ˜Jšœœœ˜J˜—Jšœµ™µJ™,J˜šŸ œœ˜Jšœœ˜J˜Jšœ œ˜Jšœœœœ˜Jšœ:˜@—J˜—šœ ™ J˜Jšœ±™±šŸœœ˜Jšœœ˜J˜J˜J˜Jšœœ(˜1J˜—šŸ œœ:˜MJšœ œœ˜$Jšœœ ˜)Jšœœ ˜)Jšœœœœ˜.šœ˜Jšœœ$œ˜U—Jšœ˜J˜—šŸœœ˜Jšœœ˜Jšœ ˜6Jšœ ˜4J˜Jšœœ ˜J˜—JšŸ œœœ,œ˜NJš Ÿ œœœ$œ œ˜WJ˜šŸ œœ™.Jšœœ™Jšœ™J™Jšœ ™-Jšœœœ# B™w—J˜šŸ œœ˜Jšœœ˜J˜Jš œœœ,œœ˜VJšœ œ–™¦J™—šŸ œœ˜Jšœœ˜J˜Jšœ˜!Jšœ˜J™HJ™——šœ™J˜šŸœœœ˜EJ™Í—J™—™J™šŸ œœ˜Jšœœ˜Jšœ˜J˜!Jšœ˜Jšœœ˜—J˜šŸ œœ˜Jšœœ˜Jšœ˜J˜J˜Jšœœ˜'—J™—šœ™J˜Jšœ“™“Jšœ#™#JšœŠ™ŠJšœ»™»J˜šŸ œœ˜Jšœœœ˜8Jšœœ˜!—J˜šŸœœ˜Jšœœ*˜6Jšœœ˜$—Jšœ4™4JšœF™FJšœB™BJ˜Jšœ“™“šŸ œœ˜Jšœœ˜$Jšœœ˜$J˜—J™´J™UšŸœœ˜Jšœœ˜Jšœ˜Jš œœœœœ œ˜GJšœœ˜$J˜—Jšœþ™þšŸœœ˜Jšœœ˜Jšœ˜Jšœœ˜Jšœœ˜$J˜—™WJšœœ™0JšŸœœœ˜>J˜—Jšœ!™!šŸœœœœ˜SJ˜—JšœÃ™ÃJ˜Jšœ™Jšœ÷™÷Jšœý™ýJ˜šŸœœœ8˜PJ˜LJšœ˜!—Jšœ=™=J˜šŸ œœœ˜9J˜@Jšœ˜!J˜—JšŸ œœœ˜9J˜šŸœœœ˜4Jšœ œ˜J™——J˜šŸœœœ˜5Jšœ œ˜J™C—J˜šŸœœœœ˜5Jšœ œ œœ˜:Jšœ œ™"—J˜—J˜J˜J˜J˜—…—’4®