/// <summary> /// Callback for a client request for Voice Account Details /// </summary> /// <param name="scene">current scene object of the client</param> /// <param name="request"></param> /// <param name="path"></param> /// <param name="param"></param> /// <param name="agentID"></param> /// <param name="caps"></param> /// <returns></returns> public string ProvisionVoiceAccountRequest(Scene scene, string request, string path, string param, UUID agentID, Caps caps) { ScenePresence avatar = scene.GetScenePresence(agentID); if (avatar == null) { System.Threading.Thread.Sleep(2000); avatar = scene.GetScenePresence(agentID); if (avatar == null) return "<llsd>undef</llsd>"; } string avatarName = avatar.Name; try { m_log.DebugFormat("[FreeSwitchVoice][PROVISIONVOICE]: request: {0}, path: {1}, param: {2}", request, path, param); //XmlElement resp; string agentname = "x" + Convert.ToBase64String(agentID.GetBytes()); string password = "******";//temp hack//new UUID(Guid.NewGuid()).ToString().Replace('-','Z').Substring(0,16); // XXX: we need to cache the voice credentials, as // FreeSwitch is later going to come and ask us for // those agentname = agentname.Replace('+', '-').Replace('/', '_'); lock (m_UUIDName) { if (m_UUIDName.ContainsKey(agentname)) { m_UUIDName[agentname] = avatarName; } else { m_UUIDName.Add(agentname, avatarName); } } // LLSDVoiceAccountResponse voiceAccountResponse = // new LLSDVoiceAccountResponse(agentname, password, m_freeSwitchRealm, "http://etsvc02.hursley.ibm.com/api"); LLSDVoiceAccountResponse voiceAccountResponse = new LLSDVoiceAccountResponse(agentname, password, m_freeSwitchRealm, String.Format("http://{0}:{1}{2}/", m_openSimWellKnownHTTPAddress, m_freeSwitchServicePort, m_freeSwitchAPIPrefix)); string r = LLSDHelpers.SerializeLLSDReply(voiceAccountResponse); m_log.DebugFormat("[FreeSwitchVoice][PROVISIONVOICE]: avatar \"{0}\": {1}", avatarName, r); return r; } catch (Exception e) { m_log.ErrorFormat("[FreeSwitchVoice][PROVISIONVOICE]: avatar \"{0}\": {1}, retry later", avatarName, e.Message); m_log.DebugFormat("[FreeSwitchVoice][PROVISIONVOICE]: avatar \"{0}\": {1} failed", avatarName, e.ToString()); return "<llsd>undef</llsd>"; } }
/// <summary> /// Callback for a client request for Voice Account Details /// </summary> /// <param name="scene">current scene object of the client</param> /// <param name="request"></param> /// <param name="path"></param> /// <param name="param"></param> /// <param name="agentID"></param> /// <param name="caps"></param> /// <returns></returns> public string ProvisionVoiceAccountRequest(Scene scene, string request, string path, string param, UUID agentID, Caps caps) { try { ScenePresence avatar = null; string avatarName = null; int avatarWait = 10000; // milliseconds int sleepWait = 100; // milliseconds if (scene == null) throw new Exception("[VivoxVoice][PROVISIONVOICE] Invalid scene"); avatar = scene.GetScenePresence(agentID); while (avatar == null || avatar.IsInTransit) { if (avatarWait <= 0) { m_log.WarnFormat("[VivoxVoice][PROVISIONVOICE]: Timeout waiting for agent {0} to enter scene.", agentID); return EMPTY_RESPONSE; } Thread.Sleep(sleepWait); avatarWait -= sleepWait; avatar = scene.GetScenePresence(agentID); } avatarName = avatar.Name; if (!scene.EventManager.TriggerOnBeforeProvisionVoiceAccount(agentID, avatarName)) { return EMPTY_RESPONSE; } m_log.DebugFormat("[VivoxVoice][PROVISIONVOICE]: scene = {0}, agentID = {1}", scene, agentID); m_log.DebugFormat("[VivoxVoice][PROVISIONVOICE]: request: {0}, path: {1}, param: {2}", request, path, param); XmlElement resp; bool retry = false; string agentname = "x" + Convert.ToBase64String(agentID.GetBytes()); string password = new UUID(Guid.NewGuid()).ToString().Replace('-','Z').Substring(0,16); string code = String.Empty; agentname = agentname.Replace('+', '-').Replace('/', '_'); do { resp = VivoxGetAccountInfo(agentname); if (XmlFind(resp, "response.level0.status", out code)) { if (code != "OK") { if (XmlFind(resp, "response.level0.body.code", out code)) { // If the request was recognized, then this should be set to something switch (code) { case "201" : // Account expired m_log.ErrorFormat("[VivoxVoice]: avatar \"{0}\": Get account information failed : expired credentials", avatarName); m_adminConnected = false; retry = DoAdminLogin(); break; case "202" : // Missing credentials m_log.ErrorFormat("[VivoxVoice]: avatar \"{0}\": Get account information failed : missing credentials", avatarName); break; case "212" : // Not authorized m_log.ErrorFormat("[VivoxVoice]: avatar \"{0}\": Get account information failed : not authorized", avatarName); break; case "300" : // Required parameter missing m_log.ErrorFormat("[VivoxVoice]: avatar \"{0}\": Get account information failed : parameter missing", avatarName); break; case "403" : // Account does not exist resp = VivoxCreateAccount(agentname,password); // Note: This REALLY MUST BE status. Create Account does not return code. if (XmlFind(resp, "response.level0.status", out code)) { switch (code) { case "201" : // Account expired m_log.ErrorFormat("[VivoxVoice]: avatar \"{0}\": Create account information failed : expired credentials", avatarName); m_adminConnected = false; retry = DoAdminLogin(); break; case "202" : // Missing credentials m_log.ErrorFormat("[VivoxVoice]: avatar \"{0}\": Create account information failed : missing credentials", avatarName); break; case "212" : // Not authorized m_log.ErrorFormat("[VivoxVoice]: avatar \"{0}\": Create account information failed : not authorized", avatarName); break; case "300" : // Required parameter missing m_log.ErrorFormat("[VivoxVoice]: avatar \"{0}\": Create account information failed : parameter missing", avatarName); break; case "400" : // Create failed m_log.ErrorFormat("[VivoxVoice]: avatar \"{0}\": Create account information failed : create failed", avatarName); break; } } break; case "404" : // Failed to retrieve account m_log.ErrorFormat("[VivoxVoice]: avatar \"{0}\": Get account information failed : retrieve failed"); // [AMW] Sleep and retry for a fixed period? Or just abandon? break; } } } } } while (retry); if (code != "OK") { m_log.DebugFormat("[VivoxVoice][PROVISIONVOICE]: Get Account Request failed for \"{0}\"", avatarName); throw new Exception("Unable to execute request"); } // Unconditionally change the password on each request VivoxPassword(agentname, password); LLSDVoiceAccountResponse voiceAccountResponse = new LLSDVoiceAccountResponse(agentname, password, m_vivoxSipUri, m_vivoxVoiceAccountApi); string r = LLSDHelpers.SerializeLLSDReply(voiceAccountResponse); m_log.DebugFormat("[VivoxVoice][PROVISIONVOICE]: avatar \"{0}\": {1}", avatarName, r); return r; } catch (Exception e) { m_log.ErrorFormat("[VivoxVoice][PROVISIONVOICE]: : {0}, retry later", e.Message); m_log.DebugFormat("[VivoxVoice][PROVISIONVOICE]: : {0} failed", e.ToString()); return EMPTY_RESPONSE; } }
/// Callback for a client request for Voice Account Details. public string ProvisionVoiceAccountRequest(Scene scene, string request, string path, string param, UUID agentID) { try { m_log.Debug("[MurmurVoice] Calling ProvisionVoiceAccountRequest..."); if (scene == null) throw new Exception("[MurmurVoice] Invalid scene."); // Wait for scene presence int retry = 0; ScenePresence avatar = scene.GetScenePresence(agentID); while (avatar == null) { if (++retry > 100) throw new Exception(String.Format("region \"{0}\": agent ID \"{1}\": wait for scene presence timed out", scene.RegionInfo.RegionName, agentID)); Thread.Sleep(100); avatar = scene.GetScenePresence(agentID); } Agent agent = new Agent(agentID, scene); LLSDVoiceAccountResponse voiceAccountResponse = new LLSDVoiceAccountResponse(agent.name, agent.pass, m_murmurd_host, String.Format("tcp://{0}:{1}", m_murmurd_host, m_murmurd_port) ); string r = LLSDHelpers.SerialiseLLSDReply(voiceAccountResponse); m_log.DebugFormat("[MurmurVoice] VoiceAccount: {0}", r); return r; } catch (Exception e) { m_log.DebugFormat("[MurmurVoice] {0} failed", e.ToString()); return "<llsd><undef /></llsd>"; } }