SHARE
TWEET

Untitled

a guest Mar 20th, 2016 48 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  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 OpenSimulator 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.  
  28. using System;
  29. using System.Text;
  30. using System.Reflection;
  31. using Nini.Config;
  32. using log4net;
  33. using OpenSim.Framework;
  34. using OpenSim.Data;
  35. using OpenSim.Services.Interfaces;
  36. using OpenMetaverse;
  37. using OpenMetaverse.StructuredData;
  38. using System.Collections;
  39.  
  40. namespace OpenSim.Services.FreeswitchService
  41. {
  42.     public class FreeswitchService : FreeswitchServiceBase, IFreeswitchService
  43.     {
  44.         private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
  45.  
  46.         public FreeswitchService(IConfigSource config) : base(config)
  47.         {
  48.             // Perform initilialization here
  49.         }
  50.  
  51.         public Hashtable HandleDialplanRequest(Hashtable request)
  52.         {
  53.             m_log.DebugFormat("[FreeSwitchVoice]: HandleDialplanRequest called with {0}",request.ToString());
  54.  
  55.             Hashtable response = new Hashtable();
  56.  
  57. //            foreach (DictionaryEntry item in request)
  58. //            {
  59. ////               m_log.InfoFormat("[FreeSwitchDirectory]: requestBody item {0} {1}",item.Key, item.Value);
  60. //            }
  61.  
  62.             string requestcontext = (string) request["Hunt-Context"];
  63.             response["content_type"] = "text/xml";
  64.             response["keepalive"] = false;
  65.             response["int_response_code"] = 200;
  66.  
  67.             if (m_freeSwitchContext != String.Empty && m_freeSwitchContext != requestcontext)
  68.             {
  69.                 m_log.Debug("[FreeSwitchDirectory]: returning empty as it's for another context");
  70.                 response["str_response_string"] = "";
  71.             }
  72.             else
  73.             {
  74.                 response["str_response_string"] = String.Format(@"<?xml version=""1.0"" encoding=""utf-8""?>
  75.                    <document type=""freeswitch/xml"">
  76.                      <section name=""dialplan"">
  77.                      <context name=""{0}"">" +
  78.  
  79. /*                           <!-- dial via SIP uri -->
  80.                             <extension name=""sip_uri"">
  81.                                    <condition field=""destination_number"" expression=""^sip:(.*)$"">
  82.                                    <action application=""bridge"" data=""sofia/${use_profile}/$1""/>
  83.                                    <!--<action application=""bridge"" data=""$1""/>-->
  84.                                    </condition>
  85.                            </extension>*/
  86.  
  87.                            @"<extension name=""opensim_conferences"">
  88.                                    <condition field=""destination_number"" expression=""^confctl-(.*)$"">
  89.                                            <action application=""answer""/>
  90.                                            <action application=""conference"" data=""$1-{1}@{0}""/>
  91.                                    </condition>
  92.                            </extension>
  93.  
  94.                            <extension name=""opensim_conf"">
  95.                                    <condition field=""destination_number"" expression=""^conf-(.*)$"">
  96.                                            <action application=""answer""/>
  97.                                            <action application=""conference"" data=""$1-{1}@{0}""/>
  98.                                    </condition>
  99.                            </extension>
  100.  
  101.                            <extension name=""avatar"">
  102.                                    <condition field=""destination_number"" expression=""^(x.*)$"">
  103.                                            <action application=""bridge"" data=""user/$1""/>
  104.                                    </condition>
  105.                            </extension>
  106.  
  107.                      </context>
  108.                    </section>
  109.                    </document>", m_freeSwitchContext, m_freeSwitchRealm);
  110.             }
  111.  
  112.             return response;
  113.         }
  114.  
  115.         public Hashtable HandleDirectoryRequest(Hashtable request)
  116.         {
  117.             Hashtable response = new Hashtable();
  118.             string domain = (string) request["domain"];
  119.             if (domain != m_freeSwitchRealm)
  120.             {
  121.                 response["content_type"] = "text/xml";
  122.                 response["keepalive"] = false;
  123.                 response["int_response_code"] = 200;
  124.                 response["str_response_string"] = "";
  125.             }
  126.             else
  127.             {
  128. //                 m_log.DebugFormat("[FreeSwitchDirectory]: HandleDirectoryRequest called with {0}",request.ToString());
  129.            
  130.                  // information in the request we might be interested in
  131.              
  132.                  // Request 1 sip_auth for users account
  133.              
  134.                  //Event-Calling-Function=sofia_reg_parse_auth
  135.                  //Event-Calling-Line-Number=1494
  136.                  //action=sip_auth
  137.                  //sip_user_agent=Vivox-SDK-2.1.3010.6151-Mac%20(Feb-11-2009/16%3A42%3A41)
  138.                  //sip_auth_username=xhZuXKmRpECyr2AARJYyGgg%3D%3D  (==)
  139.                  //sip_auth_realm=9.20.151.43
  140.                  //sip_contact_user=xhZuXKmRpECyr2AARJYyGgg%3D%3D (==)
  141.                  //sip_contact_host=192.168.0.3    // this shouldnt really be a local IP, investigate STUN servers
  142.                  //sip_to_user=xhZuXKmRpECyr2AARJYyGgg%3D%3D
  143.                  //sip_to_host=9.20.151.43
  144.                  //sip_auth_method=REGISTER
  145.                  //user=xhZuXKmRpECyr2AARJYyGgg%3D%3D
  146.                  //domain=9.20.151.43
  147.                  //ip=9.167.220.137    // this is the correct IP rather than sip_contact_host above when through a vpn or NAT setup
  148.              
  149. //                 foreach (DictionaryEntry item in request)
  150. //                    m_log.DebugFormat("[FreeSwitchDirectory]: requestBody item {0} {1}", item.Key, item.Value);
  151.              
  152.                  string eventCallingFunction = (string) request["Event-Calling-Function"];
  153.                  if (eventCallingFunction == null)
  154.                  {
  155.                      eventCallingFunction = "sofia_reg_parse_auth";
  156.                  }
  157.  
  158.                  if (eventCallingFunction.Length == 0)
  159.                  {
  160.                      eventCallingFunction = "sofia_reg_parse_auth";
  161.                  }
  162.              
  163.                  if (eventCallingFunction == "sofia_reg_parse_auth")
  164.                  {
  165.                      string sipAuthMethod = (string)request["sip_auth_method"];
  166.                  
  167.                      if (sipAuthMethod == "REGISTER")
  168.                      {
  169.                          response = HandleRegister(m_freeSwitchContext, m_freeSwitchRealm, request);
  170.                      }
  171.                      else if (sipAuthMethod == "INVITE")
  172.                      {
  173.                           response = HandleInvite(m_freeSwitchContext, m_freeSwitchRealm, request);
  174.                      }
  175.                      else
  176.                      {
  177.                          m_log.ErrorFormat("[FreeSwitchVoice]: HandleDirectoryRequest unknown sip_auth_method {0}",sipAuthMethod);
  178.                          response["int_response_code"] = 404;
  179.                          response["content_type"] = "text/xml";
  180.                          response["str_response_string"] = "";
  181.                      }
  182.                  }
  183.                  else if (eventCallingFunction == "switch_xml_locate_user")
  184.                  {
  185.                      response = HandleLocateUser(m_freeSwitchRealm, request);
  186.                  }
  187.                  else if (eventCallingFunction == "user_data_function") // gets called when an avatar to avatar call is made
  188.                  {
  189.                       response = HandleLocateUser(m_freeSwitchRealm, request);
  190.                  }
  191.                  else if (eventCallingFunction == "user_outgoing_channel")
  192.                  {
  193.                      response = HandleRegister(m_freeSwitchContext, m_freeSwitchRealm, request);
  194.                  }
  195.                  else if (eventCallingFunction == "config_sofia") // happens once on freeswitch startup
  196.                  {
  197.                      response = HandleConfigSofia(m_freeSwitchContext, m_freeSwitchRealm, request);
  198.                  }
  199.                  else if (eventCallingFunction == "switch_load_network_lists")
  200.                  {
  201.                      //response = HandleLoadNetworkLists(request);
  202.                      response["int_response_code"] = 404;
  203.                      response["keepalive"] = false;
  204.                      response["content_type"] = "text/xml";
  205.                      response["str_response_string"] = "";
  206.                  }
  207.                  else
  208.                  {
  209.                      m_log.ErrorFormat("[FreeSwitchVoice]: HandleDirectoryRequest unknown Event-Calling-Function {0}",eventCallingFunction);
  210.                      response["int_response_code"] = 404;
  211.                      response["keepalive"] = false;
  212.                      response["content_type"] = "text/xml";
  213.                      response["str_response_string"] = "";
  214.                  }
  215.             }
  216.             return response;
  217.         }
  218.        
  219.         private Hashtable HandleRegister(string Context, string Realm, Hashtable request)
  220.         {
  221.             m_log.Info("[FreeSwitchDirectory]: HandleRegister called");
  222.            
  223.             // TODO the password we return needs to match that sent in the request, this is hard coded for now
  224.             string password = "1234";
  225.             string domain = (string) request["domain"];
  226.             string user = (string) request["user"];
  227.            
  228.             Hashtable response = new Hashtable();
  229.             response["content_type"] = "text/xml";
  230.             response["keepalive"] = false;
  231.             response["int_response_code"] = 200;
  232.  
  233.             response["str_response_string"] = String.Format(
  234.                 "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n" +
  235.                 "<document type=\"freeswitch/xml\">\r\n" +
  236.                     "<section name=\"directory\" description=\"User Directory\">\r\n" +
  237.                         "<domain name=\"{0}\">\r\n" +
  238.                             "<user id=\"{1}\">\r\n" +
  239.                                 "<params>\r\n" +
  240.                                     "<param name=\"password\" value=\"{2}\" />\r\n" +
  241.                                     "<param name=\"dial-string\" value=\"{{sip_contact_user={1}}}{{presence_id=${{dialed_user}}@${{dialed_domain}}}}${{sofia_contact(${{dialed_user}}@${{dialed_domain}})}}\"/>\r\n" +
  242.                                 "</params>\r\n" +
  243.                                 "<variables>\r\n" +
  244.                                     "<variable name=\"user_context\" value=\"{3}\" />\r\n" +
  245.                                     "<variable name=\"presence_id\" value=\"{1}@{0}\"/>"+
  246.                                 "</variables>\r\n" +
  247.                             "</user>\r\n" +
  248.                         "</domain>\r\n" +
  249.                     "</section>\r\n" +
  250.                 "</document>\r\n",
  251.                 domain , user, password, Context);
  252.                
  253.             return response;
  254.         }
  255.        
  256.         private Hashtable HandleInvite(string Context, string Realm, Hashtable request)
  257.         {
  258.             m_log.Info("[FreeSwitchDirectory]: HandleInvite called");
  259.            
  260.             // TODO the password we return needs to match that sent in the request, this is hard coded for now
  261.             string password = "1234";
  262.             string domain = (string) request["domain"];
  263.             string user = (string) request["user"];
  264.             string sipRequestUser = (string) request["sip_request_user"];
  265.            
  266.             Hashtable response = new Hashtable();
  267.             response["content_type"] = "text/xml";
  268.             response["keepalive"] = false;
  269.             response["int_response_code"] = 200;
  270.             response["str_response_string"] = String.Format(
  271.                 "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n" +
  272.                 "<document type=\"freeswitch/xml\">\r\n" +
  273.                     "<section name=\"directory\" description=\"User Directory\">\r\n" +
  274.                         "<domain name=\"{0}\">\r\n" +
  275.                             "<user id=\"{1}\">\r\n" +
  276.                                 "<params>\r\n" +
  277.                                     "<param name=\"password\" value=\"{2}\" />\r\n" +
  278.                                     "<param name=\"dial-string\" value=\"{{sip_contact_user={1}}}{{presence_id=${1}@${{dialed_domain}}}}${{sofia_contact(${1}@${{dialed_domain}})}}\"/>\r\n" +
  279.                                 "</params>\r\n" +
  280.                                 "<variables>\r\n" +
  281.                                     "<variable name=\"user_context\" value=\"{4}\" />\r\n" +
  282.                                     "<variable name=\"presence_id\" value=\"{1}@$${{domain}}\"/>"+
  283.                                 "</variables>\r\n" +
  284.                             "</user>\r\n" +
  285.                             "<user id=\"{3}\">\r\n" +
  286.                                 "<params>\r\n" +
  287.                                     "<param name=\"password\" value=\"{2}\" />\r\n" +
  288.                                     "<param name=\"dial-string\" value=\"{{sip_contact_user={1}}}{{presence_id=${3}@${{dialed_domain}}}}${{sofia_contact(${3}@${{dialed_domain}})}}\"/>\r\n" +
  289.                                 "</params>\r\n" +
  290.                                 "<variables>\r\n" +
  291.                                     "<variable name=\"user_context\" value=\"{4}\" />\r\n" +
  292.                                     "<variable name=\"presence_id\" value=\"{3}@$${{domain}}\"/>"+
  293.                                 "</variables>\r\n" +
  294.                             "</user>\r\n" +
  295.                         "</domain>\r\n" +
  296.                     "</section>\r\n" +
  297.                 "</document>\r\n",
  298.                 domain , user, password,sipRequestUser, Context);
  299.                
  300.             return response;
  301.         }
  302.  
  303.         private Hashtable HandleLocateUser(String Realm, Hashtable request)
  304.         {
  305.             m_log.Info("[FreeSwitchDirectory]: HandleLocateUser called");
  306.            
  307.             // TODO the password we return needs to match that sent in the request, this is hard coded for now
  308.             string domain = (string) request["domain"];
  309.             string user = (string) request["user"];
  310.            
  311.             Hashtable response = new Hashtable();
  312.             response["content_type"] = "text/xml";
  313.             response["keepalive"] = false;
  314.             response["int_response_code"] = 200;
  315.             response["str_response_string"] = String.Format(
  316.                 "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n" +
  317.                 "<document type=\"freeswitch/xml\">\r\n" +
  318.                     "<section name=\"directory\" description=\"User Directory\">\r\n" +
  319.                         "<domain name=\"{0}\">\r\n" +
  320.                             "<params>\r\n" +
  321.                                 "<param name=\"dial-string\" value=\"{{sip_contact_user=${{dialed_user}}}}{{presence_id=${{dialed_user}}@${{dialed_domain}}}}${{sofia_contact(${{dialed_user}}@${{dialed_domain}})}}\"/>\r\n" +
  322.                             "</params>\r\n" +
  323.                             "<user id=\"{1}\">\r\n" +
  324.                             "<variables>\r\n"+
  325.                               "<variable name=\"default_gateway\" value=\"$${{default_provider}}\"/>\r\n"+
  326.                               "<variable name=\"presence_id\" value=\"{1}@$${{domain}}\"/>"+
  327.                             "</variables>\r\n"+
  328.                             "</user>\r\n" +
  329.                         "</domain>\r\n" +
  330.                     "</section>\r\n" +
  331.                 "</document>\r\n",
  332.                 domain , user);
  333.            
  334.             return response;
  335.         }
  336.        
  337.         private Hashtable HandleConfigSofia(string Context, string Realm, Hashtable request)
  338.         {
  339.             m_log.Info("[FreeSwitchDirectory]: HandleConfigSofia called.");
  340.            
  341.             // TODO the password we return needs to match that sent in the request, this is hard coded for now
  342.             string domain = (string) request["domain"];
  343.            
  344.             Hashtable response = new Hashtable();
  345.             response["content_type"] = "text/xml";
  346.             response["keepalive"] = false;
  347.             response["int_response_code"] = 200;
  348.             response["str_response_string"] = String.Format(
  349.                 "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n" +
  350.                 "<document type=\"freeswitch/xml\">\r\n" +
  351.                     "<section name=\"directory\" description=\"User Directory\">\r\n" +
  352.                         "<domain name=\"{0}\">\r\n" +
  353.                             "<params>\r\n" +
  354.                                 "<param name=\"dial-string\" value=\"{{sip_contact_user=${{dialed_user}}}}{{presence_id=${{dialed_user}}@${{dialed_domain}}}}${{sofia_contact(${{dialed_user}}@${{dialed_domain}})}}\"/>\r\n" +
  355.                             "</params>\r\n" +
  356.                             "<groups name=\"default\">\r\n"+
  357.                                 "<users>\r\n"+
  358.                                     "<user id=\"$${{default_provider}}\">\r\n"+
  359.                                         "<gateways>\r\n"+
  360.                                           "<gateway name=\"$${{default_provider}}\">\r\n"+
  361.                                             "<param name=\"username\" value=\"$${{default_provider_username}}\"/>\r\n"+
  362.                                             "<param name=\"password\" value=\"$${{default_provider_password}}\"/>\r\n"+
  363.                                             "<param name=\"from-user\" value=\"$${{default_provider_username}}\"/>\r\n"+
  364.                                             "<param name=\"from-domain\" value=\"$${{default_provider_from_domain}}\"/>\r\n"+
  365.                                             "<param name=\"expire-seconds\" value=\"600\"/>\r\n"+
  366.                                             "<param name=\"register\" value=\"$${{default_provider_register}}\"/>\r\n"+
  367.                                             "<param name=\"retry-seconds\" value=\"30\"/>\r\n"+
  368.                                             "<param name=\"extension\" value=\"$${{default_provider_contact}}\"/>\r\n"+
  369.                                             "<param name=\"contact-params\" value=\"domain_name=$${{domain}}\"/>\r\n"+
  370.                                             "<param name=\"context\" value=\"{1}\"/>\r\n"+
  371.                                           "</gateway>\r\n"+
  372.                                         "</gateways>\r\n"+
  373.                                         "<params>\r\n"+
  374.                                           "<param name=\"password\" value=\"$${{default_provider_password}}\"/>\r\n"+
  375.                                         "</params>\r\n"+
  376.                                       "</user>\r\n"+
  377.                                 "</users>"+
  378.                             "</groups>\r\n" +
  379.                             "<variables>\r\n"+
  380.                               "<variable name=\"default_gateway\" value=\"$${{default_provider}}\"/>\r\n"+
  381.                             "</variables>\r\n"+
  382.                         "</domain>\r\n" +
  383.                     "</section>\r\n" +
  384.                 "</document>\r\n",
  385.                 domain, Context);
  386.              
  387.             return response;
  388.         }
  389.  
  390.         public string GetJsonConfig()
  391.         {
  392.             OSDMap map = new OSDMap(9);
  393.  
  394.             map.Add("Realm", m_freeSwitchRealm);
  395.             map.Add("SIPProxy", m_freeSwitchSIPProxy);
  396.             map.Add("AttemptUseSTUN", m_freeSwitchAttemptUseSTUN);
  397.             map.Add("EchoServer", m_freeSwitchEchoServer);
  398.             map.Add("EchoPort", m_freeSwitchEchoPort);
  399.             map.Add("DefaultWellKnownIP", m_freeSwitchDefaultWellKnownIP);
  400.             map.Add("DefaultTimeout", m_freeSwitchDefaultTimeout);
  401.             map.Add("Context", m_freeSwitchContext);
  402.             map.Add("APIPrefix", m_freeSwitchAPIPrefix);
  403.  
  404.             return OSDParser.SerializeJsonString(map);
  405.         }
  406.     }
  407. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top