Пример #1
0
        /// <summary>
        /// Processes events received from FreeSWITCH and dispatches them to the
        /// application event handlers.  This is called from <see cref="SwitchApp" />
        /// immediately after <see cref="SwitchApp.Main" /> returns on the
        /// application thread.
        /// </summary>
        internal static void EventLoop()
        {
            // Enlist in low-level global events if the application requested.

            var options = (switch_xml_section_enum_t)0;

            if (dialPlanEvent != null)
            {
                options |= switch_xml_section_enum_t.SWITCH_XML_SECTION_DIALPLAN;
            }

            if (userDirectoryEvent != null)
            {
                options |= switch_xml_section_enum_t.SWITCH_XML_SECTION_DIRECTORY;
            }

            if (options != (switch_xml_section_enum_t)0)
            {
                eventBinding = SwitchXmlSearchBinding.Bind(OnSwitchXmlSearchEvent, options);
            }

            // Decided whether we're going to actually consume NeonSwitch events based
            // on whether the application enlisted in the [EventReceived] event within
            // its [Main()] method.  Note that we we'll exit the event loop (and the
            // application's background thread) immediately if this is the case.

            if (eventReceived == null)
            {
                return;
            }

            eventConsumer = new EventConsumer("all", string.Empty, 0);

            // Loop, waiting for the application to terminate.

            while (!stopPending)
            {
                try
                {
                    var fsEvent     = eventConsumer.pop(1, 0);
                    var switchEvent = new SwitchEvent(fsEvent.InternalEvent);

                    RaiseEventReceived(new SwitchEventArgs(switchEvent));

                    if (switchEvent.EventType == SwitchEventCode.BackgroundJob)
                    {
                        RaiseJobCompletedEvent(new JobCompletedEventArgs(switchEvent.Headers.Get("Job-ID", Guid.Empty)));
                    }
                }
                catch (Exception e)
                {
                    SysLog.LogException(e);
                }
            }
        }
Пример #2
0
        /// <summary>
        /// Called by FreeSWITCH when one of the bound events is raised.
        /// </summary>
        /// <param name="args">The event arguments.</param>
        /// <returns>The event results as an XML document.</returns>
        private static string OnSwitchXmlSearchEvent(SwitchXmlSearchBinding.XmlBindingArgs args)
        {
            string result = null;

            try
            {
                switch (args.Section.ToLower())
                {
                case "directory":
                {
                    if (userDirectoryEvent == null)
                    {
                        break;
                    }

                    var switchEvent = new SwitchEvent(args.Parameters);
                    var action      = switchEvent.Headers.Get("action", string.Empty).ToLower();

                    if (action != "sip_auth")
                    {
                        return(FsConfigNotFound.Xml);           // Ignore non-user directory operations
                    }
                    var directoryArgs = new UserDirectoryEventArgs(new SwitchEvent(args.Parameters));

                    userDirectoryEvent(null, directoryArgs);
                    if (directoryArgs.Handled)
                    {
                        if (directoryArgs.Password == null)
                        {
                            directoryArgs.Password = string.Empty;
                        }

                        if (directoryArgs.AccessDenied)
                        {
                            // $hack(jeff.lill):
                            //
                            // There's doesn't appear to be a clean way to tell the switch that the user
                            // is valid but that access should be denied and no additional lookup should
                            // be performed by other modules.  I'm going to handle this by setting the
                            // password to guid.

                            directoryArgs.Password = Guid.NewGuid().ToString("N");
                        }

                        // Validate and set the common parameters/variables.

                        try
                        {
                            Dtmf.ValidateNumeric(directoryArgs.VoiceMailPassword, 0, int.MaxValue, true);
                        }
                        catch (Exception e)
                        {
                            SysLog.LogWarning("UserDirectoryEvent handler ignored [VoiceMailPassword]: {0}", e.Message);
                        }

                        try
                        {
                            Dtmf.ValidateNumeric(directoryArgs.EffectiveCallerIDNumber, 0, 11, true);
                        }
                        catch (Exception e)
                        {
                            SysLog.LogWarning("UserDirectoryEvent handler ignored [EffectiveCallerIDNumber]: {0}", e.Message);
                        }

                        try
                        {
                            Dtmf.ValidateNumeric(directoryArgs.OutboundCallerIDNumber, 0, 11, true);
                        }
                        catch (Exception e)
                        {
                            SysLog.LogWarning("UserDirectoryEvent handler ignored [OutboundCallerIDNumber]: {0}", e.Message);
                        }

                        if (directoryArgs.VoiceMailPassword != null)
                        {
                            directoryArgs.Parameters["vm-password"] = directoryArgs.VoiceMailPassword;
                        }

                        if (directoryArgs.CallingRights != CallingRight.None)
                        {
                            var sb = new StringBuilder();

                            if ((directoryArgs.CallingRights & CallingRight.Local) != 0)
                            {
                                sb.Append("local");
                            }

                            if ((directoryArgs.CallingRights & CallingRight.Domestic) != 0)
                            {
                                if (sb.Length > 0)
                                {
                                    sb.Append(',');
                                }

                                sb.Append("domestic");
                            }

                            if ((directoryArgs.CallingRights & CallingRight.International) != 0)
                            {
                                if (sb.Length > 0)
                                {
                                    sb.Append(',');
                                }

                                sb.Append("international");
                            }

                            directoryArgs.Variables["toll_allow"] = sb.ToString();
                        }

                        if (directoryArgs.AccountCode != null)
                        {
                            directoryArgs.Variables["accountcode"] = directoryArgs.AccountCode;
                        }

                        if (directoryArgs.CallerContext != null)
                        {
                            directoryArgs.Variables["user_context"] = directoryArgs.CallerContext;
                        }

                        if (directoryArgs.EffectiveCallerIDName != null)
                        {
                            directoryArgs.Variables["effective_caller_id_name"] = directoryArgs.EffectiveCallerIDName;
                        }

                        if (directoryArgs.EffectiveCallerIDNumber != null)
                        {
                            directoryArgs.Variables["effective_caller_id_number"] = directoryArgs.EffectiveCallerIDNumber;
                        }

                        if (directoryArgs.OutboundCallerIDName != null)
                        {
                            directoryArgs.Variables["outbound_caller_id_name"] = directoryArgs.OutboundCallerIDName;
                        }

                        if (directoryArgs.OutboundCallerIDNumber != null)
                        {
                            directoryArgs.Variables["outbound_caller_id_number"] = directoryArgs.OutboundCallerIDNumber;
                        }

                        if (directoryArgs.CallGroup != null)
                        {
                            directoryArgs.Variables["callgroup"] = directoryArgs.CallGroup;
                        }

                        result = new FsConfigDirectory(directoryArgs.Domain, directoryArgs.UserID, directoryArgs.Password,
                                                       directoryArgs.Parameters, directoryArgs.Variables).ToXml();

                        Debug.WriteLine(result);            // $todo(jeff.lill): Delete this
                    }
                }
                break;

                case "dialplan":
                {
                    if (dialPlanEvent == null)
                    {
                        break;
                    }

                    var dialPlanArgs = new DialPlanEventArgs(new SwitchEvent(args.Parameters));

                    dialPlanEvent(null, dialPlanArgs);
                    if (dialPlanArgs.Handled)
                    {
                        if (dialPlanArgs.Context == null)
                        {
                            throw new ArgumentException("DialPlanEvent handler returned [Context=null].");
                        }

                        var renderContext = new ActionRenderingContext(true);

                        foreach (var action in dialPlanArgs.Actions)
                        {
                            action.Render(renderContext);
                        }

                        result = new FsConfigDialPlan(dialPlanArgs.Context, renderContext.Actions).ToXml();
                    }
                }
                break;

                default:

                    result = null;
                    break;
                }
            }
            catch (Exception e)
            {
                SysLog.LogException(e);
            }

            return(result ?? FsConfigNotFound.Xml);
        }