Large code cleanup, see change log

This commit is contained in:
skrusty 2015-01-03 15:37:29 +00:00
parent 19d1fdf418
commit ba42c2f06f
141 changed files with 7393 additions and 8578 deletions

View file

@ -1,6 +1,6 @@
using System;
using System.Text.RegularExpressions;
using System.Globalization;
using System.Text.RegularExpressions;
namespace AsterNET
{
@ -10,18 +10,24 @@ namespace AsterNET
/// <summary> The hostname to use if none is provided.</summary>
public const string DEFAULT_HOSTNAME = "localhost";
/// <summary> The port to use if none is provided.</summary>
public const int DEFAULT_PORT = 5038;
/// <summary>Line separator</summary>
public const string LINE_SEPARATOR = "\r\n";
public static Regex ASTERISK_VERSION = new Regex("^Asterisk\\s+([0-9]+.[0-9]+.[0-9]+).*", RegexOptions.Compiled | RegexOptions.IgnoreCase);
public static Regex ASTERISK_VERSION = new Regex("^Asterisk\\s+([0-9]+.[0-9]+.[0-9]+).*",
RegexOptions.Compiled | RegexOptions.IgnoreCase);
public static Regex SHOW_VERSION_FILES_PATTERN = new Regex("^([\\S]+)\\s+Revision: ([0-9\\.]+)");
public static char[] RESPONSE_KEY_VALUE_SEPARATOR = new char[] { ':' };
public static char[] MINUS_SEPARATOR = new char[] { '-' };
public static char[] RESPONSE_KEY_VALUE_SEPARATOR = {':'};
public static char[] MINUS_SEPARATOR = {'-'};
public static char INTERNAL_ACTION_ID_DELIMITER = '#';
/// <summary> Variables delimiter </summary>
public static char[] VAR_DELIMITER = new char[] { '|' };
public static char[] VAR_DELIMITER = {'|'};
public static IFormatProvider CultureInfoEn = new CultureInfo("en-US", false);
#endregion
@ -30,8 +36,10 @@ namespace AsterNET
/// <summary> The default AGI bind port. </summary>
public const int AGI_BIND_PORT = 4573;
/// <summary> The default AGI thread pool size. </summary>
public const int AGI_POOL_SIZE = 10;
/// <summary> The default AGI bind address. </summary>
public const string AGI_BIND_ADDRESS = "0.0.0.0";
@ -44,7 +52,10 @@ namespace AsterNET
public static Regex AGI_STATUS_PATTERN = new Regex("^(\\d{3})[ -]", RegexOptions.Compiled);
public static Regex AGI_RESULT_PATTERN = new Regex("^200 result= *(\\S+)", RegexOptions.Compiled);
public static Regex AGI_PARENTHESIS_PATTERN = new Regex("^200 result=\\S* +\\((.*)\\)", RegexOptions.Compiled);
public static Regex AGI_ADDITIONAL_ATTRIBUTES_PATTERN = new Regex("^200 result=\\S* +(\\(.*\\) )?(.+)$", RegexOptions.Compiled);
public static Regex AGI_ADDITIONAL_ATTRIBUTES_PATTERN = new Regex("^200 result=\\S* +(\\(.*\\) )?(.+)$",
RegexOptions.Compiled);
public static Regex AGI_ADDITIONAL_ATTRIBUTE_PATTERN = new Regex("(\\S+)=(\\S+)", RegexOptions.Compiled);
public static Regex AGI_SYNOPSIS_PATTERN = new Regex("^\\s*Usage:\\s*(.*)\\s*$", RegexOptions.Compiled);
public static Regex AGI_SCRIPT_PATTERN = new Regex("^([^\\?]*)\\?(.*)$");

View file

@ -1,3 +1,6 @@
using AsterNET.FastAGI.Command;
using AsterNET.IO;
namespace AsterNET.FastAGI
{
/// <summary>
@ -5,30 +8,30 @@ namespace AsterNET.FastAGI
/// </summary>
public class AGIChannel
{
private AGIWriter agiWriter;
private AGIReader agiReader;
private readonly bool _SC511_CAUSES_EXCEPTION;
private readonly bool _SCHANGUP_CAUSES_EXCEPTION;
private readonly AGIReader agiReader;
private readonly AGIWriter agiWriter;
private AGIReply agiReply;
private bool _SC511_CAUSES_EXCEPTION = false;
private bool _SCHANGUP_CAUSES_EXCEPTION = false;
public AGIChannel(IO.SocketConnection socket, bool SC511_CAUSES_EXCEPTION, bool SCHANGUP_CAUSES_EXCEPTION)
public AGIChannel(SocketConnection socket, bool SC511_CAUSES_EXCEPTION, bool SCHANGUP_CAUSES_EXCEPTION)
{
this.agiWriter = new AGIWriter(socket);
this.agiReader = new AGIReader(socket);
agiWriter = new AGIWriter(socket);
agiReader = new AGIReader(socket);
this._SC511_CAUSES_EXCEPTION = SC511_CAUSES_EXCEPTION;
this._SCHANGUP_CAUSES_EXCEPTION = SCHANGUP_CAUSES_EXCEPTION;
_SC511_CAUSES_EXCEPTION = SC511_CAUSES_EXCEPTION;
_SCHANGUP_CAUSES_EXCEPTION = SCHANGUP_CAUSES_EXCEPTION;
}
public AGIChannel(AGIWriter agiWriter, AGIReader agiReader, bool SC511_CAUSES_EXCEPTION, bool SCHANGUP_CAUSES_EXCEPTION)
public AGIChannel(AGIWriter agiWriter, AGIReader agiReader, bool SC511_CAUSES_EXCEPTION,
bool SCHANGUP_CAUSES_EXCEPTION)
{
this.agiWriter = agiWriter;
this.agiReader = agiReader;
this._SC511_CAUSES_EXCEPTION = SC511_CAUSES_EXCEPTION;
this._SCHANGUP_CAUSES_EXCEPTION = SCHANGUP_CAUSES_EXCEPTION;
_SC511_CAUSES_EXCEPTION = SC511_CAUSES_EXCEPTION;
_SCHANGUP_CAUSES_EXCEPTION = SCHANGUP_CAUSES_EXCEPTION;
}
/// <summary>
@ -39,18 +42,18 @@ namespace AsterNET.FastAGI
get { return agiReply; }
}
public AGIReply SendCommand(Command.AGICommand command)
public AGIReply SendCommand(AGICommand command)
{
agiWriter.SendCommand(command);
agiReply = agiReader.ReadReply();
int status = agiReply.GetStatus();
if (status == (int)AGIReplyStatuses.SC_INVALID_OR_UNKNOWN_COMMAND)
if (status == (int) AGIReplyStatuses.SC_INVALID_OR_UNKNOWN_COMMAND)
throw new InvalidOrUnknownCommandException(command.BuildCommand());
else if (status == (int)AGIReplyStatuses.SC_INVALID_COMMAND_SYNTAX)
if (status == (int) AGIReplyStatuses.SC_INVALID_COMMAND_SYNTAX)
throw new InvalidCommandSyntaxException(agiReply.GetSynopsis(), agiReply.GetUsage());
else if (status == (int)AGIReplyStatuses.SC_DEAD_CHANNEL && _SC511_CAUSES_EXCEPTION)
if (status == (int) AGIReplyStatuses.SC_DEAD_CHANNEL && _SC511_CAUSES_EXCEPTION)
throw new AGIHangupException();
else if ((status == 0) && agiReply.FirstLine == "HANGUP" && _SCHANGUP_CAUSES_EXCEPTION)
if ((status == 0) && agiReply.FirstLine == "HANGUP" && _SCHANGUP_CAUSES_EXCEPTION)
throw new AGIHangupException();
return agiReply;
}

View file

@ -1,65 +1,69 @@
using System;
using System.IO;
using System.Threading;
using AsterNET.FastAGI.Command;
using AsterNET.IO;
namespace AsterNET.FastAGI
{
/// <summary>
/// An AGIConnectionHandler is created and run by the AGIServer whenever a new
/// socket connection from an Asterisk Server is received.<br/>
/// socket connection from an Asterisk Server is received.<br />
/// It reads the request using an AGIReader and runs the AGIScript configured to
/// handle this type of request. Finally it closes the socket connection.
/// </summary>
public class AGIConnectionHandler
{
#if LOGGER
private Logger logger = Logger.Instance();
private readonly Logger logger = Logger.Instance();
#endif
private static readonly LocalDataStoreSlot channel = Thread.AllocateDataSlot();
private IO.SocketConnection socket;
private IMappingStrategy mappingStrategy;
private bool _SC511_CAUSES_EXCEPTION = false;
private bool _SCHANGUP_CAUSES_EXCEPTION = false;
private static readonly LocalDataStoreSlot _channel = Thread.AllocateDataSlot();
private readonly SocketConnection socket;
private readonly IMappingStrategy mappingStrategy;
private readonly bool _SC511_CAUSES_EXCEPTION;
private readonly bool _SCHANGUP_CAUSES_EXCEPTION;
#region Channel
/// <summary>
/// Returns the AGIChannel associated with the current thread.
/// </summary>
/// <returns>the AGIChannel associated with the current thread or <code>null</code> if none is associated.</returns>
internal static AGIChannel Channel
{
get
{
return (AGIChannel) Thread.GetData(AGIConnectionHandler.channel);
}
get { return (AGIChannel) Thread.GetData(_channel); }
}
#endregion
#region AGIConnectionHandler(socket, mappingStrategy)
/// <summary>
/// Creates a new AGIConnectionHandler to handle the given socket connection.
/// </summary>
/// <param name="socket">the socket connection to handle.</param>
/// <param name="mappingStrategy">the strategy to use to determine which script to run.</param>
public AGIConnectionHandler(IO.SocketConnection socket, IMappingStrategy mappingStrategy, bool SC511_CAUSES_EXCEPTION, bool SCHANGUP_CAUSES_EXCEPTION)
public AGIConnectionHandler(SocketConnection socket, IMappingStrategy mappingStrategy,
bool SC511_CAUSES_EXCEPTION, bool SCHANGUP_CAUSES_EXCEPTION)
{
this.socket = socket;
this.mappingStrategy = mappingStrategy;
this._SC511_CAUSES_EXCEPTION = SC511_CAUSES_EXCEPTION;
this._SCHANGUP_CAUSES_EXCEPTION = SCHANGUP_CAUSES_EXCEPTION;
_SC511_CAUSES_EXCEPTION = SC511_CAUSES_EXCEPTION;
_SCHANGUP_CAUSES_EXCEPTION = SCHANGUP_CAUSES_EXCEPTION;
}
#endregion
public void Run()
{
try
{
AGIReader reader = new AGIReader(socket);
AGIWriter writer = new AGIWriter(socket);
var reader = new AGIReader(socket);
var writer = new AGIWriter(socket);
AGIRequest request = reader.ReadRequest();
AGIChannel channel = new AGIChannel(writer, reader, this._SC511_CAUSES_EXCEPTION, this._SCHANGUP_CAUSES_EXCEPTION);
var channel = new AGIChannel(writer, reader, _SC511_CAUSES_EXCEPTION, _SCHANGUP_CAUSES_EXCEPTION);
AGIScript script = mappingStrategy.DetermineScript(request);
Thread.SetData(AGIConnectionHandler.channel, channel);
Thread.SetData(_channel, channel);
if (script != null)
{
@ -73,9 +77,9 @@ namespace AsterNET.FastAGI
}
else
{
string error;
error = "No script configured for URL '" + request.RequestURL + "' (script '" + request.Script + "')";
channel.SendCommand(new Command.VerboseCommand(error, 1));
var error = "No script configured for URL '" + request.RequestURL + "' (script '" + request.Script +
"')";
channel.SendCommand(new VerboseCommand(error, 1));
#if LOGGER
logger.Error(error);
#endif
@ -104,13 +108,13 @@ namespace AsterNET.FastAGI
#endif
}
Thread.SetData(AGIConnectionHandler.channel, null);
Thread.SetData(_channel, null);
try
{
socket.Close();
}
#if LOGGER
catch(IOException ex)
catch (IOException ex)
{
logger.Error("Error on close socket", ex);
}

View file

@ -1,30 +1,30 @@
using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using AsterNET.IO;
namespace AsterNET.FastAGI
{
public class AGIReader
{
#if LOGGER
private Logger logger = Logger.Instance();
private readonly Logger logger = Logger.Instance();
#endif
private IO.SocketConnection socket;
public AGIReader(IO.SocketConnection socket)
private readonly SocketConnection socket;
public AGIReader(SocketConnection socket)
{
this.socket = socket;
}
public AGIRequest ReadRequest()
{
string line;
List<string> lines = new List<string>();
var lines = new List<string>();
try
{
#if LOGGER
logger.Info("AGIReader.ReadRequest():");
#endif
string line;
while ((line = socket.ReadLine()) != null)
{
if (line.Length == 0)
@ -40,12 +40,13 @@ namespace AsterNET.FastAGI
throw new AGINetworkException("Unable to read request from Asterisk: " + ex.Message, ex);
}
AGIRequest request = new AGIRequest(lines);
request.LocalAddress = socket.LocalAddress;
request.LocalPort = socket.LocalPort;
request.RemoteAddress = socket.RemoteAddress;
request.RemotePort = socket.RemotePort;
var request = new AGIRequest(lines)
{
LocalAddress = socket.LocalAddress,
LocalPort = socket.LocalPort,
RemoteAddress = socket.RemoteAddress,
RemotePort = socket.RemotePort
};
return request;
}
@ -53,9 +54,9 @@ namespace AsterNET.FastAGI
public AGIReply ReadReply()
{
string line;
string badSyntax = ((int)AGIReplyStatuses.SC_INVALID_COMMAND_SYNTAX).ToString();
var badSyntax = ((int) AGIReplyStatuses.SC_INVALID_COMMAND_SYNTAX).ToString();
List<string> lines = new List<string>();
var lines = new List<string>();
try
{
line = socket.ReadLine();

View file

@ -1,38 +1,44 @@
using System;
using System.Text;
using System.Text.RegularExpressions;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
namespace AsterNET.FastAGI
{
#region Enum - AGIReplyStatuses
public enum AGIReplyStatuses
{
/// <summary>
/// Status code (200) indicating Asterisk successfully processed the AGICommand.
/// </summary>
SC_SUCCESS = 200,
/// <summary>
/// Status code (510) indicating Asterisk was unable to process the
/// AGICommand because there is no command with the given name available.
/// </summary>
SC_INVALID_OR_UNKNOWN_COMMAND = 510,
/// <summary>
/// Status code (511) indicating Asterisk was unable to process the
/// AGICommand because the channel is dead.
/// </summary>
SC_DEAD_CHANNEL = 511,
/// <summary>
/// Status code (520) indicating Asterisk was unable to process the
/// AGICommand because the syntax used was not correct. This is most likely
/// due to missing required parameters or additional parameters sent that are
/// not understood.<br/>
/// not understood.<br />
/// Ensure proper quoting of the parameters when you receive this status
/// code.
/// </summary>
SC_INVALID_COMMAND_SYNTAX = 520
}
#endregion
/// <summary>
@ -41,35 +47,51 @@ namespace AsterNET.FastAGI
public class AGIReply
{
#region Variables
private Match matcher;
private List<string> lines;
private string firstLine;
/// <summary> The result, that is the part directly following the "result=" string.</summary>
private string result;
/// <summary> The status code.</summary>
private int status;
private readonly string firstLine;
private readonly List<string> lines;
/// <summary>Additional attributes contained in this reply, for example endpos.</summary>
private Dictionary<string, string> attributes;
private bool attributesCreated;
/// <summary> The contents of the parenthesis.</summary>
private string extra;
private bool extraCreated;
private Match matcher;
/// <summary> The result, that is the part directly following the "result=" string.</summary>
private string result;
private bool resultCreated;
/// <summary> The status code.</summary>
private int status;
private bool statusCreated;
/// <summary> In case of status == 520 (invalid command syntax) this attribute contains the synopsis of the command.</summary>
private string synopsis;
private bool synopsisCreated;
/// <summary> In case of status == 520 (invalid command syntax) this attribute contains the usage of the command.</summary>
private string usage;
private bool extraCreated;
private bool synopsisCreated;
private bool attributesCreated;
private bool resultCreated;
private bool statusCreated;
#endregion
#region Constructor - AGIReply()
public AGIReply()
{
}
#endregion
#region Constructor - AGIReply(lines)
public AGIReply(List<string> lines)
{
this.lines = lines;
@ -77,25 +99,33 @@ namespace AsterNET.FastAGI
{
firstLine = lines[0];
}
catch { }
catch
{
}
}
#endregion
#region FirstLine
public string FirstLine
{
get { return firstLine; }
}
#endregion
#region Lines
public IList Lines
{
get { return lines; }
}
#endregion
#region ResultCode
/// <summary>
/// Returns the return code (the result as int).
/// </summary>
@ -118,9 +148,11 @@ namespace AsterNET.FastAGI
}
}
}
#endregion
#region ResultCodeAsChar
/// <summary>
/// Returns the return code as character.
/// </summary>
@ -129,18 +161,19 @@ namespace AsterNET.FastAGI
{
get
{
int resultCode;
resultCode = ResultCode;
int resultCode = ResultCode;
if (resultCode < 0)
return (char)(0x0);
return (char)resultCode;
return (char) (0x0);
return (char) resultCode;
}
}
#endregion
#region Extra
/// <summary>
/// Returns the text in parenthesis contained in this reply.<br/>
/// Returns the text in parenthesis contained in this reply.<br />
/// The meaning of this property depends on the command sent. Sometimes it
/// contains a flag like "timeout" or "hangup" or - in case of the
/// GetVariableCommand - the value of the variable.
@ -150,7 +183,7 @@ namespace AsterNET.FastAGI
{
get
{
if (GetStatus() != (int)AGIReplyStatuses.SC_SUCCESS)
if (GetStatus() != (int) AGIReplyStatuses.SC_SUCCESS)
return null;
if (extraCreated)
@ -164,9 +197,11 @@ namespace AsterNET.FastAGI
return extra;
}
}
#endregion
#region GetResult()
/// <summary>
/// Returns the result, that is the part directly following the "result=" string.
/// </summary>
@ -183,15 +218,17 @@ namespace AsterNET.FastAGI
resultCreated = true;
return result;
}
#endregion
#region GetStatus()
/// <summary>
/// Returns the status code.<br/>
/// Supported status codes are:<br/>
/// 200 Success<br/>
/// 510 Invalid or unknown command<br/>
/// 520 Invalid command syntax<br/>
/// Returns the status code.<br />
/// Supported status codes are:<br />
/// 200 Success<br />
/// 510 Invalid or unknown command<br />
/// 520 Invalid command syntax<br />
/// </summary>
/// <returns>the status code.</returns>
public int GetStatus()
@ -204,11 +241,13 @@ namespace AsterNET.FastAGI
statusCreated = true;
return status;
}
#endregion
#region GetAttribute(name)
/// <summary>
/// Returns an additional attribute contained in the reply.<br/>
/// Returns an additional attribute contained in the reply.<br />
/// For example the reply to the StreamFileCommand contains an additional
/// endpos attribute indicating the frame where the playback was stopped.
/// This can be retrieved by calling getAttribute("endpos") on the corresponding reply.
@ -217,7 +256,7 @@ namespace AsterNET.FastAGI
/// <returns>the value of the attribute or <code>null</code> if it is not set.</returns>
public string GetAttribute(string name)
{
if (GetStatus() != (int)AGIReplyStatuses.SC_SUCCESS)
if (GetStatus() != (int) AGIReplyStatuses.SC_SUCCESS)
return null;
if ("result".ToUpper().Equals(name.ToUpper()))
@ -231,7 +270,7 @@ namespace AsterNET.FastAGI
string s;
Match attributeMatcher;
attributes = new Dictionary<string,string>();
attributes = new Dictionary<string, string>();
s = matcher.Groups[2].Value;
attributeMatcher = Common.AGI_ADDITIONAL_ATTRIBUTE_PATTERN.Match(s);
while (attributeMatcher.Success)
@ -250,11 +289,13 @@ namespace AsterNET.FastAGI
if (attributes == null || (attributes.Count == 0))
return null;
return (string)attributes[name.ToLower(Helper.CultureInfo)];
return attributes[name.ToLower(Helper.CultureInfo)];
}
#endregion
#region GetSynopsis()
/// <summary>
/// Returns the synopsis of the command sent if Asterisk expected a different
/// syntax (getStatus() == SC_INVALID_COMMAND_SYNTAX).
@ -262,7 +303,7 @@ namespace AsterNET.FastAGI
/// <returns>the synopsis of the command sent, <code>null</code> if there were no syntax errors.</returns>
public string GetSynopsis()
{
if (GetStatus() != (int)AGIReplyStatuses.SC_INVALID_COMMAND_SYNTAX)
if (GetStatus() != (int) AGIReplyStatuses.SC_INVALID_COMMAND_SYNTAX)
return null;
if (!synopsisCreated)
@ -272,18 +313,18 @@ namespace AsterNET.FastAGI
string secondLine;
Match synopsisMatcher;
secondLine = ((string)lines[1]);
secondLine = lines[1];
synopsisMatcher = Common.AGI_SYNOPSIS_PATTERN.Match(secondLine);
if (synopsisMatcher.Success)
synopsis = synopsisMatcher.Groups[1].Value;
}
synopsisCreated = true;
StringBuilder sbUsage = new StringBuilder();
var sbUsage = new StringBuilder();
string line;
for (int i = 2; i < lines.Count; i++)
{
line = ((string)lines[i]);
line = lines[i];
if (line == Common.AGI_END_OF_PROPER_USAGE)
break;
sbUsage.Append(line.Trim());
@ -293,9 +334,11 @@ namespace AsterNET.FastAGI
}
return synopsis;
}
#endregion
#region GetUsage()
/// <summary>
/// Returns the usage of the command sent if Asterisk expected a different
/// syntax (getStatus() == SC_INVALID_COMMAND_SYNTAX).
@ -308,13 +351,16 @@ namespace AsterNET.FastAGI
{
return usage;
}
#endregion
#region ToString()
public override string ToString()
{
return Helper.ToString(this);
}
#endregion
}
}

View file

@ -1,11 +1,9 @@
using System;
using System.IO;
using System.Web;
using System.Text;
using System.Text.RegularExpressions;
using System.Collections;
using System.Net;
using System.Collections.Generic;
using System.Net;
using System.Text.RegularExpressions;
using System.Web;
namespace AsterNET.FastAGI
{
@ -15,11 +13,12 @@ namespace AsterNET.FastAGI
public class AGIRequest
{
#region Variables
#if LOGGER
private Logger logger = Logger.Instance();
#endif
private string rawCallerId;
private Dictionary<string, string> request;
private readonly Dictionary<string, string> request;
/// <summary> A map assigning the values of a parameter (an array of Strings) to the name of the parameter.</summary>
private Dictionary<string, List<string>> parameterMap;
@ -27,13 +26,11 @@ namespace AsterNET.FastAGI
private string parameters;
private string script;
private bool callerIdCreated;
private IPAddress localAddress;
private int localPort;
private IPAddress remoteAddress;
private int remotePort;
#endregion
#region Constructor - AGIRequest(ICollection environment)
/// <summary>
/// Creates a new AGIRequest.
/// </summary>
@ -44,93 +41,108 @@ namespace AsterNET.FastAGI
throw new ArgumentException("Environment must not be null.");
request = buildMap(environment);
}
#endregion
#region Request
public IDictionary Request
{
get { return request; }
}
#endregion
#region RequestURL
/// <summary>
/// Returns the full URL of the request in the form agi://host[:port][/script].
/// </summary>
public string RequestURL
{
get { return (string) request["request"]; }
get { return request["request"]; }
}
#endregion
#region Channel
/// <summary>
/// Returns the name of the channel.
/// </summary>
/// <returns>the name of the channel.</returns>
public string Channel
{
get { return (string) request["channel"]; }
get { return request["channel"]; }
}
#endregion
#region UniqueId
/// <summary>
/// Returns the unqiue id of the channel.
/// </summary>
/// <returns>the unqiue id of the channel.</returns>
public string UniqueId
{
get { return (string) request["uniqueid"]; }
get { return request["uniqueid"]; }
}
#endregion
#region Type
/// <summary>
/// Returns the type of the channel, for example "SIP".
/// </summary>
/// <returns>the type of the channel, for example "SIP".</returns>
public string Type
{
get { return (string) request["type"]; }
get { return request["type"]; }
}
#endregion
#region Language
/// <summary>
/// Returns the language, for example "en".
/// </summary>
public string Language
{
get { return (string) request["language"]; }
get { return request["language"]; }
}
#endregion
#region CallerId
public string CallerId
{
get
{
string callerIdName = (string)(request["calleridname"]);
string callerId = (string)(request["callerid"]);
string callerIdName = request["calleridname"];
string callerId = request["callerid"];
if (callerIdName != null)
{
if (callerId == null || callerId.ToLower(Helper.CultureInfo) == "unknown")
return null;
return callerId;
}
else // Asterisk 1.0
return callerId10();
}
}
#endregion
#region CallerIdName
public string CallerIdName
{
get
{
string callerIdName = (string)(request["calleridname"]);
string callerIdName = request["calleridname"];
if (callerIdName != null)
{
// Asterisk 1.2
@ -138,13 +150,14 @@ namespace AsterNET.FastAGI
return null;
return callerIdName;
}
else // Asterisk 1.0
return callerIdName10();
}
}
#endregion
#region Asterisk 1.0 CallerID and CallerIdName
private string callerId10()
{
int lbPosition;
@ -152,7 +165,7 @@ namespace AsterNET.FastAGI
if (!callerIdCreated)
{
rawCallerId = ((string) request["callerid"]);
rawCallerId = request["callerid"];
callerIdCreated = true;
}
@ -179,7 +192,7 @@ namespace AsterNET.FastAGI
if (!callerIdCreated)
{
rawCallerId = ((string) request["callerid"]);
rawCallerId = request["callerid"];
callerIdCreated = true;
}
@ -197,58 +210,67 @@ namespace AsterNET.FastAGI
if (callerIdName.Length == 0)
return null;
else
return callerIdName;
}
#endregion
#region Dnid
public string Dnid
{
get
{
string dnid = (string)(request["dnid"]);
string dnid = request["dnid"];
if (dnid == null || dnid.ToLower(Helper.CultureInfo) == "unknown")
return null;
return dnid;
}
}
#endregion
#region Rdnis
public string Rdnis
{
get
{
string rdnis = (string)(request["rdnis"]);
string rdnis = request["rdnis"];
if (rdnis == null || rdnis.ToLower(Helper.CultureInfo) == "unknown")
return null;
return rdnis;
}
}
#endregion
#region Context
/// <summary>
/// Returns the context in the dial plan from which the AGI script was called.
/// </summary>
public string Context
{
get { return (string) request["context"]; }
get { return request["context"]; }
}
#endregion
#region Extension
/// <summary>
/// Returns the extension in the dial plan from which the AGI script was called.
/// </summary>
public string Extension
{
get { return (string) request["extension"]; }
get { return request["extension"]; }
}
#endregion
#region Priority
/// <summary>
/// Returns the priority in the dial plan from which the AGI script was called.
/// </summary>
@ -258,78 +280,71 @@ namespace AsterNET.FastAGI
{
if (request["priority"] != null)
{
return (string) request["priority"];
return request["priority"];
}
return "";
}
}
#endregion
#region Enhanced
/// <summary>
/// Returns wheather this agi is passed audio (EAGI - Enhanced AGI).<br/>
/// Enhanced AGI is currently not supported on FastAGI.<br/>
/// Returns wheather this agi is passed audio (EAGI - Enhanced AGI).<br />
/// Enhanced AGI is currently not supported on FastAGI.<br />
/// <code>true</code> if this agi is passed audio, <code>false</code> otherwise.
/// </summary>
public bool Enhanced
{
get
{
if (request["enhanced"] != null && (string)request["enhanced"] == "1.0")
if (request["enhanced"] != null && request["enhanced"] == "1.0")
return true;
return false;
}
}
#endregion
#region AccountCode
/// <summary>
/// Returns the account code set for the call.
/// </summary>
public string AccountCode
{
get
{
return (string) request["accountCode"];
get { return request["accountCode"]; }
}
}
#endregion
#region LocalAddress
public IPAddress LocalAddress
{
get { return localAddress; }
set { this.localAddress = value; }
}
public IPAddress LocalAddress { get; set; }
#endregion
#region LocalPort
public int LocalPort
{
get { return localPort; }
set { this.localPort = value; }
}
public int LocalPort { get; set; }
#endregion
#region RemoteAddress
public IPAddress RemoteAddress
{
get { return remoteAddress; }
set { this.remoteAddress = value; }
}
public IPAddress RemoteAddress { get; set; }
#endregion
#region RemotePort
public int RemotePort
{
get { return remotePort; }
set { this.remotePort = value; }
}
public int RemotePort { get; set; }
#endregion
#region Script()
/// <summary>
/// Returns the name of the script to execute.
/// </summary>
@ -340,7 +355,7 @@ namespace AsterNET.FastAGI
if (script != null)
return script;
script = ((string)request["network_script"]);
script = request["network_script"];
if (script != null)
{
Match scriptMatcher = Common.AGI_SCRIPT_PATTERN.Match(script);
@ -353,9 +368,11 @@ namespace AsterNET.FastAGI
return script;
}
}
#endregion
#region CallingAni2
public int CallingAni2
{
get
@ -364,15 +381,19 @@ namespace AsterNET.FastAGI
return -1;
try
{
return Int32.Parse((string)(request["callingani2"]));
return Int32.Parse(request["callingani2"]);
}
catch
{
}
catch {}
return -1;
}
}
#endregion
#region CallingPres
public int CallingPres
{
get
@ -381,15 +402,19 @@ namespace AsterNET.FastAGI
return -1;
try
{
return Int32.Parse((string)(request["callingpres"]));
return Int32.Parse(request["callingpres"]);
}
catch
{
}
catch {}
return -1;
}
}
#endregion
#region CallingTns
public int CallingTns
{
get
@ -398,15 +423,19 @@ namespace AsterNET.FastAGI
return -1;
try
{
return Int32.Parse((string)(request["callingtns"]));
return Int32.Parse(request["callingtns"]);
}
catch
{
}
catch {}
return -1;
}
}
#endregion
#region CallingTon
public int CallingTon
{
get
@ -415,15 +444,19 @@ namespace AsterNET.FastAGI
return -1;
try
{
return Int32.Parse((String)(request["callington"]));
return Int32.Parse(request["callington"]);
}
catch
{
}
catch {}
return -1;
}
}
#endregion
#region Parameter(string name)
public string Parameter(string name)
{
List<string> values;
@ -432,9 +465,11 @@ namespace AsterNET.FastAGI
return null;
return values[0];
}
#endregion
#region ParameterValues(string name)
public List<string> ParameterValues(string name)
{
if (ParameterMap().Count == 0)
@ -442,27 +477,33 @@ namespace AsterNET.FastAGI
return parameterMap[name];
}
#endregion
#region ParameterMap()
public Dictionary<string, List<string>> ParameterMap()
{
if (parameterMap == null)
parameterMap = parseParameters(this.parameters);
parameterMap = parseParameters(parameters);
return parameterMap;
}
#endregion
#region ToString()
public override string ToString()
{
return Helper.ToString(this);
}
#endregion
#region buildMap(ICollection lines)
/// <summary>
/// Builds a map containing variable names as key (with the "agi_" prefix stripped) and the corresponding values.<br/>
/// Builds a map containing variable names as key (with the "agi_" prefix stripped) and the corresponding values.<br />
/// Syntactically invalid and empty variables are skipped.
/// </summary>
/// <param name="lines">the environment to transform.</param>
@ -473,8 +514,8 @@ namespace AsterNET.FastAGI
string key;
string value;
Dictionary<string, string> map = new Dictionary<string,string>(lines.Count);
foreach (string line in lines)
var map = new Dictionary<string, string>(lines.Count);
foreach (var line in lines)
{
colonPosition = line.IndexOf(':');
if (colonPosition < 0 || !line.StartsWith("agi_") || line.Length < colonPosition + 2)
@ -487,9 +528,11 @@ namespace AsterNET.FastAGI
}
return map;
}
#endregion
#region parseParameters(string s)
/// <summary>
/// Parses the given parameter string and caches the result.
/// </summary>
@ -497,7 +540,7 @@ namespace AsterNET.FastAGI
/// <returns> a Map made up of parameter names their values</returns>
private Dictionary<string, List<string>> parseParameters(string parameters)
{
Dictionary<string, List<string>> result = new Dictionary<string, List<string>>();
var result = new Dictionary<string, List<string>>();
string name;
string val;
@ -508,7 +551,7 @@ namespace AsterNET.FastAGI
if (pars.Length == 0)
return result;
foreach (string parameter in pars)
foreach (var parameter in pars)
{
val = string.Empty;
int i = parameter.IndexOf('=');
@ -529,6 +572,7 @@ namespace AsterNET.FastAGI
}
return result;
}
#endregion
}
}

View file

@ -1,5 +1,7 @@
using System;
using System.IO;
using AsterNET.FastAGI.Command;
using AsterNET.IO;
namespace AsterNET.FastAGI
{
/// <summary>
@ -7,15 +9,15 @@ namespace AsterNET.FastAGI
/// </summary>
public class AGIWriter
{
private IO.SocketConnection socket;
private readonly SocketConnection socket;
public AGIWriter(IO.SocketConnection socket)
public AGIWriter(SocketConnection socket)
{
lock (this)
this.socket = socket;
}
public void SendCommand(Command.AGICommand command)
public void SendCommand(AGICommand command)
{
string buffer = command.BuildCommand() + "\n";
try

View file

@ -1,14 +1,16 @@
using AsterNET.FastAGI.MappingStrategies;
using System.IO;
using System.Net;
using System.Text;
using AsterNET.FastAGI.MappingStrategies;
using AsterNET.IO;
using AsterNET.Util;
namespace AsterNET.FastAGI
{
public class AsteriskFastAGI
{
#region Flags
/// <summary>
/// If set to true, causes the AGIChannel to throw an exception when a status code of 511 (Channel Dead) is returned.
/// This is set to false by default to maintain backwards compatibility
@ -20,155 +22,186 @@ namespace AsterNET.FastAGI
/// This is set to false by default to maintain backwards compatibility
/// </summary>
public bool SCHANGUP_CAUSES_EXCEPTION = false;
#endregion
#region Variables
#if LOGGER
private Logger logger = Logger.Instance();
private readonly Logger logger = Logger.Instance();
#endif
private IO.ServerSocket serverSocket;
private ServerSocket serverSocket;
/// <summary> The port to listen on.</summary>
private int port;
/// <summary> The address to listen on.</summary>
private string address;
private readonly string address;
/// <summary>The thread pool that contains the worker threads to process incoming requests.</summary>
private Util.ThreadPool pool;
/// <summary>The number of worker threads in the thread pool. This equals the maximum number of concurrent requests this AGIServer can serve.</summary>
private ThreadPool pool;
/// <summary>
/// The number of worker threads in the thread pool. This equals the maximum number of concurrent requests this
/// AGIServer can serve.
/// </summary>
private int poolSize;
/// <summary> True while this server is shut down. </summary>
private bool stopped;
/// <summary>
/// The strategy to use for bind AGIRequests to AGIScripts that serve them.
/// </summary>
private IMappingStrategy mappingStrategy;
private Encoding socketEncoding = Encoding.ASCII;
#endregion
#region PoolSize
/// <summary>
/// Sets the number of worker threads in the thread pool.<br/>
/// This equals the maximum number of concurrent requests this AGIServer can serve.<br/>
/// Sets the number of worker threads in the thread pool.<br />
/// This equals the maximum number of concurrent requests this AGIServer can serve.<br />
/// The default pool size is 10.
/// </summary>
public int PoolSize
{
set { this.poolSize = value; }
set { poolSize = value; }
}
#endregion
#region BindPort
/// <summary>
/// Sets the TCP port to listen on for new connections.<br/>
/// Sets the TCP port to listen on for new connections.<br />
/// The default bind port is 4573.
/// </summary>
public int BindPort
{
set
{
this.port = value;
}
set { port = value; }
}
#endregion
#region MappingStrategy
/// <summary>
/// Sets the strategy to use for mapping AGIRequests to AGIScripts that serve them.<br/>
/// Sets the strategy to use for mapping AGIRequests to AGIScripts that serve them.<br />
/// The default mapping is a MappingStrategy.
/// </summary>
/// <seealso cref="MappingStrategy" />
public IMappingStrategy MappingStrategy
{
set { this.mappingStrategy = value; }
set { mappingStrategy = value; }
}
#endregion
#region SocketEncoding
public Encoding SocketEncoding
{
get { return this.socketEncoding; }
set { this.socketEncoding = value; }
get { return socketEncoding; }
set { socketEncoding = value; }
}
#endregion
#region Constructor - AsteriskFastAGI()
/// <summary>
/// Creates a new AsteriskFastAGI.
/// </summary>
public AsteriskFastAGI()
{
this.address = Common.AGI_BIND_ADDRESS;
this.port = Common.AGI_BIND_PORT;
this.poolSize = Common.AGI_POOL_SIZE;
this.mappingStrategy = new ResourceMappingStrategy();
address = Common.AGI_BIND_ADDRESS;
port = Common.AGI_BIND_PORT;
poolSize = Common.AGI_POOL_SIZE;
mappingStrategy = new ResourceMappingStrategy();
}
#endregion
#region Constructor - AsteriskFastAGI()
/// <summary>
/// Creates a new AsteriskFastAGI.
/// </summary>
public AsteriskFastAGI(string mappingStrategy)
{
this.address = Common.AGI_BIND_ADDRESS;
this.port = Common.AGI_BIND_PORT;
this.poolSize = Common.AGI_POOL_SIZE;
address = Common.AGI_BIND_ADDRESS;
port = Common.AGI_BIND_PORT;
poolSize = Common.AGI_POOL_SIZE;
this.mappingStrategy = new ResourceMappingStrategy(mappingStrategy);
}
#endregion
#region Constructor - AsteriskFastAGI()
/// <summary>
/// Creates a new AsteriskFastAGI.
/// </summary>
public AsteriskFastAGI(IMappingStrategy mappingStrategy)
{
this.address = Common.AGI_BIND_ADDRESS;
this.port = Common.AGI_BIND_PORT;
this.poolSize = Common.AGI_POOL_SIZE;
address = Common.AGI_BIND_ADDRESS;
port = Common.AGI_BIND_PORT;
poolSize = Common.AGI_POOL_SIZE;
this.mappingStrategy = mappingStrategy;
}
public AsteriskFastAGI(IMappingStrategy mappingStrategy, string ipaddress, int port, int poolSize)
{
this.address = ipaddress;
address = ipaddress;
this.port = port;
this.poolSize = poolSize;
this.mappingStrategy = mappingStrategy;
}
#endregion
#region Constructor - AsteriskFastAGI(int port, int poolSize)
/// <summary>
/// Creates a new AsteriskFastAGI.
/// </summary>
/// <param name="port">The port to listen on.</param>
/// <param name="poolSize">The number of worker threads in the thread pool.
/// This equals the maximum number of concurrent requests this AGIServer can serve.</param>
/// <param name="poolSize">
/// The number of worker threads in the thread pool.
/// This equals the maximum number of concurrent requests this AGIServer can serve.
/// </param>
public AsteriskFastAGI(int port, int poolSize)
{
this.address = Common.AGI_BIND_ADDRESS;
address = Common.AGI_BIND_ADDRESS;
this.port = port;
this.poolSize = poolSize;
this.mappingStrategy = new ResourceMappingStrategy();
mappingStrategy = new ResourceMappingStrategy();
}
#endregion
#region Constructor - AsteriskFastAGI(string address, int port, int poolSize)
/// <summary>
/// Creates a new AsteriskFastAGI.
/// </summary>
/// <param name="ipaddress">The address to listen on.</param>
/// <param name="port">The port to listen on.</param>
/// <param name="poolSize">The number of worker threads in the thread pool.
/// This equals the maximum number of concurrent requests this AGIServer can serve.</param>
/// <param name="poolSize">
/// The number of worker threads in the thread pool.
/// This equals the maximum number of concurrent requests this AGIServer can serve.
/// </param>
public AsteriskFastAGI(string ipaddress, int port, int poolSize)
{
this.address = ipaddress;
address = ipaddress;
this.port = port;
this.poolSize = poolSize;
this.mappingStrategy = new ResourceMappingStrategy();
mappingStrategy = new ResourceMappingStrategy();
}
#endregion
public AsteriskFastAGI(string ipaddress = Common.AGI_BIND_ADDRESS,
@ -177,49 +210,50 @@ namespace AsterNET.FastAGI
bool sc511_CausesException = false,
bool scHangUp_CausesException = false)
{
this.address = ipaddress;
address = ipaddress;
this.port = port;
this.poolSize = poolSize;
this.mappingStrategy = new ResourceMappingStrategy();
mappingStrategy = new ResourceMappingStrategy();
SC511_CAUSES_EXCEPTION = sc511_CausesException;
SCHANGUP_CAUSES_EXCEPTION = scHangUp_CausesException;
}
#region Start()
public void Start()
{
stopped = false;
mappingStrategy.Load();
pool = new Util.ThreadPool("AGIServer", poolSize);
pool = new ThreadPool("AGIServer", poolSize);
#if LOGGER
logger.Info("Thread pool started.");
#endif
try
{
IPAddress ipAddress = IPAddress.Parse(address);
serverSocket = new IO.ServerSocket(port, ipAddress, this.SocketEncoding);
var ipAddress = IPAddress.Parse(address);
serverSocket = new ServerSocket(port, ipAddress, SocketEncoding);
}
catch(IOException ex)
catch (IOException ex)
{
#if LOGGER
logger.Error("Unable start AGI Server: cannot to bind to "+ address + ":" + port + ".", ex);
logger.Error("Unable start AGI Server: cannot to bind to " + address + ":" + port + ".", ex);
#endif
throw ex;
}
#if LOGGER
logger.Info("Listening on "+ address + ":" + port + ".");
logger.Info("Listening on " + address + ":" + port + ".");
#endif
AGIConnectionHandler connectionHandler;
IO.SocketConnection socket;
try
{
SocketConnection socket;
while ((socket = serverSocket.Accept()) != null)
{
#if LOGGER
logger.Info("Received connection.");
#endif
connectionHandler = new AGIConnectionHandler(socket, mappingStrategy, this.SC511_CAUSES_EXCEPTION, this.SCHANGUP_CAUSES_EXCEPTION);
var connectionHandler = new AGIConnectionHandler(socket, mappingStrategy, SC511_CAUSES_EXCEPTION,
SCHANGUP_CAUSES_EXCEPTION);
pool.AddJob(connectionHandler);
}
}
@ -257,15 +291,18 @@ namespace AsterNET.FastAGI
#endif
}
}
#endregion
#region Stop()
public void Stop()
{
stopped = true;
if (serverSocket != null)
serverSocket.Close();
}
#endregion
}
}

View file

@ -1,39 +1,39 @@
using System;
using System.Collections;
using System.Resources;
using System.Reflection;
using System.Resources;
namespace AsterNET.FastAGI
{
/// <summary>
/// A MappingStrategy that is configured via a resource bundle.<br/>
/// A MappingStrategy that is configured via a resource bundle.<br />
/// The resource bundle contains the script part of the url as key and the fully
/// qualified class name of the corresponding AGIScript as value.<br/>
/// qualified class name of the corresponding AGIScript as value.<br />
/// Example:
/// <pre>
/// noopcommand = AsterNET.FastAGI.Command.NoopCommand
/// </pre>
/// NoopCommand must implement the AGIScript interface and have a default constructor with no parameters.<br/>
/// NoopCommand must implement the AGIScript interface and have a default constructor with no parameters.<br />
/// </summary>
[Obsolete("This class has been depreciated in favour of MappingStrategies.ResourceMappingStrategy", false)]
public class MappingStrategy : IMappingStrategy
{
#if LOGGER
private Logger logger = Logger.Instance();
private readonly Logger logger = Logger.Instance();
#endif
private string resourceName;
private Hashtable mapping;
public MappingStrategy()
{
this.resourceName = Common.AGI_DEFAULT_RESOURCE_BUNDLE_NAME;
this.mapping = null;
resourceName = Common.AGI_DEFAULT_RESOURCE_BUNDLE_NAME;
mapping = null;
}
public MappingStrategy(string resourceName)
{
this.resourceName = resourceName;
this.mapping = null;
mapping = null;
}
public AGIScript DetermineScript(AGIRequest request)
@ -43,7 +43,7 @@ namespace AsterNET.FastAGI
lock (mapping.SyncRoot)
{
if (mapping.Contains(request.Script))
script = (AGIScript)mapping[request.Script];
script = (AGIScript) mapping[request.Script];
}
return script;
}
@ -57,9 +57,9 @@ namespace AsterNET.FastAGI
mapping = null;
resourceName = null;
}
else if (this.resourceName != value)
else if (resourceName != value)
{
this.resourceName = value;
resourceName = value;
Load();
}
}
@ -78,14 +78,15 @@ namespace AsterNET.FastAGI
mapping.Clear();
try
{
ResourceReader rr = new ResourceReader(AppDomain.CurrentDomain.BaseDirectory + resourceName);
var rr = new ResourceReader(AppDomain.CurrentDomain.BaseDirectory + resourceName);
foreach (DictionaryEntry de in rr)
{
scriptName = (string)de.Key;
className = (string)de.Value;
scriptName = (string) de.Key;
className = (string) de.Value;
agiScript = CreateAGIScriptInstance(className);
if(mapping.Contains(scriptName))
throw new AGIException(String.Format("Duplicate mapping name '{0}' in file {1}", scriptName, resourceName));
if (mapping.Contains(scriptName))
throw new AGIException(String.Format("Duplicate mapping name '{0}' in file {1}", scriptName,
resourceName));
mapping.Add(scriptName, agiScript);
#if LOGGER
logger.Info("Added mapping for '" + scriptName + "' to class " + agiScript.GetType().FullName);
@ -111,10 +112,10 @@ namespace AsterNET.FastAGI
try
{
agiScriptClass = Type.GetType(className);
constructor = agiScriptClass.GetConstructor(new Type[]{});
agiScript = (AGIScript) constructor.Invoke(new object[]{});
constructor = agiScriptClass.GetConstructor(new Type[] {});
agiScript = (AGIScript) constructor.Invoke(new object[] {});
}
catch(Exception ex)
catch (Exception ex)
{
#if LOGGER
logger.Error("Unable to create AGIScript instance of type " + className, ex);

View file

@ -1,15 +1,12 @@
using System;
using System.Globalization;
using System.Text;
using System.Collections;
using System.Collections.Specialized;
using System.Threading;
using System.Reflection;
using System.Security.Cryptography;
using System.Collections.Generic;
using System.Globalization;
using System.Reflection;
using System.Text;
using AsterNET.Manager;
using AsterNET.Manager.Event;
using AsterNET.Manager.Response;
using AsterNET.Manager;
namespace AsterNET
{
@ -17,24 +14,31 @@ namespace AsterNET
{
private static CultureInfo defaultCulture;
#if LOGGER
private static Logger logger = Logger.Instance();
private static readonly Logger logger = Logger.Instance();
#endif
#region CultureInfo
internal static CultureInfo CultureInfo
{
get
{
if (defaultCulture == null)
defaultCulture = System.Globalization.CultureInfo.GetCultureInfo("en");
defaultCulture = CultureInfo.GetCultureInfo("en");
return defaultCulture;
}
}
#endregion
#region ToHexString(sbyte[])
/// <summary> The hex digits used to build a hex string representation of a byte array.</summary>
internal static readonly char[] hexChar = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
internal static readonly char[] hexChar =
{
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd',
'e', 'f'
};
/// <summary>
/// Converts a byte array to a hex string representing it. The hex digits are lower case.
@ -43,17 +47,19 @@ namespace AsterNET
/// <returns> the hex representation of b</returns>
internal static string ToHexString(sbyte[] b)
{
StringBuilder sb = new StringBuilder(b.Length * 2);
var sb = new StringBuilder(b.Length*2);
for (int i = 0; i < b.Length; i++)
{
sb.Append(hexChar[Helper.URShift((b[i] & 0xf0), 4)]);
sb.Append(hexChar[URShift((b[i] & 0xf0), 4)]);
sb.Append(hexChar[b[i] & 0x0f]);
}
return sb.ToString();
}
#endregion
#region GetInternalActionId(actionId)
internal static string GetInternalActionId(string actionId)
{
if (string.IsNullOrEmpty(actionId))
@ -63,9 +69,11 @@ namespace AsterNET
return actionId.Substring(0, delimiterIndex).Trim();
return string.Empty;
}
#endregion
#region StripInternalActionId(actionId)
internal static string StripInternalActionId(string actionId)
{
if (string.IsNullOrEmpty(actionId))
@ -75,16 +83,17 @@ namespace AsterNET
{
if (actionId.Length > delimiterIndex + 1)
return actionId.Substring(delimiterIndex + 1).Trim();
else
return actionId.Substring(0, delimiterIndex).Trim();
}
return string.Empty;
}
#endregion
#region IsTrue(string)
/// <summary>
/// Checks if a String represents <code>true</code> or <code>false</code> according to Asterisk's logic.<br/>
/// Checks if a String represents <code>true</code> or <code>false</code> according to Asterisk's logic.<br />
/// The original implementation is <code>util.c</code> is as follows:
/// </summary>
/// <param name="s">the String to check for <code>true</code>.</param>
@ -96,14 +105,16 @@ namespace AsterNET
{
if (s == null || s.Length == 0)
return false;
string sx = s.ToLower(Helper.CultureInfo);
string sx = s.ToLower(CultureInfo);
if (sx == "yes" || sx == "true" || sx == "y" || sx == "t" || sx == "1" || sx == "on")
return true;
return false;
}
#endregion
#region URShift(...)
/// <summary>
/// Performs an unsigned bitwise right shift with the specified number
/// </summary>
@ -114,7 +125,6 @@ namespace AsterNET
{
if (number >= 0)
return number >> bits;
else
return (number >> bits) + (2 << ~bits);
}
@ -126,7 +136,7 @@ namespace AsterNET
/// <returns>The resulting number from the shift operation</returns>
internal static int URShift(int number, long bits)
{
return URShift(number, (int)bits);
return URShift(number, (int) bits);
}
/// <summary>
@ -139,7 +149,6 @@ namespace AsterNET
{
if (number >= 0)
return number >> bits;
else
return (number >> bits) + (2L << ~bits);
}
@ -151,11 +160,13 @@ namespace AsterNET
/// <returns>The resulting number from the shift operation</returns>
internal static long URShift(long number, long bits)
{
return URShift(number, (int)bits);
return URShift(number, (int) bits);
}
#endregion
#region ToArray(ICollection c, object[] objects)
/// <summary>
/// Obtains an array containing all the elements of the collection.
/// </summary>
@ -166,7 +177,7 @@ namespace AsterNET
int index = 0;
Type type = objects.GetType().GetElementType();
object[] objs = (object[])Array.CreateInstance(type, c.Count);
var objs = (object[]) Array.CreateInstance(type, c.Count);
IEnumerator e = c.GetEnumerator();
@ -179,9 +190,11 @@ namespace AsterNET
return objs;
}
#endregion
#region ParseVariables(Dictionary<string, string> dictionary, string variables, char[] delim)
/// <summary>
/// Parse variable(s) string to dictionary.
/// </summary>
@ -189,7 +202,8 @@ namespace AsterNET
/// <param name="variables">variable(a) string</param>
/// <param name="delim">variable pairs delimiter</param>
/// <returns></returns>
internal static Dictionary<string, string> ParseVariables(Dictionary<string, string> dictionary, string variables, char[] delim)
internal static Dictionary<string, string> ParseVariables(Dictionary<string, string> dictionary,
string variables, char[] delim)
{
if (dictionary == null)
dictionary = new Dictionary<string, string>();
@ -201,7 +215,7 @@ namespace AsterNET
string[] vars = variables.Split(delim);
int idx;
string vname, vval;
foreach (string var in vars)
foreach (var var in vars)
{
idx = var.IndexOf('=');
if (idx > 0)
@ -218,9 +232,11 @@ namespace AsterNET
}
return dictionary;
}
#endregion
#region JoinVariables(IDictionary dictionary, string delim)
/// <summary>
/// Join variables dictionary to string.
/// </summary>
@ -231,11 +247,12 @@ namespace AsterNET
{
return JoinVariables(dictionary, new string(delim), delimKeyValue);
}
internal static string JoinVariables(IDictionary dictionary, string delim, string delimKeyValue)
{
if (dictionary == null)
return string.Empty;
StringBuilder sb = new StringBuilder();
var sb = new StringBuilder();
foreach (DictionaryEntry var in dictionary)
{
if (sb.Length > 0)
@ -244,28 +261,34 @@ namespace AsterNET
}
return sb.ToString();
}
#endregion
#region GetMillisecondsFrom(DateTime start)
internal static long GetMillisecondsFrom(DateTime start)
{
TimeSpan ts = (TimeSpan)(DateTime.Now - start);
return (long)ts.TotalMilliseconds;
TimeSpan ts = DateTime.Now - start;
return (long) ts.TotalMilliseconds;
}
#endregion
#region ParseString(string val)
internal static object ParseString(string val)
{
if (val == "none")
return string.Empty;
return val;
}
#endregion
#region GetGetters(class)
/// <summary>
/// Returns a Map of getter methods of the given class.<br/>
/// Returns a Map of getter methods of the given class.<br />
/// The key of the map contains the name of the attribute that can be accessed by the getter, the
/// value the getter itself . A method is considered a getter if its name starts with "get",
/// it is declared internal and takes no arguments.
@ -278,7 +301,7 @@ namespace AsterNET
string methodName;
MethodInfo method;
Dictionary<string, MethodInfo> accessors = new Dictionary<string, MethodInfo>();
var accessors = new Dictionary<string, MethodInfo>();
MethodInfo[] methods = clazz.GetMethods();
for (int i = 0; i < methods.Length; i++)
@ -297,11 +320,13 @@ namespace AsterNET
}
return accessors;
}
#endregion
#region GetSetters(Type clazz)
/// <summary>
/// Returns a Map of setter methods of the given class.<br/>
/// Returns a Map of setter methods of the given class.<br />
/// The key of the map contains the name of the attribute that can be accessed by the setter, the
/// value the setter itself. A method is considered a setter if its name starts with "set",
/// it is declared internal and takes no arguments.
@ -323,15 +348,17 @@ namespace AsterNET
// skip not "set..." methods and skip methods with != 1 parameters
if (!methodName.StartsWith("set_") || method.GetParameters().Length != 1)
continue;
name = methodName.Substring("set_".Length).ToLower(Helper.CultureInfo);
name = methodName.Substring("set_".Length).ToLower(CultureInfo);
if (name.Length == 0) continue;
accessors[name] = method;
}
return accessors;
}
#endregion
#region ToString(object obj)
/// <summary>
/// Convert object with all properties to string
/// </summary>
@ -340,33 +367,34 @@ namespace AsterNET
internal static string ToString(object obj)
{
object value;
StringBuilder sb = new StringBuilder(obj.GetType().Name, 1024);
var sb = new StringBuilder(obj.GetType().Name, 1024);
sb.Append(" {");
string strValue;
IDictionary getters = Helper.GetGetters(obj.GetType());
IDictionary getters = GetGetters(obj.GetType());
bool notFirst = false;
List<MethodInfo> arrays = new List<MethodInfo>();
var arrays = new List<MethodInfo>();
// First step - all values properties (not a list)
foreach (string name in getters.Keys)
{
MethodInfo getter = (MethodInfo)getters[name];
var getter = (MethodInfo) getters[name];
Type propType = getter.ReturnType;
if (propType == typeof(object))
if (propType == typeof (object))
continue;
if (!(propType == typeof(string) || propType == typeof(bool) || propType == typeof(double) || propType == typeof(DateTime) || propType == typeof(int) || propType == typeof(long)))
if (
!(propType == typeof (string) || propType == typeof (bool) || propType == typeof (double) ||
propType == typeof (DateTime) || propType == typeof (int) || propType == typeof (long)))
{
string propTypeName = propType.Name;
if (propTypeName.StartsWith("Dictionary") || propTypeName.StartsWith("List"))
{
arrays.Add(getter);
continue;
}
continue;
}
try
{
value = getter.Invoke(obj, new object[] { });
value = getter.Invoke(obj, new object[] {});
}
catch
{
@ -377,38 +405,38 @@ namespace AsterNET
continue;
if (value is string)
{
strValue = (string)value;
strValue = (string) value;
if (strValue.Length == 0)
continue;
}
else if (value is bool)
{
strValue = ((bool)value ? "true" : "false");
strValue = ((bool) value ? "true" : "false");
}
else if (value is double)
{
double d = (double)value;
var d = (double) value;
if (d == 0.0)
continue;
strValue = d.ToString();
}
else if (value is DateTime)
{
DateTime dt = (DateTime)value;
var dt = (DateTime) value;
if (dt == DateTime.MinValue)
continue;
strValue = dt.ToLongTimeString();
}
else if (value is int)
{
int i = (int)value;
var i = (int) value;
if (i == 0)
continue;
strValue = i.ToString();
}
else if (value is long)
{
long l = (long)value;
var l = (long) value;
if (l == 0)
continue;
strValue = l.ToString();
@ -423,12 +451,12 @@ namespace AsterNET
}
// Second step - all lists
foreach (MethodInfo getter in arrays)
foreach (var getter in arrays)
{
value = null;
try
{
value = getter.Invoke(obj, new object[] { });
value = getter.Invoke(obj, new object[] {});
}
catch
{
@ -438,8 +466,9 @@ namespace AsterNET
continue;
#region List
IList list;
if (value is IList && (list = (IList)value).Count > 0)
if (value is IList && (list = (IList) value).Count > 0)
{
if (notFirst)
sb.Append("; ");
@ -447,20 +476,19 @@ namespace AsterNET
sb.Append(getter.Name.Substring(4));
sb.Append(":[");
bool notFirst2 = false;
foreach (object o in list)
foreach (var o in list)
{
if (notFirst2)
sb.Append("; ");
notFirst2 = true;
sb.Append(o.ToString());
sb.Append(o);
}
sb.Append("]");
continue;
}
#endregion
#region IDictionary
else if (value is IDictionary && ((IDictionary)value).Count > 0)
if (value is IDictionary && ((IDictionary) value).Count > 0)
{
if (notFirst)
sb.Append("; ");
@ -468,26 +496,28 @@ namespace AsterNET
sb.Append(getter.Name.Substring(4));
sb.Append(":[");
bool notFirst2 = false;
foreach (object key in ((IDictionary)value).Keys)
foreach (var key in ((IDictionary) value).Keys)
{
object o = ((IDictionary)value)[key];
object o = ((IDictionary) value)[key];
if (notFirst2)
sb.Append("; ");
notFirst2 = true;
sb.Append(string.Concat(key, ":", o));
}
sb.Append("]");
continue;
}
#endregion
}
sb.Append("}");
return sb.ToString();
}
#endregion
#region SetAttributes(object evt, IDictionary attributes)
internal static void SetAttributes(IParseSupport o, Dictionary<string, string> attributes)
{
Type dataType;
@ -496,22 +526,22 @@ namespace AsterNET
// Preparse attributes
attributes = o.ParseSpecial(attributes);
IDictionary setters = Helper.GetSetters(o.GetType());
IDictionary setters = GetSetters(o.GetType());
MethodInfo setter;
foreach (string name in attributes.Keys)
foreach (var name in attributes.Keys)
{
if (name == "event")
continue;
if (name == "source")
setter = (MethodInfo)setters["src"];
setter = (MethodInfo) setters["src"];
else
setter = (MethodInfo)setters[stripIllegalCharacters(name)];
setter = (MethodInfo) setters[stripIllegalCharacters(name)];
if (setter == null)
{
// No setter found to key, try general parser
if (!o.Parse(name, (string)attributes[name]))
if (!o.Parse(name, attributes[name]))
{
#if LOGGER
logger.Error("Unable to set property '" + name + "' on " + o.GetType() + ": no setter");
@ -522,44 +552,46 @@ namespace AsterNET
else
{
dataType = (setter.GetParameters()[0]).ParameterType;
if (dataType == typeof(bool))
val = Helper.IsTrue((string)attributes[name]);
else if (dataType == typeof(string))
val = Helper.ParseString((string)attributes[name]);
else if (dataType == typeof(Int32))
if (dataType == typeof (bool))
val = IsTrue(attributes[name]);
else if (dataType == typeof (string))
val = ParseString(attributes[name]);
else if (dataType == typeof (Int32))
{
Int32 v = 0;
Int32.TryParse((string)attributes[name], out v);
Int32.TryParse(attributes[name], out v);
val = v;
}
else if (dataType == typeof(Int64))
else if (dataType == typeof (Int64))
{
Int64 v = 0;
Int64.TryParse((string)attributes[name], out v);
Int64.TryParse(attributes[name], out v);
val = v;
}
else if (dataType == typeof(double))
else if (dataType == typeof (double))
{
Double v = 0.0;
Double.TryParse((string)attributes[name], System.Globalization.NumberStyles.AllowDecimalPoint, Common.CultureInfoEn, out v);
Double.TryParse(attributes[name], NumberStyles.AllowDecimalPoint, Common.CultureInfoEn, out v);
val = v;
}
else if (dataType == typeof(decimal))
else if (dataType == typeof (decimal))
{
Decimal v = 0;
Decimal.TryParse((string)attributes[name], System.Globalization.NumberStyles.AllowDecimalPoint, Common.CultureInfoEn, out v);
Decimal.TryParse(attributes[name], NumberStyles.AllowDecimalPoint, Common.CultureInfoEn, out v);
val = v;
}
else if (dataType.IsEnum)
{
try
{
val = Convert.ChangeType(Enum.Parse(dataType, (string)attributes[name], true), dataType);
val = Convert.ChangeType(Enum.Parse(dataType, attributes[name], true), dataType);
}
catch (Exception ex)
{
#if LOGGER
logger.Error("Unable to convert value '" + attributes[name] + "' of property '" + name + "' on " + o.GetType() + " to required enum type " + dataType, ex);
logger.Error(
"Unable to convert value '" + attributes[name] + "' of property '" + name + "' on " +
o.GetType() + " to required enum type " + dataType, ex);
continue;
#else
throw new ManagerException("Unable to convert value '" + attributes[name] + "' of property '" + name + "' on " + o.GetType() + " to required enum type " + dataType, ex);
@ -570,13 +602,15 @@ namespace AsterNET
{
try
{
ConstructorInfo constructor = dataType.GetConstructor(new Type[] { typeof(string) });
val = constructor.Invoke(new object[] { attributes[name] });
ConstructorInfo constructor = dataType.GetConstructor(new[] {typeof (string)});
val = constructor.Invoke(new object[] {attributes[name]});
}
catch (Exception ex)
{
#if LOGGER
logger.Error("Unable to convert value '" + attributes[name] + "' of property '" + name + "' on " + o.GetType() + " to required type " + dataType, ex);
logger.Error(
"Unable to convert value '" + attributes[name] + "' of property '" + name + "' on " +
o.GetType() + " to required type " + dataType, ex);
continue;
#else
throw new ManagerException("Unable to convert value '" + attributes[name] + "' of property '" + name + "' on " + o.GetType() + " to required type " + dataType, ex);
@ -586,13 +620,12 @@ namespace AsterNET
try
{
setter.Invoke(o, new object[] { val });
setter.Invoke(o, new[] {val});
}
catch (Exception ex)
{
#if LOGGER
logger.Error("Unable to set property '" + name + "' on " + o.GetType(), ex);
continue;
#else
throw new ManagerException("Unable to set property '" + name + "' on " + o.GetType(), ex);
#endif
@ -600,15 +633,17 @@ namespace AsterNET
}
}
}
#endregion
#region AddKeyValue(IDictionary list, string line)
internal static void AddKeyValue(IDictionary list, string line)
{
int delimiterIndex = line.IndexOf(":");
if (delimiterIndex > 0 && line.Length > delimiterIndex + 1)
{
string name = line.Substring(0, delimiterIndex).ToLower(Helper.CultureInfo).Trim();
string name = line.Substring(0, delimiterIndex).ToLower(CultureInfo).Trim();
string val = line.Substring(delimiterIndex + 1).Trim();
if (val == "<null>")
list[name] = null;
@ -616,9 +651,11 @@ namespace AsterNET
list[name] = val;
}
}
#endregion
#region stripIllegalCharacters(string s)
/// <summary>
/// Strips all illegal charaters from the given lower case string.
/// </summary>
@ -637,21 +674,18 @@ namespace AsterNET
c = s[i];
if (c >= '0' && c <= '9')
continue;
else if (c >= 'a' && c <= 'z')
if (c >= 'a' && c <= 'z')
continue;
else if (c >= 'A' && c <= 'Z')
if (c >= 'A' && c <= 'Z')
continue;
else
{
needsStrip = true;
break;
}
}
if (!needsStrip)
return s;
StringBuilder sb = new StringBuilder(s.Length);
var sb = new StringBuilder(s.Length);
for (int i = 0; i < s.Length; i++)
{
c = s[i];
@ -665,9 +699,11 @@ namespace AsterNET
return sb.ToString();
}
#endregion
#region BuildResponse(IDictionary attributes)
/// <summary>
/// Constructs an instance of ManagerResponse based on a map of attributes.
/// </summary>
@ -677,7 +713,7 @@ namespace AsterNET
{
ManagerResponse response;
string responseType = ((string)attributes["response"]).ToLower(Helper.CultureInfo);
string responseType = attributes["response"].ToLower(CultureInfo);
// Determine type
if (responseType == "error")
@ -686,33 +722,38 @@ namespace AsterNET
response = new ChallengeResponse();
else if (attributes.ContainsKey("mailbox") && attributes.ContainsKey("waiting"))
response = new MailboxStatusResponse();
else if (attributes.ContainsKey("mailbox") && attributes.ContainsKey("newmessages") && attributes.ContainsKey("oldmessages"))
else if (attributes.ContainsKey("mailbox") && attributes.ContainsKey("newmessages") &&
attributes.ContainsKey("oldmessages"))
response = new MailboxCountResponse();
else if (attributes.ContainsKey("exten") && attributes.ContainsKey("context") && attributes.ContainsKey("hint") && attributes.ContainsKey("status"))
else if (attributes.ContainsKey("exten") && attributes.ContainsKey("context") &&
attributes.ContainsKey("hint") && attributes.ContainsKey("status"))
response = new ExtensionStateResponse();
else
response = new ManagerResponse();
Helper.SetAttributes(response, attributes);
SetAttributes(response, attributes);
return response;
}
#endregion
#region BuildEvent(Hashtable list, object source, IDictionary attributes)
/// <summary>
/// Builds the event based on the given map of attributes and the registered event classes.
/// </summary>
/// <param name="source">source attribute for the event</param>
/// <param name="attributes">map containing event attributes</param>
/// <returns>a concrete instance of ManagerEvent or <code>null</code> if no event class was registered for the event type.</returns>
internal static ManagerEvent BuildEvent(IDictionary<int, ConstructorInfo> list, ManagerConnection source, Dictionary<string, string> attributes)
internal static ManagerEvent BuildEvent(IDictionary<int, ConstructorInfo> list, ManagerConnection source,
Dictionary<string, string> attributes)
{
ManagerEvent e;
string eventType;
ConstructorInfo constructor = null;
int hash, hashEvent;
eventType = ((string)attributes["event"]).ToLower(Helper.CultureInfo);
eventType = attributes["event"].ToLower(CultureInfo);
// Remove Event tail from event name (ex. JabberEvent)
if (eventType.EndsWith("event"))
eventType = eventType.Substring(0, eventType.Length - 5);
@ -720,9 +761,9 @@ namespace AsterNET
if (eventType == "user")
{
string userevent = ((string)attributes["userevent"]).ToLower(Helper.CultureInfo);
string userevent = attributes["userevent"].ToLower(CultureInfo);
hash = string.Concat(eventType, userevent).GetHashCode();
if(list.ContainsKey(hash))
if (list.ContainsKey(hash))
constructor = list[hash];
else
constructor = list[hashEvent];
@ -736,7 +777,7 @@ namespace AsterNET
{
try
{
e = (ManagerEvent)constructor.Invoke(new object[] { source });
e = (ManagerEvent) constructor.Invoke(new object[] {source});
}
catch (Exception ex)
{
@ -756,20 +797,22 @@ namespace AsterNET
// the corresponding ManagerAction.
if (e is ResponseEvent)
{
ResponseEvent responseEvent = (ResponseEvent)e;
var responseEvent = (ResponseEvent) e;
string actionId = responseEvent.ActionId;
if (actionId != null)
{
responseEvent.ActionId = Helper.StripInternalActionId(actionId);
responseEvent.InternalActionId = Helper.GetInternalActionId(actionId);
responseEvent.ActionId = StripInternalActionId(actionId);
responseEvent.InternalActionId = GetInternalActionId(actionId);
}
}
return e;
}
#endregion
#region RegisterBuiltinEventClasses(Hashtable list)
/// <summary>
/// Register buildin Event classes
/// </summary>
@ -777,29 +820,31 @@ namespace AsterNET
internal static void RegisterBuiltinEventClasses(Dictionary<int, ConstructorInfo> list)
{
Assembly assembly = Assembly.GetExecutingAssembly();
Type manager = typeof(ManagerEvent);
foreach (Type type in assembly.GetTypes())
Type manager = typeof (ManagerEvent);
foreach (var type in assembly.GetTypes())
if (type.IsPublic && !type.IsAbstract && manager.IsAssignableFrom(type))
RegisterEventClass(list, type);
}
#endregion
#region RegisterEventClass(Dictionary<string, ConstructorInfo> list, Type clazz)
internal static void RegisterEventClass(Dictionary<int, ConstructorInfo> list, Type clazz)
{
// Ignore all abstract classes
// Class not derived from ManagerEvent
if (clazz.IsAbstract || !typeof(ManagerEvent).IsAssignableFrom(clazz))
if (clazz.IsAbstract || !typeof (ManagerEvent).IsAssignableFrom(clazz))
return;
string eventType = clazz.Name.ToLower(Helper.CultureInfo);
string eventType = clazz.Name.ToLower(CultureInfo);
// Remove "event" at the end (if presents)
if (eventType.EndsWith("event"))
eventType = eventType.Substring(0, eventType.Length - 5);
// If assignable from UserEvent and no "userevent" at the start - add "userevent" to beginning
if (typeof(UserEvent).IsAssignableFrom(clazz) && !eventType.StartsWith("user"))
if (typeof (UserEvent).IsAssignableFrom(clazz) && !eventType.StartsWith("user"))
eventType = "user" + eventType;
int hash = eventType.GetHashCode();
@ -809,7 +854,7 @@ namespace AsterNET
ConstructorInfo constructor = null;
try
{
constructor = clazz.GetConstructor(new Type[] { typeof(ManagerConnection) });
constructor = clazz.GetConstructor(new[] {typeof (ManagerConnection)});
}
catch (MethodAccessException ex)
{
@ -821,9 +866,11 @@ namespace AsterNET
else
throw new ArgumentException("RegisterEventClass : " + clazz + " has no public default constructor");
}
#endregion
#region RegisterEventHandler(Dictionary<int, int> list, int index, Type eventType)
internal static void RegisterEventHandler(Dictionary<int, int> list, int index, Type eventType)
{
int eventHash = eventType.Name.GetHashCode();
@ -831,6 +878,7 @@ namespace AsterNET
throw new ArgumentException("Event class already registered : " + eventType.Name);
list.Add(eventHash, index);
}
#endregion
}
}

View file

@ -1,15 +1,10 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace AsterNET
{
internal interface IParseSupport
{
Dictionary<string, string> Attributes
{
get;
}
Dictionary<string, string> Attributes { get; }
bool Parse(string key, string value);
Dictionary<string, string> ParseSpecial(Dictionary<string, string> attributes);
}

View file

@ -1,32 +1,20 @@
using System;
using System.Diagnostics;
using System.Threading;
using System.Text;
using System.Collections;
using System.Diagnostics;
using System.Reflection;
using System.Threading;
namespace AsterNET
{
#if LOGGER
#region class LogFactory
/// <summary>
/// Facade to hide details of the underlying logging system.
/// </summary>
public sealed class Logger
{
private static Logger logger;
/// <summary>
/// Returns an instance of Log suitable for logging from the given class.
/// </summary>
/// <returns> the created logger.</returns>
public static Logger Instance()
{
if(logger == null)
logger = new Logger();
return logger;
}
public enum MessageLevel
{
Info,
@ -35,6 +23,19 @@ namespace AsterNET
Debug
}
private static Logger logger;
private Hashtable visibleDebug = new Hashtable();
private bool visibleDebugDef = true;
private Hashtable visibleError = new Hashtable();
private bool visibleErrorDef = true;
private Hashtable visibleInfo = new Hashtable();
private bool visibleInfoDef = true;
private Hashtable visibleWarning = new Hashtable();
private bool visibleWarningDef = true;
/// <summary>
/// Creates a new CommonsLoggingLog obtained from commons-logging's LogFactory for the given class.
/// </summary>
@ -42,10 +43,22 @@ namespace AsterNET
{
}
/// <summary>
/// Returns an instance of Log suitable for logging from the given class.
/// </summary>
/// <returns> the created logger.</returns>
public static Logger Instance()
{
if (logger == null)
logger = new Logger();
return logger;
}
private void writeLine(string type, string msg)
{
System.Diagnostics.Debug.Print(string.Format("{0}[{1}] {2}", type, Thread.CurrentThread.Name, msg));
System.Diagnostics.Debug.Print("{0}[{1}] {2}", type, Thread.CurrentThread.Name, msg);
}
private void writeLine(string msg)
{
System.Diagnostics.Debug.Print(msg);
@ -54,22 +67,11 @@ namespace AsterNET
// Max 2 calls from original caller !
private string debugInfo()
{
System.Diagnostics.StackFrame sf = new System.Diagnostics.StackFrame(2, true);
System.Reflection.MethodBase mb = sf.GetMethod();
var sf = new StackFrame(2, true);
MethodBase mb = sf.GetMethod();
return string.Concat(mb.DeclaringType.Name, ":", mb.Name);
}
Hashtable visibleDebug = new Hashtable();
Hashtable visibleError = new Hashtable();
Hashtable visibleInfo = new Hashtable();
Hashtable visibleWarning = new Hashtable();
private bool visibleDebugDef = true;
private bool visibleErrorDef = true;
private bool visibleInfoDef = true;
private bool visibleWarningDef = true;
/// <summary>
/// Get visibility for message level of class:method
/// </summary>
@ -85,13 +87,13 @@ namespace AsterNET
switch (messageLevel)
{
case MessageLevel.Debug:
return (visibleDebug.ContainsKey(hash) ? (bool)visibleDebug[hash] : visibleDebugDef);
return (visibleDebug.ContainsKey(hash) ? (bool) visibleDebug[hash] : visibleDebugDef);
case MessageLevel.Error:
return (visibleError.ContainsKey(hash) ? (bool)visibleError[hash] : visibleErrorDef);
return (visibleError.ContainsKey(hash) ? (bool) visibleError[hash] : visibleErrorDef);
case MessageLevel.Info:
return (visibleInfo.ContainsKey(hash) ? (bool)visibleInfo[hash] : visibleInfoDef);
return (visibleInfo.ContainsKey(hash) ? (bool) visibleInfo[hash] : visibleInfoDef);
case MessageLevel.Warning:
return (visibleWarning.ContainsKey(hash) ? (bool)visibleWarning[hash] : visibleWarningDef);
return (visibleWarning.ContainsKey(hash) ? (bool) visibleWarning[hash] : visibleWarningDef);
}
return true;
}
@ -148,113 +150,134 @@ namespace AsterNET
}
#region Debug
public void Debug(object o)
{
string caller = debugInfo();
if (isVisible(MessageLevel.Debug, caller.GetHashCode()))
writeLine(" Debug:", string.Concat(caller, " - ", o.ToString()));
}
public void Debug(string msg)
{
string caller = debugInfo();
if (isVisible(MessageLevel.Debug, caller.GetHashCode()))
writeLine(" Debug:", string.Concat(caller, " - ", msg));
}
public void Debug(string format, params object[] args)
{
string caller = debugInfo();
if (isVisible(MessageLevel.Debug, caller.GetHashCode()))
writeLine(" Debug:", string.Concat(caller, " - ", string.Format(format, args)));
}
public void Debug(string msg, Exception ex)
{
string caller = debugInfo();
if (isVisible(MessageLevel.Debug, caller.GetHashCode()))
writeLine(" Debug:", string.Concat(caller, " - ", string.Format("{0}\n{1}", msg, ex)));
}
#endregion
#region Info
public void Info(object o)
{
string caller = debugInfo();
if (isVisible(MessageLevel.Info, caller.GetHashCode()))
writeLine(" Info:", string.Concat(caller, " - ", o.ToString()));
}
public void Info(string msg)
{
string caller = debugInfo();
if (isVisible(MessageLevel.Info, caller.GetHashCode()))
writeLine(" Info:", string.Concat(caller, " - ", msg));
}
public void Info(string format, params object[] args)
{
string caller = debugInfo();
if (isVisible(MessageLevel.Info, caller.GetHashCode()))
writeLine(" Info:", string.Concat(caller, " - ", string.Format(format, args)));
}
public void Info(string msg, Exception ex)
{
string caller = debugInfo();
if (isVisible(MessageLevel.Info, caller.GetHashCode()))
writeLine(" Info:", string.Concat(caller, " - ", string.Format("{0}\n{1}", msg, ex)));
}
#endregion
#region Warning
public void Warning(object o)
{
string caller = debugInfo();
if (isVisible(MessageLevel.Warning, caller.GetHashCode()))
writeLine("Warning:", string.Concat(caller, " - ", o.ToString()));
}
public void Warning(string msg)
{
string caller = debugInfo();
if (isVisible(MessageLevel.Warning, caller.GetHashCode()))
writeLine("Warning:", string.Concat(caller, " - ", msg));
}
public void Warning(string format, params object[] args)
{
string caller = debugInfo();
if (isVisible(MessageLevel.Warning, caller.GetHashCode()))
writeLine("Warning:", string.Concat(caller, " - ", string.Format(format, args)));
}
public void Warning(string msg, Exception ex)
{
string caller = debugInfo();
if (isVisible(MessageLevel.Warning, caller.GetHashCode()))
writeLine("Warning:", string.Concat(caller, " - ", string.Format("{0}\n{1}", msg, ex)));
}
#endregion
#region Error
public void Error(object o)
{
string caller = debugInfo();
if (isVisible(MessageLevel.Error, caller.GetHashCode()))
writeLine(" Error:", string.Concat(caller, " - ", o.ToString()));
}
public void Error(string msg)
{
string caller = debugInfo();
if (isVisible(MessageLevel.Error, caller.GetHashCode()))
writeLine(" Error:", string.Concat(caller, " - ", msg));
}
public void Error(string format, params object[] args)
{
string caller = debugInfo();
if (isVisible(MessageLevel.Error, caller.GetHashCode()))
writeLine(" Error:", string.Concat(caller, " - ", string.Format(format, args)));
}
public void Error(string msg, Exception ex)
{
string caller = debugInfo();
if (isVisible(MessageLevel.Error, caller.GetHashCode()))
writeLine(" Error:", string.Concat(caller, " - ", string.Format("{0}\n{1}", msg, ex)));
}
#endregion
}
#endregion
#endif

View file

@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AsterNET.Manager.Action
namespace AsterNET.Manager.Action
{
/// <summary>
/// This action lets you execute any AGI command through the Manager interface
@ -12,17 +6,6 @@ namespace AsterNET.Manager.Action
/// </summary>
public class AgiAction : ManagerAction
{
public string Channel { get; set; }
public string Command { get; set; }
/// <summary>
/// Get the name of this action, i.e. "AGI".
/// </summary>
override public string Action
{
get { return "AGI"; }
}
/// <summary>
/// Creates a new empty AgiAction.
/// </summary>
@ -32,6 +15,15 @@ namespace AsterNET.Manager.Action
Command = command;
}
public string Channel { get; set; }
public string Command { get; set; }
/// <summary>
/// Get the name of this action, i.e. "AGI".
/// </summary>
public override string Action
{
get { return "AGI"; }
}
}
}

View file

@ -1,28 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AsterNET.Manager.Action
namespace AsterNET.Manager.Action
{
public class AOCMessageAction : ManagerAction
{
private string _channel;
private string _channelPrefix;
private string _msgType;
private string _chargeType;
private int _unitAmount;
private int _unitType;
private string _currencyName;
private string _currencyAmount;
private string _currencyMultiplier;
private string _totalType;
private string _aocBillingId;
private string _chargingAssociationId;
private string _chargingAssociationNumber;
private string _chargingrAssociationPlan;
/// <summary>
/// Generate an Advice of Charge message on a channel.
/// </summary>
@ -47,22 +26,25 @@ namespace AsterNET.Manager.Action
/// <param name="chargingAssociationId"></param>
/// <param name="chargingAssociationNumber"></param>
/// <param name="chargingrAssociationPlan"></param>
public AOCMessageAction(string channel, string channelPrefix, string msgType, string chargeType, int unitAmount, int unitType, string currencyName, string currencyAmount, string currencyMultiplier, string totalType, string aocBillingId, string chargingAssociationId, string chargingAssociationNumber, string chargingrAssociationPlan)
public AOCMessageAction(string channel, string channelPrefix, string msgType, string chargeType, int unitAmount,
int unitType, string currencyName, string currencyAmount, string currencyMultiplier, string totalType,
string aocBillingId, string chargingAssociationId, string chargingAssociationNumber,
string chargingrAssociationPlan)
{
_channel = channel;
_channelPrefix = channelPrefix;
_msgType = msgType;
_chargeType = chargeType;
_unitAmount = unitAmount;
_unitType = unitType;
_currencyName = currencyName;
_currencyAmount = currencyAmount;
_currencyMultiplier = currencyMultiplier;
_totalType = totalType;
_aocBillingId = aocBillingId;
_chargingAssociationId = chargingAssociationId;
_chargingAssociationNumber = chargingAssociationNumber;
_chargingrAssociationPlan = chargingrAssociationPlan;
Channel = channel;
ChannelPrefix = channelPrefix;
MsgType = msgType;
ChargeType = chargeType;
UnitAmount = unitAmount;
UnitType = unitType;
CurrencyName = currencyName;
CurrencyAmount = currencyAmount;
CurrencyMultiplier = currencyMultiplier;
TotalType = totalType;
AocBillingId = aocBillingId;
ChargingAssociationId = chargingAssociationId;
ChargingAssociationNumber = chargingAssociationNumber;
ChargingrAssociationPlan = chargingrAssociationPlan;
}
public override string Action
@ -70,88 +52,32 @@ namespace AsterNET.Manager.Action
get { return "AOCMessage"; }
}
public string Channel
{
get { return _channel; }
set { _channel = value; }
}
public string Channel { get; set; }
public string ChannelPrefix
{
get { return _channelPrefix; }
set { _channelPrefix = value; }
}
public string ChannelPrefix { get; set; }
public string MsgType
{
get { return _msgType; }
set { _msgType = value; }
}
public string MsgType { get; set; }
public string ChargeType
{
get { return _chargeType; }
set { _chargeType = value; }
}
public string ChargeType { get; set; }
public int UnitAmount
{
get { return _unitAmount; }
set { _unitAmount = value; }
}
public int UnitAmount { get; set; }
public int UnitType
{
get { return _unitType; }
set { _unitType = value; }
}
public int UnitType { get; set; }
public string CurrencyName
{
get { return _currencyName; }
set { _currencyName = value; }
}
public string CurrencyName { get; set; }
public string CurrencyAmount
{
get { return _currencyAmount; }
set { _currencyAmount = value; }
}
public string CurrencyAmount { get; set; }
public string CurrencyMultiplier
{
get { return _currencyMultiplier; }
set { _currencyMultiplier = value; }
}
public string CurrencyMultiplier { get; set; }
public string TotalType
{
get { return _totalType; }
set { _totalType = value; }
}
public string TotalType { get; set; }
public string AocBillingId
{
get { return _aocBillingId; }
set { _aocBillingId = value; }
}
public string AocBillingId { get; set; }
public string ChargingAssociationId
{
get { return _chargingAssociationId; }
set { _chargingAssociationId = value; }
}
public string ChargingAssociationId { get; set; }
public string ChargingAssociationNumber
{
get { return _chargingAssociationNumber; }
set { _chargingAssociationNumber = value; }
}
public string ChargingAssociationNumber { get; set; }
public string ChargingrAssociationPlan
{
get { return _chargingrAssociationPlan; }
set { _chargingrAssociationPlan = value; }
}
public string ChargingrAssociationPlan { get; set; }
}
}

View file

@ -1,29 +1,29 @@
using System;
namespace AsterNET.Manager.Action
{
/// <summary>
/// The AbsoluteTimeoutAction sets the absolute maximum amount of time permitted for a call on a given channel.<br/>
/// Note that the timeout is set from the current time forward, not counting the number of seconds the call has already been up.<br/>
/// When setting a new timeout all previous absolute timeouts are cancelled.<br/>
/// The AbsoluteTimeoutAction sets the absolute maximum amount of time permitted for a call on a given channel.<br />
/// Note that the timeout is set from the current time forward, not counting the number of seconds the call has already
/// been up.<br />
/// When setting a new timeout all previous absolute timeouts are cancelled.<br />
/// When the timeout is reached the call is returned to the T extension so that
/// you can playback an explanatory note to the calling party (the called party will not hear that).<br/>
/// you can playback an explanatory note to the calling party (the called party will not hear that).<br />
/// This action corresponds the the AbsoluteTimeout command used in the dialplan.
/// </summary>
public class AbsoluteTimeoutAction : ManagerAction
{
private string channel;
private int timeout;
#region AbsoluteTimeoutAction()
/// <summary>
/// Creates a new empty AbsoluteTimeoutAction.
/// </summary>
public AbsoluteTimeoutAction()
{
}
#endregion
#region AbsoluteTimeoutAction(channel, timeout)
/// <summary>
/// Creates a new AbsoluteTimeoutAction with the given channel and timeout.
/// </summary>
@ -31,38 +31,40 @@ namespace AsterNET.Manager.Action
/// <param name="timeout">the timeout in seconds or 0 to cancel the AbsoluteTimeout</param>
public AbsoluteTimeoutAction(string channel, int timeout)
{
this.channel = channel;
this.timeout = timeout;
Channel = channel;
Timeout = timeout;
}
#endregion
#region Action
/// <summary>
/// Get the name of this action, i.e. "AbsoluteTimeout".
/// </summary>
override public string Action
public override string Action
{
get { return "AbsoluteTimeout"; }
}
#endregion
#region Channel
/// <summary>
/// Get/Set the name of the channel.</summary>
public string Channel
{
get { return channel; }
set { this.channel = value; }
}
/// Get/Set the name of the channel.
/// </summary>
public string Channel { get; set; }
#endregion
#region Timeout
/// <summary>
/// Get/Set the timeout (in seconds) to set.
/// </summary>
public int Timeout
{
get { return timeout; }
set { this.timeout = value; }
}
public int Timeout { get; set; }
#endregion
}
}

View file

@ -1,77 +1,16 @@
using System;
namespace AsterNET.Manager.Action
{
/// <summary>
/// The AgentCallbackLoginAction sets an agent as logged in with callback.<br/>
/// The AgentCallbackLoginAction sets an agent as logged in with callback.<br />
/// You can pass an extentsion (and optionally a context) to specify the
/// destination of the callback.<br/>
/// destination of the callback.<br />
/// In contrast to the AgentCallbackLogin application that you can use within
/// Asterisk's dialplan, you don't need to know the agent's password when logging
/// in an agent.<br/>
/// in an agent.<br />
/// Available since Asterisk 1.2
/// </summary>
public class AgentCallbackLoginAction : ManagerAction
{
private string agent;
private string exten;
private string context;
private bool ackCall;
private long wrapupTime;
/// <summary>
/// Get the name of this action, i.e. "AgentCallbackLogin".
/// </summary>
override public string Action
{
get { return "AgentCallbackLogin"; }
}
/// <summary>
/// Get/Set the name of the agent to log in, for example "1002".<br/>
/// This is property is mandatory.
/// </summary>
public string Agent
{
get { return this.agent; }
set { this.agent = value; }
}
/// <summary>
/// Get/Set the extension to use for callback.<br/>
/// This is property is mandatory.
/// </summary>
public string Exten
{
get { return this.exten; }
set { this.exten = value; }
}
/// <summary>
/// Get/Set the context of the extension to use for callback.
/// </summary>
public string Context
{
get { return this.context; }
set { this.context = value; }
}
/// <summary>
/// Get/Set if an acknowledgement is needed when agent is called back.<br/>
/// <code>true</code> if acknowledgement by '#' is required when agent is called back, <code>false</code> otherwise.
/// This property is optional, it allows you to override the defaults defined in Asterisk's configuration.
/// </summary>
public bool AckCall
{
get { return this.ackCall; }
set { this.ackCall = value; }
}
/// <summary>
/// Returns the minimum amount of time (in milliseconds) after disconnecting before the caller can receive a new call.<br/>
/// This property is optional, it allows you to override the defaults defined in Asterisk's configuration.
/// </summary>
public long WrapupTime
{
get { return this.wrapupTime; }
set { this.wrapupTime = value; }
}
/// <summary>
/// Creates a new empty AgentCallbackLoginAction.
/// </summary>
@ -87,8 +26,8 @@ namespace AsterNET.Manager.Action
/// <param name="exten">the extension that is called to connect a queue member with this agent</param>
public AgentCallbackLoginAction(string agent, string exten)
{
this.agent = agent;
this.exten = exten;
Agent = agent;
Exten = exten;
}
/// <summary>
@ -101,7 +40,46 @@ namespace AsterNET.Manager.Action
public AgentCallbackLoginAction(string agent, string exten, string context)
: this(agent, exten)
{
this.context = context;
Context = context;
}
/// <summary>
/// Get the name of this action, i.e. "AgentCallbackLogin".
/// </summary>
public override string Action
{
get { return "AgentCallbackLogin"; }
}
/// <summary>
/// Get/Set the name of the agent to log in, for example "1002".<br />
/// This is property is mandatory.
/// </summary>
public string Agent { get; set; }
/// <summary>
/// Get/Set the extension to use for callback.<br />
/// This is property is mandatory.
/// </summary>
public string Exten { get; set; }
/// <summary>
/// Get/Set the context of the extension to use for callback.
/// </summary>
public string Context { get; set; }
/// <summary>
/// Get/Set if an acknowledgement is needed when agent is called back.<br />
/// <code>true</code> if acknowledgement by '#' is required when agent is called back, <code>false</code> otherwise.
/// This property is optional, it allows you to override the defaults defined in Asterisk's configuration.
/// </summary>
public bool AckCall { get; set; }
/// <summary>
/// Returns the minimum amount of time (in milliseconds) after disconnecting before the caller can receive a new call.
/// <br />
/// This property is optional, it allows you to override the defaults defined in Asterisk's configuration.
/// </summary>
public long WrapupTime { get; set; }
}
}

View file

@ -1,5 +1,3 @@
using System;
namespace AsterNET.Manager.Action
{
/// <summary>
@ -7,78 +5,68 @@ namespace AsterNET.Manager.Action
/// </summary>
public class AgentLogoffAction : ManagerAction
{
private string agent;
private bool soft;
#region Action
/// <summary>
/// Returns the name of this action, i.e. "AgentLogoff".
/// </summary>
/// <returns>the name of this action</returns>
override public string Action
public override string Action
{
get
{
return "AgentLogoff";
}
get { return "AgentLogoff"; }
}
#endregion
#region Agent
/// <summary>
/// Returns the name of the agent to log off, for example "1002".
/// </summary>
/// <returns>the name of the agent to log off</returns>
/// <summary> Sets the name of the agent to log off, for example "1002".<br/>
/// <summary>
/// Sets the name of the agent to log off, for example "1002".<br />
/// This is property is mandatory.
/// </summary>
/// <param name="agent">the name of the agent to log off</param>
public string Agent
{
get
{
return agent;
}
public string Agent { get; set; }
set
{
this.agent = value;
}
}
#endregion
#region Soft
/// <summary>
/// Get/Set whether to hangup existing calls or not.<br/>
/// Get/Set whether to hangup existing calls or not.<br />
/// Default is to hangup existing calls on logoff.
/// </summary>
/// <returns> true if existing calls should not be hung up, false otherwise.<br/>
/// <returns>
/// true if existing calls should not be hung up, false otherwise.<br />
/// <code>null</code> if default should be used.
/// </returns>
public bool Soft
{
get { return soft; }
set { this.soft = value; }
}
public bool Soft { get; set; }
#endregion
#region Constructors - AgentLogoffAction()
/// <summary> Creates a new empty AgentLogoffAction.</summary>
public AgentLogoffAction()
{
}
/// <summary>
/// Creates a new AgentLogoffAction that logs off the given agent
/// </summary>
/// <param name="agent">the name of the agent to log off.</param>
public AgentLogoffAction(string agent)
{
this.agent = agent;
Agent = agent;
}
#endregion
#region Constructors - AgentLogoffAction(string agent, bool soft)
/// <summary>
/// Creates a new AgentLogoffAction that logs off the given agent
/// </summary>
@ -87,8 +75,9 @@ namespace AsterNET.Manager.Action
public AgentLogoffAction(string agent, bool soft)
: this(agent)
{
this.soft = soft;
Soft = soft;
}
#endregion
}
}

View file

@ -1,11 +1,12 @@
using System;
using AsterNET.Manager.Event;
namespace AsterNET.Manager.Action
{
/// <summary>
/// The AgentsAction requests the state of all agents.<br/>
/// The AgentsAction requests the state of all agents.<br />
/// For each agent an AgentsEvent is generated.
/// After the state of all agents has been reported an AgentsCompleteEvent is generated.<br/>
/// After the state of all agents has been reported an AgentsCompleteEvent is generated.<br />
/// Available since Asterisk 1.2
/// </summary>
/// <seealso cref="AsterNET.Manager.Event.AgentsEvent" />
@ -13,29 +14,28 @@ namespace AsterNET.Manager.Action
public class AgentsAction : ManagerActionEvent
{
#region Action
/// <summary>
/// Get the name of this action, i.e. "Agents".
/// </summary>
override public string Action
public override string Action
{
get { return "Agents"; }
}
#endregion
#region ActionCompleteEventClass
public override Type ActionCompleteEventClass()
{
return typeof(Event.AgentsCompleteEvent);
return typeof (AgentsCompleteEvent);
}
#endregion
#region AgentsAction()
/// <summary>
/// Creates a new AgentsAction.
/// </summary>
public AgentsAction()
{
}
#endregion
}
}

View file

@ -1,18 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AsterNET.Manager.Action
namespace AsterNET.Manager.Action
{
public class AtxferAction : ManagerAction
{
private string _channel;
private string _exten;
private string _context;
private string _priority;
/// <summary>
/// Attended transfer.
/// </summary>
@ -29,10 +18,10 @@ namespace AsterNET.Manager.Action
/// <param name="priority">Priority to transfer to.</param>
public AtxferAction(string channel, string exten, string context, string priority)
{
_channel = channel;
_exten = exten;
_context = context;
_priority = priority;
Channel = channel;
Exten = exten;
Context = context;
Priority = priority;
}
public override string Action
@ -43,37 +32,21 @@ namespace AsterNET.Manager.Action
/// <summary>
/// Transferer's channel.
/// </summary>
public string Channel
{
get { return _channel; }
set { _channel = value; }
}
public string Channel { get; set; }
/// <summary>
/// Extension to transfer to.
/// </summary>
public string Exten
{
get { return _exten; }
set { _exten = value; }
}
public string Exten { get; set; }
/// <summary>
/// Context to transfer to.
/// </summary>
public string Context
{
get { return _context; }
set { _context = value; }
}
public string Context { get; set; }
/// <summary>
/// Priority to transfer to.
/// </summary>
public string Priority
{
get { return _priority; }
set { _priority = value; }
}
public string Priority { get; set; }
}
}

View file

@ -1,17 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AsterNET.Manager.Action
namespace AsterNET.Manager.Action
{
public class BridgeAction : ManagerAction
{
private string _channel1;
private string _channel2;
private string _tone;
/// <summary>
/// Bridge two channels already in the PBX.
/// </summary>
@ -27,9 +17,9 @@ namespace AsterNET.Manager.Action
/// <param name="tone">Play courtesy tone to Channel 2 [yes|no]</param>
public BridgeAction(string channel1, string channel2, string tone)
{
_channel1 = channel1;
_channel2 = channel2;
_tone = tone;
Channel1 = channel1;
Channel2 = channel2;
Tone = tone;
}
public override string Action
@ -37,22 +27,10 @@ namespace AsterNET.Manager.Action
get { return "Bridge"; }
}
public string Channel1
{
get { return _channel1; }
set { _channel1 = value; }
}
public string Channel1 { get; set; }
public string Channel2
{
get { return _channel2; }
set { _channel2 = value; }
}
public string Channel2 { get; set; }
public string Tone
{
get { return _tone; }
set { _tone = value; }
}
public string Tone { get; set; }
}
}

View file

@ -1,5 +1,3 @@
using System;
namespace AsterNET.Manager.Action
{
/// <summary>
@ -7,34 +5,16 @@ namespace AsterNET.Manager.Action
/// in using challenge/response. Sending this action to the asterisk server
/// results in a ChallengeResponse being received from the server.
/// </summary>
/// <seealso cref="Manager.Action.LoginAction"/>
/// <seealso cref="Manager.Response.ChallengeResponse"/>
/// <seealso cref="Manager.Action.LoginAction" />
/// <seealso cref="Manager.Response.ChallengeResponse" />
public class ChallengeAction : ManagerAction
{
private string authType;
/// <summary>
/// Get the name of this action, i.e. "Challenge".
/// </summary>
override public string Action
{
get { return "Challenge"; }
}
/// <summary>
/// Get/Set the digest alogrithm to use. Currently asterisk only supports "MD5".
/// </summary>
public string AuthType
{
get { return this.authType; }
set { this.authType = value; }
}
/// <summary>
/// Creates a new empty ChallengeAction with MD5 algorithm
/// </summary>
public ChallengeAction()
{
this.authType = "MD5";
AuthType = "MD5";
}
/// <summary>
@ -44,7 +24,20 @@ namespace AsterNET.Manager.Action
/// <param name="authType">the digest alogrithm to use.</param>
public ChallengeAction(string authType)
{
this.authType = authType;
AuthType = authType;
}
/// <summary>
/// Get the name of this action, i.e. "Challenge".
/// </summary>
public override string Action
{
get { return "Challenge"; }
}
/// <summary>
/// Get/Set the digest alogrithm to use. Currently asterisk only supports "MD5".
/// </summary>
public string AuthType { get; set; }
}
}

View file

@ -1,58 +1,57 @@
using System;
namespace AsterNET.Manager.Action
{
/// <summary>
/// The ChangeMonitorAction changes the monitoring filename of a channel.
/// It has no effect if the channel is not monitored.<br/>
/// It has no effect if the channel is not monitored.<br />
/// It is implemented in <code>res/res_monitor.c</code>
/// </summary>
public class ChangeMonitorAction : ManagerAction
{
private string channel;
private string file;
#region Action
/// <summary>
/// Get the name of this action, i.e. "ChangeMonitor".
/// </summary>
override public string Action
public override string Action
{
get { return "ChangeMonitor"; }
}
#endregion
#region Channel
/// <summary>
/// Get/Set the name of the monitored channel.<br/>
/// Get/Set the name of the monitored channel.<br />
/// This property is mandatory.
/// </summary>
public string Channel
{
get { return this.channel; }
set { this.channel = value; }
}
public string Channel { get; set; }
#endregion
#region File
/// <summary>
/// Get/Set the name of the file to which the voice data is written.<br/>
/// Get/Set the name of the file to which the voice data is written.<br />
/// This property is mandatory.
/// </summary>
public string File
{
get { return this.file; }
set { this.file = value; }
}
public string File { get; set; }
#endregion
#region ChangeMonitorAction()
/// <summary>
/// Creates a new empty ChangeMonitorAction.
/// </summary>
public ChangeMonitorAction()
{
}
#endregion
#region ChangeMonitorAction(string channel, string file)
/// <summary>
/// Creates a new ChangeMonitorAction that causes monitoring data for the
/// given channel to be written to the given file(s).
@ -61,9 +60,10 @@ namespace AsterNET.Manager.Action
/// <param name="file">the (base) name of the file(s) to which the voice data is written</param>
public ChangeMonitorAction(string channel, string file)
{
this.channel = channel;
this.file = file;
Channel = channel;
File = file;
}
#endregion
}
}

View file

@ -1,31 +1,13 @@
using System;
namespace AsterNET.Manager.Action
{
/// <summary>
/// The CommandAction sends a command line interface (CLI) command to the asterisk server.<br/>
/// The CommandAction sends a command line interface (CLI) command to the asterisk server.<br />
/// For a list of supported commands type <code>help</code> on asterisk's command line.
/// </summary>
public class CommandAction : ManagerAction
{
protected internal string command;
/// <summary>
/// Get the name of this action, i.e. "Command".
/// </summary>
override public string Action
{
get { return "Command"; }
}
/// <summary>
/// Get/Set the CLI command to send to the asterisk server.
/// </summary>
public string Command
{
get { return this.command; }
set { this.command = value; }
}
/// <summary>
/// Creates a new CommandAction.
/// </summary>
@ -41,5 +23,22 @@ namespace AsterNET.Manager.Action
{
this.command = command;
}
/// <summary>
/// Get the name of this action, i.e. "Command".
/// </summary>
public override string Action
{
get { return "Command"; }
}
/// <summary>
/// Get/Set the CLI command to send to the asterisk server.
/// </summary>
public string Command
{
get { return command; }
set { command = value; }
}
}
}

View file

@ -1,26 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AsterNET.Manager.Action
namespace AsterNET.Manager.Action
{
public class ConfbridgeKickAction : ManagerAction
{
public string Conference { get; set; }
public string Channel { get; set; }
public override string Action
{
get { return "ConfbridgeKick"; }
}
/// <summary>
/// Removes a specified user from a specified conference.
/// </summary>
public ConfbridgeKickAction()
{ }
{
}
/// <summary>
/// Removes a specified user from a specified conference.
@ -29,8 +16,16 @@ namespace AsterNET.Manager.Action
/// <param name="channel"></param>
public ConfbridgeKickAction(string conference, string channel)
{
this.Conference = conference;
this.Channel = channel;
Conference = conference;
Channel = channel;
}
public string Conference { get; set; }
public string Channel { get; set; }
public override string Action
{
get { return "ConfbridgeKick"; }
}
}
}

View file

@ -1,12 +1,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using AsterNET.Manager.Event;
namespace AsterNET.Manager.Action
{
/*
https://wiki.asterisk.org/wiki/display/AST/ConfBridge+10#ConfBridge10-ConfBridgeAsteriskManagerInterface%28AMI%29Events
Action: ConfbridgeList
@ -19,17 +15,6 @@ namespace AsterNET.Manager.Action
/// </summary>
public class ConfbridgeListAction : ManagerActionEvent
{
public string Conference { get; set; }
public override string Action
{
get { return "ConfbridgeList"; }
}
public override Type ActionCompleteEventClass()
{
return typeof(Event.ConfbridgeListCompleteEvent);
}
/// <summary>
/// Lists all users in a particular ConfBridge conference. ConfbridgeList will follow as separate events,
/// followed by a final event called ConfbridgeListComplete
@ -37,7 +22,19 @@ namespace AsterNET.Manager.Action
/// <param name="conference"></param>
public ConfbridgeListAction(string conference)
{
this.Conference = conference;
Conference = conference;
}
public string Conference { get; set; }
public override string Action
{
get { return "ConfbridgeList"; }
}
public override Type ActionCompleteEventClass()
{
return typeof (ConfbridgeListCompleteEvent);
}
}
}

View file

@ -1,34 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using AsterNET.Manager.Event;
namespace AsterNET.Manager.Action
{
/// <summary>
/// Lists data about all active conferences. ConfbridgeListRooms will follow as separate events,
/// followed by a final event called ConfbridgeListRoomsComplete.
/// </summary>
public class ConfbridgeListRoomsAction : ManagerActionEvent
{
public override string Action
{
get { return "ConfbridgeListRooms"; }
}
public override Type ActionCompleteEventClass()
{
return typeof(Event.ConfbridgeListRoomsCompleteEvent);
}
/// <summary>
/// Lists data about all active conferences. ConfbridgeListRooms will follow as separate events,
/// followed by a final event called ConfbridgeListRoomsComplete.
/// </summary>
public ConfbridgeListRoomsAction()
{
return typeof (ConfbridgeListRoomsCompleteEvent);
}
}
}

View file

@ -1,25 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AsterNET.Manager.Action
namespace AsterNET.Manager.Action
{
public class ConfbridgeLockAction : ManagerAction
{
public string Conference { get; set; }
public override string Action
{
get { return "ConfbridgeLock"; }
}
/// <summary>
/// Locks a specified conference.
/// </summary>
public ConfbridgeLockAction()
{ }
{
}
/// <summary>
/// Locks a specified conference.
@ -27,7 +15,14 @@ namespace AsterNET.Manager.Action
/// <param name="conference"></param>
public ConfbridgeLockAction(string conference)
{
this.Conference = conference;
Conference = conference;
}
public string Conference { get; set; }
public override string Action
{
get { return "ConfbridgeLock"; }
}
}
}

View file

@ -1,26 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AsterNET.Manager.Action
namespace AsterNET.Manager.Action
{
public class ConfbridgeMuteAction : ManagerAction
{
public string Conference { get; set; }
public string Channel { get; set; }
public override string Action
{
get { return "ConfbridgeMute"; }
}
/// <summary>
/// Mutes a specified user in a specified conference.
/// </summary>
public ConfbridgeMuteAction()
{ }
{
}
/// <summary>
/// Mutes a specified user in a specified conference.
@ -29,8 +16,16 @@ namespace AsterNET.Manager.Action
/// <param name="channel"></param>
public ConfbridgeMuteAction(string conference, string channel)
{
this.Conference = conference;
this.Channel = channel;
Conference = conference;
Channel = channel;
}
public string Conference { get; set; }
public string Channel { get; set; }
public override string Action
{
get { return "ConfbridgeMute"; }
}
}
}

View file

@ -1,26 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AsterNET.Manager.Action
namespace AsterNET.Manager.Action
{
public class ConfbridgeSetSingleVideoSrcAction : ManagerAction
{
public string Conference { get; set; }
public string Channel { get; set; }
public override string Action
{
get { return "ConfbridgeSetSingleVideoSrc"; }
}
/// <summary>
/// Stops recording a specified conference.
/// </summary>
public ConfbridgeSetSingleVideoSrcAction()
{ }
{
}
/// <summary>
/// Stops recording a specified conference.
@ -28,8 +15,16 @@ namespace AsterNET.Manager.Action
/// <param name="conference"></param>
public ConfbridgeSetSingleVideoSrcAction(string conference, string channel)
{
this.Conference = conference;
this.Channel = channel;
Conference = conference;
Channel = channel;
}
public string Conference { get; set; }
public string Channel { get; set; }
public override string Action
{
get { return "ConfbridgeSetSingleVideoSrc"; }
}
}
}

View file

@ -1,20 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AsterNET.Manager.Action
namespace AsterNET.Manager.Action
{
public class ConfbridgeStartRecordAction : ManagerAction
{
public string Conference { get; set; }
public override string Action
{
get { return "ConfbridgeStartRecord"; }
}
/// <summary>
/// Starts recording a specified conference, with an optional filename.
/// If recording is already in progress, an error will be returned.
@ -22,7 +9,8 @@ namespace AsterNET.Manager.Action
/// If record_file is not specified, a file will automatically be generated in Asterisk's monitor directory.
/// </summary>
public ConfbridgeStartRecordAction()
{ }
{
}
/// <summary>
/// Starts recording a specified conference, with an optional filename.
@ -33,7 +21,14 @@ namespace AsterNET.Manager.Action
/// <param name="conference"></param>
public ConfbridgeStartRecordAction(string conference)
{
this.Conference = conference;
Conference = conference;
}
public string Conference { get; set; }
public override string Action
{
get { return "ConfbridgeStartRecord"; }
}
}
}

View file

@ -1,25 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AsterNET.Manager.Action
namespace AsterNET.Manager.Action
{
public class ConfbridgeStopRecordAction : ManagerAction
{
public string Conference { get; set; }
public override string Action
{
get { return "ConfbridgeStopRecord"; }
}
/// <summary>
/// Stops recording a specified conference.
/// </summary>
public ConfbridgeStopRecordAction()
{ }
{
}
/// <summary>
/// Stops recording a specified conference.
@ -27,7 +15,14 @@ namespace AsterNET.Manager.Action
/// <param name="conference"></param>
public ConfbridgeStopRecordAction(string conference)
{
this.Conference = conference;
Conference = conference;
}
public string Conference { get; set; }
public override string Action
{
get { return "ConfbridgeStopRecord"; }
}
}
}

View file

@ -1,25 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AsterNET.Manager.Action
namespace AsterNET.Manager.Action
{
public class ConfbridgeUnlockAction : ManagerAction
{
public string Conference { get; set; }
public override string Action
{
get { return "ConfbridgeUnlock"; }
}
/// <summary>
/// Unlocks a specified conference.
/// </summary>
public ConfbridgeUnlockAction()
{ }
{
}
/// <summary>
/// Unlocks a specified conference.
@ -27,7 +15,14 @@ namespace AsterNET.Manager.Action
/// <param name="conference"></param>
public ConfbridgeUnlockAction(string conference)
{
this.Conference = conference;
Conference = conference;
}
public string Conference { get; set; }
public override string Action
{
get { return "ConfbridgeUnlock"; }
}
}
}

View file

@ -1,26 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AsterNET.Manager.Action
namespace AsterNET.Manager.Action
{
public class ConfbridgeUnmuteAction : ManagerAction
{
public string Conference { get; set; }
public string Channel { get; set; }
public override string Action
{
get { return "ConfbridgeUnmute"; }
}
/// <summary>
/// Unmutes a specified user in a specified conference.
/// </summary>
public ConfbridgeUnmuteAction()
{ }
{
}
/// <summary>
/// Unmutes a specified user in a specified conference.
@ -29,8 +16,16 @@ namespace AsterNET.Manager.Action
/// <param name="channel"></param>
public ConfbridgeUnmuteAction(string conference, string channel)
{
this.Conference = conference;
this.Channel = channel;
Conference = conference;
Channel = channel;
}
public string Conference { get; set; }
public string Channel { get; set; }
public override string Action
{
get { return "ConfbridgeUnmute"; }
}
}
}

View file

@ -1,19 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AsterNET.Manager.Action
namespace AsterNET.Manager.Action
{
public class CoreSettingsAction : ManagerAction
{
/// <summary>
/// Show PBX core settings (version etc).
/// </summary>
public CoreSettingsAction()
{
}
public override string Action
{
get { return "CoreSettings"; }

View file

@ -1,19 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AsterNET.Manager.Action
namespace AsterNET.Manager.Action
{
public class CoreShowChannelsAction : ManagerAction
{
/// <summary>
/// List currently defined channels and some information about them.
/// </summary>
public CoreShowChannelsAction()
{
}
public override string Action
{
get { return "CoreShowChannels"; }

View file

@ -1,19 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AsterNET.Manager.Action
namespace AsterNET.Manager.Action
{
public class CoreStatusAction : ManagerAction
{
/// <summary>
/// Show PBX core status variables. Query for Core PBX status.
/// </summary>
public CoreStatusAction()
{
}
public override string Action
{
get { return "CoreStatus"; }

View file

@ -1,18 +1,11 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AsterNET.Manager.Action
namespace AsterNET.Manager.Action
{
public class CreateConfigAction : ManagerAction
{
private string _filename;
/// <summary>
/// Creates an empty file in the configuration directory.
/// This action will create an empty file in the configuration directory. This action is intended to be used before an UpdateConfig action.
/// This action will create an empty file in the configuration directory. This action is intended to be used before an
/// UpdateConfig action.
/// </summary>
public CreateConfigAction()
{
@ -20,12 +13,13 @@ namespace AsterNET.Manager.Action
/// <summary>
/// Creates an empty file in the configuration directory.
/// This action will create an empty file in the configuration directory. This action is intended to be used before an UpdateConfig action.
/// This action will create an empty file in the configuration directory. This action is intended to be used before an
/// UpdateConfig action.
/// </summary>
/// <param name="filename"></param>
public CreateConfigAction(string filename)
{
_filename = filename;
Filename = filename;
}
public override string Action
@ -33,10 +27,6 @@ namespace AsterNET.Manager.Action
get { return "CreateConfig"; }
}
public string Filename
{
get { return _filename; }
set { _filename = value; }
}
public string Filename { get; set; }
}
}

View file

@ -1,37 +1,9 @@
using System;
namespace AsterNET.Manager.Action
namespace AsterNET.Manager.Action
{
/// <summary>
///
/// </summary>
public class DBDelAction : ManagerAction
{
private string family;
private string key;
public override string Action
{
get { return "DBDel"; }
}
/// <summary>
/// Get/Set the the Family of the entry to delete.
/// </summary>
public string Family
{
get { return family; }
set { this.family = value; }
}
/// <summary>
/// Get/Set the the key of the entry to delete.
/// </summary>
public string Key
{
get { return key; }
set { this.key = value; }
}
/// <summary>
/// Creates a new empty DBDelAction.
/// </summary>
@ -47,8 +19,23 @@ namespace AsterNET.Manager.Action
/// <param name="key">the key of the entry to retrieve</param>
public DBDelAction(string family, string key)
{
this.family = family;
this.key = key;
Family = family;
Key = key;
}
public override string Action
{
get { return "DBDel"; }
}
/// <summary>
/// Get/Set the the Family of the entry to delete.
/// </summary>
public string Family { get; set; }
/// <summary>
/// Get/Set the the key of the entry to delete.
/// </summary>
public string Key { get; set; }
}
}

View file

@ -1,37 +1,9 @@
using System;
namespace AsterNET.Manager.Action
namespace AsterNET.Manager.Action
{
/// <summary>
///
/// </summary>
public class DBDelTreeAction : ManagerAction
{
private string family;
private string key;
public override string Action
{
get { return "DBDelTree"; }
}
/// <summary>
/// Get/Set the the Family of the entry to delete.
/// </summary>
public string Family
{
get { return family; }
set { this.family = value; }
}
/// <summary>
/// Get/Set the the key of the entry to delete.
/// </summary>
public string Key
{
get { return key; }
set { this.key = value; }
}
/// <summary>
/// Creates a new empty DBDelTreeAction.
/// </summary>
@ -47,8 +19,23 @@ namespace AsterNET.Manager.Action
/// <param name="key">the key of the entry to retrieve</param>
public DBDelTreeAction(string family, string key)
{
this.family = family;
this.key = key;
Family = family;
Key = key;
}
public override string Action
{
get { return "DBDelTree"; }
}
/// <summary>
/// Get/Set the the Family of the entry to delete.
/// </summary>
public string Family { get; set; }
/// <summary>
/// Get/Set the the key of the entry to delete.
/// </summary>
public string Key { get; set; }
}
}

View file

@ -1,50 +1,16 @@
using System;
using AsterNET.Manager.Event;
namespace AsterNET.Manager.Action
{
/// <summary>
/// Retrieves an entry in the Asterisk database for a given family and key.<br/>
/// Retrieves an entry in the Asterisk database for a given family and key.<br />
/// If an entry is found a DBGetResponseEvent is sent by Asterisk containing the
/// value, otherwise a ManagerError indicates that no entry matches.
/// </summary>
/// <seealso cref="AsterNET.Manager.Event.DBGetResponseEvent" />
public class DBGetAction : ManagerActionEvent
{
private string family;
private string key;
public override string Action
{
get { return "DBGet"; }
}
/// <summary> Returns the family of the key.
///
/// </summary>
/// <returns> the family of the key.
/// </returns>
/// <summary> Sets the family of the key.
///
/// </summary>
/// <param name="family">the family of the key.
/// </param>
public string Family
{
get { return family; }
set { this.family = value; }
}
/// <summary>
/// Get/Set the the key of the entry to retrieve.
/// </summary>
public string Key
{
get { return key; }
set { this.key = value; }
}
public override Type ActionCompleteEventClass()
{
return typeof(Event.DBGetResponseEvent);
}
/// <summary>
/// Creates a new empty DBGetAction.
/// </summary>
@ -60,8 +26,34 @@ namespace AsterNET.Manager.Action
/// <param name="key">the key of the entry to retrieve</param>
public DBGetAction(string family, string key)
{
this.family = family;
this.key = key;
Family = family;
Key = key;
}
public override string Action
{
get { return "DBGet"; }
}
/// <summary>
/// Returns the family of the key.
/// </summary>
/// <returns>
/// the family of the key.
/// </returns>
/// <param name="family">
/// the family of the key.
/// </param>
public string Family { get; set; }
/// <summary>
/// Get/Set the the key of the entry to retrieve.
/// </summary>
public string Key { get; set; }
public override Type ActionCompleteEventClass()
{
return typeof (DBGetResponseEvent);
}
}
}

View file

@ -1,46 +1,11 @@
using System;
namespace AsterNET.Manager.Action
{
/// <summary>
/// Adds or updates an entry in the Asterisk database for a given family, key, and value.<br/>
/// Adds or updates an entry in the Asterisk database for a given family, key, and value.<br />
/// Available since Asterisk 1.2
/// </summary>
public class DBPutAction : ManagerAction
{
private string family;
private string key;
private string val;
override public string Action
{
get { return "DBPut"; }
}
/// <summary>
/// Get/Set the family of the key to set.
/// </summary>
public string Family
{
get { return this.family; }
set { this.family = value; }
}
/// <summary>
/// Get/Set the the key to set.
/// </summary>
public string Key
{
get { return this.key; }
set { this.key = value; }
}
/// <summary>
/// Get/Set the value to set.
/// </summary>
public string Val
{
get { return val; }
set { this.val = value; }
}
/// <summary>
/// Creates a new empty DBPutAction.
/// </summary>
@ -56,9 +21,29 @@ namespace AsterNET.Manager.Action
/// <param name="val">the value to set</param>
public DBPutAction(string family, string key, string val)
{
this.family = family;
this.key = key;
this.val = val;
Family = family;
Key = key;
Val = val;
}
public override string Action
{
get { return "DBPut"; }
}
/// <summary>
/// Get/Set the family of the key to set.
/// </summary>
public string Family { get; set; }
/// <summary>
/// Get/Set the the key to set.
/// </summary>
public string Key { get; set; }
/// <summary>
/// Get/Set the value to set.
/// </summary>
public string Val { get; set; }
}
}

View file

@ -1,5 +1,3 @@
using System;
namespace AsterNET.Manager.Action
{
/// <summary>
@ -7,27 +5,6 @@ namespace AsterNET.Manager.Action
/// </summary>
public class EventsAction : ManagerAction
{
private string eventMask;
/// <summary>
/// Get the name of this action, i.e. "Events".
/// </summary>
override public string Action
{
get { return "Events"; }
}
/// <summary>
/// Get/Set the event mask.<br/>
/// Set to "on" if all events should be send, "off" if not events should be
/// sent or a combination of "system", "call" and "log" (separated by ',') to
/// specify what kind of events should be sent.
/// </summary>
public string EventMask
{
get { return this.eventMask; }
set { this.eventMask = value; }
}
/// <summary>
/// Creates a new empty EventsAction.
/// </summary>
@ -38,13 +15,30 @@ namespace AsterNET.Manager.Action
/// <summary>
/// Creates a new EventsAction that applies the given event mask to the current manager connection.
/// </summary>
/// <param name="eventMask">the event mask.<br/>
/// <param name="eventMask">
/// the event mask.<br />
/// Set to "on" if all events should be send, "off" if not events should be sent
/// or a combination of "system", "call" and "log" (separated by ',') to specify what kind of events should be sent.
/// </param>
public EventsAction(string eventMask)
{
this.eventMask = eventMask;
EventMask = eventMask;
}
/// <summary>
/// Get the name of this action, i.e. "Events".
/// </summary>
public override string Action
{
get { return "Events"; }
}
/// <summary>
/// Get/Set the event mask.<br />
/// Set to "on" if all events should be send, "off" if not events should be
/// sent or a combination of "system", "call" and "log" (separated by ',') to
/// specify what kind of events should be sent.
/// </summary>
public string EventMask { get; set; }
}
}

View file

@ -1,5 +1,3 @@
using System;
namespace AsterNET.Manager.Action
{
/// <summary>
@ -7,37 +5,34 @@ namespace AsterNET.Manager.Action
/// </summary>
public class ExtensionStateAction : ManagerAction
{
private string exten;
private string context;
#region Action
/// <summary>
/// Get the name of this action, i.e. "ExtensionState".
/// </summary>
override public string Action
public override string Action
{
get { return "ExtensionState"; }
}
#endregion
#region Exten
/// <summary>
/// Get/Set the extension to query.
/// </summary>
public string Exten
{
get { return exten; }
set { this.exten = value; }
}
public string Exten { get; set; }
#endregion
#region Context
/// <summary>
/// Get/Set the name of the context that contains the extension to query.
/// </summary>
public string Context
{
get { return context; }
set { this.context = value; }
}
public string Context { get; set; }
#endregion
}
}

View file

@ -1,6 +1,3 @@
using System;
using System.Collections.Generic;
using System.Text;
using AsterNET.Manager.Response;
namespace AsterNET.Manager.Action
@ -10,8 +7,6 @@ namespace AsterNET.Manager.Action
/// </summary>
public class GetConfigAction : ManagerActionResponse
{
private string filename;
/// <summary>
/// Creates a new GetConfigAction.
/// </summary>
@ -19,6 +14,15 @@ namespace AsterNET.Manager.Action
{
}
/// <summary>
/// Get the name of this action.
/// </summary>
/// <param name="filename">the configuration filename.</param>
public GetConfigAction(string filename)
{
Filename = filename;
}
/// <summary>
/// Get the name of this action.
/// </summary>
@ -27,24 +31,10 @@ namespace AsterNET.Manager.Action
get { return "GetConfig"; }
}
/// <summary>
/// Get the name of this action.
/// </summary>
/// <param name="filename">the configuration filename.</param>
/// </summary>
public GetConfigAction(string filename)
{
this.filename = filename;
}
/// <summary>
/// Get/Set the configuration filename.
/// </summary>
public string Filename
{
get { return this.filename; }
set { this.filename = value; }
}
public string Filename { get; set; }
public override object ActionCompleteResponseClass()
{

View file

@ -1,5 +1,3 @@
using System;
namespace AsterNET.Manager.Action
{
/// <summary>
@ -7,9 +5,6 @@ namespace AsterNET.Manager.Action
/// </summary>
public class GetVarAction : ManagerAction
{
private string channel;
private string varName;
/// <summary>
/// Creates a new empty GetVarAction.
/// </summary>
@ -23,7 +18,7 @@ namespace AsterNET.Manager.Action
/// <param name="variable">the name of the global variable to query.</param>
public GetVarAction(string variable)
{
this.varName = variable;
Variable = variable;
}
/// <summary>
@ -33,33 +28,27 @@ namespace AsterNET.Manager.Action
/// <param name="variable">the name of the variable to query.</param>
public GetVarAction(string channel, string variable)
{
this.channel = channel;
this.varName = variable;
Channel = channel;
Variable = variable;
}
/// <summary>
/// Get the name of this action, i.e. "GetVar".
/// </summary>
override public string Action
public override string Action
{
get { return "GetVar"; }
}
/// <summary>
/// Get/Set the name of the channel, if you query for a local channel variable.
/// Leave empty to query for a global variable.
/// </summary>
public string Channel
{
get { return this.channel; }
set { this.channel = value; }
}
public string Channel { get; set; }
/// <summary>
/// Get/Set the name of the variable to query.
/// </summary>
public string Variable
{
get { return this.varName; }
set { this.varName = value; }
}
public string Variable { get; set; }
}
}

View file

@ -1,5 +1,3 @@
using System;
namespace AsterNET.Manager.Action
{
/// <summary>
@ -7,8 +5,6 @@ namespace AsterNET.Manager.Action
/// </summary>
public class HangupAction : ManagerAction
{
private string channel;
/// <summary>
/// Creates a new empty HangupAction.
/// </summary>
@ -22,23 +18,20 @@ namespace AsterNET.Manager.Action
/// <param name="channel">the name of the channel to hangup.</param>
public HangupAction(string channel)
{
this.channel = channel;
Channel = channel;
}
/// <summary>
/// Get the name of this action, i.e. "Hangup".
/// </summary>
override public string Action
public override string Action
{
get { return "Hangup"; }
}
/// <summary>
/// Get/Set the name of the channel to hangup.
/// </summary>
public string Channel
{
get { return this.channel; }
set { this.channel = value; }
}
public string Channel { get; set; }
}
}

View file

@ -1,12 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AsterNET.Manager.Action
namespace AsterNET.Manager.Action
{
class ListCommandsAction
internal class ListCommandsAction
{
}
}

View file

@ -1,11 +1,9 @@
using System;
namespace AsterNET.Manager.Action
{
/// <summary>
/// The LoginAction authenticates the connection.<br/>
/// The LoginAction authenticates the connection.<br />
/// A successful login is the precondition for sending any other action except
/// for the ChallengeAction.<br/>
/// for the ChallengeAction.<br />
/// An unsuccessful login results in an ManagerError being received from the
/// server with a message set to "Authentication failed" and the socket being
/// closed by Asterisk.
@ -14,66 +12,6 @@ namespace AsterNET.Manager.Action
/// <seealso cref="Manager.Response.ManagerError" />
public class LoginAction : ManagerAction
{
private string username;
private string secret;
private string authType;
private string key;
private string events;
/// <summary>
/// Get the name of this action, i.e. "Login".
/// </summary>
override public string Action
{
get { return "Login"; }
}
/// <summary>
/// Get/Set the username as configured in asterik's <code>manager.conf</code>.</summary>
public string Username
{
get { return this.username; }
set { this.username = value; }
}
/// <summary>
/// Get/Set the secret to use when using cleartext login.<br/>
/// The secret contains the user's password as configured in Asterisk's <code>manager.conf</code>.<br/>
/// The secret and key properties are mutually exclusive.
/// </summary>
public string Secret
{
get { return this.secret; }
set { this.secret = value; }
}
/// <summary>
/// Get/Set the digest alogrithm when using challenge/response.<br/>
/// The digest algorithm is used to create the key based on the challenge and
/// the user's password.<br/>
/// Currently Asterisk supports only "MD5".
/// </summary>
public string AuthType
{
get { return this.authType; }
set { this.authType = value; }
}
/// <summary>
/// Get/Set the key.
/// </summary>
public string Key
{
get { return this.key; }
set { this.key = value; }
}
/// <summary>
/// Get/Set the event mask.<br/>
/// Set to "on" if all events should be send, "off" if not events should be sent or a combination of
/// "system", "call" and "log" (separated by ',') to specify what kind of events should be sent.
/// </summary>
public string Events
{
get { return this.events; }
set { this.events = value; }
}
/// <summary>
/// Creates a new empty LoginAction.
/// </summary>
@ -82,7 +20,7 @@ namespace AsterNET.Manager.Action
}
/// <summary>
/// Creates a new LoginAction that performs a cleartext login.<br/>
/// Creates a new LoginAction that performs a cleartext login.<br />
/// You should not use cleartext login if you are concerned about security and login with a password hash instead.
/// </summary>
/// <param name="username">the username as configured in Asterisk's <code>manager.conf</code></param>
@ -90,39 +28,86 @@ namespace AsterNET.Manager.Action
/// <seealso cref="Manager.Action.ChallengeAction" />
public LoginAction(string username, string secret)
{
this.username = username;
this.secret = secret;
Username = username;
Secret = secret;
}
/// <summary>
/// Creates a new LoginAction that performs a login via challenge/response.
/// </summary>
/// <param name="username">the username as configured in Asterisk's <code>manager.conf</code></param>
/// <param name="authType">the digest alogrithm, must match the digest algorithm that was used with the corresponding ChallengeAction.</param>
/// <param name="authType">
/// the digest alogrithm, must match the digest algorithm that was used with the corresponding
/// ChallengeAction.
/// </param>
/// <param name="key">the hash of the user's password and the challenge</param>
public LoginAction(string username, string authType, string key)
{
this.username = username;
this.authType = authType;
this.key = key;
Username = username;
AuthType = authType;
Key = key;
}
/// <summary>
/// Creates a new LoginAction that performs a login via challenge/response.
/// </summary>
/// <param name="username">the username as configured in Asterisk's <code>manager.conf</code></param>
/// <param name="authType">the digest alogrithm, must match the digest algorithm that was used with the corresponding ChallengeAction.</param>
/// <param name="authType">
/// the digest alogrithm, must match the digest algorithm that was used with the corresponding
/// ChallengeAction.
/// </param>
/// <param name="key">the hash of the user's password and the challenge</param>
/// <param name="events">the event mask.<br/>
/// <param name="events">
/// the event mask.<br />
/// Set to "on" if all events should be send, "off" if not events should be sent
/// or a combination of "system", "call" and "log" (separated by ',') to specify what kind of events should be sent.
/// </param>
public LoginAction(string username, string authType, string key, string events)
{
this.username = username;
this.authType = authType;
this.key = key;
this.events = events;
Username = username;
AuthType = authType;
Key = key;
Events = events;
}
/// <summary>
/// Get the name of this action, i.e. "Login".
/// </summary>
public override string Action
{
get { return "Login"; }
}
/// <summary>
/// Get/Set the username as configured in asterik's <code>manager.conf</code>.
/// </summary>
public string Username { get; set; }
/// <summary>
/// Get/Set the secret to use when using cleartext login.<br />
/// The secret contains the user's password as configured in Asterisk's <code>manager.conf</code>.<br />
/// The secret and key properties are mutually exclusive.
/// </summary>
public string Secret { get; set; }
/// <summary>
/// Get/Set the digest alogrithm when using challenge/response.<br />
/// The digest algorithm is used to create the key based on the challenge and
/// the user's password.<br />
/// Currently Asterisk supports only "MD5".
/// </summary>
public string AuthType { get; set; }
/// <summary>
/// Get/Set the key.
/// </summary>
public string Key { get; set; }
/// <summary>
/// Get/Set the event mask.<br />
/// Set to "on" if all events should be send, "off" if not events should be sent or a combination of
/// "system", "call" and "log" (separated by ',') to specify what kind of events should be sent.
/// </summary>
public string Events { get; set; }
}
}

View file

@ -1,5 +1,3 @@
using System;
namespace AsterNET.Manager.Action
{
/// <summary>
@ -10,16 +8,9 @@ namespace AsterNET.Manager.Action
/// <summary>
/// Get the name of this action, i.e. "Logoff".
/// </summary>
override public string Action
public override string Action
{
get { return "Logoff"; }
}
/// <summary>
/// Creates a new LogoffAction.
/// </summary>
public LogoffAction()
{
}
}
}

View file

@ -1,35 +1,12 @@
using System;
namespace AsterNET.Manager.Action
{
/// <summary>
/// The MailboxCountAction queries the number of unread and read messages in a mailbox.<br/>
/// The MailboxCountAction queries the number of unread and read messages in a mailbox.<br />
/// The MailboxCountAction returns a MailboxStatusResponse.
/// </summary>
/// <seealso cref="Manager.Response.MailboxCountResponse" />
public class MailboxCountAction : ManagerAction
{
private string mailbox;
/// <summary>
/// Get the name of this action, i.e. "MailboxCount".
/// </summary>
override public string Action
{
get { return "MailboxCount"; }
}
/// <summary>
/// Get/Set the name of the mailbox to query.<br/>
/// This can either be only the number of the mailbox or a string of the form
/// mailboxnumber@context.If no context is specified "default" is assumed.<br/>
/// This property is mandatory.
/// </summary>
public string Mailbox
{
get { return this.mailbox; }
set { this.mailbox = value; }
}
/// <summary>
/// Creates a new empty MailboxCountAction.
/// </summary>
@ -41,14 +18,31 @@ namespace AsterNET.Manager.Action
/// Creates a new MailboxCountAction that queries the number of unread and
/// read messages in the given mailbox.
/// </summary>
/// <param name="mailbox">the name of the mailbox to query.<br/>
/// <param name="mailbox">
/// the name of the mailbox to query.<br />
/// This can either be only the number of the mailbox or a string
/// of the form mailboxnumber@context.If no context is specified
/// "default" is assumed.
/// </param>
public MailboxCountAction(string mailbox)
{
this.mailbox = mailbox;
Mailbox = mailbox;
}
/// <summary>
/// Get the name of this action, i.e. "MailboxCount".
/// </summary>
public override string Action
{
get { return "MailboxCount"; }
}
/// <summary>
/// Get/Set the name of the mailbox to query.<br />
/// This can either be only the number of the mailbox or a string of the form
/// mailboxnumber@context.If no context is specified "default" is assumed.<br />
/// This property is mandatory.
/// </summary>
public string Mailbox { get; set; }
}
}

View file

@ -1,39 +1,12 @@
using System;
namespace AsterNET.Manager.Action
{
/// <summary>
/// The MailboxStatusAction checks if a mailbox contains waiting messages.<br/>
/// The MailboxStatusAction checks if a mailbox contains waiting messages.<br />
/// The MailboxStatusAction returns a MailboxStatusResponse.
/// </summary>
/// <seealso cref="Manager.Response.MailboxStatusResponse" />
public class MailboxStatusAction : ManagerAction
{
private string mailbox;
/// <summary>
/// Get the name of this action, i.e. "MailboxStatus".
/// </summary>
override public string Action
{
get { return "MailboxStatus"; }
}
/// <summary>
/// Get/Set the name of the mailbox to query.<br/>
/// This can either be only the name of the mailbox or a string of the form
/// mailboxnumber@context. If no context is specified "default" is assumed.<br/>
/// Multiple mailboxes may be given, separated by ','. In this case the
/// action checks whether at least one of the given mailboxes has waiting
/// messages.<br/>
/// This property is mandatory.<br/>
/// Example: "1234,1235@mycontext"
/// </summary>
public string Mailbox
{
get { return this.mailbox; }
set { this.mailbox = value; }
}
/// <summary>
/// Creates a new empty MailboxStatusAction.
/// </summary>
@ -44,14 +17,35 @@ namespace AsterNET.Manager.Action
/// <summary>
/// Creates a new MailboxStatusAction that checks for waiting messages in the given mailbox.
/// </summary>
/// <param name="mailbox">the name of the mailbox to check.<br/>
/// <param name="mailbox">
/// the name of the mailbox to check.<br />
/// This can either be only the number of the mailbox or a string
/// of the form mailboxnumber@context.If no context is specified
/// "default" is assumed.
/// </param>
public MailboxStatusAction(string mailbox)
{
this.mailbox = mailbox;
Mailbox = mailbox;
}
/// <summary>
/// Get the name of this action, i.e. "MailboxStatus".
/// </summary>
public override string Action
{
get { return "MailboxStatus"; }
}
/// <summary>
/// Get/Set the name of the mailbox to query.<br />
/// This can either be only the name of the mailbox or a string of the form
/// mailboxnumber@context. If no context is specified "default" is assumed.<br />
/// Multiple mailboxes may be given, separated by ','. In this case the
/// action checks whether at least one of the given mailboxes has waiting
/// messages.<br />
/// This property is mandatory.<br />
/// Example: "1234,1235@mycontext"
/// </summary>
public string Mailbox { get; set; }
}
}

View file

@ -1,6 +1,3 @@
using System.Text;
using System.Collections.Generic;
namespace AsterNET.Manager.Action
{
/// <summary>
@ -10,28 +7,28 @@ namespace AsterNET.Manager.Action
public abstract class ManagerAction
{
private string actionId;
private string server;
private string proxyKey;
private string server;
/// <summary>
/// Manager API Action key. Also use as ProxyAction key to <see cref="ProxyAction">ProxyAction</see> actions.
/// </summary>
public abstract string Action
{
get;
}
public abstract string Action { get; }
#region ActionId
public string ActionId
{
get { return this.actionId; }
set { this.actionId = value; }
}
#endregion
#region Server
/// <summary>
/// Specify a server to which to send your commands (x.x.x.x or hostname).<br/>
/// Specify a server to which to send your commands (x.x.x.x or hostname).<br />
/// This should match the server name specified in your config file's "host" entry.
/// If you do not specify a server, the proxy will pick the first one it finds -- fine in single-server configurations.
/// </summary>
@ -40,14 +37,16 @@ namespace AsterNET.Manager.Action
get { return this.server; }
set { this.server = value; }
}
#endregion
#region ProxyKey
/// <summary>
/// You can use this as a simple authentication mechanism.<br/>
/// You can use this as a simple authentication mechanism.<br />
/// Rather than have to login with a username & password,
/// you can specify a <b>ProxyKey</b> that must be passed from
/// a client before requests are processed.<br/>
/// a client before requests are processed.<br />
/// This is helpful in situations where you would like to authenticate and
/// execute an action in a single step.
/// </summary>
@ -56,6 +55,7 @@ namespace AsterNET.Manager.Action
get { return this.proxyKey; }
set { this.proxyKey = value; }
}
#endregion
public override string ToString()

View file

@ -4,17 +4,17 @@ namespace AsterNET.Manager.Action
{
/// <summary>
/// The ManagerActionEvent is implemented by ManagerActions that
/// return their result not in a ManagerResponse but by sending a series of events.<br/>
/// return their result not in a ManagerResponse but by sending a series of events.<br />
/// The event type that indicates that Asterisk is finished is returned by the
/// ActionCompleteEventClass property.
/// </summary>
/// <seealso cref="AsterNET.Manager.Event.ResponseEvent"/>
/// <seealso cref="AsterNET.Manager.Event.ResponseEvent" />
public abstract class ManagerActionEvent : ManagerAction
{
/// <summary>
/// Returns the event type that indicates that Asterisk is finished sending response events for this action.
/// </summary>
/// <seealso cref="AsterNET.Manager.Event.ResponseEvent"/>
/// <seealso cref="AsterNET.Manager.Event.ResponseEvent" />
public abstract Type ActionCompleteEventClass();
}
}

View file

@ -1,21 +1,18 @@
using System;
using AsterNET.Manager.Response;
namespace AsterNET.Manager.Action
{
/// <summary>
/// The ManagerActionResponse is implemented by ManagerActions that
/// return their result in a custom ManagerResponse<br/>
/// return their result in a custom ManagerResponse<br />
/// The response type that indicates that Asterisk is finished is returned by the
/// ActionCompleteResponseClass property.
/// </summary>
/// <seealso cref="AsterNET.Manager.Event.ResponseEvent"/>
/// <seealso cref="AsterNET.Manager.Event.ResponseEvent" />
public abstract class ManagerActionResponse : ManagerAction
{
/// <summary>
/// Returns the response type that indicates that Asterisk is finished sending response for this action.
/// </summary>
/// <seealso cref="AsterNET.Manager.Response"/>
/// <seealso cref="AsterNET.Manager.Response" />
public abstract object ActionCompleteResponseClass();
}
}

View file

@ -1,85 +1,75 @@
using System;
namespace AsterNET.Manager.Action
{
/// <summary>
/// The MonitorAction starts monitoring (recording) a channel.<br/>
/// The MonitorAction starts monitoring (recording) a channel.<br />
/// It is implemented in <code>res/res_monitor.c</code>
/// </summary>
public class MonitorAction : ManagerAction
{
private string channel;
private string file;
private string format;
private bool mix;
#region Action
/// <summary>
/// Get the name of this action, i.e. "Monitor".
/// </summary>
override public string Action
public override string Action
{
get { return "Monitor"; }
}
#endregion
#region Channel
/// <summary>
/// Get/Set the name of the channel to monitor.<br/>
/// Get/Set the name of the channel to monitor.<br />
/// This property is mandatory.
/// </summary>
public string Channel
{
get { return this.channel; }
set { this.channel = value; }
}
public string Channel { get; set; }
#endregion
#region File
/// <summary>
/// Get/Set the name of the file to which the voice data is written.<br/>
/// Get/Set the name of the file to which the voice data is written.<br />
/// If this property is not set it defaults to to the channel name as per CLI with the '/' replaced by '-'.
/// </summary>
public string File
{
get { return this.file; }
set { this.file = value; }
}
public string File { get; set; }
#endregion
#region Format
/// <summary>
/// Get/Set the format to use for encoding the voice files.<br/>
/// Get/Set the format to use for encoding the voice files.<br />
/// If this property is not set it defaults to "wav".
/// </summary>
public string Format
{
get { return this.format; }
set { this.format = value; }
}
public string Format { get; set; }
#endregion
#region Mix
/// <summary>
/// Returns true if the two voice files should be joined at the end of the call.
/// </summary>
public bool Mix
{
get { return this.mix; }
set { this.mix = value; }
}
public bool Mix { get; set; }
#endregion
#region MonitorAction()
/// <summary>
/// Creates a new empty MonitorAction.
/// </summary>
public MonitorAction()
{
}
#endregion
#region MonitorAction(string channel, string file)
/// <summary>
/// Creates a new MonitorAction that starts monitoring the given channel and
/// writes voice data to the given file(s).
@ -88,12 +78,14 @@ namespace AsterNET.Manager.Action
/// <param name="file">the (base) name of the file(s) to which the voice data is written</param>
public MonitorAction(string channel, string file)
{
this.channel = channel;
this.file = file;
Channel = channel;
File = file;
}
#endregion
#region MonitorAction(string channel, string file)
/// <summary>
/// Creates a new MonitorAction that starts monitoring the given channel and
/// writes voice data to the given file(s).
@ -103,13 +95,15 @@ namespace AsterNET.Manager.Action
/// <param name="format">the format to use for encoding the voice files</param>
public MonitorAction(string channel, string file, string format)
{
this.channel = channel;
this.file = file;
this.format = format;
Channel = channel;
File = file;
Format = format;
}
#endregion
#region MonitorAction(string channel, string file, string format, int mix)
/// <summary>
/// Creates a new MonitorAction that starts monitoring the given channel and
/// writes voice data to the given file(s).
@ -120,11 +114,12 @@ namespace AsterNET.Manager.Action
/// <param name="mix">true if the two voice files should be joined at the end of the call</param>
public MonitorAction(string channel, string file, string format, bool mix)
{
this.channel = channel;
this.file = file;
this.format = format;
this.mix = mix;
Channel = channel;
File = file;
Format = format;
Mix = mix;
}
#endregion
}
}

View file

@ -1,21 +1,21 @@
using System;
using System.Collections;
using System.Collections.Generic;
using AsterNET.Manager.Event;
namespace AsterNET.Manager.Action
{
/// <summary>
/// The OriginateAction generates an outgoing call to the extension in the given
/// context with the given priority or to a given application with optional
/// parameters.<br/>
/// parameters.<br />
/// If you want to connect to an extension use the properties context, exten and
/// priority. If you want to connect to an application use the properties
/// application and data if needed. Note that no call detail record will be
/// written when directly connecting to an application, so it may be better to
/// connect to an extension that starts the application you wish to connect to.<br/>
/// connect to an extension that starts the application you wish to connect to.<br />
/// The response to this action is sent when the channel has been answered and
/// asterisk starts connecting it to the given extension. So be careful not to
/// choose a too short timeout when waiting for the response.<br/>
/// choose a too short timeout when waiting for the response.<br />
/// If you set async to <code>true</code> Asterisk reports an OriginateSuccess-
/// and OriginateFailureEvents. The action id of these events equals the action
/// id of this OriginateAction.
@ -24,162 +24,138 @@ namespace AsterNET.Manager.Action
/// <seealso cref="AsterNET.Manager.Event.OriginateFailureEvent" />
public class OriginateAction : ManagerActionEvent
{
private string channel;
private string exten;
private string context;
private string priority;
private int timeout;
private string callerId;
private Dictionary<string, string> variables;
private string account;
private string application;
private string data;
private bool async;
#region Action
/// <summary>
/// Get the name of this action, i.e. "Originate".
/// </summary>
override public string Action
public override string Action
{
get { return "Originate"; }
}
#endregion
#region Account
/// <summary>
/// Get/Set the account code to use for the originated call.
/// The account code is included in the call detail record generated for this call and will be used for billing.
/// </summary>
public string Account
{
get { return account; }
set { this.account = value; }
}
public string Account { get; set; }
#endregion
#region CallerId
/// <summary>
/// Get/Set the caller id to set on the outgoing channel.
/// </summary>
public string CallerId
{
get { return callerId; }
set { this.callerId = value; }
}
public string CallerId { get; set; }
#endregion
#region Channel
/// <summary>
/// Get/Set Channel on which to originate the call (The same as you specify in the Dial application command)<br/>
/// Get/Set Channel on which to originate the call (The same as you specify in the Dial application command)<br />
/// This property is required.
/// </summary>
public string Channel
{
get { return channel; }
set { this.channel = value; }
}
public string Channel { get; set; }
#endregion
#region Context
/// <summary>
/// Get/Set the name of the context of the extension to connect to.
/// If you set the context you also have to set the exten and priority properties.
/// </summary>
public string Context
{
get { return context; }
set { this.context = value; }
}
public string Context { get; set; }
#endregion
#region Exten
/// <summary>
/// Get/Ser the extension to connect to.
/// If you set the extension you also have to set the context and priority properties.
/// </summary>
public string Exten
{
get { return exten; }
set { this.exten = value; }
}
public string Exten { get; set; }
#endregion
#region Priority
/// <summary>
/// Get /Set the priority of the extension to connect to.
/// If you set the priority you also have to set the context and exten properties.
/// </summary>
public string Priority
{
get { return priority; }
set { this.priority = value; }
}
public string Priority { get; set; }
#endregion
#region Application
/// <summary>
/// Get/Set Application to use on connect (use Data for parameters)
/// </summary>
public string Application
{
get { return application; }
set { this.application = value; }
}
public string Application { get; set; }
#endregion
#region Data
/// <summary>
/// Get/Set the parameters to pass to the application.
/// Data if Application parameter is user
/// </summary>
/// <summary> Sets the parameters to pass to the application.</summary>
public string Data
{
get { return data; }
set { this.data = value; }
}
public string Data { get; set; }
#endregion
#region Async
/// <summary>
/// Get/Set <code>true</code> if this is a fast origination.<br/>
/// For the origination to be asynchronous (allows multiple calls to be generated without waiting for a response).<br/>
/// Get/Set <code>true</code> if this is a fast origination.<br />
/// For the origination to be asynchronous (allows multiple calls to be generated without waiting for a response).
/// <br />
/// Will send OriginateSuccess- and OriginateFailureEvents.
/// </summary>
public bool Async
{
get { return async; }
set { this.async = value; }
}
public bool Async { get; set; }
#endregion
#region ActionCompleteEventClass
public override Type ActionCompleteEventClass()
{
return typeof(Event.OriginateResponseEvent);
return typeof (OriginateResponseEvent);
}
#endregion
#region Timeout
/// <summary>
/// Get/Set the timeout for the origination in seconds.<br/>
/// Get/Set the timeout for the origination in seconds.<br />
/// The channel must be answered within this time, otherwise the origination
/// is considered to have failed and an OriginateFailureEvent is generated.<br/>
/// is considered to have failed and an OriginateFailureEvent is generated.<br />
/// If not set, Asterisk assumes a default value of 30000 meaning 30 seconds.
/// </summary>
public int Timeout
{
get { return timeout; }
set { this.timeout = value; }
}
public int Timeout { get; set; }
#endregion
#region Variable
/// <summary>
/// Get/Set the variables to set on the originated call.<br/>
/// Get/Set the variables to set on the originated call.<br />
/// Variable assignments are of the form "VARNAME=VALUE". You can specify
/// multiple variable assignments separated by the '|' character.<br/>
/// multiple variable assignments separated by the '|' character.<br />
/// Example: "VAR1=abc|VAR2=def" sets the channel variables VAR1 to "abc" and VAR2 to "def".
/// </summary>
public string Variable
@ -187,9 +163,11 @@ namespace AsterNET.Manager.Action
get { return Helper.JoinVariables(variables, Common.VAR_DELIMITER, "="); }
set { variables = Helper.ParseVariables(variables, value, Common.VAR_DELIMITER); }
}
#endregion
#region GetVariables()
/// <summary>
/// Get the variables dictionary to set on the originated call.
/// </summary>
@ -197,19 +175,23 @@ namespace AsterNET.Manager.Action
{
return variables;
}
#endregion
#region SetVariables(IDictionary vars)
/// <summary>
/// Set the variables dictionary to set on the originated call.
/// </summary>
public void SetVariables(Dictionary<string, string> vars)
{
this.variables = vars;
variables = vars;
}
#endregion
#region GetVariable(string name, string val)
/// <summary>
/// Gets a variable on the originated call. Replaces any existing variable with the same name.
/// </summary>
@ -219,9 +201,11 @@ namespace AsterNET.Manager.Action
return string.Empty;
return variables[key];
}
#endregion
#region SetVariable(string name, string val)
/// <summary>
/// Sets a variable dictionary on the originated call. Replaces any existing variable with the same name.
/// </summary>
@ -234,6 +218,7 @@ namespace AsterNET.Manager.Action
else
variables.Add(key, value);
}
#endregion
}
}

View file

@ -1,60 +1,11 @@
using System;
namespace AsterNET.Manager.Action
namespace AsterNET.Manager.Action
{
/// <summary>
/// The ParkAction allows to send a Channel to a Parking lot.<br/>
/// The ParkAction allows to send a Channel to a Parking lot.<br />
/// A successful login is the precondition for sending for that
/// </summary>
public class ParkAction : ManagerAction
{
private string channel;
private string channel2;
private string timeout;
private string parkinglot;
/// <summary>
/// Get the name of this action, i.e. "Park".
/// </summary>
override public string Action
{
get { return "Park"; }
}
/// <summary>
/// Set the Channel which should be parked
/// </summary>
public string Channel
{
get { return this.channel; }
set { this.channel = value; }
}
/// <summary>
/// Set the Channel where the Call will end up after the timeout is reached.
/// </summary>
public string Channel2
{
get { return this.channel2; }
set { this.channel2 = value; }
}
/// <summary>
/// Timeout in msec, after timeout is reached call will come back to channel2
/// </summary>
public string Timeout
{
get { return this.timeout; }
set { this.timeout = value; }
}
/// <summary>
/// Set the Parking lot.
/// </summary>
public string Parkinglot
{
get { return this.parkinglot; }
set { this.parkinglot = value; }
}
/// <summary>
/// Creates a new ParkAction.
/// </summary>
@ -63,13 +14,13 @@ namespace AsterNET.Manager.Action
/// <param name="timeout"></param>
public ParkAction(string channel, string channel2, string timeout)
{
this.channel = channel;
this.channel2 = channel2;
this.timeout = timeout;
this.Channel = channel;
this.Channel2 = channel2;
this.Timeout = timeout;
}
/// <summary>
/// Creates a new ParkAction.<br/>
/// Creates a new ParkAction.<br />
/// </summary>
/// <param name="channel">Set the Channel which should be parked</param>
/// <param name="channel2">Set the Channel where the Call will end up after the timeout is reached.</param>
@ -77,10 +28,38 @@ namespace AsterNET.Manager.Action
/// <param name="parkinglot">Set the Parking lot.</param>
public ParkAction(string channel, string channel2, string timeout, string parkinglot)
{
this.channel = channel;
this.channel2 = channel2;
this.timeout = timeout;
this.parkinglot = parkinglot;
this.Channel = channel;
this.Channel2 = channel2;
this.Timeout = timeout;
this.Parkinglot = parkinglot;
}
/// <summary>
/// Get the name of this action, i.e. "Park".
/// </summary>
public override string Action
{
get { return "Park"; }
}
/// <summary>
/// Set the Channel which should be parked
/// </summary>
public string Channel { get; set; }
/// <summary>
/// Set the Channel where the Call will end up after the timeout is reached.
/// </summary>
public string Channel2 { get; set; }
/// <summary>
/// Timeout in msec, after timeout is reached call will come back to channel2
/// </summary>
public string Timeout { get; set; }
/// <summary>
/// Set the Parking lot.
/// </summary>
public string Parkinglot { get; set; }
}
}

View file

@ -1,14 +1,15 @@
using System;
using AsterNET.Manager.Event;
namespace AsterNET.Manager.Action
{
/// <summary>
/// The ParkedCallsAction requests a list of all currently parked calls.<br/>
/// The ParkedCallsAction requests a list of all currently parked calls.<br />
/// For each active channel a ParkedCallEvent is generated. After all parked
/// calls have been reported a ParkedCallsCompleteEvent is generated.
/// </summary>
/// <seealso cref="AsterNET.Manager.Event.ParkedCallEvent"/>
/// <seealso cref="AsterNET.Manager.Event.ParkedCallsCompleteEvent"/>
/// <seealso cref="AsterNET.Manager.Event.ParkedCallEvent" />
/// <seealso cref="AsterNET.Manager.Event.ParkedCallsCompleteEvent" />
public class ParkedCallsAction : ManagerActionEvent
{
/// <summary> Get the name of this action, i.e. "ParkedCalls".</summary>
@ -19,14 +20,7 @@ namespace AsterNET.Manager.Action
public override Type ActionCompleteEventClass()
{
return typeof(Event.ParkedCallsCompleteEvent);
}
/// <summary>
/// Creates a new ParkedCallsAction.
/// </summary>
public ParkedCallsAction()
{
return typeof (ParkedCallsCompleteEvent);
}
}
}

View file

@ -1,5 +1,3 @@
using System;
namespace AsterNET.Manager.Action
{
/// <summary>
@ -11,16 +9,9 @@ namespace AsterNET.Manager.Action
/// <summary>
/// Get the name of this action, i.e. "Ping".
/// </summary>
override public string Action
public override string Action
{
get { return "Ping"; }
}
/// <summary>
/// Creates a new PingAction.
/// </summary>
public PingAction()
{
}
}
}

View file

@ -1,7 +1,3 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace AsterNET.Manager.Action
{
public abstract class ProxyAction : ManagerAction

View file

@ -1,72 +1,11 @@
using System;
namespace AsterNET.Manager.Action
{
/// <summary>
/// The QueueAddAction adds a new member to a queue.<br/>
/// The QueueAddAction adds a new member to a queue.<br />
/// It is implemented in <code>apps/app_queue.c</code>
/// </summary>
public class QueueAddAction : ManagerAction
{
private string queue;
private string iface;
private string memberName;
private int penalty;
private bool paused;
/// <summary>
/// Get the name of this action, i.e. "QueueAdd".
/// </summary>
override public string Action
{
get { return "QueueAdd"; }
}
/// <summary>
/// Get/Set the name of the queue the new member will be added to.<br/>
/// This property is mandatory.
/// </summary>
public string Queue
{
get { return this.queue; }
set { this.queue = value; }
}
/// <summary>
/// Get/Set the interface to add. To add a specific channel just use the channel name, e.g. "SIP/1234".<br/>
/// This property is mandatory.
/// </summary>
public string Interface
{
get { return this.iface; }
set { this.iface = value; }
}
/// <summary>
/// Get/Set the member to add.
/// </summary>
public string MemberName
{
get { return this.memberName; }
set { this.memberName = value; }
}
/// <summary>
/// Get/Set the penalty for this member.<br/>
/// The penalty must be a positive integer or 0 for no penalty. If it is not set 0 is assumed.<br/>
/// When calls are distributed members with higher penalties are considered last.
/// </summary>
public int Penalty
{
get { return this.penalty; }
set { this.penalty = value; }
}
/// <summary>
/// Get/Set if the queue member should be paused when added.<br/>
/// <code>true</code> if the queue member should be paused when added.
/// </summary>
public bool Paused
{
get { return this.paused; }
set { this.paused = value; }
}
/// <summary>
/// Creates a new empty QueueAddAction.
/// </summary>
@ -81,8 +20,8 @@ namespace AsterNET.Manager.Action
/// <param name="iface">Sets the interface to add. To add a specific channel just use the channel name, e.g. "SIP/1234".</param>
public QueueAddAction(string queue, string iface)
{
this.queue = queue;
this.iface = iface;
this.Queue = queue;
this.Interface = iface;
}
/// <summary>
@ -93,9 +32,9 @@ namespace AsterNET.Manager.Action
/// <param name="memberName">the name of the the new member will be added to</param>
public QueueAddAction(string queue, string iface, string memberName)
{
this.queue = queue;
this.iface = iface;
this.memberName = memberName;
this.Queue = queue;
this.Interface = iface;
this.MemberName = memberName;
}
/// <summary>
@ -105,16 +44,55 @@ namespace AsterNET.Manager.Action
/// <param name="queue">the name of the queue the new member will be added to</param>
/// <param name="iface">Sets the interface to add. To add a specific channel just use the channel name, e.g. "SIP/1234".</param>
/// <param name="memberName">the name of the the new member will be added to</param>
/// <param name="penalty">the penalty for this member.<br/>
/// <param name="penalty">
/// the penalty for this member.<br />
/// The penalty must be a positive integer or 0 for no penalty. When calls are
/// distributed members with higher penalties are considered last.
/// </param>
public QueueAddAction(string queue, string iface, string memberName, int penalty)
{
this.queue = queue;
this.iface = iface;
this.memberName = memberName;
this.penalty = penalty;
this.Queue = queue;
this.Interface = iface;
this.MemberName = memberName;
this.Penalty = penalty;
}
/// <summary>
/// Get the name of this action, i.e. "QueueAdd".
/// </summary>
public override string Action
{
get { return "QueueAdd"; }
}
/// <summary>
/// Get/Set the name of the queue the new member will be added to.<br />
/// This property is mandatory.
/// </summary>
public string Queue { get; set; }
/// <summary>
/// Get/Set the interface to add. To add a specific channel just use the channel name, e.g. "SIP/1234".<br />
/// This property is mandatory.
/// </summary>
public string Interface { get; set; }
/// <summary>
/// Get/Set the member to add.
/// </summary>
public string MemberName { get; set; }
/// <summary>
/// Get/Set the penalty for this member.<br />
/// The penalty must be a positive integer or 0 for no penalty. If it is not set 0 is assumed.<br />
/// When calls are distributed members with higher penalties are considered last.
/// </summary>
public int Penalty { get; set; }
/// <summary>
/// Get/Set if the queue member should be paused when added.<br />
/// <code>true</code> if the queue member should be paused when added.
/// </summary>
public bool Paused { get; set; }
}
}

View file

@ -1,19 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AsterNET.Manager.Action
namespace AsterNET.Manager.Action
{
public class QueueLogAction : ManagerAction
{
private string _queue;
private string _event;
private string _uniqueid;
private string _interface;
private string _message;
/// <summary>
/// Adds custom entry in queue_log.
/// </summary>
@ -31,11 +19,11 @@ namespace AsterNET.Manager.Action
/// <param name="message"></param>
public QueueLogAction(string queue, string @event, string uniqueid, string @interface, string message)
{
_queue = queue;
_event = @event;
_uniqueid = uniqueid;
_interface = @interface;
_message = message;
Queue = queue;
Event = @event;
Uniqueid = uniqueid;
Interface = @interface;
Message = message;
}
public override string Action
@ -43,34 +31,14 @@ namespace AsterNET.Manager.Action
get { return "QueueLog"; }
}
public string Queue
{
get { return _queue; }
set { _queue = value; }
}
public string Queue { get; set; }
public string Event
{
get { return _event; }
set { _event = value; }
}
public string Event { get; set; }
public string Uniqueid
{
get { return _uniqueid; }
set { _uniqueid = value; }
}
public string Uniqueid { get; set; }
public string Interface
{
get { return _interface; }
set { _interface = value; }
}
public string Interface { get; set; }
public string Message
{
get { return _message; }
set { _message = value; }
}
public string Message { get; set; }
}
}

View file

@ -1,57 +1,12 @@
using System;
namespace AsterNET.Manager.Action
{
/// <summary>
/// The QueuePauseAction makes a queue member temporarily unavailabe (or available again).<br/>
/// It is implemented in <code>apps/app_queue.c</code><br/>
/// The QueuePauseAction makes a queue member temporarily unavailabe (or available again).<br />
/// It is implemented in <code>apps/app_queue.c</code><br />
/// Available since Asterisk 1.2.
/// </summary>
public class QueuePauseAction : ManagerAction
{
private string iface;
private bool paused;
private string queue;
/// <summary>
/// Get the name of this action, i.e. "QueuePause".
/// </summary>
override public string Action
{
get
{
return "QueuePause";
}
}
/// <summary>
/// Get/Set the interface of the member to make available or unavailable.<br/>
/// This property is mandatory.
/// </summary>
public string Interface
{
get { return this.iface; }
set { this.iface = value; }
}
/// <summary>
/// Get/Set Returns the name of the queue the member is made available or unavailable on.
/// </summary>
public string Queue
{
get { return this.queue; }
set { this.queue = value; }
}
/// <summary>
/// Get/Set if the member is made available or unavailable.<br/>
/// <code>true</code> to make the member unavailbale,<br/>
/// <code>false</code> make the member available
/// </summary>
public bool Paused
{
get { return this.paused; }
set { this.paused = value; }
}
/// <summary>
/// Creates a new empty QueuePauseAction.
/// </summary>
@ -66,8 +21,8 @@ namespace AsterNET.Manager.Action
/// <param name="iface">the interface of the member to make unavailable</param>
public QueuePauseAction(string iface)
{
this.iface = iface;
this.paused = true;
this.Interface = iface;
Paused = true;
}
/// <summary>
@ -78,9 +33,9 @@ namespace AsterNET.Manager.Action
/// <param name="queue">the queue the member is made unvailable on</param>
public QueuePauseAction(string iface, string queue)
{
this.iface = iface;
this.queue = queue;
this.paused = true;
this.Interface = iface;
this.Queue = queue;
Paused = true;
}
/// <summary>
@ -91,8 +46,8 @@ namespace AsterNET.Manager.Action
/// <param name="paused"><code>true</code> to make the member unavailbale, <code>false</code> to make the member available</param>
public QueuePauseAction(string iface, bool paused)
{
this.iface = iface;
this.paused = paused;
this.Interface = iface;
this.Paused = paused;
}
/// <summary>
@ -104,9 +59,35 @@ namespace AsterNET.Manager.Action
/// <param name="paused"><code>true</code> to make the member unavailbale, <code>false</code> to make the member available</param>
public QueuePauseAction(string iface, string queue, bool paused)
{
this.iface = iface;
this.queue = queue;
this.paused = paused;
this.Interface = iface;
this.Queue = queue;
this.Paused = paused;
}
/// <summary>
/// Get the name of this action, i.e. "QueuePause".
/// </summary>
public override string Action
{
get { return "QueuePause"; }
}
/// <summary>
/// Get/Set the interface of the member to make available or unavailable.<br />
/// This property is mandatory.
/// </summary>
public string Interface { get; set; }
/// <summary>
/// Get/Set Returns the name of the queue the member is made available or unavailable on.
/// </summary>
public string Queue { get; set; }
/// <summary>
/// Get/Set if the member is made available or unavailable.<br />
/// <code>true</code> to make the member unavailbale,<br />
/// <code>false</code> make the member available
/// </summary>
public bool Paused { get; set; }
}
}

View file

@ -1,17 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AsterNET.Manager.Action
namespace AsterNET.Manager.Action
{
public class QueuePenaltyAction : ManagerAction
{
private string _interface;
private string _penalty;
private string _queue;
/// <summary>
/// Set the penalty for a queue member.
/// </summary>
@ -27,9 +17,9 @@ namespace AsterNET.Manager.Action
/// <param name="queue"></param>
public QueuePenaltyAction(string @interface, string penalty, string queue)
{
_interface = @interface;
_penalty = penalty;
_queue = queue;
Interface = @interface;
Penalty = penalty;
Queue = queue;
}
public override string Action
@ -37,22 +27,10 @@ namespace AsterNET.Manager.Action
get { return "QueuePenalty"; }
}
public string Interface
{
get { return _interface; }
set { _interface = value; }
}
public string Interface { get; set; }
public string Penalty
{
get { return _penalty; }
set { _penalty = value; }
}
public string Penalty { get; set; }
public string Queue
{
get { return _queue; }
set { _queue = value; }
}
public string Queue { get; set; }
}
}

View file

@ -1,18 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AsterNET.Manager.Action
namespace AsterNET.Manager.Action
{
public class QueueReloadAction : ManagerAction
{
private string _queue;
private string _members;
private string _rules;
private string _parameters;
/// <summary>
/// Reload a queue, queues, or any sub-section of a queue or queues.
/// </summary>
@ -29,10 +18,10 @@ namespace AsterNET.Manager.Action
/// <param name="parameters"></param>
public QueueReloadAction(string queue, string members, string rules, string parameters)
{
_queue = queue;
_members = members;
_rules = rules;
_parameters = parameters;
Queue = queue;
Members = members;
Rules = rules;
Parameters = parameters;
}
public override string Action
@ -40,28 +29,12 @@ namespace AsterNET.Manager.Action
get { return "QueueReload"; }
}
public string Queue
{
get { return _queue; }
set { _queue = value; }
}
public string Queue { get; set; }
public string Members
{
get { return _members; }
set { _members = value; }
}
public string Members { get; set; }
public string Rules
{
get { return _rules; }
set { _rules = value; }
}
public string Rules { get; set; }
public string Parameters
{
get { return _parameters; }
set { _parameters = value; }
}
public string Parameters { get; set; }
}
}

View file

@ -1,46 +1,11 @@
using System;
namespace AsterNET.Manager.Action
{
/// <summary>
/// The QueueRemoveAction removes a member from a queue.<br/>
/// The QueueRemoveAction removes a member from a queue.<br />
/// It is implemented in <code>apps/app_queue.c</code>
/// </summary>
public class QueueRemoveAction : ManagerAction
{
/// <summary> The name of the queue the member will be removed from.</summary>
private string queue;
private string iface;
/// <summary>
/// Get the name of this action, i.e. "QueueRemove".
/// </summary>
override public string Action
{
get
{
return "QueueRemove";
}
}
/// <summary>
/// Get/Set the name of the queue the member will be removed from.
/// </summary>
public string Queue
{
get { return this.queue; }
set { this.queue = value; }
}
/// <summary>
/// Get/Set the interface to remove.<br/>
/// This property is mandatory.
/// </summary>
public string Interface
{
get { return this.iface; }
set { this.iface = value; }
}
/// <summary>
/// Creates a new empty QueueRemoveAction.
/// </summary>
@ -55,8 +20,27 @@ namespace AsterNET.Manager.Action
/// <param name="iface">the interface of the member to remove</param>
public QueueRemoveAction(string queue, string iface)
{
this.queue = queue;
this.iface = iface;
this.Queue = queue;
this.Interface = iface;
}
/// <summary>
/// Get the name of this action, i.e. "QueueRemove".
/// </summary>
public override string Action
{
get { return "QueueRemove"; }
}
/// <summary>
/// Get/Set the name of the queue the member will be removed from.
/// </summary>
public string Queue { get; set; }
/// <summary>
/// Get/Set the interface to remove.<br />
/// This property is mandatory.
/// </summary>
public string Interface { get; set; }
}
}

View file

@ -1,15 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AsterNET.Manager.Action
namespace AsterNET.Manager.Action
{
public class QueueResetAction : ManagerAction
{
private string _queue;
/// <summary>
/// Reset queue statistics.
/// </summary>
@ -23,7 +15,7 @@ namespace AsterNET.Manager.Action
/// <param name="queue"></param>
public QueueResetAction(string queue)
{
_queue = queue;
Queue = queue;
}
public override string Action
@ -31,10 +23,6 @@ namespace AsterNET.Manager.Action
get { return "QueueReset"; }
}
public string Queue
{
get { return _queue; }
set { _queue = value; }
}
public string Queue { get; set; }
}
}

View file

@ -1,22 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AsterNET.Manager.Action
namespace AsterNET.Manager.Action
{
public class QueueRuleAction : ManagerAction
{
private string _rule;
public QueueRuleAction()
{
}
public QueueRuleAction(string rule)
{
_rule = rule;
Rule = rule;
}
public override string Action
@ -24,10 +16,6 @@ namespace AsterNET.Manager.Action
get { return "QueueRule"; }
}
public string Rule
{
get { return _rule; }
set { _rule = value; }
}
public string Rule { get; set; }
}
}

View file

@ -1,12 +1,14 @@
using System;
using AsterNET.Manager.Event;
namespace AsterNET.Manager.Action
{
/// <summary>
/// The QueueStatusAction requests the state of all defined queues their members (agents) and entries (callers).<br/>
/// The QueueStatusAction requests the state of all defined queues their members (agents) and entries (callers).<br />
/// For each queue a QueueParamsEvent is generated, followed by a
/// QueueMemberEvent for each member of that queue and a QueueEntryEvent for each
/// entry in the queue.<br/>
/// Since Asterisk 1.2 a QueueStatusCompleteEvent is sent to denote the end of the generated dump.<br/>
/// entry in the queue.<br />
/// Since Asterisk 1.2 a QueueStatusCompleteEvent is sent to denote the end of the generated dump.<br />
/// This action is implemented in <code>apps/app_queue.c</code>
/// </summary>
/// <seealso cref="Manager.event.QueueParamsEvent" />
@ -15,10 +17,8 @@ namespace AsterNET.Manager.Action
/// <seealso cref="Manager.event.QueueStatusCompleteEvent" />
public class QueueStatusAction : ManagerActionEvent
{
private string queue;
private string member;
#region Action
/// <summary>
/// Get the name of this action, i.e. "QueueStatus".
/// </summary>
@ -26,40 +26,38 @@ namespace AsterNET.Manager.Action
{
get { return "QueueStatus"; }
}
#endregion
#region Queue
/// <summary>
/// Get/Set the queue filter.
/// </summary>
public string Queue
{
get { return queue; }
set { this.queue = value; }
}
public string Queue { get; set; }
#endregion
#region Member
/// <summary>
/// Get/Set the member filter.
/// </summary>
public string Member
{
get { return member; }
set { this.member = value; }
}
public string Member { get; set; }
#endregion
#region ActionCompleteEventClass
public override Type ActionCompleteEventClass()
{
return typeof(Event.QueueStatusCompleteEvent);
return typeof (QueueStatusCompleteEvent);
}
#endregion
#region QueueStatusAction()
/// <summary> Creates a new QueueStatusAction.</summary>
public QueueStatusAction()
{
}
#endregion
}
}

View file

@ -1,5 +1,3 @@
using System;
namespace AsterNET.Manager.Action
{
/// <summary>
@ -7,59 +5,6 @@ namespace AsterNET.Manager.Action
/// </summary>
public class RedirectAction : ManagerAction
{
private string channel;
private string extraChannel;
private string exten;
private string context;
private int priority;
/// <summary>
/// Get the name of this action, i.e. "Redirect".
/// </summary>
override public string Action
{
get { return "Redirect"; }
}
/// <summary>
/// Get/Set name of the channel to redirect.
public string Channel
{
get { return this.channel; }
set { this.channel = value; }
}
/// <summary>
/// Get/Set the name of the additional channel to redirect.
/// </summary>
public string ExtraChannel
{
get { return this.extraChannel; }
set { this.extraChannel = value; }
}
/// <summary>
/// Get/Set the destination context.
/// </summary>
public string Context
{
get { return this.context; }
set { this.context = value; }
}
/// <summary>
/// Get/Set the destination extension.
/// </summary>
public string Exten
{
get { return this.exten; }
set { this.exten = value; }
}
/// <summary>
/// Get/Set the destination priority.
/// </summary>
public int Priority
{
get { return this.priority; }
set { this.priority = value; }
}
/// <summary>
/// Creates a new empty RedirectAction.
/// </summary>
@ -76,10 +21,10 @@ namespace AsterNET.Manager.Action
/// <param name="priority">the destination priority</param>
public RedirectAction(string channel, string context, string exten, int priority)
{
this.channel = channel;
this.context = context;
this.exten = exten;
this.priority = priority;
this.Channel = channel;
this.Context = context;
this.Exten = exten;
this.Priority = priority;
}
/// <summary>
@ -92,11 +37,43 @@ namespace AsterNET.Manager.Action
/// <param name="priority">the destination priority</param>
public RedirectAction(string channel, string extraChannel, string context, string exten, int priority)
{
this.channel = channel;
this.extraChannel = extraChannel;
this.context = context;
this.exten = exten;
this.priority = priority;
this.Channel = channel;
this.ExtraChannel = extraChannel;
this.Context = context;
this.Exten = exten;
this.Priority = priority;
}
/// <summary>
/// Get the name of this action, i.e. "Redirect".
/// </summary>
public override string Action
{
get { return "Redirect"; }
}
/// <summary>
/// Get/Set name of the channel to redirect.
public string Channel { get; set; }
/// <summary>
/// Get/Set the name of the additional channel to redirect.
/// </summary>
public string ExtraChannel { get; set; }
/// <summary>
/// Get/Set the destination context.
/// </summary>
public string Context { get; set; }
/// <summary>
/// Get/Set the destination extension.
/// </summary>
public string Exten { get; set; }
/// <summary>
/// Get/Set the destination priority.
/// </summary>
public int Priority { get; set; }
}
}

View file

@ -1,11 +1,12 @@
using System;
using AsterNET.Manager.Event;
namespace AsterNET.Manager.Action
{
/// <summary>
/// Retrieves a list of all defined SIP peers.<br/>
/// Retrieves a list of all defined SIP peers.<br />
/// For each peer that is found a PeerEntryEvent is sent by Asterisk containing
/// the details. When all peers have been reported a PeerlistCompleteEvent is sent.<br/>
/// the details. When all peers have been reported a PeerlistCompleteEvent is sent.<br />
/// Available since Asterisk 1.2
/// </summary>
/// <seealso cref="Manager.event.PeerEntryEvent" />
@ -16,16 +17,10 @@ namespace AsterNET.Manager.Action
{
get { return "SIPPeers"; }
}
public override Type ActionCompleteEventClass()
{
return typeof(Event.PeerlistCompleteEvent);
}
/// <summary>
/// Creates a new SIPPeersAction.
/// </summary>
public SIPPeersAction()
{
return typeof (PeerlistCompleteEvent);
}
}
}

View file

@ -1,37 +1,18 @@
using System;
using AsterNET.Manager.Event;
namespace AsterNET.Manager.Action
{
/// <summary>
/// Retrieves a the details about a given SIP peer.<br/>
/// Retrieves a the details about a given SIP peer.<br />
/// For a PeerEntryEvent is sent by Asterisk containing the details of the peer
/// followed by a PeerlistCompleteEvent.<br/>
/// followed by a PeerlistCompleteEvent.<br />
/// Available since Asterisk 1.2
/// </summary>
/// <seealso cref="Manager.event.PeerEntryEvent" />
/// <seealso cref="Manager.event.PeerlistCompleteEvent" />
public class SIPShowPeerAction : ManagerActionEvent
{
private string peer;
override public string Action
{
get { return "SIPShowPeer"; }
}
/// <summary>
/// Get/Set the name of the peer to retrieve.<br/>
/// This parameter is mandatory.
/// </summary>
public string Peer
{
get { return this.peer; }
set { this.peer = value; }
}
public override Type ActionCompleteEventClass()
{
return typeof(Event.PeerlistCompleteEvent);
}
/// <summary> Creates a new empty SIPShowPeerAction.</summary>
public SIPShowPeerAction()
{
@ -42,7 +23,23 @@ namespace AsterNET.Manager.Action
/// </summary>
public SIPShowPeerAction(string peer)
{
this.peer = peer;
this.Peer = peer;
}
public override string Action
{
get { return "SIPShowPeer"; }
}
/// <summary>
/// Get/Set the name of the peer to retrieve.<br />
/// This parameter is mandatory.
/// </summary>
public string Peer { get; set; }
public override Type ActionCompleteEventClass()
{
return typeof (PeerlistCompleteEvent);
}
}
}

View file

@ -1,52 +1,13 @@
using System;
namespace AsterNET.Manager.Action
{
/// <summary>
/// The SetCDRUserFieldAction causes the user field of the call detail record for the given channel to be changed.<br/>
/// Depending on the value of the append property the value is appended or overwritten.<br/>
/// The SetCDRUserFieldAction causes the user field of the call detail record for the given channel to be changed.
/// <br />
/// Depending on the value of the append property the value is appended or overwritten.<br />
/// The SetCDRUserFieldAction is implemented in <code>apps/app_setcdruserfield.c</code>
/// </summary>
public class SetCDRUserFieldAction : ManagerAction
{
private string channel;
private string userField;
private bool append;
/// <summary>
/// Get the name of the action, i.e. "SetCDRUserField".
/// </summary>
override public string Action
{
get { return "SetCDRUserField"; }
}
/// <summary>
/// Get/Set the name of the channel to set the cdr user field on.<br/>
/// This property is mandatory.
/// </summary>
public string Channel
{
get { return this.channel; }
set { this.channel = value; }
}
/// <summary>
/// Get/Set the value of the cdr user field to set or append.<br/>
/// This property is mandatory.
/// </summary>
public string UserField
{
get { return this.userField; }
set { this.userField = value; }
}
/// <summary>
/// Get/Set if the value of the cdr user field is appended or overwritten.<br/>
/// <code>true</code> to append the value to the cdr user field or <code>false</code> to overwrite.
/// </summary>
public bool Append
{
get { return this.append; }
set { this.append = value; }
}
/// <summary>
/// Creates a new empty SetCDRUserFieldAction.
/// </summary>
@ -55,27 +16,55 @@ namespace AsterNET.Manager.Action
}
/// <summary>
/// Creates a new SetCDRUserFieldAction that sets the user field of the call detail record for the given channel to the given value.
/// Creates a new SetCDRUserFieldAction that sets the user field of the call detail record for the given channel to the
/// given value.
/// </summary>
/// <param name="channel">the name of the channel</param>
/// <param name="userField">the new value of the userfield</param>
public SetCDRUserFieldAction(string channel, string userField)
{
this.channel = channel;
this.userField = userField;
this.Channel = channel;
this.UserField = userField;
}
/// <summary>
/// Creates a new SetCDRUserFieldAction that sets the user field of the call detail record for the given channel to the given value.
/// Creates a new SetCDRUserFieldAction that sets the user field of the call detail record for the given channel to the
/// given value.
/// </summary>
/// <param name="channel">the name of the channel</param>
/// <param name="userField">the new value of the userfield</param>
/// <param name="append">true to append the value to the cdr user field or false to overwrite</param>
public SetCDRUserFieldAction(string channel, string userField, bool append)
{
this.channel = channel;
this.userField = userField;
this.append = append;
this.Channel = channel;
this.UserField = userField;
this.Append = append;
}
/// <summary>
/// Get the name of the action, i.e. "SetCDRUserField".
/// </summary>
public override string Action
{
get { return "SetCDRUserField"; }
}
/// <summary>
/// Get/Set the name of the channel to set the cdr user field on.<br />
/// This property is mandatory.
/// </summary>
public string Channel { get; set; }
/// <summary>
/// Get/Set the value of the cdr user field to set or append.<br />
/// This property is mandatory.
/// </summary>
public string UserField { get; set; }
/// <summary>
/// Get/Set if the value of the cdr user field is appended or overwritten.<br />
/// <code>true</code> to append the value to the cdr user field or <code>false</code> to overwrite.
/// </summary>
public bool Append { get; set; }
}
}

View file

@ -1,5 +1,3 @@
using System;
namespace AsterNET.Manager.Action
{
/// <summary>
@ -9,43 +7,13 @@ namespace AsterNET.Manager.Action
{
/// <summary> The channel on which to set the variable.</summary>
public string channel;
/// <summary> The name of the variable to set.</summary>
public string varName;
/// <summary> The value to store.</summary>
public string varValue;
/// <summary>
/// Get the name of this action, i.e. "SetVar".
/// </summary>
override public string Action
{
get { return "SetVar"; }
}
/// <summary>
/// Get/Set the name of the channel.
/// </summary>
public string Channel
{
get { return channel; }
set { this.channel = value; }
}
/// <summary>
/// Get/Set the name of the variable to set.
/// </summary>
public string Variable
{
get { return this.varName; }
set { this.varName = value; }
}
/// <summary>
/// Get/Set the value to store.
/// </summary>
public string Value
{
get { return this.varValue; }
set { this.varValue = value; }
}
/// <summary>
/// Creates a new empty SetVarAction.
/// </summary>
@ -60,8 +28,8 @@ namespace AsterNET.Manager.Action
/// <param name="value">the new value</param>
public SetVarAction(string variable, string value)
{
this.varName = variable;
this.varValue = value;
varName = variable;
varValue = value;
}
/// <summary>
@ -74,8 +42,43 @@ namespace AsterNET.Manager.Action
public SetVarAction(string channel, string variable, string value)
{
this.channel = channel;
this.varName = variable;
this.varValue = value;
varName = variable;
varValue = value;
}
/// <summary>
/// Get the name of this action, i.e. "SetVar".
/// </summary>
public override string Action
{
get { return "SetVar"; }
}
/// <summary>
/// Get/Set the name of the channel.
/// </summary>
public string Channel
{
get { return channel; }
set { channel = value; }
}
/// <summary>
/// Get/Set the name of the variable to set.
/// </summary>
public string Variable
{
get { return varName; }
set { varName = value; }
}
/// <summary>
/// Get/Set the value to store.
/// </summary>
public string Value
{
get { return varValue; }
set { varValue = value; }
}
}
}

View file

@ -1,9 +1,10 @@
using System;
using AsterNET.Manager.Event;
namespace AsterNET.Manager.Action
{
/// <summary>
/// The StatusAction requests the state of all active channels.<br/>
/// The StatusAction requests the state of all active channels.<br />
/// For each active channel a StatusEvent is generated. After the state of all
/// channels has been reported a StatusCompleteEvent is generated.
/// </summary>
@ -18,16 +19,10 @@ namespace AsterNET.Manager.Action
{
get { return "Status"; }
}
public override Type ActionCompleteEventClass()
{
return typeof(Event.StatusCompleteEvent);
}
/// <summary>
/// Creates a new StatusAction.
/// </summary>
public StatusAction()
{
return typeof (StatusCompleteEvent);
}
}
}

View file

@ -1,53 +1,54 @@
using System;
namespace AsterNET.Manager.Action
{
/// <summary>
/// The StopMonitorAction ends monitoring (recording) a channel.<br/>
/// The StopMonitorAction ends monitoring (recording) a channel.<br />
/// It is implemented in <code>res/res_monitor.c</code>
/// </summary>
public class StopMonitorAction : ManagerAction
{
/// <summary> The name of the channel to end monitoring.</summary>
private string channel;
#region Action
/// <summary>
/// Get the name of this action, i.e. "StopMonitor".
/// </summary>
override public string Action
public override string Action
{
get { return "StopMonitor"; }
}
#endregion
#region Channel
/// <summary>
/// Get/Set the name of the channel to end monitoring.<br/>
/// Get/Set the name of the channel to end monitoring.<br />
/// This property is mandatory.
/// </summary>
public string Channel
{
get { return this.channel; }
set { this.channel = value; }
}
public string Channel { get; set; }
#endregion
#region StopMonitorAction()
/// <summary>
/// Creates a new empty StopMonitorAction.
/// </summary>
public StopMonitorAction()
{
}
#endregion
#region StopMonitorAction(string channel)
/// <summary>
/// Creates a new StopMonitorAction that ends monitoring of the given channel.
/// </summary>
public StopMonitorAction(string channel)
{
this.channel = channel;
this.Channel = channel;
}
#endregion
}
}

View file

@ -1,6 +1,5 @@
using System;
using AsterNET.Manager.Response;
using System.Collections.Generic;
using AsterNET.Manager.Response;
namespace AsterNET.Manager.Action
{
@ -12,15 +11,15 @@ namespace AsterNET.Manager.Action
/// what actions you would like to take on the configuration file. It will
/// generate appropriate sequence numbers for the command. You may use the static
/// ACTION_* fields provided by this action to specify what action you would like
/// to take, while avoiding handling the strings required. Plain fields:<br/>
/// SrcFilename: Configuration filename to read(e.g. foo.conf)<br/>
/// DstFilename: Configuration filename to write(e.g. foo.conf)<br/>
/// Reload: Whether or not a reload should take place (or name of specific module)<br/>
/// Repeatable fields:<br/>
/// Action-XXXXXX: Action to Take (NewCat,RenameCat,DelCat,Update,Delete,Append)<br/>
/// Cat-XXXXXX: Category to operate on<br/>
/// Var-XXXXXX: Variable to work on<br/>
/// Value-XXXXXX: Value to work on<br/>
/// to take, while avoiding handling the strings required. Plain fields:<br />
/// SrcFilename: Configuration filename to read(e.g. foo.conf)<br />
/// DstFilename: Configuration filename to write(e.g. foo.conf)<br />
/// Reload: Whether or not a reload should take place (or name of specific module)<br />
/// Repeatable fields:<br />
/// Action-XXXXXX: Action to Take (NewCat,RenameCat,DelCat,Update,Delete,Append)<br />
/// Cat-XXXXXX: Category to operate on<br />
/// Var-XXXXXX: Variable to work on<br />
/// Value-XXXXXX: Value to work on<br />
/// Match-XXXXXX: Extra match required to match line
/// </summary>
public class UpdateConfigAction : ManagerActionResponse
@ -32,20 +31,16 @@ namespace AsterNET.Manager.Action
public const string ACTION_DELETE = "delete";
public const string ACTION_APPEND = "append";
private string reload;
private string srcFileName;
private string dstFileName;
private readonly Dictionary<string, string> actions;
private int actionCounter;
private Dictionary<string, string> actions;
/// <summary>
/// Creates a new UpdateConfigAction.
/// </summary>
public UpdateConfigAction()
: base()
{
actionCounter = 0;
actions = new Dictionary<string,string>();
actions = new Dictionary<string, string>();
}
/// <summary>
@ -54,9 +49,9 @@ namespace AsterNET.Manager.Action
public UpdateConfigAction(string srcFilename, string dstFilename, string reload)
: this()
{
this.srcFileName = srcFilename;
this.dstFileName = dstFilename;
this.reload = reload;
SrcFileName = srcFilename;
DstFileName = dstFilename;
this.Reload = reload;
}
/// <summary>
@ -65,9 +60,9 @@ namespace AsterNET.Manager.Action
public UpdateConfigAction(string srcFilename, string dstFilename, bool reload)
: this()
{
this.srcFileName = srcFilename;
this.dstFileName = dstFilename;
this.reload = (reload ? "true" : "");
SrcFileName = srcFilename;
DstFileName = dstFilename;
this.Reload = (reload ? "true" : "");
}
/// <summary>
@ -76,38 +71,26 @@ namespace AsterNET.Manager.Action
public UpdateConfigAction(string srcFilename, string dstFilename)
: this()
{
this.srcFileName = srcFilename;
this.dstFileName = dstFilename;
this.reload = "";
SrcFileName = srcFilename;
DstFileName = dstFilename;
Reload = "";
}
/// <summary>
/// Get/Set the destination filename.
/// </summary>
public string DstFileName
{
get { return dstFileName; }
set { dstFileName = value; }
}
public string DstFileName { get; set; }
/// <summary>
/// Get/Set the source filename.
/// </summary>
public string SrcFileName
{
get { return srcFileName; }
set { srcFileName = value; }
}
public string SrcFileName { get; set; }
/// <summary>
/// Get/Set the reload behavior of this action (yes), or sets a specific module (name) to be reloaded.<br/>
/// Get/Set the reload behavior of this action (yes), or sets a specific module (name) to be reloaded.<br />
/// Set to empty string to update without reload.
/// </summary>
public string Reload
{
get { return reload; }
set { reload = value; }
}
public string Reload { get; set; }
/// <summary>
/// Get the name of this action.
@ -118,6 +101,7 @@ namespace AsterNET.Manager.Action
}
#region AddCommand(...)
/// <summary>
/// Adds a command to update a config file while sparing you the details of
/// the Manager's required syntax. If you want to omit one of the command's
@ -175,24 +159,27 @@ namespace AsterNET.Manager.Action
{
AddCommand(null, null, null, null, null);
}
#endregion
#region Actions
/// <summary>
/// Dictionary of the action's desired operations where Map keys contain:<br/>
/// Dictionary of the action's desired operations where Map keys contain:<br />
/// action,cat,var,value,match pairs followed by -XXXXXX, and the values contain the values for those keys.
/// This method will typically only be used by the ActionBuilder to generate the actual strings to be sent to the manager interface.
/// This method will typically only be used by the ActionBuilder to generate the actual strings to be sent to the
/// manager interface.
/// </summary>
public Dictionary<string, string> Actions
{
get { return actions; }
}
#endregion
public override object ActionCompleteResponseClass()
{
return new ManagerResponse();
}
}
}

View file

@ -1,5 +1,3 @@
using System;
namespace AsterNET.Manager.Action
{
/// <summary>
@ -7,36 +5,33 @@ namespace AsterNET.Manager.Action
/// </summary>
public class ZapDNDOffAction : ManagerAction
{
private int zapChannel;
/// <summary>
/// Get the name of this action, i.e. "ZapDNDOff".
/// </summary>
override public string Action
{
get { return "ZapDNDOff"; }
}
/// <summary>
/// Get/Set the number of the zap channel to switch to dnd off.<br/>
/// This property is mandatory.
/// </summary>
public int ZapChannel
{
get { return this.zapChannel; }
set { this.zapChannel = value; }
}
/// <summary>
/// Creates a new empty ZapDNDOffAction.
/// </summary>
public ZapDNDOffAction()
{
}
/// <summary>
/// Creates a new ZapDNDOffAction that disables "Do Not Disturb" status for the given zap channel.
/// </summary>
public ZapDNDOffAction(int zapChannel)
{
this.zapChannel = zapChannel;
this.ZapChannel = zapChannel;
}
/// <summary>
/// Get the name of this action, i.e. "ZapDNDOff".
/// </summary>
public override string Action
{
get { return "ZapDNDOff"; }
}
/// <summary>
/// Get/Set the number of the zap channel to switch to dnd off.<br />
/// This property is mandatory.
/// </summary>
public int ZapChannel { get; set; }
}
}

View file

@ -1,5 +1,3 @@
using System;
namespace AsterNET.Manager.Action
{
/// <summary>
@ -7,24 +5,6 @@ namespace AsterNET.Manager.Action
/// </summary>
public class ZapDNDOnAction : ManagerAction
{
private int zapChannel;
/// <summary>
/// Get the name of this action, i.e. "ZapDNDOn".
/// </summary>
override public string Action
{
get { return "ZapDNDOn"; }
}
/// <summary>
/// Get/Set the number of the zap channel to switch to dnd on.<br/>
/// This property is mandatory.
/// </summary>
public int ZapChannel
{
get { return this.zapChannel; }
set { this.zapChannel = value; }
}
/// <summary>
/// Creates a new empty ZapDNDOnAction.
/// </summary>
@ -37,7 +17,21 @@ namespace AsterNET.Manager.Action
/// </summary>
public ZapDNDOnAction(int zapChannel)
{
this.zapChannel = zapChannel;
this.ZapChannel = zapChannel;
}
/// <summary>
/// Get the name of this action, i.e. "ZapDNDOn".
/// </summary>
public override string Action
{
get { return "ZapDNDOn"; }
}
/// <summary>
/// Get/Set the number of the zap channel to switch to dnd on.<br />
/// This property is mandatory.
/// </summary>
public int ZapChannel { get; set; }
}
}

View file

@ -1,5 +1,3 @@
using System;
namespace AsterNET.Manager.Action
{
/// <summary>
@ -7,35 +5,6 @@ namespace AsterNET.Manager.Action
/// </summary>
public class ZapDialOffhookAction : ManagerAction
{
private int zapChannel;
private string number;
/// <summary>
/// Get the name of this action, i.e. "ZapDialOffhook".
/// </summary>
override public string Action
{
get { return "ZapDialOffhook"; }
}
/// <summary>
/// Get/Set the number of the zap channel.<br/>
/// This property is mandatory.
/// </summary>
public int ZapChannel
{
get { return this.zapChannel; }
set { this.zapChannel = value; }
}
/// <summary>
/// Get/Set the number to dial.<br/>
/// This property is mandatory.
/// </summary>
public string Number
{
get { return this.number; }
set { this.number = value; }
}
/// <summary> Creates a new empty ZapDialOffhookAction.</summary>
public ZapDialOffhookAction()
{
@ -46,8 +15,28 @@ namespace AsterNET.Manager.Action
/// </summary>
public ZapDialOffhookAction(int zapChannel, string number)
{
this.zapChannel = zapChannel;
this.number = number;
this.ZapChannel = zapChannel;
this.Number = number;
}
/// <summary>
/// Get the name of this action, i.e. "ZapDialOffhook".
/// </summary>
public override string Action
{
get { return "ZapDialOffhook"; }
}
/// <summary>
/// Get/Set the number of the zap channel.<br />
/// This property is mandatory.
/// </summary>
public int ZapChannel { get; set; }
/// <summary>
/// Get/Set the number to dial.<br />
/// This property is mandatory.
/// </summary>
public string Number { get; set; }
}
}

View file

@ -1,5 +1,3 @@
using System;
namespace AsterNET.Manager.Action
{
/// <summary>
@ -7,25 +5,6 @@ namespace AsterNET.Manager.Action
/// </summary>
public class ZapHangupAction : ManagerAction
{
private int zapChannel;
/// <summary>
/// Get the name of this action, i.e. "ZapHangup".
/// </summary>
override public string Action
{
get { return "ZapHangup"; }
}
/// <summary>
/// Get/Set the number of the zap channel to hangup.<br/>
/// This property is mandatory.
/// </summary>
public int ZapChannel
{
get { return this.zapChannel; }
set { this.zapChannel = value; }
}
/// <summary>
/// Creates a new empty ZapHangupAction.
/// </summary>
@ -38,7 +17,21 @@ namespace AsterNET.Manager.Action
/// </summary>
public ZapHangupAction(int zapChannel)
{
this.zapChannel = zapChannel;
this.ZapChannel = zapChannel;
}
/// <summary>
/// Get the name of this action, i.e. "ZapHangup".
/// </summary>
public override string Action
{
get { return "ZapHangup"; }
}
/// <summary>
/// Get/Set the number of the zap channel to hangup.<br />
/// This property is mandatory.
/// </summary>
public int ZapChannel { get; set; }
}
}

View file

@ -1,8 +1,10 @@
using System;
using AsterNET.Manager.Event;
namespace AsterNET.Manager.Action
{
/// <summary>
/// The ZapShowChannelsAction requests the state of all zap channels.<br/>
/// The ZapShowChannelsAction requests the state of all zap channels.<br />
/// For each zap channel a ZapShowChannelsEvent is generated. After all zap
/// channels have been listed a ZapShowChannelsCompleteEvent is generated.
/// </summary>
@ -17,16 +19,10 @@ namespace AsterNET.Manager.Action
{
get { return "ZapShowChannels"; }
}
public override Type ActionCompleteEventClass()
{
return typeof(Event.ZapShowChannelsCompleteEvent);
}
/// <summary>
/// Creates a new ZapShowChannelsAction.
/// </summary>
public ZapShowChannelsAction()
{
return typeof (ZapShowChannelsCompleteEvent);
}
}
}

View file

@ -1,4 +1,3 @@
using System;
namespace AsterNET.Manager.Action
{
/// <summary>
@ -6,23 +5,18 @@ namespace AsterNET.Manager.Action
/// </summary>
public class ZapTransferAction : ManagerAction
{
private int zapChannel;
/// <summary>
/// Get the name of this action, i.e. "ZapTransfer".
/// </summary>
override public string Action
public override string Action
{
get { return "ZapTransfer"; }
}
/// <summary>
/// Get/Set the number of the zap channel to transfer.<br/>
/// Get/Set the number of the zap channel to transfer.<br />
/// This property is mandatory.
/// </summary>
public int ZapChannel
{
get { return this.zapChannel; }
set { this.zapChannel = value; }
}
public int ZapChannel { get; set; }
}
}

View file

@ -1,5 +1,3 @@
using System;
namespace AsterNET.Manager
{
public enum AsteriskVersion

View file

@ -1,19 +1,11 @@
using System;
namespace AsterNET.Manager.Event
{
/// <summary>
/// AgiExecEvents are triggered when an AGI command is executed.<br/>
/// AgiExecEvents are triggered when an AGI command is executed.<br />
/// For each command two events are triggered: one before excution ("Start") and one after execution ("End").
/// </summary>
public class AGIExecEvent : ManagerEvent
{
private string subEvent;
private long commandId;
private string command;
private int resultCode;
private string result;
/// <summary>
/// Creates a new AGIExecEvent.
/// </summary>
@ -22,30 +14,14 @@ namespace AsterNET.Manager.Event
{
}
public long CommandId
{
get { return commandId; }
set { this.commandId = value; }
}
public string Command
{
get { return command; }
set { this.command = value; }
}
public string SubEvent
{
get { return subEvent; }
set { this.subEvent = value; }
}
public string Result
{
get { return result; }
set { this.result = value; }
}
public int ResultCode
{
get { return resultCode; }
set { this.resultCode = value; }
}
public long CommandId { get; set; }
public string Command { get; set; }
public string SubEvent { get; set; }
public string Result { get; set; }
public int ResultCode { get; set; }
}
}

View file

@ -5,38 +5,24 @@ namespace AsterNET.Manager.Event
/// </summary>
public abstract class AbstractAgentEvent : AbstractAgentVariables
{
private string queue;
private string member;
private string memberName;
public AbstractAgentEvent(ManagerConnection source)
: base(source)
{
}
/// <summary>
/// Get/Set the name of the queue.
/// </summary>
public string Queue
{
get { return queue; }
set { this.queue = value; }
}
/// <summary>
/// Get/Set the name of the member's interface.
/// </summary>
public string Member
{
get { return member; }
set { this.member = value; }
}
public string Queue { get; set; }
/// <summary>
/// Get/Set the name of the member's interface.
/// </summary>
public string MemberName
{
get { return memberName; }
set { this.memberName = value; }
}
public string Member { get; set; }
public AbstractAgentEvent(ManagerConnection source)
: base(source)
{ }
/// <summary>
/// Get/Set the name of the member's interface.
/// </summary>
public string MemberName { get; set; }
}
}

View file

@ -5,26 +5,16 @@ namespace AsterNET.Manager.Event
/// </summary>
public abstract class AbstractMeetmeEvent : ManagerEvent
{
private string meetMe;
private int userNum;
/// <summary>
/// Get/Set the conference number.
/// </summary>
public string Meetme
{
get { return meetMe; }
set { this.meetMe = value; }
}
public int Usernum
{
get { return userNum; }
set { this.userNum = value; }
}
public AbstractMeetmeEvent(ManagerConnection source)
: base(source)
{
}
/// <summary>
/// Get/Set the conference number.
/// </summary>
public string Meetme { get; set; }
public int Usernum { get; set; }
}
}

View file

@ -5,46 +5,29 @@ namespace AsterNET.Manager.Event
/// </summary>
public abstract class AbstractParkedCallEvent : ManagerEvent
{
private string exten;
private string callerId;
private string callerIdNum;
private string callerIdName;
public AbstractParkedCallEvent(ManagerConnection source)
: base(source)
{
}
/// <summary>
/// Get/Set the extension the channel is or was parked at.
/// </summary>
public string Exten
{
get { return this.exten; }
set { this.exten = value; }
}
public string Exten { get; set; }
/// <summary>
/// Get/Set the Caller*ID number of the parked channel.
/// </summary>
public string CallerId
{
get { return this.callerId; }
set { this.callerId = value; }
}
public string CallerId { get; set; }
/// <summary>
/// Get/Set the Caller*ID number of the parked channel.
/// </summary>
public string CallerIdNum
{
get { return this.callerIdNum; }
set { this.callerIdNum = value; }
}
public string CallerIdNum { get; set; }
/// <summary>
/// Get/Set the Caller*ID name of the parked channel.
/// </summary>
public string CallerIdName
{
get { return this.callerIdName; }
set { this.callerIdName = value; }
}
public AbstractParkedCallEvent(ManagerConnection source)
: base(source)
{ }
public string CallerIdName { get; set; }
}
}

View file

@ -5,29 +5,20 @@ namespace AsterNET.Manager.Event
/// </summary>
public abstract class AbstractQueueMemberEvent : ManagerEvent
{
private string queue;
private string location;
public AbstractQueueMemberEvent(ManagerConnection source)
: base(source)
{
}
/// <summary>
/// Returns the name of the queue.
/// </summary>
public string Queue
{
get { return queue; }
set { this.queue = value; }
}
public string Queue { get; set; }
/// <summary>
/// Returns the name of the member's interface.<br/>
/// Returns the name of the member's interface.<br />
/// E.g. the channel name or agent group.
/// </summary>
public string Location
{
get { return location; }
set { this.location = value; }
}
public AbstractQueueMemberEvent(ManagerConnection source)
: base(source)
{ }
public string Location { get; set; }
}
}

View file

@ -1,31 +1,22 @@
namespace AsterNET.Manager.Event
{
/// <summary>
/// An AgentCallbackLoginEvent is triggered when an agent is successfully logged in using AgentCallbackLogin.<br/>
/// An AgentCallbackLoginEvent is triggered when an agent is successfully logged in using AgentCallbackLogin.<br />
/// It is implemented in <code>channels/chan_agent.c</code>
/// </summary>
/// <seealso cref="Manager.event.AgentCallbackLogoffEvent" />
public class AgentCallbackLoginEvent : ManagerEvent
{
private string agent;
private string loginChan;
public AgentCallbackLoginEvent(ManagerConnection source)
: base(source)
{
}
/// <summary>
/// Get/Set the name of the agent that logged in.
/// </summary>
public string Agent
{
get { return agent; }
set { this.agent = value; }
}
public string LoginChan
{
get { return loginChan; }
set { this.loginChan = value; }
}
public string Agent { get; set; }
public AgentCallbackLoginEvent(ManagerConnection source)
: base(source)
{ }
public string LoginChan { get; set; }
}
}

View file

@ -2,91 +2,47 @@ namespace AsterNET.Manager.Event
{
/// <summary>
/// An AgentCallbackLogoffEvent is triggered when an agent that previously logged in using
/// AgentCallbackLogin is logged of.<br/>
/// AgentCallbackLogin is logged of.<br />
/// It is implemented in <code>channels/chan_agent.c</code>
/// </summary>
/// <seealso cref="Manager.event.AgentCallbackLoginEvent" />
public class AgentCallbackLogoffEvent : ManagerEvent
{
private string agent;
private string loginChan;
private string loginTime;
private string reason;
#region Agent
/// <summary> Returns the name of the agent that logged off.</summary>
/// <summary> Sets the name of the agent that logged off.</summary>
public string Agent
{
get
{
return agent;
}
public string Agent { get; set; }
set
{
this.agent = value;
}
}
#endregion
#region LoginChan
public string LoginChan
{
get
{
return loginChan;
}
set
{
this.loginChan = value;
}
public string LoginChan { get; set; }
}
#endregion
#region LoginTime
public string LoginTime
{
get
{
return loginTime;
}
set
{
this.loginTime = value;
}
public string LoginTime { get; set; }
}
#endregion
#region Reason
/// <summary>
/// Returns the reason for the logoff. The reason is set to Autologoff if the agent has been
/// logged off due to not answering the phone in time. Autologoff is configured by setting
/// <code>autologoff</code> to the appropriate number of seconds in <code>agents.conf</code>.
/// </summary>
/// <summary>Sets the reason for the logoff.</summary>
public string Reason
{
get
{
return reason;
}
public string Reason { get; set; }
set
{
this.reason = value;
}
}
#endregion
public AgentCallbackLogoffEvent(ManagerConnection source)
: base(source)
{ }
{
}
}
}

View file

@ -1,89 +1,43 @@
using System.Collections;
namespace AsterNET.Manager.Event
{
/// <summary>
/// An AgentCalledEvent is triggered when an agent is rung.<br/>
/// To enable AgentCalledEvents you have to set <code>eventwhencalled = yes</code> in <code>queues.conf</code>.<br/>
/// An AgentCalledEvent is triggered when an agent is rung.<br />
/// To enable AgentCalledEvents you have to set <code>eventwhencalled = yes</code> in <code>queues.conf</code>.<br />
/// This event is implemented in <code>apps/app_queue.c</code>
/// </summary>
public class AgentCalledEvent : AbstractAgentVariables
{
private string agentCalled;
private string agentName;
private string callerId;
private string callerIdName;
private string callerIdNum;
private string channelCalling;
private string context;
private string destinationChannel;
private string extension;
private string priority;
private string queue;
public AgentCalledEvent(ManagerConnection source)
: base(source)
{
}
public string Queue { get; set; }
public string AgentName { get; set; }
public string AgentCalled { get; set; }
public string ChannelCalling { get; set; }
public string DestinationChannel { get; set; }
public string CallerId { get; set; }
public string Queue
{
get { return this.queue; }
set { this.queue = value; }
}
public string AgentName
{
get { return agentName; }
set { this.agentName = value; }
}
public string AgentCalled
{
get { return agentCalled; }
set { this.agentCalled = value; }
}
public string ChannelCalling
{
get { return channelCalling; }
set { this.channelCalling = value; }
}
public string DestinationChannel
{
get { return this.destinationChannel; }
set { this.destinationChannel = value; }
}
public string CallerId
{
get { return callerId; }
set { this.callerId = value; }
}
/// <summary>
/// Get/Set the Caller*ID number of the calling channel.
/// </summary>
public string CallerIdNum
{
get { return callerIdNum; }
set { this.callerIdNum = value; }
}
public string CallerIdNum { get; set; }
/// <summary>
/// Get/Set the Caller*ID name of the calling channel.
/// </summary>
public string CallerIdName
{
get { return callerIdName; }
set { this.callerIdName = value; }
}
public string Context
{
get { return context; }
set { this.context = value; }
}
public string Extension
{
get { return extension; }
set { this.extension = value; }
}
public string Priority
{
get { return priority; }
set { this.priority = value; }
}
public string CallerIdName { get; set; }
public AgentCalledEvent(ManagerConnection source)
: base(source)
{ }
public string Context { get; set; }
public string Extension { get; set; }
public string Priority { get; set; }
}
}

View file

@ -5,37 +5,24 @@ namespace AsterNET.Manager.Event
/// </summary>
public class AgentCompleteEvent : AbstractAgentEvent
{
private long holdTime;
private string reason;
private long talkTime;
public AgentCompleteEvent(ManagerConnection source)
: base(source)
{
}
/// <summary>
/// Get/Set the amount of time the caller was on hold.
/// </summary>
public long HoldTime
{
get { return holdTime; }
set { this.holdTime = value; }
}
public long HoldTime { get; set; }
/// <summary>
/// Get/Set the amount of time the caller talked to the agent.
/// </summary>
public long TalkTime
{
get { return talkTime; }
set { this.talkTime = value; }
}
public long TalkTime { get; set; }
/// <summary>
/// Get/Set if the agent or the caller terminated the call.
/// </summary>
public string Reason
{
get { return reason; }
set { this.reason = value; }
}
public AgentCompleteEvent(ManagerConnection source)
: base(source)
{ }
public string Reason { get; set; }
}
}

View file

@ -5,40 +5,24 @@ namespace AsterNET.Manager.Event
/// </summary>
public class AgentConnectEvent : AbstractAgentEvent
{
private string bridgedChannel;
private long holdTime;
private long ringTime;
/// <summary>
/// Get/Set the amount of time the caller was on hold.
/// </summary>
public long HoldTime
{
get { return holdTime; }
set { this.holdTime = value; }
}
/// <summary>
/// Get/Set bridged channel.
/// </summary>
public string BridgedChannel
{
get { return this.bridgedChannel; }
set { this.bridgedChannel = value; }
}
/// <summary>
/// Get/Set the amount of time the caller was on ring.
/// </summary>
public long RingTime
{
get { return ringTime; }
set { this.ringTime = value; }
}
public AgentConnectEvent(ManagerConnection source)
: base(source)
{
}
/// <summary>
/// Get/Set the amount of time the caller was on hold.
/// </summary>
public long HoldTime { get; set; }
/// <summary>
/// Get/Set bridged channel.
/// </summary>
public string BridgedChannel { get; set; }
/// <summary>
/// Get/Set the amount of time the caller was on ring.
/// </summary>
public long RingTime { get; set; }
}
}

View file

@ -1,32 +1,22 @@
namespace AsterNET.Manager.Event
{
/// <summary>
/// An AgentLoginEvent is triggered when an agent is successfully logged in using AgentLogin.<br/>
/// An AgentLoginEvent is triggered when an agent is successfully logged in using AgentLogin.<br />
/// It is implemented in <code>channels/chan_agent.c</code>
/// </summary>
/// <seealso cref="Manager.event.AgentLogoffEvent" />
public class AgentLoginEvent : ManagerEvent
{
private string agent;
private string loginChan;
/// <summary>
/// Get/Set the name of the agent that logged in.
/// </summary>
public string Agent
{
get { return agent; }
set { this.agent = value; }
}
public string LoginChan
{
get { return loginChan; }
set { this.loginChan = value; }
}
public AgentLoginEvent(ManagerConnection source)
: base(source)
{
}
/// <summary>
/// Get/Set the name of the agent that logged in.
/// </summary>
public string Agent { get; set; }
public string LoginChan { get; set; }
}
}

View file

@ -1,32 +1,23 @@
namespace AsterNET.Manager.Event
{
/// <summary>
/// An AgentCallbackLogoffEvent is triggered when an agent that previously logged in using AgentLogin is logged of.<br/>
/// An AgentCallbackLogoffEvent is triggered when an agent that previously logged in using AgentLogin is logged of.
/// <br />
/// It is implemented in <code>channels/chan_agent.c</code>
/// </summary>
/// <seealso cref="Manager.event.AgentLoginEvent" />
public class AgentLogoffEvent : ManagerEvent
{
private string agent;
private string loginTime;
/// <summary>
/// Get/Set the name of the agent that logged off.
/// </summary>
public string Agent
{
get { return agent; }
set { this.agent = value; }
}
public string LoginTime
{
get { return loginTime; }
set { this.loginTime = value; }
}
public AgentLogoffEvent(ManagerConnection source)
: base(source)
{
}
/// <summary>
/// Get/Set the name of the agent that logged off.
/// </summary>
public string Agent { get; set; }
public string LoginTime { get; set; }
}
}

View file

@ -1,37 +1,29 @@
namespace AsterNET.Manager.Event
{
/// <summary>
/// An AgentsEvent is triggered for each agent in response to an AgentsAction.<br/>
/// An AgentsEvent is triggered for each agent in response to an AgentsAction.<br />
/// Available since Asterisk 1.2
/// </summary>
/// <seealso cref="Manager.Action.AgentsAction" />
public class AgentsEvent : ResponseEvent
{
private string agent;
private string name;
private string status;
private string loggedInChan;
private string talkingTo;
private long loggedInTime;
public AgentsEvent(ManagerConnection source)
: base(source)
{
}
/// <summary>
/// Get/Set the agentid.
/// </summary>
public string Agent
{
get { return this.agent; }
set { this.agent = value; }
}
public string Agent { get; set; }
/// <summary>
/// Get/Set the name of this agent.
/// </summary>
public string Name
{
get { return this.name; }
set { this.name = value; }
}
public string Name { get; set; }
/// <summary>
/// Get/Set the status of this agent.<br/>
/// Get/Set the status of this agent.<br />
/// This is one of
/// <dl>
/// <dt>"AGENT_LOGGEDOFF"</dt>
@ -44,39 +36,21 @@ namespace AsterNET.Manager.Event
/// <dd>Don't know anything about agent. Shouldn't ever get this.</dd>
/// </dl>
/// </summary>
public string Status
{
get { return this.status; }
set { this.status = value; }
}
public string Status { get; set; }
/// <summary>
/// Get/Set the name of channel this agent logged in from or "n/a" if the agent is not logged in.
/// </summary>
public string LoggedInChan
{
get { return this.loggedInChan; }
set { this.loggedInChan = value; }
}
public string LoggedInChan { get; set; }
/// <summary>
/// Get/Set the time (in seconds since 01/01/1970) when the agent logged in or 0 if the user is not logged.
/// </summary>
public long LoggedInTime
{
get { return this.loggedInTime; }
set { this.loggedInTime = value; }
}
public long LoggedInTime { get; set; }
/// <summary>
/// Get/Set the numerical Caller*ID of the channel this agent is talking toor "n/a" if this agent is talking to nobody.
/// </summary>
public string TalkingTo
{
get { return this.talkingTo; }
set { this.talkingTo = value; }
}
public AgentsEvent(ManagerConnection source)
: base(source)
{
}
public string TalkingTo { get; set; }
}
}

View file

@ -1,15 +1,18 @@
namespace AsterNET.Manager.Event
{
/// <summary>
/// An AlarmEvent is triggered when a Zap channel enters or changes alarm state.<br/>
/// An AlarmEvent is triggered when a Zap channel enters or changes alarm state.<br />
/// It is implemented in <code>channels/chan_zap.c</code>
/// </summary>
public class AlarmEvent : ManagerEvent
{
private string alarm;
public AlarmEvent(ManagerConnection source)
: base(source)
{
}
/// <summary>
/// Get/Set the kind of alarm that happened.<br/>
/// Get/Set the kind of alarm that happened.<br />
/// This may be one of
/// <ul>
/// <li>Red Alarm</li>
@ -20,15 +23,6 @@ namespace AsterNET.Manager.Event
/// <li>Not Open</li>
/// </ul>
/// </summary>
public string Alarm
{
get { return alarm; }
set { this.alarm = value; }
}
public AlarmEvent(ManagerConnection source)
: base(source)
{
}
public string Alarm { get; set; }
}
}

View file

@ -1,40 +1,22 @@
using System;
namespace AsterNET.Manager.Event
{
public class AsyncAGIEvent : ManagerEvent
{
private string subEvent;
private string env;
private string result;
private string commandId;
public string Result { get; set; }
public string Result
{
get { return result; }
set { result = value; }
}
public string CommandId
{
get { return commandId; }
set { commandId = value; }
}
public string SubEvent
{
get { return subEvent; }
set { subEvent = value; }
}
public string Env
{
get { return env; }
set { env = value; }
}
public string CommandId { get; set; }
public string SubEvent { get; set; }
public string Env { get; set; }
#region Constructor - AsyncAGIEvent(ManagerConnection source)
public AsyncAGIEvent(ManagerConnection source)
: base(source)
{
}
#endregion
}
}

View file

@ -1,114 +1,48 @@
namespace AsterNET.Manager.Event
{
/// <summary>
/// A CdrEvent is triggered when a call detail record is generated, usually at the end of a call.<br/>
/// A CdrEvent is triggered when a call detail record is generated, usually at the end of a call.<br />
/// To enable CdrEvents you have to add <code>enabled = yes</code> to the general section in
/// <code>cdr_manager.conf</code>.<br/>
/// <code>cdr_manager.conf</code>.<br />
/// This event is implemented in <code>cdr/cdr_manager.c</code>
/// </summary>
public class CdrEvent : ManagerEvent
{
private string accountCode;
private string src;
private string destination;
private string destinationContext;
private string callerId;
private string destinationChannel;
private string lastApplication;
private string lastData;
private string startTime;
private string answerTime;
private string endTime;
private long duration;
private long billableSeconds;
private string disposition;
private string amaFlags;
private string userField;
public CdrEvent(ManagerConnection source)
: base(source)
{
}
public string AccountCode
{
get { return accountCode; }
set { this.accountCode = value; }
}
public string Src
{
get { return src; }
set { this.src = value; }
}
public string Destination
{
get { return destination; }
set { this.destination = value; }
}
public string DestinationContext
{
get { return destinationContext; }
set { this.destinationContext = value; }
}
public string CallerId
{
get { return callerId; }
set { this.callerId = value; }
}
public string DestinationChannel
{
get { return destinationChannel; }
set { this.destinationChannel = value; }
}
public string LastApplication
{
get { return lastApplication; }
set { this.lastApplication = value; }
}
public string LastData
{
get { return lastData; }
set { this.lastData = value; }
}
public string StartTime
{
get { return startTime; }
set { this.startTime = value; }
}
public string AnswerTime
{
get { return answerTime; }
set { this.answerTime = value; }
}
public string EndTime
{
get { return endTime; }
set { this.endTime = value; }
}
public long Duration
{
get { return duration; }
set { this.duration = value; }
}
public long BillableSeconds
{
get { return billableSeconds; }
set { this.billableSeconds = value; }
}
public string Disposition
{
get { return disposition; }
set { this.disposition = value; }
}
public string AmaFlags
{
get { return amaFlags; }
set { this.amaFlags = value; }
}
public string UserField
{
get { return userField; }
set { this.userField = value; }
}
public string AccountCode { get; set; }
public string Src { get; set; }
public string Destination { get; set; }
public string DestinationContext { get; set; }
public string CallerId { get; set; }
public string DestinationChannel { get; set; }
public string LastApplication { get; set; }
public string LastData { get; set; }
public string StartTime { get; set; }
public string AnswerTime { get; set; }
public string EndTime { get; set; }
public long Duration { get; set; }
public long BillableSeconds { get; set; }
public string Disposition { get; set; }
public string AmaFlags { get; set; }
public string UserField { get; set; }
}
}

Some files were not shown because too many files have changed in this diff Show more