aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs
diff options
context:
space:
mode:
authorSean Dague2009-04-17 20:00:30 +0000
committerSean Dague2009-04-17 20:00:30 +0000
commit7f30be17d0ee841961262ee9e9b8fab27ccf6d83 (patch)
tree77a48e8135b5086ba4fd9225f72ce77f702011ce /OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs
parentCorrect detected rotation to return the same value as llGetRot in the object ... (diff)
downloadopensim-SC_OLD-7f30be17d0ee841961262ee9e9b8fab27ccf6d83.zip
opensim-SC_OLD-7f30be17d0ee841961262ee9e9b8fab27ccf6d83.tar.gz
opensim-SC_OLD-7f30be17d0ee841961262ee9e9b8fab27ccf6d83.tar.bz2
opensim-SC_OLD-7f30be17d0ee841961262ee9e9b8fab27ccf6d83.tar.xz
experimental freeswitch code, imported from Rob Smart's tree
Diffstat (limited to 'OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs')
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs571
1 files changed, 571 insertions, 0 deletions
diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs
new file mode 100644
index 0000000..a8f9de6
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs
@@ -0,0 +1,571 @@
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.IO;
30using System.Net;
31using System.Web;
32using System.Text;
33using System.Xml;
34using System.Collections;
35using System.Collections.Generic;
36using System.Reflection;
37using OpenMetaverse;
38using log4net;
39using Nini.Config;
40using Nwc.XmlRpc;
41using OpenSim.Framework;
42using OpenSim.Framework.Communications.Cache;
43using OpenSim.Framework.Communications.Capabilities;
44using OpenSim.Framework.Servers;
45using OpenSim.Region.Framework.Interfaces;
46using OpenSim.Region.Framework.Scenes;
47using Caps = OpenSim.Framework.Communications.Capabilities.Caps;
48
49namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
50{
51 public class FreeSwitchVoiceModule : IRegionModule
52 {
53
54 // Infrastructure
55 private static readonly ILog m_log =
56 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
57 private static readonly bool DUMP = true;
58
59 // Capability string prefixes
60 private static readonly string m_parcelVoiceInfoRequestPath = "0007/";
61 private static readonly string m_provisionVoiceAccountRequestPath = "0008/";
62 private static readonly string m_chatSessionRequestPath = "0009/";
63
64 // Control info
65 private static bool m_WOF = true;
66 private static bool m_pluginEnabled = false;
67
68 // FreeSwitch server is going to contact us and ask us all
69 // sorts of things.
70 private static string m_freeSwitchServerUser;
71 private static string m_freeSwitchServerPass;
72
73 // SLVoice client will do a GET on this prefix
74 private static string m_freeSwitchAPIPrefix;
75
76 // We need to return some information to SLVoice
77 // figured those out via curl
78 // http://vd1.vivox.com/api2/viv_get_prelogin.php
79 //
80 // need to figure out whether we do need to return ALL of
81 // these...
82 private static string m_freeSwitchRealm;
83 private static string m_freeSwitchSIPProxy;
84 private static bool m_freeSwitchAttemptUseSTUN;
85 private static string m_freeSwitchSTUNServer;
86 private static string m_freeSwitchEchoServer;
87 private static int m_freeSwitchEchoPort;
88 private static string m_freeSwitchDefaultWellKnownIP;
89 private static int m_freeSwitchDefaultTimeout;
90 private static int m_freeSwitchSubscribeRetry;
91 private static string m_freeSwitchUrlResetPassword;
92 private static IPEndPoint m_FreeSwitchServiceIP;
93
94 private FreeSwitchDirectory m_FreeSwitchDirectory;
95 private FreeSwitchDialplan m_FreeSwitchDialplan;
96
97 private IConfig m_config;
98
99 public void Initialise(Scene scene, IConfigSource config)
100 {
101
102 m_config = config.Configs["FreeSwitchVoice"];
103
104 if (null == m_config)
105 {
106 m_log.Info("[FreeSwitchVoice] no config found, plugin disabled");
107 return;
108 }
109
110 if (!m_config.GetBoolean("enabled", false))
111 {
112 m_log.Info("[FreeSwitchVoice] plugin disabled by configuration");
113 return;
114 }
115
116 // This is only done the FIRST time this method is invoked.
117 if (m_WOF)
118 {
119 m_pluginEnabled = true;
120 m_WOF = false;
121
122 try
123 {
124 m_freeSwitchServerUser = m_config.GetString("freeswitch_server_user", String.Empty);
125 m_freeSwitchServerPass = m_config.GetString("freeswitch_server_pass", String.Empty);
126 m_freeSwitchAPIPrefix = m_config.GetString("freeswitch_api_prefix", String.Empty);
127
128 // XXX: get IP address of HTTP server. (This can be this OpenSim server or another, or could be a dedicated grid service or may live on the freeswitch server)
129
130 string serviceIP = m_config.GetString("freeswitch_service_server", String.Empty);
131 int servicePort = m_config.GetInt("freeswitch_service_port", 80);
132 IPAddress serviceIPAddress = IPAddress.Parse(serviceIP);
133 m_FreeSwitchServiceIP = new IPEndPoint(serviceIPAddress, servicePort);
134
135 m_freeSwitchRealm = m_config.GetString("freeswitch_realm", String.Empty);
136 m_freeSwitchSIPProxy = m_config.GetString("freeswitch_sip_proxy", m_freeSwitchRealm);
137 m_freeSwitchAttemptUseSTUN = m_config.GetBoolean("freeswitch_attempt_stun", true);
138 m_freeSwitchSTUNServer = m_config.GetString("freeswitch_stun_server", m_freeSwitchRealm);
139 m_freeSwitchEchoServer = m_config.GetString("freeswitch_echo_server", m_freeSwitchRealm);
140 m_freeSwitchEchoPort = m_config.GetInt("freeswitch_echo_port", 50505);
141 m_freeSwitchDefaultWellKnownIP = m_config.GetString("freeswitch_well_known_ip", m_freeSwitchRealm);
142 m_freeSwitchDefaultTimeout = m_config.GetInt("freeswitch_default_timeout", 5000);
143 m_freeSwitchSubscribeRetry = m_config.GetInt("freeswitch_subscribe_retry", 120);
144 m_freeSwitchUrlResetPassword = m_config.GetString("freeswitch_password_reset_url", String.Empty);
145
146
147
148
149 if (String.IsNullOrEmpty(m_freeSwitchServerUser) ||
150 String.IsNullOrEmpty(m_freeSwitchServerPass) ||
151 String.IsNullOrEmpty(m_freeSwitchRealm) ||
152 String.IsNullOrEmpty(m_freeSwitchAPIPrefix))
153 {
154 m_log.Error("[FreeSwitchVoice] plugin mis-configured");
155 m_log.Info("[FreeSwitchVoice] plugin disabled: incomplete configuration");
156 return;
157 }
158
159 // set up http request handlers for
160 // - prelogin: viv_get_prelogin.php
161 // - signin: viv_signin.php
162 scene.CommsManager.HttpServer.AddHTTPHandler(String.Format("{0}/viv_get_prelogin.php", m_freeSwitchAPIPrefix),
163 FreeSwitchSLVoiceGetPreloginHTTPHandler);
164
165 // RestStreamHandler h = new RestStreamHandler("GET", String.Format("{0}/viv_get_prelogin.php", m_freeSwitchAPIPrefix), FreeSwitchSLVoiceGetPreloginHTTPHandler);
166 // scene.CommsManager.HttpServer.AddStreamHandler(h);
167
168
169
170 scene.CommsManager.HttpServer.AddHTTPHandler(String.Format("{0}/viv_signin.php", m_freeSwitchAPIPrefix),
171 FreeSwitchSLVoiceSigninHTTPHandler);
172
173 // set up http request handlers to provide
174 // on-demand FreeSwitch configuration to
175 // FreeSwitch's mod_curl_xml
176 scene.CommsManager.HttpServer.AddHTTPHandler(String.Format("{0}/freeswitch-config", m_freeSwitchAPIPrefix),
177 FreeSwitchConfigHTTPHandler);
178
179 m_log.InfoFormat("[FreeSwitchVoice] using FreeSwitch server {0}", m_freeSwitchRealm);
180
181 m_FreeSwitchDirectory = new FreeSwitchDirectory();
182 m_FreeSwitchDialplan = new FreeSwitchDialplan();
183
184 m_pluginEnabled = true;
185 m_WOF = false;
186
187 m_log.Info("[FreeSwitchVoice] plugin enabled");
188 }
189 catch (Exception e)
190 {
191 m_log.ErrorFormat("[FreeSwitchVoice] plugin initialization failed: {0}", e.Message);
192 m_log.DebugFormat("[FreeSwitchVoice] plugin initialization failed: {0}", e.ToString());
193 return;
194 }
195 }
196
197 if (m_pluginEnabled)
198 {
199 // we need to capture scene in an anonymous method
200 // here as we need it later in the callbacks
201 scene.EventManager.OnRegisterCaps += delegate(UUID agentID, Caps caps)
202 {
203 OnRegisterCaps(scene, agentID, caps);
204 };
205
206
207
208 }
209 }
210
211 public void PostInitialise()
212 {
213 }
214
215 public void Close()
216 {
217 }
218
219 public string Name
220 {
221 get { return "FreeSwitchVoiceModule"; }
222 }
223
224 public bool IsSharedModule
225 {
226 get { return true; }
227 }
228
229
230 // <summary>
231 // OnRegisterCaps is invoked via the scene.EventManager
232 // everytime OpenSim hands out capabilities to a client
233 // (login, region crossing). We contribute two capabilities to
234 // the set of capabilities handed back to the client:
235 // ProvisionVoiceAccountRequest and ParcelVoiceInfoRequest.
236 //
237 // ProvisionVoiceAccountRequest allows the client to obtain
238 // the voice account credentials for the avatar it is
239 // controlling (e.g., user name, password, etc).
240 //
241 // ParcelVoiceInfoRequest is invoked whenever the client
242 // changes from one region or parcel to another.
243 //
244 // Note that OnRegisterCaps is called here via a closure
245 // delegate containing the scene of the respective region (see
246 // Initialise()).
247 // </summary>
248 public void OnRegisterCaps(Scene scene, UUID agentID, Caps caps)
249 {
250 m_log.DebugFormat("[FreeSwitchVoice] OnRegisterCaps: agentID {0} caps {1}", agentID, caps);
251
252 string capsBase = "/CAPS/" + caps.CapsObjectPath;
253 caps.RegisterHandler("ProvisionVoiceAccountRequest",
254 new RestStreamHandler("POST", capsBase + m_provisionVoiceAccountRequestPath,
255 delegate(string request, string path, string param,
256 OSHttpRequest httpRequest, OSHttpResponse httpResponse)
257 {
258 return ProvisionVoiceAccountRequest(scene, request, path, param,
259 agentID, caps);
260 }));
261 caps.RegisterHandler("ParcelVoiceInfoRequest",
262 new RestStreamHandler("POST", capsBase + m_parcelVoiceInfoRequestPath,
263 delegate(string request, string path, string param,
264 OSHttpRequest httpRequest, OSHttpResponse httpResponse)
265 {
266 return ParcelVoiceInfoRequest(scene, request, path, param,
267 agentID, caps);
268 }));
269 caps.RegisterHandler("ChatSessionRequest",
270 new RestStreamHandler("POST", capsBase + m_chatSessionRequestPath,
271 delegate(string request, string path, string param,
272 OSHttpRequest httpRequest, OSHttpResponse httpResponse)
273 {
274 return ChatSessionRequest(scene, request, path, param,
275 agentID, caps);
276 }));
277 }
278
279 /// <summary>
280 /// Callback for a client request for Voice Account Details
281 /// </summary>
282 /// <param name="scene">current scene object of the client</param>
283 /// <param name="request"></param>
284 /// <param name="path"></param>
285 /// <param name="param"></param>
286 /// <param name="agentID"></param>
287 /// <param name="caps"></param>
288 /// <returns></returns>
289 public string ProvisionVoiceAccountRequest(Scene scene, string request, string path, string param,
290 UUID agentID, Caps caps)
291 {
292 ScenePresence avatar = scene.GetScenePresence(agentID);
293 string avatarName = avatar.Name;
294
295 try
296 {
297 m_log.DebugFormat("[FreeSwitchVoice][PROVISIONVOICE]: request: {0}, path: {1}, param: {2}",
298 request, path, param);
299
300 //XmlElement resp;
301 string agentname = "x" + Convert.ToBase64String(agentID.GetBytes());
302 string password = "1234";//temp hack//new UUID(Guid.NewGuid()).ToString().Replace('-','Z').Substring(0,16);
303
304 // XXX: we need to cache the voice credentials, as
305 // FreeSwitch is later going to come and ask us for
306 // those
307
308 agentname = agentname.Replace('+', '-').Replace('/', '_');
309
310 // LLSDVoiceAccountResponse voiceAccountResponse =
311 // new LLSDVoiceAccountResponse(agentname, password, m_freeSwitchRealm, "http://etsvc02.hursley.ibm.com/api");
312 LLSDVoiceAccountResponse voiceAccountResponse =
313 new LLSDVoiceAccountResponse(agentname, password, m_freeSwitchRealm,
314 String.Format("http://{0}/{1}/", m_FreeSwitchServiceIP,
315 m_freeSwitchAPIPrefix));
316
317 string r = LLSDHelpers.SerialiseLLSDReply(voiceAccountResponse);
318
319 m_log.DebugFormat("[FreeSwitchVoice][PROVISIONVOICE]: avatar \"{0}\": {1}", avatarName, r);
320
321 return r;
322 }
323 catch (Exception e)
324 {
325 m_log.ErrorFormat("[FreeSwitchVoice][PROVISIONVOICE]: avatar \"{0}\": {1}, retry later", avatarName, e.Message);
326 m_log.DebugFormat("[FreeSwitchVoice][PROVISIONVOICE]: avatar \"{0}\": {1} failed", avatarName, e.ToString());
327
328 return "<llsd>undef</llsd>";
329 }
330 }
331
332 /// <summary>
333 /// Callback for a client request for ParcelVoiceInfo
334 /// </summary>
335 /// <param name="scene">current scene object of the client</param>
336 /// <param name="request"></param>
337 /// <param name="path"></param>
338 /// <param name="param"></param>
339 /// <param name="agentID"></param>
340 /// <param name="caps"></param>
341 /// <returns></returns>
342 public string ParcelVoiceInfoRequest(Scene scene, string request, string path, string param,
343 UUID agentID, Caps caps)
344 {
345 ScenePresence avatar = scene.GetScenePresence(agentID);
346 string avatarName = avatar.Name;
347
348 // - check whether we have a region channel in our cache
349 // - if not:
350 // create it and cache it
351 // - send it to the client
352 // - send channel_uri: as "sip:regionID@m_sipDomain"
353 try
354 {
355 LLSDParcelVoiceInfoResponse parcelVoiceInfo;
356 string channelUri;
357
358 if (null == scene.LandChannel)
359 throw new Exception(String.Format("region \"{0}\": avatar \"{1}\": land data not yet available",
360 scene.RegionInfo.RegionName, avatarName));
361
362
363
364 // get channel_uri: check first whether estate
365 // settings allow voice, then whether parcel allows
366 // voice, if all do retrieve or obtain the parcel
367 // voice channel
368 LandData land = scene.GetLandData(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y);
369
370 m_log.DebugFormat("[FreeSwitchVoice][PARCELVOICE]: region \"{0}\": Parcel \"{1}\" ({2}): avatar \"{3}\": request: {4}, path: {5}, param: {6}",
371 scene.RegionInfo.RegionName, land.Name, land.LocalID, avatarName, request, path, param);
372
373 // TODO: EstateSettings don't seem to get propagated...
374 // if (!scene.RegionInfo.EstateSettings.AllowVoice)
375 // {
376 // m_log.DebugFormat("[FreeSwitchVoice][PARCELVOICE]: region \"{0}\": voice not enabled in estate settings",
377 // scene.RegionInfo.RegionName);
378 // channel_uri = String.Empty;
379 // }
380 // else
381
382 if ((land.Flags & (uint)Parcel.ParcelFlags.AllowVoiceChat) == 0)
383 {
384 m_log.DebugFormat("[FreeSwitchVoice][PARCELVOICE]: region \"{0}\": Parcel \"{1}\" ({2}): avatar \"{3}\": voice not enabled for parcel",
385 scene.RegionInfo.RegionName, land.Name, land.LocalID, avatarName);
386 channelUri = String.Empty;
387 }
388 else
389 {
390 channelUri = ChannelUri(scene, land);
391 }
392
393 // fill in our response to the client
394 Hashtable creds = new Hashtable();
395 creds["channel_uri"] = channelUri;
396
397 parcelVoiceInfo = new LLSDParcelVoiceInfoResponse(scene.RegionInfo.RegionName, land.LocalID, creds);
398 string r = LLSDHelpers.SerialiseLLSDReply(parcelVoiceInfo);
399
400 m_log.DebugFormat("[FreeSwitchVoice][PARCELVOICE]: region \"{0}\": Parcel \"{1}\" ({2}): avatar \"{3}\": {4}",
401 scene.RegionInfo.RegionName, land.Name, land.LocalID, avatarName, r);
402 return r;
403 }
404 catch (Exception e)
405 {
406 m_log.ErrorFormat("[FreeSwitchVoice][PARCELVOICE]: region \"{0}\": avatar \"{1}\": {2}, retry later",
407 scene.RegionInfo.RegionName, avatarName, e.Message);
408 m_log.DebugFormat("[FreeSwitchVoice][PARCELVOICE]: region \"{0}\": avatar \"{1}\": {2} failed",
409 scene.RegionInfo.RegionName, avatarName, e.ToString());
410
411 return "<llsd>undef</llsd>";
412 }
413 }
414
415
416 /// <summary>
417 /// Callback for a client request for ChatSessionRequest
418 /// </summary>
419 /// <param name="scene">current scene object of the client</param>
420 /// <param name="request"></param>
421 /// <param name="path"></param>
422 /// <param name="param"></param>
423 /// <param name="agentID"></param>
424 /// <param name="caps"></param>
425 /// <returns></returns>
426 public string ChatSessionRequest(Scene scene, string request, string path, string param,
427 UUID agentID, Caps caps)
428 {
429 ScenePresence avatar = scene.GetScenePresence(agentID);
430 string avatarName = avatar.Name;
431
432 m_log.DebugFormat("[FreeSwitchVoice][CHATSESSION]: avatar \"{0}\": request: {1}, path: {2}, param: {3}",
433 avatarName, request, path, param);
434 return "<llsd>true</llsd>";
435 }
436
437
438 public Hashtable FreeSwitchSLVoiceGetPreloginHTTPHandler(Hashtable request)
439 {
440 m_log.Debug("[FreeSwitchVoice] FreeSwitchSLVoiceGetPreloginHTTPHandler called");
441
442 Hashtable response = new Hashtable();
443 response["content_type"] = "text/xml";
444 response["keepalive"] = false;
445
446 response["str_response_string"] = String.Format(
447 "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n" +
448 "<VCConfiguration>\r\n"+
449 "<DefaultRealm>{0}</DefaultRealm>\r\n" +
450 "<DefaultSIPProxy>{1}</DefaultSIPProxy>\r\n"+
451 "<DefaultAttemptUseSTUN>{2}</DefaultAttemptUseSTUN>\r\n"+
452 "<DefaultEchoServer>{3}</DefaultEchoServer>\r\n"+
453 "<DefaultEchoPort>{4}</DefaultEchoPort>\r\n"+
454 "<DefaultWellKnownIP>{5}</DefaultWellKnownIP>\r\n"+
455 "<DefaultTimeout>{6}</DefaultTimeout>\r\n"+
456 "<UrlResetPassword>{7}</UrlResetPassword>\r\n"+
457 "<UrlPrivacyNotice>{8}</UrlPrivacyNotice>\r\n"+
458 "<UrlEulaNotice/>\r\n"+
459 "<App.NoBottomLogo>false</App.NoBottomLogo>\r\n"+
460 "</VCConfiguration>"
461 ,
462 m_freeSwitchRealm,m_freeSwitchSIPProxy,m_freeSwitchAttemptUseSTUN,
463 m_freeSwitchSTUNServer,m_freeSwitchEchoServer,m_freeSwitchEchoPort,
464 m_freeSwitchDefaultWellKnownIP,m_freeSwitchDefaultTimeout,m_freeSwitchUrlResetPassword,"");
465
466 response["int_response_code"] = 200;
467
468 m_log.DebugFormat("[FreeSwitchVoice] FreeSwitchSLVoiceGetPreloginHTTPHandler return {0}",response["str_response_string"]);
469 return response;
470 }
471
472 public Hashtable FreeSwitchSLVoiceSigninHTTPHandler(Hashtable request)
473 {
474 m_log.Debug("[FreeSwitchVoice] FreeSwitchSLVoiceSigninHTTPHandler called");
475
476 Hashtable response = new Hashtable();
477 response["str_response_string"] = @"<response xsi:schemaLocation=""/xsd/error.xsd"">
478 <level0>
479 <status>OK</status>
480 <body>
481 <code>200</code>
482 <msg>auth successful</msg>
483 </body>
484 </level0>
485 </response>";
486 response["int_response_code"] = 200;
487 return response;
488 }
489
490
491 public Hashtable FreeSwitchConfigHTTPHandler(Hashtable request)
492 {
493 m_log.DebugFormat("[FreeSwitchVoice] FreeSwitchConfigHTTPHandler called with {0}",request.ToString());
494
495 Hashtable response = new Hashtable();
496
497 // all the params come as NVPs in the request body
498 Hashtable requestBody = parseRequestBody((string) request["body"]);
499
500 // is this a dialplan or directory request
501 string section = (string) requestBody["section"];
502
503 if(section=="directory")
504 response = m_FreeSwitchDirectory.HandleDirectoryRequest(requestBody);
505 else if (section=="dialplan")
506 response = m_FreeSwitchDialplan.HandleDialplanRequest(requestBody);
507
508 // XXX: re-generate dialplan:
509 // - conf == region UUID
510 // - conf number = region port
511 // -> TODO Initialise(): keep track of regions via events
512 // re-generate accounts for all avatars
513 // -> TODO Initialise(): keep track of avatars via events
514 m_log.DebugFormat("[FreeSwitchVoice] FreeSwitchConfigHTTPHandler return {0}",response["str_response_string"]);
515 return response;
516 }
517
518 public Hashtable parseRequestBody(string body)
519 {
520 Hashtable bodyParams = new Hashtable();
521 // split string
522 string [] nvps = body.Split(new Char [] {'&'});
523
524 foreach (string s in nvps) {
525
526 if (s.Trim() != "")
527 {
528 string [] nvp = s.Split(new Char [] {'='});
529 bodyParams.Add(HttpUtility.UrlDecode(nvp[0]),HttpUtility.UrlDecode(nvp[1]));
530 }
531 }
532
533 return bodyParams;
534
535 }
536
537 private string ChannelUri(Scene scene, LandData land)
538 {
539
540 string channelUri = null;
541
542 string landUUID;
543 string landName;
544
545 // Create parcel voice channel. If no parcel exists, then the voice channel ID is the same
546 // as the directory ID. Otherwise, it reflects the parcel's ID.
547
548 if (land.LocalID != 1 && (land.Flags & (uint)Parcel.ParcelFlags.UseEstateVoiceChan) == 0)
549 {
550 landName = String.Format("{0}:{1}", scene.RegionInfo.RegionName, land.Name);
551 landUUID = land.GlobalID.ToString();
552 m_log.DebugFormat("[FreeSwitchVoice]: Region:Parcel \"{0}\": parcel id {1}: using channel name {2}",
553 landName, land.LocalID, landUUID);
554 }
555 else
556 {
557 landName = String.Format("{0}:{1}", scene.RegionInfo.RegionName, scene.RegionInfo.RegionName);
558 landUUID = scene.RegionInfo.RegionID.ToString();
559 m_log.DebugFormat("[FreeSwitchVoice]: Region:Parcel \"{0}\": parcel id {1}: using channel name {2}",
560 landName, land.LocalID, landUUID);
561 }
562 System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
563 channelUri = String.Format("sip:confctl-{0}@{1}", "x" + Convert.ToBase64String(encoding.GetBytes(landUUID)), m_freeSwitchRealm);
564
565 //channelUri="sip:confctl-3001@9.20.151.43";
566 //channelUri="sip:opensimconf-3001@9.20.151.43";
567
568 return channelUri;
569 }
570 }
571}