aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs')
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs275
1 files changed, 112 insertions, 163 deletions
diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs
index 242bc3f..a5e553c 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;
37using System.Collections.Generic; 37using System.Collections.Generic;
38using System.Reflection; 38using System.Reflection;
39using OpenMetaverse; 39using OpenMetaverse;
40using OpenMetaverse.StructuredData;
40using log4net; 41using log4net;
41using Nini.Config; 42using Nini.Config;
42using Nwc.XmlRpc; 43using Nwc.XmlRpc;
43using OpenSim.Framework; 44using OpenSim.Framework;
45using Mono.Addins;
44 46
45using OpenSim.Framework.Capabilities; 47using OpenSim.Framework.Capabilities;
46using OpenSim.Framework.Servers; 48using OpenSim.Framework.Servers;
@@ -49,28 +51,27 @@ using OpenSim.Region.Framework.Interfaces;
49using OpenSim.Region.Framework.Scenes; 51using OpenSim.Region.Framework.Scenes;
50using Caps = OpenSim.Framework.Capabilities.Caps; 52using Caps = OpenSim.Framework.Capabilities.Caps;
51using System.Text.RegularExpressions; 53using System.Text.RegularExpressions;
54using OpenSim.Server.Base;
55using OpenSim.Services.Interfaces;
56using OSDMap = OpenMetaverse.StructuredData.OSDMap;
52 57
53namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice 58namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
54{ 59{
55 public class FreeSwitchVoiceModule : IRegionModule, IVoiceModule 60 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "FreeSwitchVoiceModule")]
61 public class FreeSwitchVoiceModule : INonSharedRegionModule, IVoiceModule
56 { 62 {
57 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 63 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
58 64
59 private bool UseProxy = false;
60
61 // Capability string prefixes 65 // Capability string prefixes
62 private static readonly string m_parcelVoiceInfoRequestPath = "0007/"; 66 private static readonly string m_parcelVoiceInfoRequestPath = "0007/";
63 private static readonly string m_provisionVoiceAccountRequestPath = "0008/"; 67 private static readonly string m_provisionVoiceAccountRequestPath = "0008/";
64 private static readonly string m_chatSessionRequestPath = "0009/"; 68 private static readonly string m_chatSessionRequestPath = "0009/";
65 69
66 // Control info 70 // Control info
67 private static bool m_WOF = true; 71 private static bool m_Enabled = false;
68 private static bool m_pluginEnabled = false;
69 72
70 // FreeSwitch server is going to contact us and ask us all 73 // FreeSwitch server is going to contact us and ask us all
71 // sorts of things. 74 // sorts of things.
72 private static string m_freeSwitchServerUser;
73 private static string m_freeSwitchServerPass;
74 75
75 // SLVoice client will do a GET on this prefix 76 // SLVoice client will do a GET on this prefix
76 private static string m_freeSwitchAPIPrefix; 77 private static string m_freeSwitchAPIPrefix;
@@ -84,143 +85,146 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
84 private static string m_freeSwitchRealm; 85 private static string m_freeSwitchRealm;
85 private static string m_freeSwitchSIPProxy; 86 private static string m_freeSwitchSIPProxy;
86 private static bool m_freeSwitchAttemptUseSTUN; 87 private static bool m_freeSwitchAttemptUseSTUN;
87 // private static string m_freeSwitchSTUNServer;
88 private static string m_freeSwitchEchoServer; 88 private static string m_freeSwitchEchoServer;
89 private static int m_freeSwitchEchoPort; 89 private static int m_freeSwitchEchoPort;
90 private static string m_freeSwitchDefaultWellKnownIP; 90 private static string m_freeSwitchDefaultWellKnownIP;
91 private static int m_freeSwitchDefaultTimeout; 91 private static int m_freeSwitchDefaultTimeout;
92 // private static int m_freeSwitchSubscribeRetry;
93 private static string m_freeSwitchUrlResetPassword; 92 private static string m_freeSwitchUrlResetPassword;
94 // private static IPEndPoint m_FreeSwitchServiceIP; 93 private uint m_freeSwitchServicePort;
95 private int m_freeSwitchServicePort;
96 private string m_openSimWellKnownHTTPAddress; 94 private string m_openSimWellKnownHTTPAddress;
97 private string m_freeSwitchContext; 95 private string m_freeSwitchContext;
98 96
99 private FreeSwitchDirectory m_FreeSwitchDirectory;
100 private FreeSwitchDialplan m_FreeSwitchDialplan;
101
102 private readonly Dictionary<string, string> m_UUIDName = new Dictionary<string, string>(); 97 private readonly Dictionary<string, string> m_UUIDName = new Dictionary<string, string>();
103 private Dictionary<string, string> m_ParcelAddress = new Dictionary<string, string>(); 98 private Dictionary<string, string> m_ParcelAddress = new Dictionary<string, string>();
104 99
105 private Scene m_scene; 100 private Scene m_Scene;
106 101
102 private IConfig m_Config;
107 103
108 private IConfig m_config; 104 private IFreeswitchService m_FreeswitchService;
109 105
110 public void Initialise(Scene scene, IConfigSource config) 106 public void Initialise(IConfigSource config)
111 { 107 {
112 m_scene = scene; 108 m_Config = config.Configs["FreeSwitchVoice"];
113 m_config = config.Configs["FreeSwitchVoice"];
114 109
115 if (null == m_config) 110 if (m_Config == null)
116 { 111 {
117 m_log.Info("[FreeSwitchVoice] no config found, plugin disabled"); 112 m_log.Info("[FreeSwitchVoice] no config found, plugin disabled");
118 return; 113 return;
119 } 114 }
120 115
121 if (!m_config.GetBoolean("enabled", false)) 116 if (!m_Config.GetBoolean("Enabled", false))
122 { 117 {
123 m_log.Info("[FreeSwitchVoice] plugin disabled by configuration"); 118 m_log.Info("[FreeSwitchVoice] plugin disabled by configuration");
124 return; 119 return;
125 } 120 }
126 121
127 // This is only done the FIRST time this method is invoked. 122 try
128 if (m_WOF)
129 { 123 {
130 m_pluginEnabled = true; 124 string serviceDll = m_Config.GetString("LocalServiceModule",
131 m_WOF = false; 125 String.Empty);
132 126
133 try 127 if (serviceDll == String.Empty)
134 { 128 {
135 m_freeSwitchServerUser = m_config.GetString("freeswitch_server_user", String.Empty); 129 m_log.Error("[FreeSwitchVoice]: No LocalServiceModule named in section FreeSwitchVoice");
136 m_freeSwitchServerPass = m_config.GetString("freeswitch_server_pass", String.Empty); 130 return;
137 m_freeSwitchAPIPrefix = m_config.GetString("freeswitch_api_prefix", String.Empty); 131 }
138
139 // 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)
140
141 string serviceIP = m_config.GetString("freeswitch_service_server", String.Empty);
142 int servicePort = m_config.GetInt("freeswitch_service_port", 80);
143 IPAddress serviceIPAddress = IPAddress.Parse(serviceIP);
144 // m_FreeSwitchServiceIP = new IPEndPoint(serviceIPAddress, servicePort);
145 m_freeSwitchServicePort = servicePort;
146 m_freeSwitchRealm = m_config.GetString("freeswitch_realm", String.Empty);
147 m_freeSwitchSIPProxy = m_config.GetString("freeswitch_sip_proxy", m_freeSwitchRealm);
148 m_freeSwitchAttemptUseSTUN = m_config.GetBoolean("freeswitch_attempt_stun", true);
149 // m_freeSwitchSTUNServer = m_config.GetString("freeswitch_stun_server", m_freeSwitchRealm);
150 m_freeSwitchEchoServer = m_config.GetString("freeswitch_echo_server", m_freeSwitchRealm);
151 m_freeSwitchEchoPort = m_config.GetInt("freeswitch_echo_port", 50505);
152 m_freeSwitchDefaultWellKnownIP = m_config.GetString("freeswitch_well_known_ip", m_freeSwitchRealm);
153 m_openSimWellKnownHTTPAddress = m_config.GetString("opensim_well_known_http_address", serviceIPAddress.ToString());
154 m_freeSwitchDefaultTimeout = m_config.GetInt("freeswitch_default_timeout", 5000);
155 // m_freeSwitchSubscribeRetry = m_config.GetInt("freeswitch_subscribe_retry", 120);
156 m_freeSwitchUrlResetPassword = m_config.GetString("freeswitch_password_reset_url", String.Empty);
157 m_freeSwitchContext = m_config.GetString("freeswitch_context", "default");
158
159 if (String.IsNullOrEmpty(m_freeSwitchServerUser) ||
160 String.IsNullOrEmpty(m_freeSwitchServerPass) ||
161 String.IsNullOrEmpty(m_freeSwitchRealm) ||
162 String.IsNullOrEmpty(m_freeSwitchAPIPrefix))
163 {
164 m_log.Error("[FreeSwitchVoice] plugin mis-configured");
165 m_log.Info("[FreeSwitchVoice] plugin disabled: incomplete configuration");
166 return;
167 }
168 132
169 // set up http request handlers for 133 Object[] args = new Object[] { config };
170 // - prelogin: viv_get_prelogin.php 134 m_FreeswitchService = ServerUtils.LoadPlugin<IFreeswitchService>(serviceDll, args);
171 // - signin: viv_signin.php 135
172 // - buddies: viv_buddy.php 136 string jsonConfig = m_FreeswitchService.GetJsonConfig();
173 // - ???: viv_watcher.php 137 OSDMap map = (OSDMap)OSDParser.DeserializeJson(jsonConfig);
174 // - signout: viv_signout.php 138
175 if (UseProxy) 139 m_freeSwitchAPIPrefix = map["APIPrefix"].AsString();
176 { 140 m_freeSwitchRealm = map["Realm"].AsString();
177 MainServer.Instance.AddHTTPHandler(String.Format("{0}/", m_freeSwitchAPIPrefix), 141 m_freeSwitchSIPProxy = map["SIPProxy"].AsString();
178 ForwardProxyRequest); 142 m_freeSwitchAttemptUseSTUN = map["AttemptUseSTUN"].AsBoolean();
179 } 143 m_freeSwitchEchoServer = map["EchoServer"].AsString();
180 else 144 m_freeSwitchEchoPort = map["EchoPort"].AsInteger();
181 { 145 m_freeSwitchDefaultWellKnownIP = map["DefaultWellKnownIP"].AsString();
182 MainServer.Instance.AddHTTPHandler(String.Format("{0}/viv_get_prelogin.php", m_freeSwitchAPIPrefix), 146 m_freeSwitchDefaultTimeout = map["DefaultTimeout"].AsInteger();
183 FreeSwitchSLVoiceGetPreloginHTTPHandler); 147 m_freeSwitchUrlResetPassword = String.Empty;
148 m_freeSwitchContext = map["Context"].AsString();
149
150 if (String.IsNullOrEmpty(m_freeSwitchRealm) ||
151 String.IsNullOrEmpty(m_freeSwitchAPIPrefix))
152 {
153 m_log.Error("[FreeSwitchVoice] plugin mis-configured");
154 m_log.Info("[FreeSwitchVoice] plugin disabled: incomplete configuration");
155 return;
156 }
184 157
185 // RestStreamHandler h = new 158 // set up http request handlers for
186 // RestStreamHandler("GET", 159 // - prelogin: viv_get_prelogin.php
187 // String.Format("{0}/viv_get_prelogin.php", m_freeSwitchAPIPrefix), FreeSwitchSLVoiceGetPreloginHTTPHandler); 160 // - signin: viv_signin.php
188 // MainServer.Instance.AddStreamHandler(h); 161 // - buddies: viv_buddy.php
162 // - ???: viv_watcher.php
163 // - signout: viv_signout.php
164 MainServer.Instance.AddHTTPHandler(String.Format("{0}/viv_get_prelogin.php", m_freeSwitchAPIPrefix),
165 FreeSwitchSLVoiceGetPreloginHTTPHandler);
189 166
167 // RestStreamHandler h = new
168 // RestStreamHandler("GET",
169 // String.Format("{0}/viv_get_prelogin.php", m_freeSwitchAPIPrefix), FreeSwitchSLVoiceGetPreloginHTTPHandler);
170 // MainServer.Instance.AddStreamHandler(h);
190 171
191 172
192 MainServer.Instance.AddHTTPHandler(String.Format("{0}/viv_signin.php", m_freeSwitchAPIPrefix),
193 FreeSwitchSLVoiceSigninHTTPHandler);
194 173
195 // set up http request handlers to provide 174 MainServer.Instance.AddHTTPHandler(String.Format("{0}/viv_signin.php", m_freeSwitchAPIPrefix),
196 // on-demand FreeSwitch configuration to 175 FreeSwitchSLVoiceSigninHTTPHandler);
197 // FreeSwitch's mod_curl_xml
198 MainServer.Instance.AddHTTPHandler(String.Format("{0}/freeswitch-config", m_freeSwitchAPIPrefix),
199 FreeSwitchConfigHTTPHandler);
200 176
201 MainServer.Instance.AddHTTPHandler(String.Format("{0}/viv_buddy.php", m_freeSwitchAPIPrefix), 177 MainServer.Instance.AddHTTPHandler(String.Format("{0}/viv_buddy.php", m_freeSwitchAPIPrefix),
202 FreeSwitchSLVoiceBuddyHTTPHandler); 178 FreeSwitchSLVoiceBuddyHTTPHandler);
203 }
204 179
205 m_log.InfoFormat("[FreeSwitchVoice] using FreeSwitch server {0}", m_freeSwitchRealm); 180 m_log.InfoFormat("[FreeSwitchVoice] using FreeSwitch server {0}", m_freeSwitchRealm);
206 181
207 m_FreeSwitchDirectory = new FreeSwitchDirectory(); 182 m_Enabled = true;
208 m_FreeSwitchDialplan = new FreeSwitchDialplan();
209 183
210 m_pluginEnabled = true; 184 m_log.Info("[FreeSwitchVoice] plugin enabled");
211 m_WOF = false; 185 }
186 catch (Exception e)
187 {
188 m_log.ErrorFormat("[FreeSwitchVoice] plugin initialization failed: {0}", e.Message);
189 m_log.DebugFormat("[FreeSwitchVoice] plugin initialization failed: {0}", e.ToString());
190 return;
191 }
212 192
213 m_log.Info("[FreeSwitchVoice] plugin enabled"); 193 // This here is a region module trying to make a global setting.
194 // Not really a good idea but it's Windows only, so I can't test.
195 try
196 {
197 ServicePointManager.ServerCertificateValidationCallback += CustomCertificateValidation;
198 }
199 catch (NotImplementedException)
200 {
201 try
202 {
203#pragma warning disable 0612, 0618
204 // Mono does not implement the ServicePointManager.ServerCertificateValidationCallback yet! Don't remove this!
205 ServicePointManager.CertificatePolicy = new MonoCert();
206#pragma warning restore 0612, 0618
214 } 207 }
215 catch (Exception e) 208 catch (Exception)
216 { 209 {
217 m_log.ErrorFormat("[FreeSwitchVoice] plugin initialization failed: {0}", e.Message); 210 // COmmented multiline spam log message
218 m_log.DebugFormat("[FreeSwitchVoice] plugin initialization failed: {0}", e.ToString()); 211 //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.");
219 return;
220 } 212 }
221 } 213 }
214 }
222 215
223 if (m_pluginEnabled) 216 public void AddRegion(Scene scene)
217 {
218 m_Scene = scene;
219
220 // We generate these like this: The region's external host name
221 // as defined in Regions.ini is a good address to use. It's a
222 // dotted quad (or should be!) and it can reach this host from
223 // a client. The port is grabbed from the region's HTTP server.
224 m_openSimWellKnownHTTPAddress = m_Scene.RegionInfo.ExternalHostName;
225 m_freeSwitchServicePort = MainServer.Instance.Port;
226
227 if (m_Enabled)
224 { 228 {
225 // we need to capture scene in an anonymous method 229 // we need to capture scene in an anonymous method
226 // here as we need it later in the callbacks 230 // here as we need it later in the callbacks
@@ -228,36 +232,21 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
228 { 232 {
229 OnRegisterCaps(scene, agentID, caps); 233 OnRegisterCaps(scene, agentID, caps);
230 }; 234 };
231
232 try
233 {
234 ServicePointManager.ServerCertificateValidationCallback += CustomCertificateValidation;
235 }
236 catch (NotImplementedException)
237 {
238 try
239 {
240#pragma warning disable 0612, 0618
241 // Mono does not implement the ServicePointManager.ServerCertificateValidationCallback yet! Don't remove this!
242 ServicePointManager.CertificatePolicy = new MonoCert();
243#pragma warning restore 0612, 0618
244 }
245 catch (Exception)
246 {
247 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.");
248 }
249 }
250 } 235 }
251 } 236 }
252 237
253 public void PostInitialise() 238 public void RemoveRegion(Scene scene)
254 { 239 {
255 if (m_pluginEnabled) 240 }
241
242 public void RegionLoaded(Scene scene)
243 {
244 if (m_Enabled)
256 { 245 {
257 m_log.Info("[FreeSwitchVoice] registering IVoiceModule with the scene"); 246 m_log.Info("[FreeSwitchVoice] registering IVoiceModule with the scene");
258 247
259 // register the voice interface for this module, so the script engine can call us 248 // register the voice interface for this module, so the script engine can call us
260 m_scene.RegisterModuleInterface<IVoiceModule>(this); 249 scene.RegisterModuleInterface<IVoiceModule>(this);
261 } 250 }
262 } 251 }
263 252
@@ -270,9 +259,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
270 get { return "FreeSwitchVoiceModule"; } 259 get { return "FreeSwitchVoiceModule"; }
271 } 260 }
272 261
273 public bool IsSharedModule 262 public Type ReplaceableInterface
274 { 263 {
275 get { return true; } 264 get { return null; }
276 } 265 }
277 266
278 // <summary> 267 // <summary>
@@ -725,46 +714,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
725 714
726 response["int_response_code"] = 200; 715 response["int_response_code"] = 200;
727 return response; 716 return response;
728 /*
729 <level0>
730 <status>OK</status><body><status>Ok</status><cookie_name>lib_session</cookie_name>
731 * <cookie>xMj1QJSc7TA-G7XqcW6QXAg==:1290551700:050d35c6fef96f132f780d8039ff7592::</cookie>
732 * <auth_token>xMj1QJSc7TA-G7XqcW6QXAg==:1290551700:050d35c6fef96f132f780d8039ff7592::</auth_token>
733 * <primary>1</primary>
734 * <account_id>7449</account_id>
735 * <displayname>Teravus Ousley</displayname></body></level0>
736 */
737 }
738
739 public Hashtable FreeSwitchConfigHTTPHandler(Hashtable request)
740 {
741 m_log.DebugFormat("[FreeSwitchVoice] FreeSwitchConfigHTTPHandler called with {0}", (string)request["body"]);
742
743 Hashtable response = new Hashtable();
744 response["str_response_string"] = string.Empty;
745 // all the params come as NVPs in the request body
746 Hashtable requestBody = parseRequestBody((string) request["body"]);
747
748 // is this a dialplan or directory request
749 string section = (string) requestBody["section"];
750
751 if (section == "directory")
752 response = m_FreeSwitchDirectory.HandleDirectoryRequest(m_freeSwitchContext, m_freeSwitchRealm, requestBody);
753 else if (section == "dialplan")
754 response = m_FreeSwitchDialplan.HandleDialplanRequest(m_freeSwitchContext, m_freeSwitchRealm, requestBody);
755 else
756 m_log.WarnFormat("[FreeSwitchVoice]: section was {0}", section);
757
758 // XXX: re-generate dialplan:
759 // - conf == region UUID
760 // - conf number = region port
761 // -> TODO Initialise(): keep track of regions via events
762 // re-generate accounts for all avatars
763 // -> TODO Initialise(): keep track of avatars via events
764 Regex normalizeEndLines = new Regex(@"\r\n", RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.Multiline);
765
766 m_log.DebugFormat("[FreeSwitchVoice] FreeSwitchConfigHTTPHandler return {0}",normalizeEndLines.Replace(((string)response["str_response_string"]), ""));
767 return response;
768 } 717 }
769 718
770 public Hashtable parseRequestBody(string body) 719 public Hashtable parseRequestBody(string body)