mirror of
https://github.com/signalwire/freeswitch.git
synced 2026-10-14 15:24:13 +00:00
Merge Mono and CLR into mod_managed
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@9643 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
1 parent
2db3a00bb7
commit
0f0efa6719
23 files changed
+52333
No files matched your search
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - mod_cli
|
||||
* Copyright (C) 2008, Michael Giagnocavo <mgg@packetrino.com>
|
||||
*
|
||||
* Version: MPL 1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - mod_cli
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Michael Giagnocavo <mgg@packetrino.com>
|
||||
* Portions created by the Initial Developer are Copyright (C)
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Michael Giagnocavo <mgg@packetrino.com>
|
||||
*
|
||||
* AppFunction.cs -- Base class for API functions
|
||||
*
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace FreeSWITCH
|
||||
{
|
||||
public abstract class ApiFunction
|
||||
{
|
||||
protected static bool Load() { return true; }
|
||||
|
||||
protected static void Unload() { }
|
||||
|
||||
public abstract void ExecuteBackground(string args);
|
||||
|
||||
public abstract void Execute(FreeSWITCH.Native.Stream stream, FreeSWITCH.Native.Event evt, string args);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - mod_cli
|
||||
* Copyright (C) 2008, Michael Giagnocavo <mgg@packetrino.com>
|
||||
*
|
||||
* Version: MPL 1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - mod_cli
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Michael Giagnocavo <mgg@packetrino.com>
|
||||
* Portions created by the Initial Developer are Copyright (C)
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Michael Giagnocavo <mgg@packetrino.com>
|
||||
*
|
||||
* AppFunction.cs -- Base class for applications
|
||||
*
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
|
||||
namespace FreeSWITCH
|
||||
{
|
||||
public abstract class AppFunction
|
||||
{
|
||||
protected static bool Load() { return true; }
|
||||
|
||||
protected static void Unload() { }
|
||||
|
||||
protected Native.ManagedSession Session { get; private set; }
|
||||
|
||||
protected string Arguments { get; private set; }
|
||||
|
||||
public bool IsAvailable
|
||||
{
|
||||
get
|
||||
{
|
||||
if (this.Session == null) return false;
|
||||
return this.Session.Ready();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Determines if the thread used for Run will have Abort called on it on hangup. Defaults to false.</summary>
|
||||
protected virtual bool AbortOnHangup { get { return false; } }
|
||||
bool abortable = false;
|
||||
readonly object abortLock = new object();
|
||||
Thread runThread;
|
||||
internal void AbortRun()
|
||||
{
|
||||
if (!AbortOnHangup) return;
|
||||
if (runThread == Thread.CurrentThread) {
|
||||
Log.WriteLine(LogLevel.Warning, "Thread will not be aborted because Hangup was called from the Run thread.");
|
||||
return;
|
||||
}
|
||||
lock (abortLock) {
|
||||
if (abortable) {
|
||||
Log.WriteLine(LogLevel.Critical, "Aborting run thread.");
|
||||
runThread.Abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected Guid Uuid { get; private set; }
|
||||
|
||||
internal void RunInternal(FreeSWITCH.Native.ManagedSession session, string args)
|
||||
{
|
||||
this.Session = session;
|
||||
this.Arguments = args;
|
||||
Session.AppToAbort = this;
|
||||
try { this.Uuid = new Guid(Session.GetUuid()); }
|
||||
catch { }
|
||||
try {
|
||||
runThread = Thread.CurrentThread;
|
||||
lock (abortLock) abortable = true;
|
||||
Run();
|
||||
}
|
||||
catch (ThreadAbortException) {
|
||||
Log.WriteLine(LogLevel.Critical, "Run thread aborted.");
|
||||
Thread.ResetAbort();
|
||||
}
|
||||
finally {
|
||||
lock (abortLock) { abortable = false; }
|
||||
if (runThread.ThreadState == ThreadState.AbortRequested) {
|
||||
try { Thread.ResetAbort(); }
|
||||
catch { }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void Run();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("mod_mono_managed")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("mod_mono_managed")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2008")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("b66ea632-ec95-4c9e-9cf7-7c0805a50526")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - mod_cli
|
||||
* Copyright (C) 2008, Michael Giagnocavo <mgg@packetrino.com>
|
||||
*
|
||||
* Version: MPL 1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - mod_cli
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Michael Giagnocavo <mgg@packetrino.com>
|
||||
* Portions created by the Initial Developer are Copyright (C)
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Michael Giagnocavo <mgg@packetrino.com>
|
||||
*
|
||||
* Demo.cs -- mod_mono demo classes
|
||||
*
|
||||
*/
|
||||
|
||||
#if DEBUG
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace FreeSWITCH.Demo
|
||||
{
|
||||
public class AppDemo : AppFunction
|
||||
{
|
||||
new protected static bool Load()
|
||||
{
|
||||
Log.WriteLine(LogLevel.Info, "Inside AppDemo::Load.");
|
||||
return true;
|
||||
}
|
||||
|
||||
new protected static void Unload()
|
||||
{
|
||||
Log.WriteLine(LogLevel.Info, "Inside AppDemo::Unload.");
|
||||
}
|
||||
|
||||
protected override void Run()
|
||||
{
|
||||
Session.Answer();
|
||||
Session.DtmfReceivedFunction = (d, t) => {
|
||||
Log.WriteLine(LogLevel.Info, "Received {0} for {1}.", d, t);
|
||||
return "";
|
||||
};
|
||||
Log.WriteLine(LogLevel.Info, "Inside AppDemo.Run (args '{0}'); HookState is {1}. Now will collect digits.", Arguments, Session.HookState);
|
||||
Session.CollectDigits(5000); // Hanging up here will cause an abort and the next line won't be written
|
||||
Log.WriteLine(LogLevel.Info, "AppDemo is finishing its run and will now hang up.");
|
||||
Session.Hangup("USER_BUSY");
|
||||
}
|
||||
|
||||
void hangupHook()
|
||||
{
|
||||
Log.WriteLine(LogLevel.Debug, "AppDemo hanging up, UUID: {0}.", this.Uuid);
|
||||
}
|
||||
|
||||
protected override bool AbortOnHangup { get { return true; } }
|
||||
}
|
||||
|
||||
public class ApiDemo : ApiFunction
|
||||
{
|
||||
new protected static bool Load()
|
||||
{
|
||||
Log.WriteLine(LogLevel.Debug, "Inside ApiDemo::Load.");
|
||||
return true;
|
||||
}
|
||||
|
||||
new protected static void Unload()
|
||||
{
|
||||
Log.WriteLine(LogLevel.Debug, "Inside ApiDemo::Unload.");
|
||||
}
|
||||
|
||||
public override void ExecuteBackground(string args)
|
||||
{
|
||||
Log.WriteLine(LogLevel.Debug, "ApiDemo on a background thread #({0}), with args '{1}'.",
|
||||
System.Threading.Thread.CurrentThread.ManagedThreadId,
|
||||
args);
|
||||
}
|
||||
|
||||
public override void Execute(Native.Stream stream, Native.Event evt, string args)
|
||||
{
|
||||
stream.Write(string.Format("ApiDemo executed with args '{0}' and event type {1}.",
|
||||
args, evt == null ? "<none>" : evt.GetEventType()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - mod_cli
|
||||
* Copyright (C) 2008, Michael Giagnocavo <mgg@packetrino.com>
|
||||
*
|
||||
* Version: MPL 1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - mod_cli
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Michael Giagnocavo <mgg@packetrino.com>
|
||||
* Portions created by the Initial Developer are Copyright (C)
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Michael Giagnocavo <mgg@packetrino.com>
|
||||
*
|
||||
* Extensions.cs -- Helper extensions
|
||||
*
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace System.Linq
|
||||
{
|
||||
internal static class EnumerableExtensions
|
||||
{
|
||||
public static void ForEach<T>(this IEnumerable<T> source, Action<T> f)
|
||||
{
|
||||
foreach (var item in source) {
|
||||
f(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,260 @@
|
||||
/*
|
||||
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - mod_cli
|
||||
* Copyright (C) 2008, Michael Giagnocavo <mgg@packetrino.com>
|
||||
*
|
||||
* Version: MPL 1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - mod_cli
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Michael Giagnocavo <mgg@packetrino.com>
|
||||
* Portions created by the Initial Developer are Copyright (C)
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Michael Giagnocavo <mgg@packetrino.com>
|
||||
* David Brazier <David.Brazier@360crm.co.uk>
|
||||
*
|
||||
* Loader.cs -- mod_mono managed loader
|
||||
*
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
namespace FreeSWITCH
|
||||
{
|
||||
internal static class Loader
|
||||
{
|
||||
// Stores a list of the loaded function types so we can instantiate them as needed
|
||||
static readonly Dictionary<string, Type> functions = new Dictionary<string, Type>(StringComparer.InvariantCultureIgnoreCase);
|
||||
// Only class name. Last in wins.
|
||||
static readonly Dictionary<string, Type> shortFunctions = new Dictionary<string, Type>(StringComparer.InvariantCultureIgnoreCase);
|
||||
|
||||
#region Load/Unload
|
||||
|
||||
public static bool Load()
|
||||
{
|
||||
string managedDir = Path.Combine(Native.freeswitch.SWITCH_GLOBAL_dirs.mod_dir, "managed");
|
||||
Log.WriteLine(LogLevel.Debug, "mod_managed_lib loader is starting with directory '{0}'.", managedDir);
|
||||
if (!Directory.Exists(managedDir)) {
|
||||
Log.WriteLine(LogLevel.Error, "Managed directory not found: {0}", managedDir);
|
||||
return false;
|
||||
}
|
||||
|
||||
// This is a simple one-time loader to get things in memory
|
||||
// Some day we should allow reloading of modules or something
|
||||
loadAssemblies(managedDir)
|
||||
.SelectMany(a => a.GetExportedTypes())
|
||||
.Where(t => !t.IsAbstract)
|
||||
.Where(t => t.IsSubclassOf(typeof(AppFunction)) || t.IsSubclassOf(typeof(ApiFunction)))
|
||||
.ToList()
|
||||
.loadFunctions();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Be rather lenient in finding the Load and Unload methods
|
||||
static readonly BindingFlags methodBindingFlags =
|
||||
BindingFlags.Static | // Required
|
||||
BindingFlags.Public | BindingFlags.NonPublic | // Implementors might decide to make the load method private
|
||||
BindingFlags.IgnoreCase | // Some case insensitive languages?
|
||||
BindingFlags.FlattenHierarchy; // Allow inherited methods for hierarchies
|
||||
|
||||
static void loadFunctions(this List<Type> allTypes)
|
||||
{
|
||||
foreach (var t in allTypes) {
|
||||
try {
|
||||
if (functions.ContainsKey(t.FullName)) {
|
||||
Log.WriteLine(LogLevel.Error, "Duplicate function {0}. Skipping.", t.FullName);
|
||||
continue;
|
||||
}
|
||||
var loadMethod = t.GetMethod("Load", methodBindingFlags, null, Type.EmptyTypes, null);
|
||||
var shouldLoad = Convert.ToBoolean(loadMethod.Invoke(null, null)); // We don't require the Load method to return a bool exactly
|
||||
if (shouldLoad) {
|
||||
Log.WriteLine(LogLevel.Notice, "Function {0} loaded.", t.FullName);
|
||||
functions.Add(t.FullName, t);
|
||||
shortFunctions[t.Name] = t;
|
||||
}
|
||||
else {
|
||||
Log.WriteLine(LogLevel.Notice, "Function {0} requested not to be loaded.", t.FullName);
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
logException("Load", t.FullName, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static Assembly[] loadAssemblies(string managedDir)
|
||||
{
|
||||
// load the modules in the mod/managed directory
|
||||
Log.WriteLine(LogLevel.Notice, "loadAssemblies: {0}", managedDir);
|
||||
foreach (string s in Directory.GetFiles(managedDir, "*.dll", SearchOption.AllDirectories))
|
||||
{
|
||||
string f = Path.Combine(managedDir, s);
|
||||
try {
|
||||
System.Reflection.Assembly.LoadFile(f);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
Log.WriteLine(LogLevel.Notice, "Assembly.LoadFile failed; skipping {0} ({1})", f, ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
return AppDomain.CurrentDomain.GetAssemblies(); // Includes anything else already loaded
|
||||
}
|
||||
|
||||
public static void Unload()
|
||||
{
|
||||
Log.WriteLine(LogLevel.Debug, "mod_managed_lib Loader is unloading.");
|
||||
foreach (var t in functions.Values) {
|
||||
try {
|
||||
var unloadMethod = t.GetMethod("Unload", methodBindingFlags, null, Type.EmptyTypes, null);
|
||||
unloadMethod.Invoke(null, null);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
logException("Unload", t.FullName, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Execution
|
||||
|
||||
static Type getFunctionType<TFunction>(string fullName)
|
||||
{
|
||||
Type t;
|
||||
if (!functions.TryGetValue(fullName, out t) || !t.IsSubclassOf(typeof(TFunction))) {
|
||||
if (!shortFunctions.TryGetValue(fullName, out t) || !t.IsSubclassOf(typeof(TFunction))) {
|
||||
Log.WriteLine(LogLevel.Error, "Could not find function {0}.", fullName);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
static readonly char[] spaceArray = new[] { ' ' };
|
||||
/// <summary>Returns a string couple containing the module name and arguments</summary>
|
||||
static string[] parseCommand(string command)
|
||||
{
|
||||
if (string.IsNullOrEmpty(command)) {
|
||||
Log.WriteLine(LogLevel.Error, "No arguments supplied.");
|
||||
return null;
|
||||
}
|
||||
var args = command.Split(spaceArray, 2, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (args.Length == 0 || string.IsNullOrEmpty(args[0]) || string.IsNullOrEmpty(args[0].Trim())) {
|
||||
Log.WriteLine(LogLevel.Error, "Module name not supplied.");
|
||||
return null;
|
||||
}
|
||||
if (args.Length == 1) {
|
||||
return new[] { args[0], "" };
|
||||
}
|
||||
else {
|
||||
return args;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool ExecuteBackground(string command)
|
||||
{
|
||||
var parsed = parseCommand(command);
|
||||
if (parsed == null) return false;
|
||||
var fullName = parsed[0];
|
||||
var args = parsed[1];
|
||||
|
||||
var fType = getFunctionType<ApiFunction>(fullName);
|
||||
if (fType == null) return false;
|
||||
|
||||
new System.Threading.Thread(() => {
|
||||
try {
|
||||
var f = (ApiFunction)Activator.CreateInstance(fType);
|
||||
f.ExecuteBackground(args);
|
||||
Log.WriteLine(LogLevel.Debug, "ExecuteBackground in {0} completed.", fullName);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
logException("ExecuteBackground", fullName, ex);
|
||||
}
|
||||
}).Start();
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool Execute(string command, IntPtr streamHandle, IntPtr eventHandle)
|
||||
{
|
||||
System.Diagnostics.Debug.Assert(streamHandle != IntPtr.Zero, "streamHandle is null.");
|
||||
var parsed = parseCommand(command);
|
||||
if (parsed == null) return false;
|
||||
var fullName = parsed[0];
|
||||
var args = parsed[1];
|
||||
|
||||
var fType = getFunctionType<ApiFunction>(fullName);
|
||||
if (fType == null) return false;
|
||||
|
||||
using (var stream = new Native.Stream(new Native.switch_stream_handle(streamHandle, false)))
|
||||
using (var evt = eventHandle == IntPtr.Zero ? null : new Native.Event(new Native.switch_event(eventHandle, false), 0)) {
|
||||
|
||||
try {
|
||||
var f = (ApiFunction)Activator.CreateInstance(fType);
|
||||
f.Execute(stream, evt, args);
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex) {
|
||||
logException("Execute", fullName, ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Runs an application function.</summary>
|
||||
public static bool Run(string command, IntPtr sessionHandle)
|
||||
{
|
||||
Log.WriteLine(LogLevel.Debug, "mod_mono attempting to run application '{0}'.", command);
|
||||
System.Diagnostics.Debug.Assert(sessionHandle != IntPtr.Zero, "sessionHandle is null.");
|
||||
var parsed = parseCommand(command);
|
||||
if (parsed == null) return false;
|
||||
var fullName = parsed[0];
|
||||
var args = parsed[1];
|
||||
|
||||
var fType = getFunctionType<AppFunction>(fullName);
|
||||
if (fType == null) return false;
|
||||
|
||||
using (var session = new Native.ManagedSession(new Native.SWIGTYPE_p_switch_core_session(sessionHandle, false))) {
|
||||
session.Initialize();
|
||||
session.SetAutoHangup(false);
|
||||
try {
|
||||
var f = (AppFunction)Activator.CreateInstance(fType);
|
||||
f.RunInternal(session, args);
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex) {
|
||||
logException("Run", fullName, ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void logException(string action, string moduleName, Exception ex)
|
||||
{
|
||||
Log.WriteLine(LogLevel.Error, "{0} exception in {1}: {2}", action, moduleName, ex.Message);
|
||||
Log.WriteLine(LogLevel.Debug, "{0} exception: {1}", moduleName, ex.ToString());
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - mod_cli
|
||||
* Copyright (C) 2008, Michael Giagnocavo <mgg@packetrino.com>
|
||||
*
|
||||
* Version: MPL 1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - mod_cli
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Michael Giagnocavo <mgg@packetrino.com>
|
||||
* Portions created by the Initial Developer are Copyright (C)
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Michael Giagnocavo <mgg@packetrino.com>
|
||||
*
|
||||
* Log.cs -- Log wrappers
|
||||
*
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace FreeSWITCH
|
||||
{
|
||||
public static class Log
|
||||
{
|
||||
public static void Write(LogLevel level, string message)
|
||||
{
|
||||
Native.freeswitch.console_log(level.ToLogString(), message);
|
||||
}
|
||||
public static void Write(LogLevel level, string format, params object[] args)
|
||||
{
|
||||
Native.freeswitch.console_log(level.ToLogString(), string.Format(format, args));
|
||||
}
|
||||
public static void WriteLine(LogLevel level, string message)
|
||||
{
|
||||
Native.freeswitch.console_log(level.ToLogString(), message + Environment.NewLine);
|
||||
}
|
||||
public static void WriteLine(LogLevel level, string format, params object[] args)
|
||||
{
|
||||
Native.freeswitch.console_log(level.ToLogString(), string.Format(format, args) + Environment.NewLine);
|
||||
}
|
||||
|
||||
static string ToLogString(this LogLevel level)
|
||||
{
|
||||
switch (level) {
|
||||
case LogLevel.Alert: return "ALERT";
|
||||
case LogLevel.Critical: return "CRIT";
|
||||
case LogLevel.Debug: return "DEBUG";
|
||||
case LogLevel.Error: return "ERR";
|
||||
case LogLevel.Info: return "INFO";
|
||||
case LogLevel.Notice: return "NOTICE";
|
||||
case LogLevel.Warning: return "WARNING";
|
||||
default:
|
||||
System.Diagnostics.Debug.Fail("Invalid LogLevel: " + level.ToString() + " (" + (int)level+ ").");
|
||||
return "INFO";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*switch_log.c:
|
||||
tatic const char *LEVELS[] = {
|
||||
"CONSOLE",
|
||||
"ALERT",
|
||||
"CRIT",
|
||||
"ERR",
|
||||
"WARNING",
|
||||
"NOTICE",
|
||||
"INFO",
|
||||
"DEBUG",
|
||||
NULL
|
||||
};*/
|
||||
public enum LogLevel
|
||||
{
|
||||
Debug,
|
||||
Info,
|
||||
Error,
|
||||
Critical,
|
||||
Alert,
|
||||
Warning,
|
||||
Notice,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
all: Debug Debug/mod_managed_lib.dll
|
||||
|
||||
clean:
|
||||
rm -fr Debug
|
||||
|
||||
Debug:
|
||||
mkdir Debug
|
||||
|
||||
Debug/mod_managed_lib.dll: Loader.cs ManagedSession.cs ApiFunction.cs AppFunction.cs Extensions.cs Log.cs Demo.cs swig.cs
|
||||
gmcs -target:library -out:Debug/mod_managed_lib.dll -d:DEBUG Loader.cs ManagedSession.cs ApiFunction.cs AppFunction.cs Extensions.cs Log.cs Demo.cs swig.cs
|
||||
|
||||
install: Debug/mod_managed_lib.dll
|
||||
install Debug/mod_managed_lib.dll /usr/local/freeswitch/mod
|
||||
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - mod_cli
|
||||
* Copyright (C) 2008, Michael Giagnocavo <mgg@packetrino.com>
|
||||
*
|
||||
* Version: MPL 1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - mod_cli
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Michael Giagnocavo <mgg@packetrino.com>
|
||||
* Portions created by the Initial Developer are Copyright (C)
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Michael Giagnocavo <mgg@packetrino.com>
|
||||
*
|
||||
* ManagedSession.cs -- ManagedSession additional functions
|
||||
*
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace FreeSWITCH.Native
|
||||
{
|
||||
// switch_status_t ManagedSession::run_dtmf_callback(void *input, switch_input_type_t itype)
|
||||
// But, process_callback_result is used to turn a string into a switch_status_t
|
||||
using DtmfCallback = Func<IntPtr, Native.switch_input_type_t, string>;
|
||||
public partial class ManagedSession
|
||||
{
|
||||
// SWITCH_DECLARE(void) InitManagedSession(ManagedSession *session, MonoObject *dtmfDelegate, MonoObject *hangupDelegate)
|
||||
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)]
|
||||
static extern void InitManagedSession(IntPtr sessionPtr, DtmfCallback dtmfDelegate, Action hangupDelegate);
|
||||
|
||||
/// <summary>Initializes the native ManagedSession. Must be called after Originate.</summary>
|
||||
public void Initialize()
|
||||
{
|
||||
InitManagedSession(ManagedSession.getCPtr(this).Handle, inputCallback, hangupCallback);
|
||||
}
|
||||
|
||||
/// <summary>Function to execute when this session hangs up.</summary>
|
||||
public Action HangupFunction { get; set; }
|
||||
|
||||
/// <summary>Sets the application that should have it's run thread aborted (if enabled) when this session is hungup.</summary>
|
||||
internal AppFunction AppToAbort { get; set; }
|
||||
|
||||
void hangupCallback()
|
||||
{
|
||||
Log.WriteLine(LogLevel.Debug, "AppFunction is in hangupCallback.");
|
||||
try {
|
||||
if (AppToAbort != null) AppToAbort.AbortRun();
|
||||
var f = HangupFunction;
|
||||
if (f != null) f();
|
||||
}
|
||||
catch (Exception ex) {
|
||||
Log.WriteLine(LogLevel.Warning, "Exception in hangupCallback: {0}", ex.ToString());
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public Func<Char, TimeSpan, string> DtmfReceivedFunction { get; set; }
|
||||
|
||||
public Func<Native.Event, string> EventReceivedFunction { get; set; }
|
||||
|
||||
string inputCallback(IntPtr input, Native.switch_input_type_t inputType)
|
||||
{
|
||||
switch (inputType) {
|
||||
case FreeSWITCH.Native.switch_input_type_t.SWITCH_INPUT_TYPE_DTMF:
|
||||
using (var dtmf = new Native.switch_dtmf_t(input, false)) {
|
||||
return dtmfCallback(dtmf);
|
||||
}
|
||||
case FreeSWITCH.Native.switch_input_type_t.SWITCH_INPUT_TYPE_EVENT:
|
||||
using (var swevt = new Native.switch_event(input, false)) {
|
||||
return eventCallback(swevt);
|
||||
}
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
string dtmfCallback(Native.switch_dtmf_t dtmf)
|
||||
{
|
||||
var f = DtmfReceivedFunction;
|
||||
return f == null ?
|
||||
"-ERR No DtmfReceivedFunction set." :
|
||||
f(((char)(byte)dtmf.digit), TimeSpan.FromMilliseconds(dtmf.duration));
|
||||
}
|
||||
|
||||
string eventCallback(Native.switch_event swevt)
|
||||
{
|
||||
using (var evt = new FreeSWITCH.Native.Event(swevt, 0)) {
|
||||
var f = EventReceivedFunction;
|
||||
return f == null ?
|
||||
"-ERR No EventReceivedFunction set." :
|
||||
f(evt);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>9.0.30729</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{834E2B2F-5483-4B80-8FE3-FE48FF76E5C0}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>mod_managed_lib</RootNamespace>
|
||||
<AssemblyName>mod_managed_lib</AssemblyName>
|
||||
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<StartupObject>
|
||||
</StartupObject>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>..\..\..\..\..\Debug\mod\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>..\..\..\..\..\Release\mod\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core">
|
||||
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.Linq">
|
||||
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
||||
</Reference>
|
||||
<Reference Include="System.Data.DataSetExtensions">
|
||||
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
||||
</Reference>
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="AssemblyInfo.cs" />
|
||||
<Compile Include="ManagedSession.cs" />
|
||||
<Compile Include="Loader.cs" />
|
||||
<Compile Include="Extensions.cs" />
|
||||
<Compile Include="Log.cs" />
|
||||
<Compile Include="ApiFunction.cs" />
|
||||
<Compile Include="AppFunction.cs" />
|
||||
<Compile Include="Demo.cs" />
|
||||
<Compile Include="swig.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
File diff suppressed because it is too large.
Load diff
Reference in new issue
Block a user