aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorJustin Clarke Casey2008-04-03 15:44:20 +0000
committerJustin Clarke Casey2008-04-03 15:44:20 +0000
commit042cd57e948f6e3695d1d5b2b2a473ee77a1e9c4 (patch)
tree347f7abdb075b4acba5ece213d667c7c562c99fb
parent* Minor: fix doc glitch (diff)
downloadopensim-SC-042cd57e948f6e3695d1d5b2b2a473ee77a1e9c4.zip
opensim-SC-042cd57e948f6e3695d1d5b2b2a473ee77a1e9c4.tar.gz
opensim-SC-042cd57e948f6e3695d1d5b2b2a473ee77a1e9c4.tar.bz2
opensim-SC-042cd57e948f6e3695d1d5b2b2a473ee77a1e9c4.tar.xz
* From: Dr Scofield <hud@zurich.ibm.com>
* This patch removes voice code into a region module. This required the implementation of events and other code to allow region modules to register their own caps handlers, and should allow different voice module implementations. * CAVEAT: This does not provide complete voice support, it merely provides the hooks so that it can be plugged in.
-rw-r--r--OpenSim/Framework/Communications/Capabilities/Caps.cs189
-rwxr-xr-xOpenSim/Framework/Communications/Capabilities/CapsHandlers.cs144
-rw-r--r--OpenSim/Framework/Communications/Capabilities/LLSDCapsDetails.cs52
-rw-r--r--OpenSim/Region/Environment/Modules/VoiceModule.cs196
-rw-r--r--OpenSim/Region/Environment/Scenes/Scene.cs6
-rw-r--r--OpenSim/Region/Environment/Scenes/SceneEvents.cs34
-rw-r--r--bin/OpenSim.ini.example2
7 files changed, 427 insertions, 196 deletions
diff --git a/OpenSim/Framework/Communications/Capabilities/Caps.cs b/OpenSim/Framework/Communications/Capabilities/Caps.cs
index 53cad66..886ca49 100644
--- a/OpenSim/Framework/Communications/Capabilities/Caps.cs
+++ b/OpenSim/Framework/Communications/Capabilities/Caps.cs
@@ -55,25 +55,22 @@ namespace OpenSim.Region.Capabilities
55 public delegate List<InventoryItemBase> FetchInventoryDescendentsCAPS(LLUUID agentID, LLUUID folderID, LLUUID ownerID, 55 public delegate List<InventoryItemBase> FetchInventoryDescendentsCAPS(LLUUID agentID, LLUUID folderID, LLUUID ownerID,
56 bool fetchFolders, bool fetchItems, int sortOrder); 56 bool fetchFolders, bool fetchItems, int sortOrder);
57 57
58 /// <summary>
59 /// FIXME This is a temporary delegate, and should disappear once the voice code is fleshed out and moved into its
60 /// own region module.
61 /// </summary>
62 public delegate CachedUserInfo GetUserDetailsCAPS(LLUUID agentID);
63
64 public class Caps 58 public class Caps
65 { 59 {
66 private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 60 private static readonly log4net.ILog m_log =
67 61 log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
62
68 private string m_httpListenerHostName; 63 private string m_httpListenerHostName;
69 private uint m_httpListenPort; 64 private uint m_httpListenPort;
70 65
71 /// <summary> 66 /// <summary>
72 /// This is the uuid portion of every CAPS path. It is used to make capability urls private to the requester. 67 /// This is the uuid portion of every CAPS path. It is used to make capability urls private to the requester.
73 /// </summary> 68 /// </summary>
74 private string m_capsObjectPath; 69 private string m_capsObjectPath;
75 public string CapsObjectPath { get { return m_capsObjectPath; } } 70 public string CapsObjectPath { get { return m_capsObjectPath; } }
76 71
72 private CapsHandlers m_capsHandlers;
73
77 private static readonly string m_requestPath = "0000/"; 74 private static readonly string m_requestPath = "0000/";
78 private static readonly string m_mapLayerPath = "0001/"; 75 private static readonly string m_mapLayerPath = "0001/";
79 private static readonly string m_newInventory = "0002/"; 76 private static readonly string m_newInventory = "0002/";
@@ -99,7 +96,6 @@ namespace OpenSim.Region.Capabilities
99 public TaskScriptUpdatedCallback TaskScriptUpdatedCall = null; 96 public TaskScriptUpdatedCallback TaskScriptUpdatedCall = null;
100 // 97 //
101 public FetchInventoryDescendentsCAPS CAPSFetchInventoryDescendents = null; 98 public FetchInventoryDescendentsCAPS CAPSFetchInventoryDescendents = null;
102 public GetUserDetailsCAPS CAPSGetUserDetails = null;
103 99
104 public Caps(AssetCache assetCache, BaseHttpServer httpServer, string httpListen, uint httpPort, string capsPath, 100 public Caps(AssetCache assetCache, BaseHttpServer httpServer, string httpListen, uint httpPort, string capsPath,
105 LLUUID agent, bool dumpAssetsToFile) 101 LLUUID agent, bool dumpAssetsToFile)
@@ -111,6 +107,7 @@ namespace OpenSim.Region.Capabilities
111 m_httpListenPort = httpPort; 107 m_httpListenPort = httpPort;
112 m_agentID = agent; 108 m_agentID = agent;
113 m_dumpAssetsToFile = dumpAssetsToFile; 109 m_dumpAssetsToFile = dumpAssetsToFile;
110 m_capsHandlers = new CapsHandlers(httpServer, httpListen, httpPort);
114 } 111 }
115 112
116 /// <summary> 113 /// <summary>
@@ -123,27 +120,31 @@ namespace OpenSim.Region.Capabilities
123 string capsBase = "/CAPS/" + m_capsObjectPath; 120 string capsBase = "/CAPS/" + m_capsObjectPath;
124 121
125 try 122 try
126 { 123 {
127 m_httpListener.AddStreamHandler( 124 // the root of all evil
128 new LLSDStreamhandler<LLSDMapRequest, LLSDMapLayerResponse>("POST", capsBase + m_mapLayerPath, GetMapLayer)); 125 m_capsHandlers["SEED"] = new RestStreamHandler("POST", capsBase + m_requestPath, CapsRequest);
129 m_httpListener.AddStreamHandler( 126 m_capsHandlers["MapLayer"] =
127 new LLSDStreamhandler<LLSDMapRequest, LLSDMapLayerResponse>("POST",
128 capsBase + m_mapLayerPath,
129 GetMapLayer);
130 m_capsHandlers["NewFileAgentInventory"] =
130 new LLSDStreamhandler<LLSDAssetUploadRequest, LLSDAssetUploadResponse>("POST", 131 new LLSDStreamhandler<LLSDAssetUploadRequest, LLSDAssetUploadResponse>("POST",
131 capsBase + m_newInventory, 132 capsBase + m_newInventory,
132 NewAgentInventoryRequest)); 133 NewAgentInventoryRequest);
133 134 m_capsHandlers["UpdateNotecardAgentInventory"] =
134 // m_httpListener.AddStreamHandler( 135 new RestStreamHandler("POST", capsBase + m_notecardUpdatePath, NoteCardAgentInventory);
135 // new LLSDStreamhandler<LLSDFetchInventoryDescendents, LLSDInventoryDescendents>("POST", 136 m_capsHandlers["UpdateScriptAgentInventory"] = m_capsHandlers["UpdateNotecardAgentInventory"];
136 // capsBase + m_fetchInventory, 137 m_capsHandlers["UpdateScriptTaskInventory"] =
137 // FetchInventory)); 138 new RestStreamHandler("POST", capsBase + m_notecardTaskUpdatePath, ScriptTaskInventory);
138 139 m_capsHandlers["FetchInventoryDescendents"] =
139 140 new RestStreamHandler("POST", capsBase + m_fetchInventoryPath, FetchInventoryRequest);
140 AddLegacyCapsHandler(m_httpListener, m_requestPath, CapsRequest); 141 // m_capsHandlers["FetchInventoryDescendents"] =
141 //AddLegacyCapsHandler(m_httpListener, m_requestTexture , RequestTexture); 142 // new LLSDStreamhandler<LLSDFetchInventoryDescendents, LLSDInventoryDescendents>("POST",
142 AddLegacyCapsHandler(m_httpListener, m_parcelVoiceInfoRequestPath, ParcelVoiceInfoRequest); 143 // capsBase + m_fetchInventory,
143 AddLegacyCapsHandler(m_httpListener, m_provisionVoiceAccountRequestPath, ProvisionVoiceAccountRequest); 144 // FetchInventory));
144 AddLegacyCapsHandler(m_httpListener, m_notecardUpdatePath, NoteCardAgentInventory); 145 // m_capsHandlers["RequestTextureDownload"] = new RestStreamHandler("POST",
145 AddLegacyCapsHandler(m_httpListener, m_notecardTaskUpdatePath, ScriptTaskInventory); 146 // capsBase + m_requestTexture,
146 AddLegacyCapsHandler(m_httpListener, m_fetchInventoryPath, FetchInventoryRequest); 147 // RequestTexture);
147 } 148 }
148 catch (Exception e) 149 catch (Exception e)
149 { 150 {
@@ -152,35 +153,29 @@ namespace OpenSim.Region.Capabilities
152 } 153 }
153 154
154 /// <summary> 155 /// <summary>
156 /// Register a handler. This allows modules to register handlers.
157 /// </summary>
158 /// <param name="capName"></param>
159 /// <param name="handler"></param>
160 public void RegisterHandler(string capName, IRequestHandler handler)
161 {
162 m_capsHandlers[capName] = handler;
163 m_log.DebugFormat("[CAPS]: Registering handler for \"{0}\": path {1}", capName, handler.Path);
164 }
165
166 /// <summary>
155 /// Remove all CAPS service handlers. 167 /// Remove all CAPS service handlers.
156 /// 168 ///
157 /// FIXME: Would be much nicer to remove and all paths to a single list. However, this is a little awkward
158 /// than it could be as we set up some handlers differently (legacy and non-legacy)
159 /// </summary> 169 /// </summary>
160 /// <param name="httpListener"></param> 170 /// <param name="httpListener"></param>
161 /// <param name="path"></param> 171 /// <param name="path"></param>
162 /// <param name="restMethod"></param> 172 /// <param name="restMethod"></param>
163 public void DeregisterHandlers() 173 public void DeregisterHandlers()
164 { 174 {
165 string capsBase = "/CAPS/" + m_capsObjectPath; 175 foreach(string capsName in m_capsHandlers.Caps)
166 176 {
167 m_httpListener.RemoveStreamHandler("POST", capsBase + m_mapLayerPath); 177 m_capsHandlers.Remove(capsName);
168 m_httpListener.RemoveStreamHandler("POST", capsBase + m_newInventory); 178 }
169 m_httpListener.RemoveStreamHandler("POST", capsBase + m_requestPath);
170 m_httpListener.RemoveStreamHandler("POST", capsBase + m_parcelVoiceInfoRequestPath);
171 m_httpListener.RemoveStreamHandler("POST", capsBase + m_provisionVoiceAccountRequestPath);
172 m_httpListener.RemoveStreamHandler("POST", capsBase + m_notecardUpdatePath);
173 m_httpListener.RemoveStreamHandler("POST", capsBase + m_notecardTaskUpdatePath);
174 m_httpListener.RemoveStreamHandler("POST", capsBase + m_fetchInventoryPath);
175 }
176
177 //[Obsolete("Use BaseHttpServer.AddStreamHandler(new LLSDStreamHandler( LLSDMethod delegate )) instead.")]
178 //Commented out the obsolete as at this time the first caps request can not use the new Caps method
179 //as the sent type is a array and not a map and the deserialising doesn't deal properly with arrays.
180 private void AddLegacyCapsHandler(BaseHttpServer httpListener, string path, RestMethod restMethod)
181 {
182 string capsBase = "/CAPS/" + m_capsObjectPath;
183 httpListener.AddStreamHandler(new RestStreamHandler("POST", capsBase + path, restMethod));
184 } 179 }
185 180
186 /// <summary> 181 /// <summary>
@@ -193,31 +188,12 @@ namespace OpenSim.Region.Capabilities
193 public string CapsRequest(string request, string path, string param) 188 public string CapsRequest(string request, string path, string param)
194 { 189 {
195 //Console.WriteLine("caps request " + request); 190 //Console.WriteLine("caps request " + request);
196 string result = LLSDHelpers.SerialiseLLSDReply(GetCapabilities()); 191 string result = LLSDHelpers.SerialiseLLSDReply(m_capsHandlers.CapsDetails);
197 return result; 192 return result;
198 } 193 }
199 194
200 /// <summary> 195 // FIXME: these all should probably go into the respective region
201 /// Return an LLSDCapsDetails listing all the capabilities this server can provide 196 // modules
202 /// </summary>
203 /// <returns></returns>
204 protected LLSDCapsDetails GetCapabilities()
205 {
206 LLSDCapsDetails caps = new LLSDCapsDetails();
207 string capsBaseUrl = "http://" + m_httpListenerHostName + ":" + m_httpListenPort.ToString() + "/CAPS/" +
208 m_capsObjectPath;
209 caps.MapLayer = capsBaseUrl + m_mapLayerPath;
210 // caps.RequestTextureDownload = capsBaseUrl + m_requestTexture;
211 caps.NewFileAgentInventory = capsBaseUrl + m_newInventory;
212 caps.UpdateNotecardAgentInventory = capsBaseUrl + m_notecardUpdatePath;
213 caps.UpdateScriptAgentInventory = capsBaseUrl + m_notecardUpdatePath;
214 caps.UpdateScriptTaskInventory = capsBaseUrl + m_notecardTaskUpdatePath;
215 caps.FetchInventoryDescendents = capsBaseUrl + m_fetchInventoryPath;
216 caps.ParcelVoiceInfoRequest = capsBaseUrl + m_parcelVoiceInfoRequestPath;
217 caps.ProvisionVoiceAccountRequest = capsBaseUrl + m_provisionVoiceAccountRequestPath;
218
219 return caps;
220 }
221 197
222 public string FetchInventoryRequest(string request, string path, string param) 198 public string FetchInventoryRequest(string request, string path, string param)
223 { 199 {
@@ -443,75 +419,6 @@ namespace OpenSim.Region.Capabilities
443 return null; 419 return null;
444 } 420 }
445 421
446 /// <summary>
447 /// Callback for a client request for ParcelVoiceInfo
448 /// </summary>
449 /// <param name="request"></param>
450 /// <param name="path"></param>
451 /// <param name="param"></param>
452 /// <returns></returns>
453 public string ParcelVoiceInfoRequest(string request, string path, string param) {
454 try
455 {
456 m_log.DebugFormat("[CAPS][PARCELVOICE]: request: {0}, path: {1}, param: {2}", request, path, param);
457
458 // XXX brutal hack, we need to get channel_uri, region
459 // name, and parcel_local_id from somewhere
460 Hashtable creds = new Hashtable();
461
462 creds["channel_uri"] = "sip:testroom@testserver.com";
463
464 LLSDParcelVoiceInfoResponse parcelVoiceInfo =
465 new LLSDParcelVoiceInfoResponse("OpenSim Test", 1, creds);
466
467 // XXX for debugging purposes:
468 string r = LLSDHelpers.SerialiseLLSDReply(parcelVoiceInfo);
469 m_log.DebugFormat("[CAPS][PARCELVOICE]: {0}", r);
470
471 return r;
472 }
473 catch (Exception e)
474 {
475 m_log.Error("[CAPS]: " + e.ToString());
476 }
477
478 return null;
479 }
480
481 /// <summary>
482 /// Callback for a client request for Voice Account Details
483 /// </summary>
484 /// <param name="request"></param>
485 /// <param name="path"></param>
486 /// <param name="param"></param>
487 /// <returns></returns>
488 public string ProvisionVoiceAccountRequest(string request, string path, string param) {
489 try
490 {
491 m_log.DebugFormat("[CAPS][PROVISIONVOICE]: request: {0}, path: {1}, param: {2}", request, path, param);
492
493 if (null == CAPSGetUserDetails) throw new Exception("CAPSGetUserDetails null");
494
495 string voiceUser = "x" + Convert.ToBase64String(m_agentID.GetBytes());
496 voiceUser = voiceUser.Replace('+', '-').Replace('/', '_');
497
498 CachedUserInfo userInfo = CAPSGetUserDetails(m_agentID);
499 if (null == userInfo) throw new Exception("CAPSGetUserDetails returned null");
500
501 LLSDVoiceAccountResponse voiceAccountResponse =
502 new LLSDVoiceAccountResponse(voiceUser, "$1$" + userInfo.UserProfile.passwordHash);
503 string r = LLSDHelpers.SerialiseLLSDReply(voiceAccountResponse);
504 m_log.DebugFormat("[CAPS][PROVISIONVOICE]: {0}", r);
505 return r;
506 }
507 catch (Exception e)
508 {
509 m_log.Error("[CAPS][PROVISIONVOICE]: " + e.ToString());
510 }
511
512 return null;
513 }
514
515 /// <summary> 422 /// <summary>
516 /// Called by the notecard update handler. Provides a URL to which the client can upload a new asset. 423 /// Called by the notecard update handler. Provides a URL to which the client can upload a new asset.
517 /// </summary> 424 /// </summary>
diff --git a/OpenSim/Framework/Communications/Capabilities/CapsHandlers.cs b/OpenSim/Framework/Communications/Capabilities/CapsHandlers.cs
new file mode 100755
index 0000000..a3d6b71
--- /dev/null
+++ b/OpenSim/Framework/Communications/Capabilities/CapsHandlers.cs
@@ -0,0 +1,144 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using System.IO;
32using libsecondlife;
33using OpenSim.Framework;
34using OpenSim.Framework.Communications.Cache;
35using OpenSim.Framework.Console;
36using OpenSim.Framework.Servers;
37
38namespace OpenSim.Region.Capabilities
39{
40 /// <summary>
41 /// CapsHandlers is a cap handler container but also takes
42 /// care of adding and removing cap handlers to and from the
43 /// supplied BaseHttpServer.
44 /// </summary>
45 public class CapsHandlers
46 {
47 private Dictionary <string, IRequestHandler> m_capsHandlers = new Dictionary<string, IRequestHandler>();
48 private BaseHttpServer m_httpListener;
49 private string m_httpListenerHostName;
50 private uint m_httpListenerPort;
51
52 /// <summary></summary>
53 /// <param name="httpListener">base HTTP server</param>
54 /// <param name="httpListenerHostname">host name of the HTTP
55 /// server</param>
56 /// <param name="httpListenerPort">HTTP port</param>
57 public CapsHandlers(BaseHttpServer httpListener, string httpListenerHostname, uint httpListenerPort)
58 {
59 m_httpListener = httpListener;
60 m_httpListenerHostName = httpListenerHostname;
61 m_httpListenerPort = httpListenerPort;
62 }
63
64 /// <summary>
65 /// Remove the cap handler for a capability.
66 /// </summary>
67 /// <param name="capsName">name of the capability of the cap
68 /// handler to be removed</param>
69 public void Remove(string capsName)
70 {
71 m_capsHandlers.Remove(capsName);
72 }
73
74 public bool ContainsCap(string cap)
75 {
76 return m_capsHandlers.ContainsKey(cap);
77 }
78
79 /// <summary>
80 /// The indexer allows us to treat the CapsHandlers object
81 /// in an intuitive dictionary like way.
82 /// </summary>
83 /// <Remarks>
84 /// The indexer will throw an exception when you try to
85 /// retrieve a cap handler for a cap that is not contained in
86 /// CapsHandlers.
87 /// </Remarks>
88 public IRequestHandler this[string idx]
89 {
90 get
91 {
92 return m_capsHandlers[idx];
93 }
94
95 set
96 {
97 if (m_capsHandlers.ContainsKey(idx))
98 {
99 m_httpListener.RemoveStreamHandler("POST", m_capsHandlers[idx].Path);
100 m_capsHandlers.Remove(idx);
101 }
102
103 if (null == value) return;
104
105 m_capsHandlers[idx] = value;
106 m_httpListener.AddStreamHandler(value);
107 }
108 }
109
110 /// <summary>
111 /// Return the list of cap names for which this CapsHandlers
112 /// object contains cap handlers.
113 /// </summary>
114 public string[] Caps
115 {
116 get
117 {
118 string[] __keys = new string[m_capsHandlers.Keys.Count];
119 m_capsHandlers.Keys.CopyTo(__keys, 0);
120 return __keys;
121 }
122 }
123
124 /// <summary>
125 /// Return an LLSD-serializable Hashtable describing the
126 /// capabilities and their handler details.
127 /// </summary>
128 public Hashtable CapsDetails
129 {
130 get
131 {
132 Hashtable caps = new Hashtable();
133 string baseUrl = "http://" + m_httpListenerHostName + ":" + m_httpListenerPort.ToString();
134 foreach (string capsName in m_capsHandlers.Keys)
135 {
136 // skip SEED cap
137 if ("SEED" == capsName) continue;
138 caps[capsName] = baseUrl + m_capsHandlers[capsName].Path;
139 }
140 return caps;
141 }
142 }
143 }
144}
diff --git a/OpenSim/Framework/Communications/Capabilities/LLSDCapsDetails.cs b/OpenSim/Framework/Communications/Capabilities/LLSDCapsDetails.cs
deleted file mode 100644
index bd1c9da..0000000
--- a/OpenSim/Framework/Communications/Capabilities/LLSDCapsDetails.cs
+++ /dev/null
@@ -1,52 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29
30namespace OpenSim.Region.Capabilities
31{
32 [LLSDType("MAP")]
33 public class LLSDCapsDetails
34 {
35 public string MapLayer = String.Empty;
36 public string NewFileAgentInventory = String.Empty;
37 //public string EventQueueGet = String.Empty;
38 // public string RequestTextureDownload = String.Empty;
39 // public string ChatSessionRequest = String.Empty;
40 public string UpdateNotecardAgentInventory = String.Empty;
41 public string UpdateScriptAgentInventory = String.Empty;
42 public string UpdateScriptTaskInventory = String.Empty;
43 public string ParcelVoiceInfoRequest = String.Empty;
44 public string FetchInventoryDescendents = String.Empty;
45 public string ProvisionVoiceAccountRequest = String.Empty;
46
47
48 public LLSDCapsDetails()
49 {
50 }
51 }
52}
diff --git a/OpenSim/Region/Environment/Modules/VoiceModule.cs b/OpenSim/Region/Environment/Modules/VoiceModule.cs
new file mode 100644
index 0000000..b254507
--- /dev/null
+++ b/OpenSim/Region/Environment/Modules/VoiceModule.cs
@@ -0,0 +1,196 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using libsecondlife;
32using Nini.Config;
33using OpenSim.Framework;
34using OpenSim.Framework.Communications.Cache;
35using OpenSim.Framework.Servers;
36using OpenSim.Region.Capabilities;
37using Caps = OpenSim.Region.Capabilities.Caps;
38using OpenSim.Region.Environment.Interfaces;
39using OpenSim.Region.Environment.Scenes;
40
41namespace OpenSim.Region.Environment.Modules
42{
43 public class VoiceModule : IRegionModule
44 {
45 private static readonly log4net.ILog m_log =
46 log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
47
48 private Scene m_scene;
49 private IConfig m_config;
50 private string m_sipDomain;
51
52 private static readonly string m_parcelVoiceInfoRequestPath = "0007/";
53 private static readonly string m_provisionVoiceAccountRequestPath = "0008/";
54
55 public void Initialise(Scene scene, IConfigSource config)
56 {
57 m_scene = scene;
58 m_config = config.Configs["Voice"];
59
60 if (null == m_config || !m_config.GetBoolean("enabled", false))
61 {
62 m_log.Info("[VOICE] plugin disabled");
63 return;
64 }
65 m_log.Info("[VOICE] plugin enabled");
66
67 m_sipDomain = m_config.GetString("sip_domain", String.Empty);
68 if (String.IsNullOrEmpty(m_sipDomain))
69 {
70 m_log.Error("[VOICE] plugin mis-configured: missing sip_domain configuration");
71 m_log.Info("[VOICE] plugin disabled");
72 return;
73 }
74 m_log.InfoFormat("[VOICE] using SIP domain {0}", m_sipDomain);
75
76 scene.EventManager.OnRegisterCaps += OnRegisterCaps;
77 }
78
79 public void PostInitialise()
80 {
81 }
82
83 public void Close()
84 {
85 }
86
87 public string Name
88 {
89 get { return "VoiceModule"; }
90 }
91
92 public bool IsSharedModule
93 {
94 get { return false; }
95 }
96
97 public void OnRegisterCaps(LLUUID agentID, Caps caps)
98 {
99 m_log.DebugFormat("[VOICE] OnRegisterCaps: agentID {0} caps {1}", agentID, caps);
100 string capsBase = "/CAPS/" + caps.CapsObjectPath;
101 caps.RegisterHandler("ParcelVoiceInfoRequest",
102 new RestStreamHandler("POST", capsBase + m_parcelVoiceInfoRequestPath,
103 delegate(string request, string path, string param)
104 {
105 return ParcelVoiceInfoRequest(request, path, param,
106 agentID, caps);
107 }));
108 caps.RegisterHandler("ProvisionVoiceAccountRequest",
109 new RestStreamHandler("POST", capsBase + m_provisionVoiceAccountRequestPath,
110 delegate(string request, string path, string param)
111 {
112 return ProvisionVoiceAccountRequest(request, path, param,
113 agentID, caps);
114 }));
115 }
116
117 /// <summary>
118 /// Callback for a client request for ParcelVoiceInfo
119 /// </summary>
120 /// <param name="request"></param>
121 /// <param name="path"></param>
122 /// <param name="param"></param>
123 /// <param name="agentID"></param>
124 /// <param name="caps"></param>
125 /// <returns></returns>
126 public string ParcelVoiceInfoRequest(string request, string path, string param,
127 LLUUID agentID, Caps caps)
128 {
129 try
130 {
131 m_log.DebugFormat("[VOICE][PARCELVOICE]: request: {0}, path: {1}, param: {2}", request, path, param);
132
133 // FIXME: get the creds from region file or from config
134 Hashtable creds = new Hashtable();
135
136 creds["channel_uri"] = String.Format("sip:{0}@{1}", agentID.ToString(), m_sipDomain);
137
138 string regionName = m_scene.RegionInfo.RegionName;
139 ScenePresence avatar = m_scene.GetScenePresence(agentID);
140 if (null == m_scene.LandChannel) throw new Exception("land data not yet available");
141 LandData land = m_scene.GetLandData(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y);
142
143 LLSDParcelVoiceInfoResponse parcelVoiceInfo =
144 new LLSDParcelVoiceInfoResponse(regionName, land.localID, creds);
145
146 string r = LLSDHelpers.SerialiseLLSDReply(parcelVoiceInfo);
147 m_log.DebugFormat("[VOICE][PARCELVOICE]: {0}", r);
148
149 return r;
150 }
151 catch (Exception e)
152 {
153 m_log.ErrorFormat("[CAPS]: {0}, try again later", e.ToString());
154 }
155
156 return null;
157 }
158
159 /// <summary>
160 /// Callback for a client request for Voice Account Details
161 /// </summary>
162 /// <param name="request"></param>
163 /// <param name="path"></param>
164 /// <param name="param"></param>
165 /// <param name="agentID"></param>
166 /// <param name="caps"></param>
167 /// <returns></returns>
168 public string ProvisionVoiceAccountRequest(string request, string path, string param,
169 LLUUID agentID, Caps caps)
170 {
171 try
172 {
173 m_log.DebugFormat("[VOICE][PROVISIONVOICE]: request: {0}, path: {1}, param: {2}",
174 request, path, param);
175
176 string voiceUser = "x" + Convert.ToBase64String(agentID.GetBytes());
177 voiceUser = voiceUser.Replace('+', '-').Replace('/', '_');
178
179 CachedUserInfo userInfo = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(agentID);
180 if (null == userInfo) throw new Exception("cannot get user details");
181
182 LLSDVoiceAccountResponse voiceAccountResponse =
183 new LLSDVoiceAccountResponse(voiceUser, "$1$" + userInfo.UserProfile.passwordHash);
184 string r = LLSDHelpers.SerialiseLLSDReply(voiceAccountResponse);
185 m_log.DebugFormat("[CAPS][PROVISIONVOICE]: {0}", r);
186 return r;
187 }
188 catch (Exception e)
189 {
190 m_log.ErrorFormat("[CAPS][PROVISIONVOICE]: {0}, retry later", e.Message);
191 }
192
193 return null;
194 }
195 }
196}
diff --git a/OpenSim/Region/Environment/Scenes/Scene.cs b/OpenSim/Region/Environment/Scenes/Scene.cs
index 2237922..64c443d 100644
--- a/OpenSim/Region/Environment/Scenes/Scene.cs
+++ b/OpenSim/Region/Environment/Scenes/Scene.cs
@@ -1737,14 +1737,14 @@ namespace OpenSim.Region.Environment.Scenes
1737 Caps cap = 1737 Caps cap =
1738 new Caps(AssetCache, m_httpListener, m_regInfo.ExternalHostName, m_httpListener.Port, 1738 new Caps(AssetCache, m_httpListener, m_regInfo.ExternalHostName, m_httpListener.Port,
1739 capsObjectPath, agentId, m_dumpAssetsToFile); 1739 capsObjectPath, agentId, m_dumpAssetsToFile);
1740
1741 cap.RegisterHandlers(); 1740 cap.RegisterHandlers();
1741
1742 EventManager.TriggerOnRegisterCaps(agentId, cap);
1742 1743
1743 cap.AddNewInventoryItem = AddInventoryItem; 1744 cap.AddNewInventoryItem = AddInventoryItem;
1744 cap.ItemUpdatedCall = CapsUpdateInventoryItemAsset; 1745 cap.ItemUpdatedCall = CapsUpdateInventoryItemAsset;
1745 cap.TaskScriptUpdatedCall = CapsUpdateTaskInventoryScriptAsset; 1746 cap.TaskScriptUpdatedCall = CapsUpdateTaskInventoryScriptAsset;
1746 cap.CAPSFetchInventoryDescendents = CommsManager.UserProfileCacheService.HandleFetchInventoryDescendentsCAPS; 1747 cap.CAPSFetchInventoryDescendents = CommsManager.UserProfileCacheService.HandleFetchInventoryDescendentsCAPS;
1747 cap.CAPSGetUserDetails = CommsManager.UserProfileCacheService.GetUserDetails;
1748 1748
1749 m_capsHandlers[agentId] = cap; 1749 m_capsHandlers[agentId] = cap;
1750 } 1750 }
@@ -1764,6 +1764,8 @@ namespace OpenSim.Region.Environment.Scenes
1764 agentId, RegionInfo.RegionName); 1764 agentId, RegionInfo.RegionName);
1765 1765
1766 m_capsHandlers[agentId].DeregisterHandlers(); 1766 m_capsHandlers[agentId].DeregisterHandlers();
1767 EventManager.TriggerOnDeregisterCaps(agentId, m_capsHandlers[agentId]);
1768
1767 m_capsHandlers.Remove(agentId); 1769 m_capsHandlers.Remove(agentId);
1768 } 1770 }
1769 else 1771 else
diff --git a/OpenSim/Region/Environment/Scenes/SceneEvents.cs b/OpenSim/Region/Environment/Scenes/SceneEvents.cs
index 809507c..c916009 100644
--- a/OpenSim/Region/Environment/Scenes/SceneEvents.cs
+++ b/OpenSim/Region/Environment/Scenes/SceneEvents.cs
@@ -29,6 +29,7 @@ using libsecondlife;
29using System; 29using System;
30using OpenSim.Framework; 30using OpenSim.Framework;
31using OpenSim.Region.Environment.Interfaces; 31using OpenSim.Region.Environment.Interfaces;
32using Caps = OpenSim.Region.Capabilities.Caps;
32 33
33namespace OpenSim.Region.Environment.Scenes 34namespace OpenSim.Region.Environment.Scenes
34{ 35{
@@ -136,6 +137,19 @@ namespace OpenSim.Region.Environment.Scenes
136 137
137 public event OnNewPresenceDelegate OnMakeChildAgent; 138 public event OnNewPresenceDelegate OnMakeChildAgent;
138 139
140 /// <summary>
141 /// RegisterCapsEvent is called by Scene after the Caps object
142 /// has been instantiated and before it is return to the
143 /// client and provides region modules to add their caps.
144 /// </summary>
145 public delegate void RegisterCapsEvent(LLUUID agentID, Caps caps);
146 public event RegisterCapsEvent OnRegisterCaps;
147 /// <summary>
148 /// DeregisterCapsEvent is called by Scene when the caps
149 /// handler for an agent are removed.
150 /// </summary>
151 public delegate void DeregisterCapsEvent(LLUUID agentID, Caps caps);
152 public event DeregisterCapsEvent OnDeregisterCaps;
139 153
140 public class MoneyTransferArgs : System.EventArgs 154 public class MoneyTransferArgs : System.EventArgs
141 { 155 {
@@ -191,6 +205,8 @@ namespace OpenSim.Region.Environment.Scenes
191 private ClientClosed handlerClientClosed = null; //OnClientClosed; 205 private ClientClosed handlerClientClosed = null; //OnClientClosed;
192 private OnNewPresenceDelegate handlerMakeChildAgent = null; //OnMakeChildAgent; 206 private OnNewPresenceDelegate handlerMakeChildAgent = null; //OnMakeChildAgent;
193 private OnTerrainTickDelegate handlerTerrainTick = null; // OnTerainTick; 207 private OnTerrainTickDelegate handlerTerrainTick = null; // OnTerainTick;
208 private RegisterCapsEvent handlerRegisterCaps = null; // OnRegisterCaps;
209 private DeregisterCapsEvent handlerDeregisterCaps = null; // OnDeregisterCaps;
194 210
195 public void TriggerOnScriptChangedEvent(uint localID, uint change) 211 public void TriggerOnScriptChangedEvent(uint localID, uint change)
196 { 212 {
@@ -428,5 +444,23 @@ namespace OpenSim.Region.Environment.Scenes
428 handlerMakeChildAgent(presence); 444 handlerMakeChildAgent(presence);
429 } 445 }
430 } 446 }
447
448 public void TriggerOnRegisterCaps(LLUUID agentID, Caps caps)
449 {
450 handlerRegisterCaps = OnRegisterCaps;
451 if (handlerRegisterCaps != null)
452 {
453 handlerRegisterCaps(agentID, caps);
454 }
455 }
456
457 public void TriggerOnDeregisterCaps(LLUUID agentID, Caps caps)
458 {
459 handlerDeregisterCaps = OnDeregisterCaps;
460 if (handlerDeregisterCaps != null)
461 {
462 handlerDeregisterCaps(agentID, caps);
463 }
464 }
431 } 465 }
432} 466}
diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example
index 5a6ef06..bf8a48f 100644
--- a/bin/OpenSim.ini.example
+++ b/bin/OpenSim.ini.example
@@ -164,7 +164,7 @@ enabled = false
164; changed in future. :-) 164; changed in future. :-)
165account_management_server = https://www.bhr.vivox.com/api2 165account_management_server = https://www.bhr.vivox.com/api2
166; Global SIP Server for conference calls 166; Global SIP Server for conference calls
167sip_uri = sip:testroom@testserver.com 167sip_domain = testserver.com
168 168
169; Uncomment the following to control the progression of daytime 169; Uncomment the following to control the progression of daytime
170; in the Sim. The defaults are what is shown below 170; in the Sim. The defaults are what is shown below