Beispiel #1
0
        /// <summary>
        /// The application worker thread.
        /// </summary>
        private void AppThread()
        {
            // All NeonSwitch applications (except for the core service) need to wait for
            // the core to be initialized before the application can be started.  We're
            // going to spin here until the core indicates that it's ready.

            var warningTimer = new PolledTimer(TimeSpan.FromSeconds(60));

            if (!SwitchApp.IsCore)
            {
                while (true)
                {
                    if (String.Compare(Switch.GetGlobal(SwitchGlobal.NeonSwitchReady), "true", true) == 0)
                    {
                        break;
                    }

                    if (warningTimer.HasFired)
                    {
                        warningTimer.Disable();
                        SysLog.LogWarning("NeonSwitch application [{0}] has waited [{1}] for the core NeonSwitch service to start.", SwitchApp.Name, warningTimer.Interval);
                    }

                    Thread.Sleep(TimeSpan.FromSeconds(1));
                }
            }

            // Continue performing wwitch initialization.  We needed to wait until after
            // the NeonSwitch core service started before calling this.

            Switch.Initialize();

            // Call the application entry point so it can initalize itself.

            try
            {
                InMain = true;

                Main();

                InMain     = false;
                mainCalled = true;
            }
            catch (Exception e)
            {
                SysLog.LogException(e, "The NeonSwitch application's Main() method threw an exception.");
                throw;
            }
            finally
            {
                InMain = false;
            }

            // NeonSwitch handles the event dispatching.

            Switch.EventLoop();
        }
Beispiel #2
0
        /// <summary>
        /// Continues the application load process by scanning the loaded assemblies
        /// for the class definition that derives from <see cref="SwitchApp" />
        /// and then constructing an instance.
        /// </summary>
        /// <param name="appName">Name to be used for the module.</param>
        /// <param name="appPath">Path to the application folder.</param>
        /// <param name="loaderDllName">Name of the NeonSwitch application loader DLL file.</param>
        /// <param name="appClassName">The optional application class name or <c>null</c>.</param>
        /// <exception cref="TypeLoadException">Thrown if a single derived <see cref="SwitchApp" /> type could not be found or instantiated.</exception>
        /// <exception cref="NotSupportedException">Thrown if the application is not running on a NeonSwitch enabled build of FreeSWITCH.</exception>
        /// <remarks>
        /// <note>
        /// If <paramref name="appClassName" /> is passed as <c>null</c> then only one type
        /// deriving from <see cref="SwitchApp" /> may be defined across all of the loaded
        /// assemblies.  A <see cref="TypeLoadException" /> will be thrown if more than one
        /// definitions are located.
        /// </note>
        /// </remarks>
        public void Load(string loaderDllName, string appName, string appPath, string appClassName)
        {
            var  thisAssembly    = Assembly.GetExecutingAssembly();
            var  appRefs         = new List <AppRef>();
            var  NeonSwitchValue = Switch.GetGlobal("NeonSwitch");
            bool isNeonSwitch;

            // Verify that we're actually running on a NeonSwitch enabled version of FreeSwitch
            // by looking for the [NeonSwitch] global variable.

            if (NeonSwitchValue == null || !bool.TryParse(NeonSwitchValue, out isNeonSwitch) || !isNeonSwitch)
            {
                throw new NotSupportedException("NeonSwitch applications require a NeonSwitch enabled FreeSWITCH build.  Load terminated.");
            }

            // Continue the loading process.

            foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
            {
                foreach (var type in assembly.GetTypes())
                {
                    if (type.IsDerivedFrom(typeof(SwitchApp)))
                    {
                        appRefs.Add(new AppRef(assembly, type.FullName));
                    }
                }
            }

            // Attempt to construct a specific type if one was specified.

            if (!string.IsNullOrWhiteSpace(appClassName))
            {
                foreach (var appRef in appRefs)
                {
                    if (appClassName == appRef.TypeName)
                    {
                        app = (SwitchApp)appRef.Assembly.CreateInstance(appClassName);
                        app.Load(appName, loaderDllName, appPath);
                        return;
                    }
                }

                throw new TypeLoadException(string.Format("Could not locate application class [{0}] in the loaded assemblies.", appClassName));
            }

            // Remove any references to test applications in this assembly.

            var delList = new List <AppRef>();

            foreach (var appRef in appRefs)
            {
                if (appRef.Assembly == thisAssembly)
                {
                    delList.Add(appRef);
                }
            }

            foreach (var appRef in delList)
            {
                appRefs.Remove(appRef);
            }

            // Make sure we found a single entry class in the assemblies.

            if (appRefs.Count == 0)
            {
                throw new TypeLoadException("Could not find a NeonSwitch application class that derives from [LillTek.Telephony.NeonSwitch.SwitchApp].");
            }
            else if (appRefs.Count > 1)
            {
                var sb = new StringBuilder();

                sb.AppendLine("Multiple NeonSwitch application classes defined:");
                sb.AppendLine();

                foreach (var appRef in appRefs)
                {
                    sb.AppendFormatLine("[{0}] in [{1}]", appRef.TypeName, appRef.Assembly.Location);
                }

                throw new TypeLoadException(sb.ToString());
            }

            // Instantiate the application's entry point class.  Note that the base
            // SwitchApp class will take over the remainder of the NeonSwitch
            // platform initialization.

            app = (SwitchApp)appRefs[0].Assembly.CreateInstance(appRefs[0].TypeName);
            app.Load(appName, loaderDllName, appPath);
        }