diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDialplan.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDialplan.cs
deleted file mode 100644
index 46ad30fdfd..0000000000
--- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDialplan.cs
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (c) Contributors, http://opensimulator.org/
- * See CONTRIBUTORS.TXT for a full list of copyright holders.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of the OpenSimulator Project nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-using log4net;
-using System;
-using System.Reflection;
-using System.Text;
-using System.Collections;
-
-namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
-{
- public class FreeSwitchDialplan
- {
- private static readonly ILog m_log =
- LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
-
-
- public Hashtable HandleDialplanRequest(string Context, string Realm, Hashtable request)
- {
- m_log.DebugFormat("[FreeSwitchVoice] HandleDialplanRequest called with {0}",request.ToString());
-
- Hashtable response = new Hashtable();
-
- foreach (DictionaryEntry item in request)
- {
- m_log.InfoFormat("[FreeSwitchDirectory] requestBody item {0} {1}",item.Key, item.Value);
- }
-
- string requestcontext = (string) request["Hunt-Context"];
- response["content_type"] = "text/xml";
- response["keepalive"] = false;
- response["int_response_code"] = 200;
- if (Context != String.Empty && Context != requestcontext)
- {
- m_log.Debug("[FreeSwitchDirectory] returning empty as it's for another context");
- response["str_response_string"] = "";
- } else {
- response["str_response_string"] = String.Format(@"
-
-
- " +
-
-/*
-
-
-
-
-
- */
-
- @"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ", Context, Realm);
- }
-
- return response;
- }
- }
-
-}
diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs
deleted file mode 100644
index 17cdf741b5..0000000000
--- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs
+++ /dev/null
@@ -1,348 +0,0 @@
-/*
- * Copyright (c) Contributors, http://opensimulator.org/
- * See CONTRIBUTORS.TXT for a full list of copyright holders.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of the OpenSimulator Project nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-using log4net;
-using System;
-using System.Reflection;
-using System.Text;
-using System.Collections;
-
-namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
-{
- public class FreeSwitchDirectory
- {
- private static readonly ILog m_log =
- LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
-
- public Hashtable HandleDirectoryRequest(string Context, string Realm, Hashtable request)
- {
- Hashtable response = new Hashtable();
- string domain = (string) request["domain"];
- if (domain != Realm) {
- response["content_type"] = "text/xml";
- response["keepalive"] = false;
- response["int_response_code"] = 200;
- response["str_response_string"] = "";
- } else {
- m_log.DebugFormat("[FreeSwitchDirectory] HandleDirectoryRequest called with {0}",request.ToString());
-
- // information in the request we might be interested in
-
- // Request 1 sip_auth for users account
-
- //Event-Calling-Function=sofia_reg_parse_auth
- //Event-Calling-Line-Number=1494
- //action=sip_auth
- //sip_user_agent=Vivox-SDK-2.1.3010.6151-Mac%20(Feb-11-2009/16%3A42%3A41)
- //sip_auth_username=xhZuXKmRpECyr2AARJYyGgg%3D%3D (==)
- //sip_auth_realm=9.20.151.43
- //sip_contact_user=xhZuXKmRpECyr2AARJYyGgg%3D%3D (==)
- //sip_contact_host=192.168.0.3 // this shouldnt really be a local IP, investigate STUN servers
- //sip_to_user=xhZuXKmRpECyr2AARJYyGgg%3D%3D
- //sip_to_host=9.20.151.43
- //sip_auth_method=REGISTER
- //user=xhZuXKmRpECyr2AARJYyGgg%3D%3D
- //domain=9.20.151.43
- //ip=9.167.220.137 // this is the correct IP rather than sip_contact_host above when through a vpn or NAT setup
-
- foreach (DictionaryEntry item in request)
- {
- m_log.InfoFormat("[FreeSwitchDirectory] requestBody item {0} {1}", item.Key, item.Value);
- }
-
- string eventCallingFunction = (string) request["Event-Calling-Function"];
- if (eventCallingFunction == null)
- {
- eventCallingFunction = "sofia_reg_parse_auth";
- }
-
- if (eventCallingFunction.Length == 0)
- {
- eventCallingFunction = "sofia_reg_parse_auth";
- }
-
- if (eventCallingFunction == "sofia_reg_parse_auth")
- {
- string sipAuthMethod = (string)request["sip_auth_method"];
-
- if (sipAuthMethod == "REGISTER")
- {
- response = HandleRegister(Context, Realm, request);
- }
- else if (sipAuthMethod == "INVITE")
- {
- response = HandleInvite(Context, Realm, request);
- }
- else
- {
- m_log.ErrorFormat("[FreeSwitchVoice] HandleDirectoryRequest unknown sip_auth_method {0}",sipAuthMethod);
- response["int_response_code"] = 404;
- response["content_type"] = "text/xml";
- response["str_response_string"] = "";
- }
- }
- else if (eventCallingFunction == "switch_xml_locate_user")
- {
- response = HandleLocateUser(Realm, request);
- }
- else if (eventCallingFunction == "user_data_function") // gets called when an avatar to avatar call is made
- {
- response = HandleLocateUser(Realm, request);
- }
- else if (eventCallingFunction == "user_outgoing_channel")
- {
- response = HandleRegister(Context, Realm, request);
- }
- else if (eventCallingFunction == "config_sofia") // happens once on freeswitch startup
- {
- response = HandleConfigSofia(Context, Realm, request);
- }
- else if (eventCallingFunction == "switch_load_network_lists")
- {
- //response = HandleLoadNetworkLists(request);
- response["int_response_code"] = 404;
- response["keepalive"] = false;
- response["content_type"] = "text/xml";
- response["str_response_string"] = "";
- }
- else
- {
- m_log.ErrorFormat("[FreeSwitchVoice] HandleDirectoryRequest unknown Event-Calling-Function {0}",eventCallingFunction);
- response["int_response_code"] = 404;
- response["keepalive"] = false;
- response["content_type"] = "text/xml";
- response["str_response_string"] = "";
- }
- }
- return response;
- }
-
- private Hashtable HandleRegister(string Context, string Realm, Hashtable request)
- {
- m_log.Info("[FreeSwitchDirectory] HandleRegister called");
-
- // TODO the password we return needs to match that sent in the request, this is hard coded for now
- string password = "1234";
- string domain = (string) request["domain"];
- string user = (string) request["user"];
-
- Hashtable response = new Hashtable();
- response["content_type"] = "text/xml";
- response["keepalive"] = false;
- response["int_response_code"] = 200;
-
- response["str_response_string"] = String.Format(
- "\r\n" +
- "\r\n" +
- "\r\n" +
- "\r\n" +
- "\r\n" +
- "\r\n" +
- "\r\n" +
- "\r\n" +
- "\r\n" +
- "\r\n" +
- "\r\n" +
- ""+
- "\r\n" +
- "\r\n" +
- "\r\n" +
- "\r\n" +
- "\r\n",
- domain , user, password, Context);
-
- return response;
- }
-
- private Hashtable HandleInvite(string Context, string Realm, Hashtable request)
- {
- m_log.Info("[FreeSwitchDirectory] HandleInvite called");
-
- // TODO the password we return needs to match that sent in the request, this is hard coded for now
- string password = "1234";
- string domain = (string) request["domain"];
- string user = (string) request["user"];
- string sipRequestUser = (string) request["sip_request_user"];
-
- Hashtable response = new Hashtable();
- response["content_type"] = "text/xml";
- response["keepalive"] = false;
- response["int_response_code"] = 200;
- response["str_response_string"] = String.Format(
- "\r\n" +
- "\r\n" +
- "\r\n" +
- "\r\n" +
- "\r\n" +
- "\r\n" +
- "\r\n" +
- "\r\n" +
- "\r\n" +
- "\r\n" +
- "\r\n" +
- ""+
- "\r\n" +
- "\r\n" +
- "\r\n" +
- "\r\n" +
- "\r\n" +
- "\r\n" +
- "\r\n" +
- "\r\n" +
- "\r\n" +
- ""+
- "\r\n" +
- "\r\n" +
- "\r\n" +
- "\r\n" +
- "\r\n",
- domain , user, password,sipRequestUser, Context);
-
- return response;
- }
-
- private Hashtable HandleLocateUser(String Realm, Hashtable request)
- {
- m_log.Info("[FreeSwitchDirectory] HandleLocateUser called");
-
- // TODO the password we return needs to match that sent in the request, this is hard coded for now
- string domain = (string) request["domain"];
- string user = (string) request["user"];
-
- Hashtable response = new Hashtable();
- response["content_type"] = "text/xml";
- response["keepalive"] = false;
- response["int_response_code"] = 200;
- response["str_response_string"] = String.Format(
- "\r\n" +
- "\r\n" +
- "\r\n" +
- "\r\n" +
- "\r\n" +
- "\r\n" +
- "\r\n" +
- "\r\n" +
- "\r\n"+
- "\r\n"+
- ""+
- "\r\n"+
- "\r\n" +
- "\r\n" +
- "\r\n" +
- "\r\n",
- domain , user);
-
- return response;
- }
-
- private Hashtable HandleConfigSofia(string Context, string Realm, Hashtable request)
- {
- m_log.Info("[FreeSwitchDirectory] HandleConfigSofia called");
-
- // TODO the password we return needs to match that sent in the request, this is hard coded for now
- string domain = (string) request["domain"];
-
- Hashtable response = new Hashtable();
- response["content_type"] = "text/xml";
- response["keepalive"] = false;
- response["int_response_code"] = 200;
- response["str_response_string"] = String.Format(
- "\r\n" +
- "\r\n" +
- "\r\n" +
- "\r\n" +
- "\r\n" +
- "\r\n" +
- "\r\n" +
- "\r\n"+
- "\r\n"+
- "\r\n"+
- "\r\n"+
- "\r\n"+
- "\r\n"+
- "\r\n"+
- "\r\n"+
- "\r\n"+
- "\r\n"+
- "\r\n"+
- "\r\n"+
- "\r\n"+
- "\r\n"+
- "\r\n"+
- "\r\n"+
- "\r\n"+
- "\r\n"+
- "\r\n"+
- "\r\n"+
- "\r\n"+
- ""+
- "\r\n" +
- "\r\n"+
- "\r\n"+
- "\r\n"+
- "\r\n" +
- "\r\n" +
- "\r\n",
- domain, Context);
-
- return response;
- }
-
-
-// private Hashtable HandleLoadNetworkLists(Hashtable request)
-// {
-// m_log.Info("[FreeSwitchDirectory] HandleLoadNetworkLists called");
-//
-// // TODO the password we return needs to match that sent in the request, this is hard coded for now
-// string domain = (string) request["domain"];
-//
-// Hashtable response = new Hashtable();
-// response["content_type"] = "text/xml";
-// response["keepalive"] = false;
-// response["int_response_code"] = 200;
-// response["str_response_string"] = String.Format(
-// "\r\n" +
-// "\r\n" +
-// "\r\n" +
-// "\r\n" +
-// "\r\n" +
-// "\r\n" +
-// "\r\n" +
-// "\r\n" +
-// "\r\n"+
-// "\r\n"+
-// "\r\n"+
-// "\r\n" +
-// "\r\n" +
-// "\r\n",
-// domain);
-//
-//
-// return response;
-// }
- }
-}
diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs
index 242bc3fdeb..a5e553cbae 100644
--- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs
@@ -37,10 +37,12 @@ using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using OpenMetaverse;
+using OpenMetaverse.StructuredData;
using log4net;
using Nini.Config;
using Nwc.XmlRpc;
using OpenSim.Framework;
+using Mono.Addins;
using OpenSim.Framework.Capabilities;
using OpenSim.Framework.Servers;
@@ -49,28 +51,27 @@ using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using Caps = OpenSim.Framework.Capabilities.Caps;
using System.Text.RegularExpressions;
+using OpenSim.Server.Base;
+using OpenSim.Services.Interfaces;
+using OSDMap = OpenMetaverse.StructuredData.OSDMap;
namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
{
- public class FreeSwitchVoiceModule : IRegionModule, IVoiceModule
+ [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "FreeSwitchVoiceModule")]
+ public class FreeSwitchVoiceModule : INonSharedRegionModule, IVoiceModule
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
- private bool UseProxy = false;
-
// Capability string prefixes
private static readonly string m_parcelVoiceInfoRequestPath = "0007/";
private static readonly string m_provisionVoiceAccountRequestPath = "0008/";
private static readonly string m_chatSessionRequestPath = "0009/";
// Control info
- private static bool m_WOF = true;
- private static bool m_pluginEnabled = false;
+ private static bool m_Enabled = false;
// FreeSwitch server is going to contact us and ask us all
// sorts of things.
- private static string m_freeSwitchServerUser;
- private static string m_freeSwitchServerPass;
// SLVoice client will do a GET on this prefix
private static string m_freeSwitchAPIPrefix;
@@ -84,143 +85,146 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
private static string m_freeSwitchRealm;
private static string m_freeSwitchSIPProxy;
private static bool m_freeSwitchAttemptUseSTUN;
- // private static string m_freeSwitchSTUNServer;
private static string m_freeSwitchEchoServer;
private static int m_freeSwitchEchoPort;
private static string m_freeSwitchDefaultWellKnownIP;
private static int m_freeSwitchDefaultTimeout;
- // private static int m_freeSwitchSubscribeRetry;
private static string m_freeSwitchUrlResetPassword;
- // private static IPEndPoint m_FreeSwitchServiceIP;
- private int m_freeSwitchServicePort;
+ private uint m_freeSwitchServicePort;
private string m_openSimWellKnownHTTPAddress;
private string m_freeSwitchContext;
- private FreeSwitchDirectory m_FreeSwitchDirectory;
- private FreeSwitchDialplan m_FreeSwitchDialplan;
-
private readonly Dictionary m_UUIDName = new Dictionary();
private Dictionary m_ParcelAddress = new Dictionary();
- private Scene m_scene;
+ private Scene m_Scene;
+ private IConfig m_Config;
- private IConfig m_config;
+ private IFreeswitchService m_FreeswitchService;
- public void Initialise(Scene scene, IConfigSource config)
+ public void Initialise(IConfigSource config)
{
- m_scene = scene;
- m_config = config.Configs["FreeSwitchVoice"];
+ m_Config = config.Configs["FreeSwitchVoice"];
- if (null == m_config)
+ if (m_Config == null)
{
m_log.Info("[FreeSwitchVoice] no config found, plugin disabled");
return;
}
- if (!m_config.GetBoolean("enabled", false))
+ if (!m_Config.GetBoolean("Enabled", false))
{
m_log.Info("[FreeSwitchVoice] plugin disabled by configuration");
return;
}
- // This is only done the FIRST time this method is invoked.
- if (m_WOF)
+ try
{
- m_pluginEnabled = true;
- m_WOF = false;
+ string serviceDll = m_Config.GetString("LocalServiceModule",
+ String.Empty);
- try
+ if (serviceDll == String.Empty)
{
- m_freeSwitchServerUser = m_config.GetString("freeswitch_server_user", String.Empty);
- m_freeSwitchServerPass = m_config.GetString("freeswitch_server_pass", String.Empty);
- m_freeSwitchAPIPrefix = m_config.GetString("freeswitch_api_prefix", String.Empty);
-
- // 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)
-
- string serviceIP = m_config.GetString("freeswitch_service_server", String.Empty);
- int servicePort = m_config.GetInt("freeswitch_service_port", 80);
- IPAddress serviceIPAddress = IPAddress.Parse(serviceIP);
- // m_FreeSwitchServiceIP = new IPEndPoint(serviceIPAddress, servicePort);
- m_freeSwitchServicePort = servicePort;
- m_freeSwitchRealm = m_config.GetString("freeswitch_realm", String.Empty);
- m_freeSwitchSIPProxy = m_config.GetString("freeswitch_sip_proxy", m_freeSwitchRealm);
- m_freeSwitchAttemptUseSTUN = m_config.GetBoolean("freeswitch_attempt_stun", true);
- // m_freeSwitchSTUNServer = m_config.GetString("freeswitch_stun_server", m_freeSwitchRealm);
- m_freeSwitchEchoServer = m_config.GetString("freeswitch_echo_server", m_freeSwitchRealm);
- m_freeSwitchEchoPort = m_config.GetInt("freeswitch_echo_port", 50505);
- m_freeSwitchDefaultWellKnownIP = m_config.GetString("freeswitch_well_known_ip", m_freeSwitchRealm);
- m_openSimWellKnownHTTPAddress = m_config.GetString("opensim_well_known_http_address", serviceIPAddress.ToString());
- m_freeSwitchDefaultTimeout = m_config.GetInt("freeswitch_default_timeout", 5000);
- // m_freeSwitchSubscribeRetry = m_config.GetInt("freeswitch_subscribe_retry", 120);
- m_freeSwitchUrlResetPassword = m_config.GetString("freeswitch_password_reset_url", String.Empty);
- m_freeSwitchContext = m_config.GetString("freeswitch_context", "default");
-
- if (String.IsNullOrEmpty(m_freeSwitchServerUser) ||
- String.IsNullOrEmpty(m_freeSwitchServerPass) ||
- String.IsNullOrEmpty(m_freeSwitchRealm) ||
- String.IsNullOrEmpty(m_freeSwitchAPIPrefix))
- {
- m_log.Error("[FreeSwitchVoice] plugin mis-configured");
- m_log.Info("[FreeSwitchVoice] plugin disabled: incomplete configuration");
- return;
- }
-
- // set up http request handlers for
- // - prelogin: viv_get_prelogin.php
- // - signin: viv_signin.php
- // - buddies: viv_buddy.php
- // - ???: viv_watcher.php
- // - signout: viv_signout.php
- if (UseProxy)
- {
- MainServer.Instance.AddHTTPHandler(String.Format("{0}/", m_freeSwitchAPIPrefix),
- ForwardProxyRequest);
- }
- else
- {
- MainServer.Instance.AddHTTPHandler(String.Format("{0}/viv_get_prelogin.php", m_freeSwitchAPIPrefix),
- FreeSwitchSLVoiceGetPreloginHTTPHandler);
-
- // RestStreamHandler h = new
- // RestStreamHandler("GET",
- // String.Format("{0}/viv_get_prelogin.php", m_freeSwitchAPIPrefix), FreeSwitchSLVoiceGetPreloginHTTPHandler);
- // MainServer.Instance.AddStreamHandler(h);
-
-
-
- MainServer.Instance.AddHTTPHandler(String.Format("{0}/viv_signin.php", m_freeSwitchAPIPrefix),
- FreeSwitchSLVoiceSigninHTTPHandler);
-
- // set up http request handlers to provide
- // on-demand FreeSwitch configuration to
- // FreeSwitch's mod_curl_xml
- MainServer.Instance.AddHTTPHandler(String.Format("{0}/freeswitch-config", m_freeSwitchAPIPrefix),
- FreeSwitchConfigHTTPHandler);
-
- MainServer.Instance.AddHTTPHandler(String.Format("{0}/viv_buddy.php", m_freeSwitchAPIPrefix),
- FreeSwitchSLVoiceBuddyHTTPHandler);
- }
-
- m_log.InfoFormat("[FreeSwitchVoice] using FreeSwitch server {0}", m_freeSwitchRealm);
-
- m_FreeSwitchDirectory = new FreeSwitchDirectory();
- m_FreeSwitchDialplan = new FreeSwitchDialplan();
-
- m_pluginEnabled = true;
- m_WOF = false;
-
- m_log.Info("[FreeSwitchVoice] plugin enabled");
- }
- catch (Exception e)
- {
- m_log.ErrorFormat("[FreeSwitchVoice] plugin initialization failed: {0}", e.Message);
- m_log.DebugFormat("[FreeSwitchVoice] plugin initialization failed: {0}", e.ToString());
+ m_log.Error("[FreeSwitchVoice]: No LocalServiceModule named in section FreeSwitchVoice");
return;
}
+
+ Object[] args = new Object[] { config };
+ m_FreeswitchService = ServerUtils.LoadPlugin(serviceDll, args);
+
+ string jsonConfig = m_FreeswitchService.GetJsonConfig();
+ OSDMap map = (OSDMap)OSDParser.DeserializeJson(jsonConfig);
+
+ m_freeSwitchAPIPrefix = map["APIPrefix"].AsString();
+ m_freeSwitchRealm = map["Realm"].AsString();
+ m_freeSwitchSIPProxy = map["SIPProxy"].AsString();
+ m_freeSwitchAttemptUseSTUN = map["AttemptUseSTUN"].AsBoolean();
+ m_freeSwitchEchoServer = map["EchoServer"].AsString();
+ m_freeSwitchEchoPort = map["EchoPort"].AsInteger();
+ m_freeSwitchDefaultWellKnownIP = map["DefaultWellKnownIP"].AsString();
+ m_freeSwitchDefaultTimeout = map["DefaultTimeout"].AsInteger();
+ m_freeSwitchUrlResetPassword = String.Empty;
+ m_freeSwitchContext = map["Context"].AsString();
+
+ if (String.IsNullOrEmpty(m_freeSwitchRealm) ||
+ String.IsNullOrEmpty(m_freeSwitchAPIPrefix))
+ {
+ m_log.Error("[FreeSwitchVoice] plugin mis-configured");
+ m_log.Info("[FreeSwitchVoice] plugin disabled: incomplete configuration");
+ return;
+ }
+
+ // set up http request handlers for
+ // - prelogin: viv_get_prelogin.php
+ // - signin: viv_signin.php
+ // - buddies: viv_buddy.php
+ // - ???: viv_watcher.php
+ // - signout: viv_signout.php
+ MainServer.Instance.AddHTTPHandler(String.Format("{0}/viv_get_prelogin.php", m_freeSwitchAPIPrefix),
+ FreeSwitchSLVoiceGetPreloginHTTPHandler);
+
+ // RestStreamHandler h = new
+ // RestStreamHandler("GET",
+ // String.Format("{0}/viv_get_prelogin.php", m_freeSwitchAPIPrefix), FreeSwitchSLVoiceGetPreloginHTTPHandler);
+ // MainServer.Instance.AddStreamHandler(h);
+
+
+
+ MainServer.Instance.AddHTTPHandler(String.Format("{0}/viv_signin.php", m_freeSwitchAPIPrefix),
+ FreeSwitchSLVoiceSigninHTTPHandler);
+
+ MainServer.Instance.AddHTTPHandler(String.Format("{0}/viv_buddy.php", m_freeSwitchAPIPrefix),
+ FreeSwitchSLVoiceBuddyHTTPHandler);
+
+ m_log.InfoFormat("[FreeSwitchVoice] using FreeSwitch server {0}", m_freeSwitchRealm);
+
+ m_Enabled = true;
+
+ m_log.Info("[FreeSwitchVoice] plugin enabled");
+ }
+ catch (Exception e)
+ {
+ m_log.ErrorFormat("[FreeSwitchVoice] plugin initialization failed: {0}", e.Message);
+ m_log.DebugFormat("[FreeSwitchVoice] plugin initialization failed: {0}", e.ToString());
+ return;
}
- if (m_pluginEnabled)
+ // This here is a region module trying to make a global setting.
+ // Not really a good idea but it's Windows only, so I can't test.
+ try
+ {
+ ServicePointManager.ServerCertificateValidationCallback += CustomCertificateValidation;
+ }
+ catch (NotImplementedException)
+ {
+ try
+ {
+#pragma warning disable 0612, 0618
+ // Mono does not implement the ServicePointManager.ServerCertificateValidationCallback yet! Don't remove this!
+ ServicePointManager.CertificatePolicy = new MonoCert();
+#pragma warning restore 0612, 0618
+ }
+ catch (Exception)
+ {
+ // COmmented multiline spam log message
+ //m_log.Error("[FreeSwitchVoice]: Certificate validation handler change not supported. You may get ssl certificate validation errors teleporting from your region to some SSL regions.");
+ }
+ }
+ }
+
+ public void AddRegion(Scene scene)
+ {
+ m_Scene = scene;
+
+ // We generate these like this: The region's external host name
+ // as defined in Regions.ini is a good address to use. It's a
+ // dotted quad (or should be!) and it can reach this host from
+ // a client. The port is grabbed from the region's HTTP server.
+ m_openSimWellKnownHTTPAddress = m_Scene.RegionInfo.ExternalHostName;
+ m_freeSwitchServicePort = MainServer.Instance.Port;
+
+ if (m_Enabled)
{
// we need to capture scene in an anonymous method
// here as we need it later in the callbacks
@@ -228,36 +232,21 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
{
OnRegisterCaps(scene, agentID, caps);
};
-
- try
- {
- ServicePointManager.ServerCertificateValidationCallback += CustomCertificateValidation;
- }
- catch (NotImplementedException)
- {
- try
- {
-#pragma warning disable 0612, 0618
- // Mono does not implement the ServicePointManager.ServerCertificateValidationCallback yet! Don't remove this!
- ServicePointManager.CertificatePolicy = new MonoCert();
-#pragma warning restore 0612, 0618
- }
- catch (Exception)
- {
- m_log.Error("[FreeSwitchVoice]: Certificate validation handler change not supported. You may get ssl certificate validation errors teleporting from your region to some SSL regions.");
- }
- }
}
}
- public void PostInitialise()
+ public void RemoveRegion(Scene scene)
{
- if (m_pluginEnabled)
+ }
+
+ public void RegionLoaded(Scene scene)
+ {
+ if (m_Enabled)
{
m_log.Info("[FreeSwitchVoice] registering IVoiceModule with the scene");
// register the voice interface for this module, so the script engine can call us
- m_scene.RegisterModuleInterface(this);
+ scene.RegisterModuleInterface(this);
}
}
@@ -270,9 +259,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
get { return "FreeSwitchVoiceModule"; }
}
- public bool IsSharedModule
+ public Type ReplaceableInterface
{
- get { return true; }
+ get { return null; }
}
//
@@ -725,46 +714,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
response["int_response_code"] = 200;
return response;
- /*
-
- OKOklib_session
- * xMj1QJSc7TA-G7XqcW6QXAg==:1290551700:050d35c6fef96f132f780d8039ff7592::
- * xMj1QJSc7TA-G7XqcW6QXAg==:1290551700:050d35c6fef96f132f780d8039ff7592::
- * 1
- * 7449
- * Teravus Ousley
- */
- }
-
- public Hashtable FreeSwitchConfigHTTPHandler(Hashtable request)
- {
- m_log.DebugFormat("[FreeSwitchVoice] FreeSwitchConfigHTTPHandler called with {0}", (string)request["body"]);
-
- Hashtable response = new Hashtable();
- response["str_response_string"] = string.Empty;
- // all the params come as NVPs in the request body
- Hashtable requestBody = parseRequestBody((string) request["body"]);
-
- // is this a dialplan or directory request
- string section = (string) requestBody["section"];
-
- if (section == "directory")
- response = m_FreeSwitchDirectory.HandleDirectoryRequest(m_freeSwitchContext, m_freeSwitchRealm, requestBody);
- else if (section == "dialplan")
- response = m_FreeSwitchDialplan.HandleDialplanRequest(m_freeSwitchContext, m_freeSwitchRealm, requestBody);
- else
- m_log.WarnFormat("[FreeSwitchVoice]: section was {0}", section);
-
- // XXX: re-generate dialplan:
- // - conf == region UUID
- // - conf number = region port
- // -> TODO Initialise(): keep track of regions via events
- // re-generate accounts for all avatars
- // -> TODO Initialise(): keep track of avatars via events
- Regex normalizeEndLines = new Regex(@"\r\n", RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.Multiline);
-
- m_log.DebugFormat("[FreeSwitchVoice] FreeSwitchConfigHTTPHandler return {0}",normalizeEndLines.Replace(((string)response["str_response_string"]), ""));
- return response;
}
public Hashtable parseRequestBody(string body)
diff --git a/OpenSim/Server/Handlers/Freeswitch/FreeswitchServerConnector.cs b/OpenSim/Server/Handlers/Freeswitch/FreeswitchServerConnector.cs
index 07bafc8c01..da56b8778d 100644
--- a/OpenSim/Server/Handlers/Freeswitch/FreeswitchServerConnector.cs
+++ b/OpenSim/Server/Handlers/Freeswitch/FreeswitchServerConnector.cs
@@ -26,18 +26,27 @@
*/
using System;
+using System.Collections;
+using System.Web;
+using System.Reflection;
using Nini.Config;
using OpenSim.Server.Base;
using OpenSim.Services.Interfaces;
using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Server.Handlers.Base;
+using log4net;
+using OpenMetaverse;
+using OpenMetaverse.StructuredData;
namespace OpenSim.Server.Handlers.Freeswitch
{
public class FreeswitchServerConnector : ServiceConnector
{
+ private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
private IFreeswitchService m_FreeswitchService;
private string m_ConfigName = "FreeswitchService";
+ protected readonly string m_freeSwitchAPIPrefix = "/fsapi";
public FreeswitchServerConnector(IConfigSource config, IHttpServer server, string configName) :
base(config, server, configName)
@@ -59,7 +68,61 @@ namespace OpenSim.Server.Handlers.Freeswitch
m_FreeswitchService =
ServerUtils.LoadPlugin(freeswitchService, args);
- server.AddStreamHandler(new FreeswitchServerGetHandler(m_FreeswitchService));
+ server.AddHTTPHandler(String.Format("{0}/freeswitch-config", m_freeSwitchAPIPrefix), FreeSwitchConfigHTTPHandler);
+ server.AddHTTPHandler(String.Format("{0}/region-config", m_freeSwitchAPIPrefix), RegionConfigHTTPHandler);
}
+
+ public Hashtable FreeSwitchConfigHTTPHandler(Hashtable request)
+ {
+ Hashtable response = new Hashtable();
+ response["str_response_string"] = string.Empty;
+ response["content_type"] = "text/plain";
+ response["keepalive"] = false;
+ response["int_response_code"] = 500;
+
+ Hashtable requestBody = ParseRequestBody((string) request["body"]);
+
+ string section = (string) requestBody["section"];
+
+ if (section == "directory")
+ response = m_FreeswitchService.HandleDirectoryRequest(requestBody);
+ else if (section == "dialplan")
+ response = m_FreeswitchService.HandleDialplanRequest(requestBody);
+ else
+ m_log.WarnFormat("[FreeSwitchVoice]: section was {0}", section);
+
+ return response;
+ }
+
+ private Hashtable ParseRequestBody(string body)
+ {
+ Hashtable bodyParams = new Hashtable();
+ // split string
+ string [] nvps = body.Split(new Char [] {'&'});
+
+ foreach (string s in nvps)
+ {
+ if (s.Trim() != "")
+ {
+ string [] nvp = s.Split(new Char [] {'='});
+ bodyParams.Add(HttpUtility.UrlDecode(nvp[0]), HttpUtility.UrlDecode(nvp[1]));
+ }
+ }
+
+ return bodyParams;
+ }
+
+ public Hashtable RegionConfigHTTPHandler(Hashtable request)
+ {
+ Hashtable response = new Hashtable();
+ response["content_type"] = "text/json";
+ response["keepalive"] = false;
+ response["int_response_code"] = 200;
+
+ response["str_response_string"] = m_FreeswitchService.GetJsonConfig();
+
+ return response;
+ }
+
}
}
diff --git a/OpenSim/Server/Handlers/Freeswitch/FreeswitchServerGetHandler.cs b/OpenSim/Server/Handlers/Freeswitch/FreeswitchServerGetHandler.cs
deleted file mode 100644
index 8b41742916..0000000000
--- a/OpenSim/Server/Handlers/Freeswitch/FreeswitchServerGetHandler.cs
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (c) Contributors, http://opensimulator.org/
- * See CONTRIBUTORS.TXT for a full list of copyright holders.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of the OpenSimulator Project nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-using Nini.Config;
-using log4net;
-using System;
-using System.IO;
-using System.Reflection;
-using System.Net;
-using System.Text;
-using System.Text.RegularExpressions;
-using System.Xml;
-using System.Xml.Serialization;
-using OpenSim.Server.Base;
-using OpenSim.Services.Interfaces;
-using OpenSim.Framework;
-using OpenSim.Framework.Servers.HttpServer;
-
-namespace OpenSim.Server.Handlers.Freeswitch
-{
- public class FreeswitchServerGetHandler : BaseStreamHandler
- {
- // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
-
- //private IFreeswitchService m_FreeswitchService;
-
- public FreeswitchServerGetHandler(IFreeswitchService service) :
- base("GET", "/api")
- {
- //m_FreeswitchService = service;
- }
-
- public override byte[] Handle(string path, Stream request,
- OSHttpRequest httpRequest, OSHttpResponse httpResponse)
- {
- byte[] result = new byte[0];
-
- string[] p = SplitParams(path);
-
- if (p.Length == 0)
- return result;
-
- // Process web request
-
- return result;
- }
- }
-}
diff --git a/OpenSim/Services/Connectors/Freeswitch/RemoteFreeswitchConnector.cs b/OpenSim/Services/Connectors/Freeswitch/RemoteFreeswitchConnector.cs
new file mode 100644
index 0000000000..d63d99d336
--- /dev/null
+++ b/OpenSim/Services/Connectors/Freeswitch/RemoteFreeswitchConnector.cs
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSimulator Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using log4net;
+using System;
+using System.IO;
+using System.Collections;
+using System.Reflection;
+using Nini.Config;
+using OpenSim.Framework;
+using OpenSim.Framework.Communications;
+using OpenSim.Framework.Servers.HttpServer;
+using OpenSim.Services.Interfaces;
+using OpenSim.Server.Base;
+using OpenMetaverse;
+
+namespace OpenSim.Services.Connectors
+{
+ public class RemoteFreeswitchConnector : IFreeswitchService
+ {
+ private static readonly ILog m_log =
+ LogManager.GetLogger(
+ MethodBase.GetCurrentMethod().DeclaringType);
+
+ private string m_ServerURI = String.Empty;
+
+ public RemoteFreeswitchConnector()
+ {
+ }
+
+ public RemoteFreeswitchConnector(string serverURI)
+ {
+ m_ServerURI = Path.Combine(serverURI.TrimEnd('/'), "region-config");
+ }
+
+ public RemoteFreeswitchConnector(IConfigSource source)
+ {
+ Initialise(source);
+ }
+
+ public virtual void Initialise(IConfigSource source)
+ {
+ IConfig freeswitchConfig = source.Configs["FreeSwitchVoice"];
+ if (freeswitchConfig == null)
+ {
+ m_log.Error("[FREESWITCH CONNECTOR]: FreeSwitchVoice missing from OpenSim.ini");
+ throw new Exception("Freeswitch connector init error");
+ }
+
+ string serviceURI = freeswitchConfig.GetString("FreeswitchServiceURL",
+ String.Empty);
+
+ if (serviceURI == String.Empty)
+ {
+ m_log.Error("[FREESWITCH CONNECTOR]: No FreeswitchServiceURL named in section FreeSwitchVoice");
+ throw new Exception("Freeswitch connector init error");
+ }
+ m_ServerURI = serviceURI;
+ }
+
+ public Hashtable HandleDirectoryRequest(Hashtable requestBody)
+ {
+ // not used here
+ return new Hashtable();
+ }
+
+ public Hashtable HandleDialplanRequest(Hashtable requestBody)
+ {
+ // not used here
+ return new Hashtable();
+ }
+
+ public string GetJsonConfig()
+ {
+ return SynchronousRestFormsRequester.MakeRequest("GET",
+ m_ServerURI, String.Empty);
+ }
+ }
+}
diff --git a/OpenSim/Services/FreeswitchService/FreeswitchService.cs b/OpenSim/Services/FreeswitchService/FreeswitchService.cs
index 0a3830060e..fe6f5cd503 100644
--- a/OpenSim/Services/FreeswitchService/FreeswitchService.cs
+++ b/OpenSim/Services/FreeswitchService/FreeswitchService.cs
@@ -26,6 +26,7 @@
*/
using System;
+using System.Text;
using System.Reflection;
using Nini.Config;
using log4net;
@@ -33,19 +34,373 @@ using OpenSim.Framework;
using OpenSim.Data;
using OpenSim.Services.Interfaces;
using OpenMetaverse;
+using OpenMetaverse.StructuredData;
+using System.Collections;
namespace OpenSim.Services.FreeswitchService
{
public class FreeswitchService : FreeswitchServiceBase, IFreeswitchService
{
- //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+ private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public FreeswitchService(IConfigSource config) : base(config)
{
// Perform initilialization here
}
+ public Hashtable HandleDialplanRequest(Hashtable request)
+ {
+ m_log.DebugFormat("[FreeSwitchVoice] HandleDialplanRequest called with {0}",request.ToString());
- // Implement IFreeswitchService here
+ Hashtable response = new Hashtable();
+
+ foreach (DictionaryEntry item in request)
+ {
+ m_log.InfoFormat("[FreeSwitchDirectory] requestBody item {0} {1}",item.Key, item.Value);
+ }
+
+ string requestcontext = (string) request["Hunt-Context"];
+ response["content_type"] = "text/xml";
+ response["keepalive"] = false;
+ response["int_response_code"] = 200;
+
+ if (m_freeSwitchContext != String.Empty && m_freeSwitchContext != requestcontext)
+ {
+ m_log.Debug("[FreeSwitchDirectory] returning empty as it's for another context");
+ response["str_response_string"] = "";
+ }
+ else
+ {
+ response["str_response_string"] = String.Format(@"
+
+
+ " +
+
+/*
+
+
+
+
+
+ */
+
+ @"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ", m_freeSwitchContext, m_freeSwitchRealm);
+ }
+
+ return response;
+ }
+
+ public Hashtable HandleDirectoryRequest(Hashtable request)
+ {
+ Hashtable response = new Hashtable();
+ string domain = (string) request["domain"];
+ if (domain != m_freeSwitchRealm) {
+ response["content_type"] = "text/xml";
+ response["keepalive"] = false;
+ response["int_response_code"] = 200;
+ response["str_response_string"] = "";
+ } else {
+ m_log.DebugFormat("[FreeSwitchDirectory] HandleDirectoryRequest called with {0}",request.ToString());
+
+ // information in the request we might be interested in
+
+ // Request 1 sip_auth for users account
+
+ //Event-Calling-Function=sofia_reg_parse_auth
+ //Event-Calling-Line-Number=1494
+ //action=sip_auth
+ //sip_user_agent=Vivox-SDK-2.1.3010.6151-Mac%20(Feb-11-2009/16%3A42%3A41)
+ //sip_auth_username=xhZuXKmRpECyr2AARJYyGgg%3D%3D (==)
+ //sip_auth_realm=9.20.151.43
+ //sip_contact_user=xhZuXKmRpECyr2AARJYyGgg%3D%3D (==)
+ //sip_contact_host=192.168.0.3 // this shouldnt really be a local IP, investigate STUN servers
+ //sip_to_user=xhZuXKmRpECyr2AARJYyGgg%3D%3D
+ //sip_to_host=9.20.151.43
+ //sip_auth_method=REGISTER
+ //user=xhZuXKmRpECyr2AARJYyGgg%3D%3D
+ //domain=9.20.151.43
+ //ip=9.167.220.137 // this is the correct IP rather than sip_contact_host above when through a vpn or NAT setup
+
+ foreach (DictionaryEntry item in request)
+ {
+ m_log.InfoFormat("[FreeSwitchDirectory] requestBody item {0} {1}", item.Key, item.Value);
+ }
+
+ string eventCallingFunction = (string) request["Event-Calling-Function"];
+ if (eventCallingFunction == null)
+ {
+ eventCallingFunction = "sofia_reg_parse_auth";
+ }
+
+ if (eventCallingFunction.Length == 0)
+ {
+ eventCallingFunction = "sofia_reg_parse_auth";
+ }
+
+ if (eventCallingFunction == "sofia_reg_parse_auth")
+ {
+ string sipAuthMethod = (string)request["sip_auth_method"];
+
+ if (sipAuthMethod == "REGISTER")
+ {
+ response = HandleRegister(m_freeSwitchContext, m_freeSwitchRealm, request);
+ }
+ else if (sipAuthMethod == "INVITE")
+ {
+ response = HandleInvite(m_freeSwitchContext, m_freeSwitchRealm, request);
+ }
+ else
+ {
+ m_log.ErrorFormat("[FreeSwitchVoice] HandleDirectoryRequest unknown sip_auth_method {0}",sipAuthMethod);
+ response["int_response_code"] = 404;
+ response["content_type"] = "text/xml";
+ response["str_response_string"] = "";
+ }
+ }
+ else if (eventCallingFunction == "switch_xml_locate_user")
+ {
+ response = HandleLocateUser(m_freeSwitchRealm, request);
+ }
+ else if (eventCallingFunction == "user_data_function") // gets called when an avatar to avatar call is made
+ {
+ response = HandleLocateUser(m_freeSwitchRealm, request);
+ }
+ else if (eventCallingFunction == "user_outgoing_channel")
+ {
+ response = HandleRegister(m_freeSwitchContext, m_freeSwitchRealm, request);
+ }
+ else if (eventCallingFunction == "config_sofia") // happens once on freeswitch startup
+ {
+ response = HandleConfigSofia(m_freeSwitchContext, m_freeSwitchRealm, request);
+ }
+ else if (eventCallingFunction == "switch_load_network_lists")
+ {
+ //response = HandleLoadNetworkLists(request);
+ response["int_response_code"] = 404;
+ response["keepalive"] = false;
+ response["content_type"] = "text/xml";
+ response["str_response_string"] = "";
+ }
+ else
+ {
+ m_log.ErrorFormat("[FreeSwitchVoice] HandleDirectoryRequest unknown Event-Calling-Function {0}",eventCallingFunction);
+ response["int_response_code"] = 404;
+ response["keepalive"] = false;
+ response["content_type"] = "text/xml";
+ response["str_response_string"] = "";
+ }
+ }
+ return response;
+ }
+
+ private Hashtable HandleRegister(string Context, string Realm, Hashtable request)
+ {
+ m_log.Info("[FreeSwitchDirectory] HandleRegister called");
+
+ // TODO the password we return needs to match that sent in the request, this is hard coded for now
+ string password = "1234";
+ string domain = (string) request["domain"];
+ string user = (string) request["user"];
+
+ Hashtable response = new Hashtable();
+ response["content_type"] = "text/xml";
+ response["keepalive"] = false;
+ response["int_response_code"] = 200;
+
+ response["str_response_string"] = String.Format(
+ "\r\n" +
+ "\r\n" +
+ "\r\n" +
+ "\r\n" +
+ "\r\n" +
+ "\r\n" +
+ "\r\n" +
+ "\r\n" +
+ "\r\n" +
+ "\r\n" +
+ "\r\n" +
+ ""+
+ "\r\n" +
+ "\r\n" +
+ "\r\n" +
+ "\r\n" +
+ "\r\n",
+ domain , user, password, Context);
+
+ return response;
+ }
+
+ private Hashtable HandleInvite(string Context, string Realm, Hashtable request)
+ {
+ m_log.Info("[FreeSwitchDirectory] HandleInvite called");
+
+ // TODO the password we return needs to match that sent in the request, this is hard coded for now
+ string password = "1234";
+ string domain = (string) request["domain"];
+ string user = (string) request["user"];
+ string sipRequestUser = (string) request["sip_request_user"];
+
+ Hashtable response = new Hashtable();
+ response["content_type"] = "text/xml";
+ response["keepalive"] = false;
+ response["int_response_code"] = 200;
+ response["str_response_string"] = String.Format(
+ "\r\n" +
+ "\r\n" +
+ "\r\n" +
+ "\r\n" +
+ "\r\n" +
+ "\r\n" +
+ "\r\n" +
+ "\r\n" +
+ "\r\n" +
+ "\r\n" +
+ "\r\n" +
+ ""+
+ "\r\n" +
+ "\r\n" +
+ "\r\n" +
+ "\r\n" +
+ "\r\n" +
+ "\r\n" +
+ "\r\n" +
+ "\r\n" +
+ "\r\n" +
+ ""+
+ "\r\n" +
+ "\r\n" +
+ "\r\n" +
+ "\r\n" +
+ "\r\n",
+ domain , user, password,sipRequestUser, Context);
+
+ return response;
+ }
+
+ private Hashtable HandleLocateUser(String Realm, Hashtable request)
+ {
+ m_log.Info("[FreeSwitchDirectory] HandleLocateUser called");
+
+ // TODO the password we return needs to match that sent in the request, this is hard coded for now
+ string domain = (string) request["domain"];
+ string user = (string) request["user"];
+
+ Hashtable response = new Hashtable();
+ response["content_type"] = "text/xml";
+ response["keepalive"] = false;
+ response["int_response_code"] = 200;
+ response["str_response_string"] = String.Format(
+ "\r\n" +
+ "\r\n" +
+ "\r\n" +
+ "\r\n" +
+ "\r\n" +
+ "\r\n" +
+ "\r\n" +
+ "\r\n" +
+ "\r\n"+
+ "\r\n"+
+ ""+
+ "\r\n"+
+ "\r\n" +
+ "\r\n" +
+ "\r\n" +
+ "\r\n",
+ domain , user);
+
+ return response;
+ }
+
+ private Hashtable HandleConfigSofia(string Context, string Realm, Hashtable request)
+ {
+ m_log.Info("[FreeSwitchDirectory] HandleConfigSofia called");
+
+ // TODO the password we return needs to match that sent in the request, this is hard coded for now
+ string domain = (string) request["domain"];
+
+ Hashtable response = new Hashtable();
+ response["content_type"] = "text/xml";
+ response["keepalive"] = false;
+ response["int_response_code"] = 200;
+ response["str_response_string"] = String.Format(
+ "\r\n" +
+ "\r\n" +
+ "\r\n" +
+ "\r\n" +
+ "\r\n" +
+ "\r\n" +
+ "\r\n" +
+ "\r\n"+
+ "\r\n"+
+ "\r\n"+
+ "\r\n"+
+ "\r\n"+
+ "\r\n"+
+ "\r\n"+
+ "\r\n"+
+ "\r\n"+
+ "\r\n"+
+ "\r\n"+
+ "\r\n"+
+ "\r\n"+
+ "\r\n"+
+ "\r\n"+
+ "\r\n"+
+ "\r\n"+
+ "\r\n"+
+ "\r\n"+
+ "\r\n"+
+ "\r\n"+
+ ""+
+ "\r\n" +
+ "\r\n"+
+ "\r\n"+
+ "\r\n"+
+ "\r\n" +
+ "\r\n" +
+ "\r\n",
+ domain, Context);
+
+ return response;
+ }
+
+ public string GetJsonConfig()
+ {
+ OSDMap map = new OSDMap(9);
+
+ map.Add("Realm", m_freeSwitchRealm);
+ map.Add("SIPProxy", m_freeSwitchSIPProxy);
+ map.Add("AttemptUseSTUN", m_freeSwitchAttemptUseSTUN);
+ map.Add("EchoServer", m_freeSwitchEchoServer);
+ map.Add("EchoPort", m_freeSwitchEchoPort);
+ map.Add("DefaultWellKnownIP", m_freeSwitchDefaultWellKnownIP);
+ map.Add("DefaultTimeout", m_freeSwitchDefaultTimeout);
+ map.Add("Context", m_freeSwitchContext);
+ map.Add("APIPrefix", m_freeSwitchAPIPrefix);
+
+ return OSDParser.SerializeJsonString(map);
+ }
}
}
diff --git a/OpenSim/Services/FreeswitchService/FreeswitchServiceBase.cs b/OpenSim/Services/FreeswitchService/FreeswitchServiceBase.cs
index 83fecef847..ebbb1b06ec 100644
--- a/OpenSim/Services/FreeswitchService/FreeswitchServiceBase.cs
+++ b/OpenSim/Services/FreeswitchService/FreeswitchServiceBase.cs
@@ -31,11 +31,28 @@ using Nini.Config;
using OpenSim.Framework;
using OpenSim.Services.Interfaces;
using OpenSim.Services.Base;
+using log4net;
namespace OpenSim.Services.FreeswitchService
{
public class FreeswitchServiceBase : ServiceBase
{
+ private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
+ protected string m_freeSwitchRealm;
+ protected string m_freeSwitchSIPProxy;
+ protected bool m_freeSwitchAttemptUseSTUN = false;
+ protected string m_freeSwitchEchoServer;
+ protected int m_freeSwitchEchoPort = 50505;
+ protected string m_freeSwitchDefaultWellKnownIP;
+ protected int m_freeSwitchDefaultTimeout = 5000;
+ protected string m_freeSwitchContext = "default";
+ protected string m_freeSwitchServerUser = "freeswitch";
+ protected string m_freeSwitchServerPass = "password";
+ protected readonly string m_freeSwitchAPIPrefix = "/fsapi";
+
+ protected bool m_Enabled = false;
+
public FreeswitchServiceBase(IConfigSource config) : base(config)
{
//
@@ -44,7 +61,24 @@ namespace OpenSim.Services.FreeswitchService
IConfig freeswitchConfig = config.Configs["FreeswitchService"];
if (freeswitchConfig != null)
{
- // Read config here !!
+ m_freeSwitchDefaultWellKnownIP = freeswitchConfig.GetString("ServerAddress", String.Empty);
+ if (m_freeSwitchDefaultWellKnownIP == String.Empty)
+ {
+ m_log.Error("[FREESWITCH]: No FreeswitchServerAddress given, can't continue");
+ return;
+ }
+
+ m_freeSwitchRealm = freeswitchConfig.GetString("Realm", m_freeSwitchDefaultWellKnownIP);
+ m_freeSwitchSIPProxy = freeswitchConfig.GetString("SIPProxy", m_freeSwitchDefaultWellKnownIP + ":5060");
+ m_freeSwitchEchoServer = freeswitchConfig.GetString("EchoServer", m_freeSwitchDefaultWellKnownIP);
+ m_freeSwitchEchoPort = freeswitchConfig.GetInt("EchoPort", m_freeSwitchEchoPort);
+ m_freeSwitchAttemptUseSTUN = freeswitchConfig.GetBoolean("AttemptSTUN", false); // This may not work
+ m_freeSwitchDefaultTimeout = freeswitchConfig.GetInt("DefaultTimeout", m_freeSwitchDefaultTimeout);
+ m_freeSwitchContext = freeswitchConfig.GetString("Context", m_freeSwitchContext);
+ m_freeSwitchServerUser = freeswitchConfig.GetString("UserName", m_freeSwitchServerUser);
+ m_freeSwitchServerPass = freeswitchConfig.GetString("Password", m_freeSwitchServerPass);
+
+ m_Enabled = true;
}
}
}
diff --git a/OpenSim/Services/Interfaces/IFreeswitchService.cs b/OpenSim/Services/Interfaces/IFreeswitchService.cs
index d1f635b11d..e7941d5406 100644
--- a/OpenSim/Services/Interfaces/IFreeswitchService.cs
+++ b/OpenSim/Services/Interfaces/IFreeswitchService.cs
@@ -27,11 +27,14 @@
using System;
using OpenSim.Framework;
+using System.Collections;
namespace OpenSim.Services.Interfaces
{
public interface IFreeswitchService
{
- // Place anything the connector eeds to access here!
+ Hashtable HandleDirectoryRequest(Hashtable requestBody);
+ Hashtable HandleDialplanRequest(Hashtable requestBody);
+ string GetJsonConfig();
}
}
diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example
index 9d348548c0..988831fd4a 100644
--- a/bin/OpenSim.ini.example
+++ b/bin/OpenSim.ini.example
@@ -580,44 +580,33 @@
[FreeSwitchVoice]
;; In order for this to work you need a functioning FreeSWITCH PBX set up.
;; Configuration details at http://opensimulator.org/wiki/Freeswitch_Module
- ; enabled = false
+ ; Enabled = false
- ;; FreeSWITCH server is going to contact us and ask us all sorts of things
- ; freeswitch_server_user = freeswitch
- ; freeswitch_server_pass = password
- ; freeswitch_api_prefix = /api
+ ;; You need to load a local service for a standalone, and a remote service
+ ;; for a grid region. Use one of the lines below, as appropriate
+ ; LocalServiceModule = OpenSim.Services.FreeswitchService.dll:FreeswitchService
+ ; LocalServiceModule = OpenSim.Services.Connectors.dll:RemoteFreeswitchConnector
- ;; external IP address of your OpenSim voice enabled region
- ;; note: all regions running on same OpenSim.exe will be enabled
- ; freeswitch_service_server = ip.address.of.your.sim
+ ;; If using a remote module, specify the server URL
+ ; FreeswitchServiceURL = http://my.grid.server:8003/fsapi
- ;; this should be the same port the region listens on
- ; freeswitch_service_port = 9000
- ; freeswitch_realm = ip.address.of.freeswitch.server
- ; freeswitch_sip_proxy = ip.address.of.freeswitch.server:5060
+[FreeswitchService]
+ ;; !!!!!!!!!!!!!!!!!!!!!!!!!!!
+ ;; !!!!!!STANDALONE ONLY!!!!!!
+ ;; !!!!!!!!!!!!!!!!!!!!!!!!!!!
+ ;; IP of your FS server
+ ;ServerAddress = 85.25.142.92
- ;; STUN = Simple Traversal of UDP through NATs
- ;; See http://wiki.freeswitch.org/wiki/NAT_Traversal
- ;; stun.freeswitch.org is not guaranteed to be running so use it in
- ;; production at your own risk
- ; freeswitch_attempt_stun = false
- ; freeswitch_stun_server = ip.address.of.stun.server
- ; freeswitch_echo_server = ip.address.of.freeswitch.server
- ; freeswitch_echo_port = 50505
- ; freeswitch_well_known_ip = ip.address.of.freeswitch.server
-
- ;; Type the address of your http server here, hostname is allowed.
- ;; This is provided so you can specify a hostname
- ;; This is used by client for account verification. By default, it's the
- ;; same as the freeswitch service server.
- ; opensim_well_known_http_address = Address_Of_Your_SIM_HTTP_Server
-
- ;; Timeouts
- ; freeswitch_default_timeout = 5000
- ; freeswitch_subscribe_retry = 120
-
- ;; Misc
- ; freeswitch_password_reset_url =
+ ;; All other options are - well - optional
+ ; Realm = "127.0.0.1"
+ ; SIPProxy = "127.0.0.1:5060"
+ ; EchoServer = "127.0.0.1"
+ ; EchoPort = 50505
+ ; AttemptSTUN = "false"
+ ; DefaultTimeout = 5000
+ ; Context = "default"
+ ; UserName = "freeswitch"
+ ; Password = "password"
[Groups]
;# {Enabled} {} {Enable groups?} {true false} false
diff --git a/bin/Robust.ini.example b/bin/Robust.ini.example
index bc87ac286d..b12e05b398 100644
--- a/bin/Robust.ini.example
+++ b/bin/Robust.ini.example
@@ -69,6 +69,19 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003
; * This is the configuration for the freeswitch server in grid mode
[FreeswitchService]
LocalServiceModule = "OpenSim.Services.FreeswitchService.dll:FreeswitchService"
+ ;; IP of your FS server
+ ; ServerAddress = 127.0.0.1
+
+ ;; All other options are - well - optional
+ ; Realm = "127.0.0.1"
+ ; SIPProxy = "127.0.0.1:5060"
+ ; EchoServer = "127.0.0.1"
+ ; EchoPort = 50505
+ ; AttemptSTUN = "false"
+ ; DefaultTimeout = 5000
+ ; Context = "default"
+ ; UserName = "freeswitch"
+ ; Password = "password"
; * This is the new style authentication service. Currently, only MySQL
; * is implemented. "Realm" is the table that is used for user lookup.
diff --git a/prebuild.xml b/prebuild.xml
index ac003d9a17..00be4f9a37 100644
--- a/prebuild.xml
+++ b/prebuild.xml
@@ -1023,6 +1023,7 @@
../../../bin/
+