DIRECTORY BasicTime USING [ GMT ], GVBasics USING [Password], IV USING [KeyTableBody], LoganBerry USING [ Attribute ], Pup USING [ Address ], RefID USING [ ID ], Rope USING [ Concat ], RPC USING [ InterfaceName, ShortROPE, VersionRange ], SRPCCalls USING [ Conversation, Error, GetSHandle, NewRPCConversation, ReleaseConversation, ReportProc, SHandle, TimeoutEnable ], ThParty, ThPartySunRPC, ThPartySunRPControl, ThPartySunRPCClient, Thrush, ThrushSunRPC, ThrushSunRPCConvert ; ThPartyToThPartySunRPC: CEDAR MONITOR IMPORTS Rope, SRPCCalls, ThPartySunRPCClient, ThrushSunRPCConvert EXPORTS ThParty, ThPartySunRPControl ~ { OPEN ThrushSunRPCConvert; Attributes: TYPE = ThParty.Attributes; Conversation: TYPE ~ SRPCCalls.Conversation; ConversationInfo: TYPE = ThParty.ConversationInfo; ConversationID: TYPE = Thrush.ConversationID; PartyID: TYPE = Thrush.PartyID; SmartsID: TYPE = Thrush.SmartsID; nullID: RefID.ID = Thrush.nullID; Credentials: TYPE = Thrush.Credentials; SRCredentials: TYPE = ThrushSunRPC.Credentials; NB: TYPE = Thrush.NB; ROPE: TYPE = Thrush.ROPE; SHHH: TYPE = Thrush.SHHH; none: SHHH = Thrush.none; SHandle: TYPE ~ SRPCCalls.SHandle; SmartsInterfaceName: TYPE = RPC.InterfaceName; sunSHHH: INT = 0; ThPartyHandle: TYPE ~ REF ThPartyHandleRec; ThPartyHandleRec: TYPE ~ RECORD [ rName: ROPE, type: Thrush.PartyType, interface: SmartsInterfaceName, properties: ThParty.SmartsProperties, reportState: ThPartySunRPControl.ReportState _ NIL, reportProblem: ThPartySunRPControl.ReportProblem _ NIL, reportData: REF _ NIL, -- supplied by client, returned in reports. registered: BOOL _ FALSE, -- implies sHandle.connected; also registered with Thrush. sHandle: SHandle, partyID: Thrush.PartyID_ nullID, smartsID: Thrush.SmartsID_ nullID ]; RetryAfterReconnect: ERROR = CODE; recentShhh: SHHH _ NIL; CreateConversation: PUBLIC PROC [shhh: SHHH _ none, credentials: Credentials, state: Thrush.StateInConv_$initiating, reason: Thrush.Reason _ NIL, comment: ROPE _ NIL, convAttributes: Attributes_NIL, partyAttributes: Attributes_NIL, checkConflict: BOOL _ FALSE] RETURNS [ nb: NB, convEvent: Thrush.ConvEvent ] ~ { ENABLE { SRPCCalls.Error => { nb _ ReportError[shhh, errCode, explanation]; CONTINUE; }; RetryAfterReconnect => RETRY; UNWIND => NULL; }; srNB: ThrushSunRPC.NB; srConvEvent: ThrushSunRPC.ConvEvent; pHandle: ThPartyHandle; srCredentials: SRCredentials; [pHandle, srCredentials] _ GetInfo[shhh, credentials]; [srNB, srConvEvent] _ ThPartySunRPCClient.CreateConversation[pHandle.sHandle.handle, sunSHHH, srCredentials, StateToSr[state], ATOMToSr[reason], ROPEToSr[comment], AttributesToSr[convAttributes], AttributesToSr[partyAttributes], checkConflict ]; nb _ SrToATOM[srNB]; ReRegisterOnFailure[pHandle, nb]; convEvent _ SrToConvEvent[srConvEvent]; }; Alert: PUBLIC PROC [shhh: SHHH _ none, credentials: Credentials, calledPartyID: PartyID_nullID, comment: ROPE_NIL, convAttributes: Attributes_NIL, partyAttributes: Attributes_NIL] RETURNS [nb: NB ] ~ { ENABLE { SRPCCalls.Error => { nb _ ReportError[shhh, errCode, explanation]; CONTINUE; }; RetryAfterReconnect => RETRY; UNWIND => NULL; }; srNB: ThrushSunRPC.NB; pHandle: ThPartyHandle; srCredentials: SRCredentials; [pHandle, srCredentials] _ GetInfo[shhh, credentials]; [srNB] _ ThPartySunRPCClient.Alert[pHandle.sHandle.handle, sunSHHH, srCredentials, calledPartyID, ROPEToSr[comment], AttributesToSr[convAttributes], AttributesToSr[partyAttributes] ]; nb _ SrToATOM[srNB]; ReRegisterOnFailure[pHandle, nb]; }; Advance: PUBLIC PROC [shhh: SHHH _ none, credentials: Credentials, state: Thrush.StateInConv, reportToAll: BOOL_FALSE, reason: Thrush.Reason_NIL, comment: ROPE_NIL, convAttributes: Attributes_NIL, partyAttributes: Attributes_NIL,bilateral: BOOL _ FALSE, checkConflict: BOOL _ FALSE ] RETURNS [nb: NB, convEvent: Thrush.ConvEvent ] ~ { ENABLE { SRPCCalls.Error => { nb _ ReportError[shhh, errCode, explanation]; CONTINUE; }; RetryAfterReconnect => RETRY; UNWIND => NULL; }; srNB: ThrushSunRPC.NB; srConvEvent: ThrushSunRPC.ConvEvent; pHandle: ThPartyHandle; srCredentials: SRCredentials; [pHandle, srCredentials] _ GetInfo[shhh, credentials]; [srNB, srConvEvent] _ ThPartySunRPCClient.Advance[pHandle.sHandle.handle, sunSHHH, srCredentials, StateToSr[state], reportToAll, ATOMToSr[reason], ROPEToSr[comment], AttributesToSr[convAttributes], AttributesToSr[partyAttributes], bilateral, checkConflict ]; nb _ SrToATOM[srNB]; ReRegisterOnFailure[pHandle, nb]; convEvent _ SrToConvEvent[srConvEvent]; }; ReportAction: PUBLIC PROC [shhh: SHHH _ none, report: Thrush.ActionReport, reportToAll: BOOL _ FALSE, selfOnCompletion: BOOL_FALSE ] RETURNS [nb: NB, numReportsIssued: NAT_0] ~ { ENABLE { SRPCCalls.Error => { nb _ ReportError[shhh, errCode, explanation]; CONTINUE; }; RetryAfterReconnect => RETRY; UNWIND => NULL; }; srNB: ThrushSunRPC.NB; pHandle: ThPartyHandle; srCredentials: SRCredentials; [pHandle, srCredentials] _ GetInfo[shhh, report.other]; -- This is where caller puts its credentials! report.other _ SrToCredentials[srCredentials]; [srNB, numReportsIssued] _ ThPartySunRPCClient.ReportAction[pHandle.sHandle.handle, sunSHHH, ActionReportToSr[report], reportToAll, selfOnCompletion ]; nb _ SrToATOM[srNB]; ReRegisterOnFailure[pHandle, nb]; }; GetConversationInfo: PUBLIC PROC [ shh: SHHH_none, convID: ConversationID ] RETURNS [nb: NB, cInfo: ConversationInfo] ~ { ENABLE { SRPCCalls.Error => { nb _ ReportError[shh, errCode, explanation]; CONTINUE; }; RetryAfterReconnect => RETRY; UNWIND => NULL; }; srNB: ThrushSunRPC.NB; srCInfo: ThPartySunRPC.ConversationInfo; pHandle: ThPartyHandle _ GetInfo[shh].pHandle; [srNB, srCInfo] _ ThPartySunRPCClient.GetConversationInfo[pHandle.sHandle.handle, sunSHHH, ConvIDToSr[convID] ]; nb _ SrToATOM[srNB]; ReRegisterOnFailure[pHandle, nb]; cInfo _ SrToConversationInfo[srCInfo]; }; RegisterConversation: PUBLIC PROC [ shhh: SHHH _ none, credentials: Credentials, name: ROPE, convType: ThParty.ConvType _ $meeting, convAttributes: Attributes _ NIL, accessList: ThParty.AccessList _ NIL ] RETURNS [ nb: NB ] ~ { ENABLE { SRPCCalls.Error => { nb _ ReportError[shhh, errCode, explanation]; CONTINUE; }; RetryAfterReconnect => RETRY; UNWIND => NULL; }; srNB: ThrushSunRPC.NB; pHandle: ThPartyHandle; srCredentials: SRCredentials; [pHandle, srCredentials] _ GetInfo[shhh, credentials]; [srNB] _ ThPartySunRPCClient.RegisterConversation[pHandle.sHandle.handle, sunSHHH, srCredentials, ROPEToSr[name], ConvTypeToSr[convType], AttributesToSr[convAttributes], AccessListToSr[accessList] ]; nb _ SrToATOM[srNB]; ReRegisterOnFailure[pHandle, nb]; }; GetConversationFromName: PUBLIC PROC [ shhh: SHHH _ none, partyID: PartyID, name: ROPE ] RETURNS [ nb: NB, cInfo: ConversationInfo ] ~ { ENABLE { SRPCCalls.Error => { nb _ ReportError[shhh, errCode, explanation]; CONTINUE; }; RetryAfterReconnect => RETRY; UNWIND => NULL; }; srNB: ThrushSunRPC.NB; srCInfo: ThPartySunRPC.ConversationInfo; pHandle: ThPartyHandle; srCredentials: SRCredentials; [pHandle, srCredentials] _ GetInfo[shhh]; partyID _ srCredentials.partyID; [srNB, srCInfo] _ ThPartySunRPCClient.GetConversationFromName[pHandle.sHandle.handle, sunSHHH, partyID, ROPEToSr[name] ]; nb _ SrToATOM[srNB]; ReRegisterOnFailure[pHandle, nb]; cInfo _ SrToConversationInfo[srCInfo]; }; EnumerateNamedConversations: PUBLIC PROC [ shhh: SHHH _ none, partyID: PartyID ] RETURNS [ nb: NB, candidates: LIST OF ConversationInfo ] ~ { ENABLE { SRPCCalls.Error => { nb _ ReportError[shhh, errCode, explanation]; CONTINUE; }; RetryAfterReconnect => RETRY; UNWIND => NULL; }; srNB: ThrushSunRPC.NB; srCandidates: ThPartySunRPC.CandidateList; pHandle: ThPartyHandle; srCredentials: SRCredentials; [pHandle, srCredentials] _ GetInfo[shhh]; partyID _ srCredentials.partyID; [srNB, srCandidates] _ ThPartySunRPCClient.EnumerateNamedConversations[ pHandle.sHandle.handle, sunSHHH, partyID ]; nb _ SrToATOM[srNB]; ReRegisterOnFailure[pHandle, nb]; candidates _ SrToCandidateList[srCandidates]; }; GetPartyInfo: PUBLIC PROC [ shh: SHHH_none, credentials: Credentials, nameReq: ThParty.NameReq_$current, allParties: BOOL_FALSE ] RETURNS [ nb: NB, pInfo: ThParty.PartyInfo ] ~ { ENABLE { SRPCCalls.Error => { nb _ ReportError[shh, errCode, explanation]; CONTINUE; }; RetryAfterReconnect => RETRY; UNWIND => NULL; }; srNB: ThrushSunRPC.NB; srPInfo: ThPartySunRPC.PartyInfo; pHandle: ThPartyHandle; srCredentials: SRCredentials; [pHandle, srCredentials] _ GetInfo[shh, credentials]; [srNB, srPInfo] _ ThPartySunRPCClient.GetPartyInfo[pHandle.sHandle.handle, sunSHHH, srCredentials, ATOMToSr[nameReq], allParties ]; nb _ SrToATOM[srNB]; ReRegisterOnFailure[pHandle, nb]; pInfo _ SrToPartyInfo[srPInfo]; }; DescribeParty: PUBLIC PROC[ partyID: Thrush.PartyID, nameReq: ThParty.NameReq ] RETURNS [ nb: NB, description: Thrush.ROPE, type: Thrush.PartyType, partner: Thrush.PartyID_nullID, visitee: Thrush.PartyID_nullID, visitors: LIST OF Thrush.PartyID_NIL ] ~ { shhh: SHHH _ recentShhh; { ENABLE { SRPCCalls.Error => { nb _ ReportError[shhh, errCode, explanation]; CONTINUE; }; RetryAfterReconnect => RETRY; UNWIND => NULL; }; srNB: ThrushSunRPC.NB; srType: ThrushSunRPC.PartyType; srVisitors: ThPartySunRPC.VisitorList; pHandle: ThPartyHandle; pHandle _ GetInfo[shhh].pHandle; [srNB, description, srType, partner, visitee, srVisitors] _ ThPartySunRPCClient.DescribeParty[pHandle.sHandle.handle, --sunSHHH,-- partyID, ATOMToSr[nameReq] ]; nb _ SrToATOM[srNB]; ReRegisterOnFailure[pHandle, nb]; type _ SrToATOM[srType]; visitors _ SrToVisitorList[srVisitors]; description _ SrToROPE[description]; }; }; AddAttributes: PUBLIC PROC[ credentials: Credentials, convAttributes: Attributes_NIL, partyAttributes: Attributes_NIL ] RETURNS [nb: NB] ~ { shhh: SHHH _ recentShhh; { ENABLE { SRPCCalls.Error => { nb _ ReportError[shhh, errCode, explanation]; CONTINUE; }; RetryAfterReconnect => RETRY; UNWIND => NULL; }; srNB: ThrushSunRPC.NB; pHandle: ThPartyHandle; srCredentials: SRCredentials; [pHandle, srCredentials] _ GetInfo[shhh, credentials]; srNB _ ThPartySunRPCClient.AddAttributes[pHandle.sHandle.handle, --sunSHHH, -- srCredentials, AttributesToSr[convAttributes], AttributesToSr[partyAttributes] ]; nb _ SrToATOM[srNB]; ReRegisterOnFailure[pHandle, nb]; }; }; RegisterServiceInterface: PUBLIC PROC[ shhh: SHHH _ none, credentials: Credentials, interfaceSpecPattern: Thrush.InterfaceSpec ] RETURNS [nb: NB, interfaceSpec: Thrush.InterfaceSpec] ~ { ENABLE { SRPCCalls.Error => { nb _ ReportError[shhh, errCode, explanation]; CONTINUE; }; RetryAfterReconnect => RETRY; UNWIND => NULL; }; srNB: ThrushSunRPC.NB; srInterfaceSpec: ThrushSunRPC.InterfaceSpec; pHandle: ThPartyHandle; srCredentials: SRCredentials; [pHandle, srCredentials] _ GetInfo[shhh, credentials]; interfaceSpecPattern.interfaceName.type _ Rope.Concat[interfaceSpecPattern.interfaceName.type, "-Sun"]; [srNB, srInterfaceSpec] _ ThPartySunRPCClient.RegisterServiceInterface[ pHandle.sHandle.handle, sunSHHH, srCredentials, InterfaceSpecToSr[interfaceSpecPattern] ]; nb _ SrToATOM[srNB]; ReRegisterOnFailure[pHandle, nb]; interfaceSpec _ SrToInterfaceSpec[srInterfaceSpec]; }; LookupServiceInterface: PUBLIC PROC[ shhh: SHHH _ none, credentials: Credentials, serviceParty: PartyID, type: RPC.ShortROPE ] RETURNS [nb: NB, interfaceSpec: Thrush.InterfaceSpec] ~ { ENABLE { SRPCCalls.Error => { nb _ ReportError[shhh, errCode, explanation]; CONTINUE; }; RetryAfterReconnect => RETRY; UNWIND => NULL; }; srNB: ThrushSunRPC.NB; srInterfaceSpec: ThrushSunRPC.InterfaceSpec; pHandle: ThPartyHandle; srCredentials: SRCredentials; [pHandle, srCredentials] _ GetInfo[shhh, credentials]; [srNB, srInterfaceSpec] _ ThPartySunRPCClient.LookupServiceInterface[ pHandle.sHandle.handle, sunSHHH, srCredentials, serviceParty, Rope.Concat[type, "-Sun"] ]; nb _ SrToATOM[srNB]; ReRegisterOnFailure[pHandle, nb]; interfaceSpec _ SrToInterfaceSpec[srInterfaceSpec]; }; RegisterKey: PUBLIC PROC[ shh: SHHH _ none, credentials: Credentials, key: Thrush.EncryptionKey, reportNewKeys: BOOL_FALSE ] RETURNS [ nb: NB, keyIndex: [0..17B] ] ~ { ENABLE { SRPCCalls.Error => { nb _ ReportError[shh, errCode, explanation]; CONTINUE; }; RetryAfterReconnect => RETRY; UNWIND => NULL; }; srNB: ThrushSunRPC.NB; pHandle: ThPartyHandle; srCredentials: SRCredentials; [pHandle, srCredentials] _ GetInfo[shh, credentials]; [srNB, keyIndex] _ ThPartySunRPCClient.RegisterKey[ pHandle.sHandle.handle, sunSHHH, srCredentials, EncryptionKeyToSr[key], reportNewKeys ]; nb _ SrToATOM[srNB]; ReRegisterOnFailure[pHandle, nb]; }; GetKeyTable: PUBLIC PROC [ shh: SHHH_none, credentials: Credentials ] RETURNS [ nb: NB, keyTable: Thrush.KeyTable ] ~ { ENABLE { SRPCCalls.Error => { nb _ ReportError[shh, errCode, explanation]; CONTINUE; }; RetryAfterReconnect => RETRY; UNWIND => NULL; }; srNB: ThrushSunRPC.NB; srKeyTable: ThrushSunRPC.KeyTable; pHandle: ThPartyHandle; srCredentials: SRCredentials; [pHandle, srCredentials] _ GetInfo[shh, credentials]; [srNB, srKeyTable] _ ThPartySunRPCClient.GetKeyTable[ pHandle.sHandle.handle, sunSHHH, srCredentials ]; nb _ SrToATOM[srNB]; ReRegisterOnFailure[pHandle, nb]; keyTable _ SrToKeyTable[srKeyTable]; }; UnregisterKey: PUBLIC PROC[ shh: SHHH _ none, credentials: Credentials, key: Thrush.EncryptionKey ] RETURNS [ nb: NB ] ~ { ENABLE { SRPCCalls.Error => { nb _ ReportError[shh, errCode, explanation]; CONTINUE; }; RetryAfterReconnect => RETRY; UNWIND => NULL; }; srNB: ThrushSunRPC.NB; pHandle: ThPartyHandle; srCredentials: SRCredentials; [pHandle, srCredentials] _ GetInfo[shh, credentials]; srNB _ ThPartySunRPCClient.UnregisterKey[ pHandle.sHandle.handle, sunSHHH, srCredentials, EncryptionKeyToSr[key] ]; nb _ SrToATOM[srNB]; ReRegisterOnFailure[pHandle, nb]; }; GetParty: PUBLIC PROC[ shh: SHHH_none, partyID: PartyID, rName: ROPE_NIL, type: Thrush.PartyType_NIL ] RETURNS [nb: NB, newPartyID: PartyID] ~ { ENABLE { SRPCCalls.Error => { nb _ ReportError[shh, errCode, explanation]; CONTINUE; }; RetryAfterReconnect => RETRY; UNWIND => NULL; }; srNB: ThrushSunRPC.NB; pHandle: ThPartyHandle; srCredentials: SRCredentials; [pHandle, srCredentials] _ GetInfo[shh]; partyID _ srCredentials.partyID; -- This is the right partyID to use. [srNB, newPartyID] _ ThPartySunRPCClient.GetParty[ pHandle.sHandle.handle, sunSHHH, partyID, ROPEToSr[rName], ATOMToSr[type] ]; nb _ SrToATOM[srNB]; ReRegisterOnFailure[pHandle, nb]; }; GetPartyFromNumber: PUBLIC PROC[ shh: SHHH_none, partyID: PartyID, phoneNumber: Thrush.ROPE_NIL, description: ROPE_NIL ] RETURNS [nb: NB, newPartyID: PartyID] ~ { ENABLE { SRPCCalls.Error => { nb _ ReportError[shh, errCode, explanation]; CONTINUE; }; RetryAfterReconnect => RETRY; UNWIND => NULL; }; srNB: ThrushSunRPC.NB; pHandle: ThPartyHandle; srCredentials: SRCredentials; [pHandle, srCredentials] _ GetInfo[shh]; partyID _ srCredentials.partyID; -- This is the right partyID to use. [srNB, newPartyID] _ ThPartySunRPCClient.GetPartyFromNumber[ pHandle.sHandle.handle, sunSHHH, partyID, ROPEToSr[phoneNumber], ROPEToSr[description] ]; nb _ SrToATOM[srNB]; ReRegisterOnFailure[pHandle, nb]; }; GetPartyFromFeepNum: PUBLIC PROC[ shh: SHHH_none, partyID: PartyID, feepNum: Thrush.ROPE_NIL ] RETURNS [nb: NB, newPartyID: PartyID] ~ { ENABLE { SRPCCalls.Error => { nb _ ReportError[shh, errCode, explanation]; CONTINUE; }; RetryAfterReconnect => RETRY; UNWIND => NULL; }; srNB: ThrushSunRPC.NB; pHandle: ThPartyHandle; srCredentials: SRCredentials; [pHandle, srCredentials] _ GetInfo[shh]; partyID _ srCredentials.partyID; -- This is the right partyID to use. [srNB, newPartyID] _ ThPartySunRPCClient.GetPartyFromFeepNum[ pHandle.sHandle.handle, sunSHHH, partyID, ROPEToSr[feepNum] ]; nb _ SrToATOM[srNB]; ReRegisterOnFailure[pHandle, nb]; }; GetCurrentParty: PUBLIC PROC[shh: SHHH_none, smartsID: SmartsID] RETURNS [nb: NB, partyID: Thrush.PartyID] ~ { ENABLE { SRPCCalls.Error => { nb _ ReportError[shh, errCode, explanation]; CONTINUE; }; RetryAfterReconnect => RETRY; UNWIND => NULL; }; srNB: ThrushSunRPC.NB; pHandle: ThPartyHandle; srCredentials: SRCredentials; [pHandle, srCredentials] _ GetInfo[shh]; smartsID _ srCredentials.smartsID; [srNB, partyID] _ ThPartySunRPCClient.GetCurrentParty[pHandle.sHandle.handle, sunSHHH, smartsID ]; nb _ SrToATOM[srNB]; ReRegisterOnFailure[pHandle, nb]; }; ReleaseParty: PUBLIC PROC[shh: SHHH_none, partyID: PartyID, targetPartyID: PartyID] RETURNS [nb: NB] ~ { ENABLE { SRPCCalls.Error => { nb _ ReportError[shh, errCode, explanation]; CONTINUE; }; RetryAfterReconnect => RETRY; UNWIND => NULL; }; srNB: ThrushSunRPC.NB; pHandle: ThPartyHandle; srCredentials: SRCredentials; [pHandle, srCredentials] _ GetInfo[shh]; partyID _ srCredentials.partyID; -- This is the right partyID to use. srNB _ ThPartySunRPCClient.ReleaseParty[ pHandle.sHandle.handle, sunSHHH, partyID, targetPartyID ]; nb _ SrToATOM[srNB]; ReRegisterOnFailure[pHandle, nb]; }; GetNumbersForRName: PUBLIC PROC[shh: SHHH_none, rName: ROPE] RETURNS [fullRName: ROPE, number: ROPE, homeNumber: ROPE] ~ { ENABLE { SRPCCalls.Error => { [] _ ReportError[shh, errCode, explanation]; CONTINUE; }; RetryAfterReconnect => RETRY; UNWIND => NULL; }; pHandle: ThPartyHandle; pHandle _ GetInfo[shhh: shh, rereg: FALSE].pHandle; [fullRName, number, homeNumber] _ ThPartySunRPCClient.GetNumbersForRName[ pHandle.sHandle.handle, sunSHHH, ROPEToSr[rName] ]; RETURN[fullRName: SrToROPE[fullRName], number: SrToROPE[number], homeNumber: SrToROPE[homeNumber] ]; }; Register: PUBLIC PROC[ shh: SHHH_none, rName: ROPE_NIL, type: Thrush.PartyType_ $individual, clonePartyID: PartyID _ nullID, interface: SmartsInterfaceName, properties: ThParty.SmartsProperties ] RETURNS [ nb: NB, credentials: Credentials ] ~ { ERROR; -- Shouldn't call this directly! }; CheckIn: PUBLIC PROC[shh: SHHH_none, credentials: Credentials] RETURNS [nb: NB] ~ { ENABLE { SRPCCalls.Error => { nb _ ReportError[shh, errCode, explanation]; CONTINUE; }; RetryAfterReconnect => RETRY; UNWIND => NULL; }; srNB: ThrushSunRPC.NB; pHandle: ThPartyHandle; srCredentials: SRCredentials; [pHandle, srCredentials] _ GetInfo[shh, credentials]; srNB _ ThPartySunRPCClient.CheckIn[ pHandle.sHandle.handle, sunSHHH, srCredentials ]; nb _ SrToATOM[srNB]; ReRegisterOnFailure[pHandle, nb]; }; Deregister: PUBLIC PROC[shh: SHHH_none, smartsID: SmartsID] RETURNS [nb: NB] ~ { ENABLE { SRPCCalls.Error => { nb _ ReportError[shh, errCode, explanation]; CONTINUE; }; RetryAfterReconnect => RETRY; UNWIND => NULL; }; srNB: ThrushSunRPC.NB; pHandle: ThPartyHandle; srCredentials: SRCredentials; [pHandle, srCredentials] _ GetInfo[shhh: shh, rereg: FALSE]; smartsID _ srCredentials.smartsID; srNB _ ThPartySunRPCClient.Deregister[ pHandle.sHandle.handle, sunSHHH, smartsID ]; nb _ SrToATOM[srNB]; ReRegisterOnFailure[pHandle, nb]; }; Enable: PUBLIC PROC[shh: SHHH_none, smartsID: SmartsID] RETURNS [nb: Thrush.NB] ~ { ENABLE { SRPCCalls.Error => { nb _ ReportError[shh, errCode, explanation]; CONTINUE; }; RetryAfterReconnect => RETRY; UNWIND => NULL; }; srNB: ThrushSunRPC.NB; pHandle: ThPartyHandle; srCredentials: SRCredentials; [pHandle, srCredentials] _ GetInfo[shh]; smartsID _ srCredentials.smartsID; srNB _ ThPartySunRPCClient.Enable[ pHandle.sHandle.handle, sunSHHH, smartsID ]; nb _ SrToATOM[srNB]; ReRegisterOnFailure[pHandle, nb]; }; Disable: PUBLIC PROC[shh: SHHH_none, smartsID: SmartsID] RETURNS [nb: Thrush.NB] ~ { ENABLE { SRPCCalls.Error => { nb _ ReportError[shh, errCode, explanation]; CONTINUE; }; RetryAfterReconnect => RETRY; UNWIND => NULL; }; srNB: ThrushSunRPC.NB; pHandle: ThPartyHandle; srCredentials: SRCredentials; [pHandle, srCredentials] _ GetInfo[shh]; smartsID _ srCredentials.smartsID; srNB _ ThPartySunRPCClient.Disable[ pHandle.sHandle.handle, sunSHHH, smartsID ]; nb _ SrToATOM[srNB]; ReRegisterOnFailure[pHandle, nb]; }; Visit: PUBLIC PROC[ shh: SHHH_none, hostPartyID: PartyID, guestPartyID: PartyID, guestPassword: GVBasics.Password ] RETURNS [nb: Thrush.NB] ~ { ENABLE { SRPCCalls.Error => { nb _ ReportError[shh, errCode, explanation]; CONTINUE; }; RetryAfterReconnect => RETRY; UNWIND => NULL; }; srNB: ThrushSunRPC.NB; pHandle: ThPartyHandle; srCredentials: SRCredentials; [pHandle, srCredentials] _ GetInfo[shh]; hostPartyID _ srCredentials.partyID; srNB _ ThPartySunRPCClient.Visit[ pHandle.sHandle.handle, sunSHHH, hostPartyID, guestPartyID, PasswordToSr[guestPassword] ]; nb _ SrToATOM[srNB]; ReRegisterOnFailure[pHandle, nb]; }; Unvisit: PUBLIC PROC[ shh: SHHH_none, hostPartyID: PartyID, guestPartyID: PartyID, guestPassword: GVBasics.Password ] RETURNS [nb: Thrush.NB] ~ { ENABLE { SRPCCalls.Error => { nb _ ReportError[shh, errCode, explanation]; CONTINUE; }; RetryAfterReconnect => RETRY; UNWIND => NULL; }; srNB: ThrushSunRPC.NB; pHandle: ThPartyHandle; srCredentials: SRCredentials; [pHandle, srCredentials] _ GetInfo[shh]; hostPartyID _ srCredentials.partyID; srNB _ ThPartySunRPCClient.Unvisit[ pHandle.sHandle.handle, sunSHHH, hostPartyID, guestPartyID, PasswordToSr[guestPassword] ]; nb _ SrToATOM[srNB]; ReRegisterOnFailure[pHandle, nb]; }; UnvisitSelf: PUBLIC PROC[ shh: SHHH_none, guestPartyID: PartyID ] RETURNS [nb: Thrush.NB] ~ { ENABLE { SRPCCalls.Error => { nb _ ReportError[shh, errCode, explanation]; CONTINUE; }; RetryAfterReconnect => RETRY; UNWIND => NULL; }; srNB: ThrushSunRPC.NB; pHandle: ThPartyHandle; srCredentials: SRCredentials; [pHandle, srCredentials] _ GetInfo[shh]; guestPartyID _ srCredentials.partyID; srNB _ ThPartySunRPCClient.UnvisitSelf[ pHandle.sHandle.handle, sunSHHH, guestPartyID]; nb _ SrToATOM[srNB]; ReRegisterOnFailure[pHandle, nb]; }; sunPgm: CARD _ 390909; -- decimal program number for ThParty sunPgmVersion: CARD _ 1; sunCallTimeout: INT _ 3000; sunCallRetries: INT _ 3; sunCallTimeoutEnable: SRPCCalls.TimeoutEnable _ always; ThrushConnect: PUBLIC PROC [ server: ROPE, rName: ROPE, type: Thrush.PartyType, interface: SmartsInterfaceName, properties: ThParty.SmartsProperties, reportState: ThPartySunRPControl.ReportState, reportProblem: ThPartySunRPControl.ReportProblem_NIL, reportData: REF_NIL] RETURNS [shhh: SHHH _ none] ~ { sHandle: SHandle; pHandle: ThPartyHandle; shhh _ SRPCCalls.NewRPCConversation[ serverName: server, rpcProgram: sunPgm, rpcVersion: sunPgmVersion, timeoutEnable: sunCallTimeoutEnable, timeoutInMs: sunCallTimeout, retries: sunCallRetries, reportProc: ReportNonfatalRPCError]; sHandle _ SRPCCalls.GetSHandle[shhh]; pHandle _ NEW[ThPartyHandleRec _ [rName: rName, type: type, interface: interface, properties: properties, sHandle: sHandle, reportState: reportState, reportProblem: reportProblem, reportData: reportData]]; sHandle.clientData _ pHandle; sHandle.enabled _ TRUE; -- Unilaterally assert a will to connect. { ENABLE { SRPCCalls.Error => { []_ReportError[shhh, errCode, explanation]; CONTINUE; }; RetryAfterReconnect => CONTINUE; -- Successful completion of very strange procedure. }; ReRegisterOnFailure[pHandle, $unbound]; }; }; ThrushDisconnect: PUBLIC PROC [shhh: Thrush.SHHH, disable: BOOL_TRUE] ~ { ENABLE { SRPCCalls.Error => { []_ReportError[shhh, errCode, explanation]; CONTINUE; }; UNWIND => NULL; }; pHandle: ThPartyHandle _ GetInfo[shhh: shhh, rereg: FALSE].pHandle; wasRegistered: BOOL _ pHandle.registered; pHandle.registered _ FALSE; -- even if it fails! IF disable THEN pHandle.sHandle.enabled _ FALSE; IF wasRegistered THEN [] _ Deregister[shhh, pHandle.smartsID]; [] _ ReportError[shhh, $disconnected, "Disconnected from server"]; }; ThrushReportState: PUBLIC PROC [shhh: Thrush.SHHH, enabled: BOOL, connected: BOOL] ~ { ENABLE { SRPCCalls.Error => { []_ReportError[shhh, errCode, explanation]; CONTINUE; }; UNWIND => NULL; }; pHandle: ThPartyHandle _ GetInfo[shhh: shhh, rereg: FALSE].pHandle; IF ~enabled THEN pHandle.sHandle.enabled _ FALSE; pHandle.registered _ connected; }; ReleaseConversation: PUBLIC PROC [shhh: Thrush.SHHH] ~ { ENABLE { SRPCCalls.Error => { []_ReportError[shhh, errCode, explanation]; CONTINUE; }; UNWIND => NULL; }; SRPCCalls.ReleaseConversation[shhh]; -- Thrush already assumed disconnected, for now. }; GetInfo: ENTRY PROC[shhh: Conversation, credentials: Credentials_[], rereg: BOOL_TRUE] RETURNS [pHandle: ThPartyHandle, updatedCredentials: SRCredentials] ~ { ENABLE UNWIND => NULL; -- !!!!!!!!!!! DCS September 14, 1990 3:43:51 pm PDT sHandle: SHandle; IF shhh = NIL THEN SRPCCalls.Error[$noConversationSupplied]; sHandle _ SRPCCalls.GetSHandle[shhh]; IF sHandle=NIL THEN SRPCCalls.Error[$invalidConversationSupplied]; pHandle _ NARROW[sHandle.clientData]; IF pHandle = NIL THEN SRPCCalls.Error[$invalidConversationSupplied]; recentShhh _ shhh; -- Any port in a storm; see usage for explanation. IF ~pHandle.registered AND rereg THEN RROFInt[pHandle, $unbound]; credentials.partyID _ pHandle.partyID; credentials.smartsID _ pHandle.smartsID; updatedCredentials _ ThrushSunRPCConvert.CredentialsToSr[credentials]; }; ReportNonfatalRPCError: SRPCCalls.ReportProc ~ { IF sHandle#NIL AND sHandle.conversation#NIL THEN []_ReportError[sHandle.conversation, ec, expl]; }; ReportError: PROC[shhh: SHHH, ec: ATOM, expl: ROPE] RETURNS [nb: NB] ~ { pHandle: ThPartyHandle _ NARROW[SRPCCalls.GetSHandle[shhh].clientData]; IF pHandle.reportProblem#NIL THEN pHandle.reportProblem[pHandle.reportData, ec, expl]; ReportState[pHandle]; nb _ $callFailed; }; ReRegisterOnFailure: ENTRY PROC[pHandle: ThPartyHandle, nb: NB] ~ { ENABLE UNWIND => NULL; RROFInt[pHandle, nb]; }; RROFInt: INTERNAL PROC[pHandle: ThPartyHandle, nb: NB] ~ { credentials: Credentials; srNB: ThrushSunRPC.NB; srCredentials: SRCredentials; SELECT nb FROM $noSuchParty, $noSuchSmarts, $unbound => NULL; ENDCASE => RETURN; -- $success, or some error that implies the connection is still around. pHandle.registered _ FALSE; IF ~pHandle.sHandle.enabled THEN RETURN; [srNB, srCredentials] _ ThPartySunRPCClient.Register[ h: pHandle.sHandle.handle, shh: sunSHHH, rName: ROPEToSr[pHandle.rName], type: ATOMToSr[pHandle.type], interface: InterfaceNameToSr[pHandle.interface], properties: SmartsPropertiesToSr[pHandle.properties], clonePartyID: nullID ]; nb _ SrToATOM[srNB]; credentials _ SrToCredentials[srCredentials]; IF nb=$success THEN { srNB _ ThPartySunRPCClient.Enable[ pHandle.sHandle.handle, sunSHHH, credentials.smartsID ]; nb _ SrToATOM[srNB]; }; IF nb=$success THEN { [srNB, credentials.partyID] _ ThPartySunRPCClient.GetCurrentParty[ h: pHandle.sHandle.handle, shh: sunSHHH, smartsID: credentials.smartsID]; nb _ SrToATOM[srNB]; }; IF nb#$success THEN { nb _ ReportError[pHandle.sHandle.conversation, nb, "Can't register with server"]; RETURN; }; pHandle.registered _ TRUE; pHandle.partyID _ credentials.partyID; pHandle.smartsID _ credentials.smartsID; ReportState[pHandle]; ERROR RetryAfterReconnect; -- really success. }; ReportState: PROC[pHandle: ThPartyHandle] ~ { IF NOT pHandle.sHandle.connected THEN pHandle.registered _ FALSE; IF pHandle.reportState#NIL THEN pHandle.reportState[ pHandle.reportData, pHandle.registered, pHandle.sHandle.connected, pHandle.sHandle.enabled, pHandle.partyID, pHandle.smartsID]; }; }.  ThPartyToThPartySunRPC.mesa Copyright Σ 1990 by Xerox Corporation. All rights reserved. Polle Zellweger (PTZ) October 29, 1990 4:00:19 pm PST Pier, May 10, 1990 11:33:09 pm PDT Swinehart, October 1, 1990 11:11 am PDT Note: RegisterServiceInterface and LookupServiceInterface append "-Sun" to their type parameters, to promote PCedar/DCedar source sharing. All action routines should be implemented as entry procedures protecting monitored records, but that would require redefining RPC.Conversation as a monitored record. We can do that once D-systems are dead. Current fallback: monitor the error management procedures, and hope for the best. If that doesn't work fallback: use a global monitor. This will sequentialize all party calls on the machine, but that's probably not much of a loss. DCS September 8, 1990 If problems arise, remember that we can easily enough require our clients, which are always "smartses", to serialize all calls on a per-shhh basis. DCS September 13, 1990 8:23:59 am PDT Definitions connected: connection exists and is healthy; enabled: autoConnect is still in effect. Both reportState and reportProblem are optional ways to report events to a common site. If reportProblem is not supplied and a problem is discovered, it will be reported only through nb error code returns. Derived values Conversation Management Enumerations, registrations, queries Named conversations Rope.InlineFlatten the rope?? Party information Use a remembered one; can sometimes slow performance of other instances. Use a remembered one; can sometimes slow performance of other instances. Service action registration, lookup. See also ReportAction, above. Encryption key registration. Names to Parties, Numbers to Parties Information about people and parties ReRegisterOnFailure[pHandle, $success]; -- Call won't fail here due to no registration Party and Smarts creation, initialization ENABLE { SRPCCalls.Error => { nb _ ReportError[shh, errCode, explanation]; CONTINUE; }; RetryAfterReconnect => RETRY; UNWIND => NULL; }; srNB: ThrushSunRPC.NB; pHandle: ThPartyHandle; srCredentials: SRCredentials; pHandle _ GetInfo[shh].pHandle; [srNB, srCredentials] _ ThPartySunRPCClient.Register[ pHandle.sHandle.handle, sunSHHH, rName, ATOMToSr[type], clonePartyID, InterfaceNameToSr[interface], SmartsPropertiesToSr[properties] ]; nb _ SrToATOM[srNB]; ReRegisterOnFailure[pHandle, nb]; credentials _ SrToCredentials[srCredentials]; Connecting If this procedure fails to import, it reports the failure as Report or Problem, and indicates the resulting connection state via the reportState routine. It will return a shhh value in any case, since that will be needed in order to retry later. Worry about what happens when interface is already imported. Perhaps not idempotent yet. Worry about how to unregister (Unfinch.) Consider a lookup that identifies already-imported interfaces? Consider a version of this that takes an existing, unregistered, pHandle as an argument! Register with Thrush Entry holds others out during error recovery. Else the error is not at present reported at all. Could use some default Feedback call. Fatal errors at this level will be caught and reported by the caller! When successful, this procedure raises RetryAfterReconnect, in order to permit its caller to retry the entire procedure. (Turns each of the callers into a kind of LOOP). Entry here should be enough to eliminate most important reentrancy problems? If there's an entry here, we can't call GetInfo or allow ReRegisterOnFailure to be recursively entered. Fatal errors at this level will be caught and reported by the caller! When successful, this procedure raises RetryAfterReconnect, in order to permit its caller to retry the entire procedure. (Turns each of the callers into a kind of LOOP). Entry here should be enough to eliminate most important reentrancy problems? If there's an entry here, we can't call GetInfo or allow ReRegisterOnFailure to be recursively entered. Notify any interested parties about current connection state. Polle Zellweger (PTZ) October 1, 1989 5:03:15 pm PDT changes to: ThPartyToThPartySunRPC, CreateConversation, Alert, SrToCredentials, } Polle Zellweger (PTZ) October 3, 1989 12:54:30 pm PDT changes to: ThPartyToThPartySunRPC, CreateConversation, Alert, SrToAttributes, AttributesToSr, SrToCredentials, SrToConvEvent, ConvEventToSr, Advance, ReportAction, SrToActionReport, ActionReportToSr Polle Zellweger (PTZ) March 16, 1990 6:14:47 pm PST changes to: ReportAction Polle Zellweger (PTZ) March 21, 1990 11:09:01 pm PST changes to: ThPartyToThPartySunRPC, GetConversationInfo, SrToConversationInfo, SrToAddress, SrToCredentials, thPartyInfo, GetInfo Polle Zellweger (PTZ) April 19, 1990 12:57:36 pm PDT changes to: ThPartyToThPartySunRPC, SrToAddress, } Polle Zellweger (PTZ) May 2, 1990 9:43:19 pm PDT changes to: DIRECTORY, ThPartyToThPartySunRPC, SmartsInterfaceRecord, sunSHHH, ThPartyInfo, ThPartyRecord, thinfo, GetInfo, FinchRegister, SrToConversationInfo Polle Zellweger (PTZ) May 4, 1990 4:53:29 pm PDT changes to: SrToKeyTable, KeyTableToSr, GetKeyTable, UnregisterKey, GetParty, GetPartyFromNumber, GetPartyFromFeepNum, GetCurrentParty, ReleaseParty, GetNumbersForRName, Visit, Unvisit Polle Zellweger (PTZ) May 8, 1990 4:50:33 pm PDT changes to: SrToAttributes, SmartsPropertiesToSr, SrToVisitorList, ReleaseParty, Register, CheckIn, Deregister, Enable, Disable, Visit, Unvisit, UnvisitSelf, DIRECTORY, SmartsInterfaceName, RegisterConversation, EnumerateNamedConversations, GetPartyInfo, SrToPartyInfo, PartySeq, SrToPartyList, DescribeParty, AddAttributes, GetKeyTable, UnregisterKey, SrToCandidateList, CredentialsToSr, SrToInterfaceSpec, SrToKeyTable, KeyTableToSr, SrToVersionRange, VersionRangeToSr, SrToSmartsInterface, SmartsInterfaceToSr, CreateConversation, Advance, GetConversationInfo, SrToConvEvent, ConvEventToSr, SrToConversationInfo, SrToConvID, ConvIDToSr, SrToConvType, ConvTypeToSr, SrToCredentials, SrToEncryptionKey, EncryptionKeyToSr, SrToGMT, GMTToSr, InterfaceSpecToSr, SrToPartyInfoSpec, PasswordToSr, SrToState, StateToSr Pier, May 10, 1990 11:33:09 am PDT moved data conversion routines to ThrushSunRPCConvert Polle Zellweger (PTZ) May 11, 1990 4:08:39 pm PDT Atom.GetPName couldn't handle NIL, so make a new conversion routine. Polle Zellweger (PTZ) July 24, 1990 7:28:23 pm PDT SunYPAgent.Match has different # params in DCedar & PCedar changes to: SunYPNameToAddress Polle Zellweger (PTZ) August 1, 1990 6:39:57 pm PDT Keep multiple handles for multiple callers. NOTE: 2 ThParty calls have no SHHH param!!! changes to: ImportInterface, GetInfo & all procs GetInfo[] -> GetInfo[shh or shhh] Polle Zellweger (PTZ) August 14, 1990 9:22:53 am PDT Append "-Sun" to calls to (Register|Lookup)ServiceInterface (promotes PCedar/DCedar source sharing). changes to: DIRECTORY, LookupServiceInterface, RegisterServiceInterface Swinehart, August 30, 1990 6:36:07 pm PDT Add robust failure management code. Primary concerns: invalid initial server specifications, response to timeouts due to server or network failures. Polle Zellweger (PTZ) October 29, 1990 3:58:11 pm PST Allow detection of NIL ropes across a SunRPC connection. changes to: CreateConversation, Alert, Advance, RegisterConversation, GetConversationFromName, DescribeParty, GetParty, GetPartyFromNumber, GetPartyFromFeepNum, GetNumbersForRName, RROFInt Κ\•NewlineDelimiter – "cedar" style˜šœ™Jšœ<™žœžœ˜zš’˜Jš’N˜NJš’˜Jš’˜Jš’˜—Jšœžœ˜Jš’5˜5Jš’5˜5Kšœ‘ œ#’ œ˜sKšœ˜Kš’!˜!K˜—K™—™$K˜š‘œžœžœžœ žœžœžœžœžœ˜š’˜Jš’N˜NJš’˜Jš’˜Jš’˜—Jšœžœ˜Jš’5˜5Jš’(˜(Jš’E˜EKšœ)‘œN˜Kšœ˜Kš’!˜!K˜K˜—š‘œžœžœžœ-žœžœžœžœžœžœ˜’š’˜Jš’N˜NJš’˜Jš’˜Jš’˜—Jšœžœ˜Jš’5˜5Jš’(˜(Jš’E˜EKšœ)‘œ[˜–Kšœ˜Kš’!˜!K˜K˜—š‘œžœžœžœ)žœžœžœžœ˜ˆš’˜Jš’N˜NJš’˜Jš’˜Jš’˜—Jšœžœ˜Jš’5˜5Jš’(˜(Jš’E˜EKšœ)‘œ@˜|Kšœ˜Kš’!˜!K˜K˜—š ‘œžœžœžœžœžœ˜nš’˜Jš’N˜NJš’˜Jš’˜Jš’˜—Jšœžœ˜Jš’5˜5Jš’(˜(Kš’"˜"Kšœ&‘œ-˜bKšœ˜Kš’!˜!K˜K˜—š ‘ œžœžœžœ0žœžœ˜hš’˜Jš’N˜NJš’˜Jš’˜Jš’˜—Jšœžœ˜Jš’5˜5Jš’(˜(Jš’E˜EKšœ‘ œ<˜cKšœ˜Kš’!˜!K˜—K™—™$K™š‘œžœžœžœžœžœ žœ žœžœ˜zš’˜Jš’N˜NJš’˜Jš’˜Jš’˜—Jš’˜Jš’$Ρkos’ ˜3Kšœ6‘œ5˜}Kš’V™VKšžœ^˜dK˜—K™—™)K™š‘œžœžœžœžœžœžœžœ ˜τJšžœ  ˜'š’™Jš’N™NJš’™Jš’™Jš’™—Jšœžœ™Jš’5™5Jš’™Kšœ,‘œ‰™½Kšœ™Kš’!™!Kšœ-™-K˜—K˜š ‘œžœžœžœ!žœžœ˜Sš’˜Jš’N˜NJš’˜Jš’˜Jš’˜—Jšœžœ˜Jš’5˜5Jš’5˜5Kšœ‘œ#’ œ˜UKšœ˜Kš’!˜!K˜K˜—š ‘ œžœžœžœžœžœ˜Pš’˜Jš’N˜NJš’˜Jš’˜Jš’˜—Jšœžœ˜Jš’5˜5Jš’5₯’˜K˜BK˜K˜—š ‘œžœžœžœ žœ žœ˜Všžœ˜KšœAžœ˜MKšžœžœ˜K˜—Kšœ4žœ ˜CKšžœ žœžœ˜1Kšœ˜K˜K˜—š‘œžœžœžœ˜8šžœ˜KšœAžœ˜MKšžœžœ˜K˜—Kšœ%  -˜WK˜K˜—š ‘œžœžœ9žœžœžœ@˜žK™-Kšžœžœžœ 4˜KKšœ˜Kšžœžœžœ*˜