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

View file

@ -1,3 +1,6 @@
using AsterNET.FastAGI.Command;
using AsterNET.IO;
namespace AsterNET.FastAGI namespace AsterNET.FastAGI
{ {
/// <summary> /// <summary>
@ -5,30 +8,30 @@ namespace AsterNET.FastAGI
/// </summary> /// </summary>
public class AGIChannel public class AGIChannel
{ {
private AGIWriter agiWriter; private readonly bool _SC511_CAUSES_EXCEPTION;
private AGIReader agiReader; private readonly bool _SCHANGUP_CAUSES_EXCEPTION;
private readonly AGIReader agiReader;
private readonly AGIWriter agiWriter;
private AGIReply agiReply; private AGIReply agiReply;
private bool _SC511_CAUSES_EXCEPTION = false;
private bool _SCHANGUP_CAUSES_EXCEPTION = false;
public AGIChannel(SocketConnection socket, bool SC511_CAUSES_EXCEPTION, bool SCHANGUP_CAUSES_EXCEPTION)
public AGIChannel(IO.SocketConnection socket, bool SC511_CAUSES_EXCEPTION, bool SCHANGUP_CAUSES_EXCEPTION)
{ {
this.agiWriter = new AGIWriter(socket); agiWriter = new AGIWriter(socket);
this.agiReader = new AGIReader(socket); agiReader = new AGIReader(socket);
this._SC511_CAUSES_EXCEPTION = SC511_CAUSES_EXCEPTION; _SC511_CAUSES_EXCEPTION = SC511_CAUSES_EXCEPTION;
this._SCHANGUP_CAUSES_EXCEPTION = SCHANGUP_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.agiWriter = agiWriter;
this.agiReader = agiReader; this.agiReader = agiReader;
this._SC511_CAUSES_EXCEPTION = SC511_CAUSES_EXCEPTION; _SC511_CAUSES_EXCEPTION = SC511_CAUSES_EXCEPTION;
this._SCHANGUP_CAUSES_EXCEPTION = SCHANGUP_CAUSES_EXCEPTION; _SCHANGUP_CAUSES_EXCEPTION = SCHANGUP_CAUSES_EXCEPTION;
} }
/// <summary> /// <summary>
@ -39,18 +42,18 @@ namespace AsterNET.FastAGI
get { return agiReply; } get { return agiReply; }
} }
public AGIReply SendCommand(Command.AGICommand command) public AGIReply SendCommand(AGICommand command)
{ {
agiWriter.SendCommand(command); agiWriter.SendCommand(command);
agiReply = agiReader.ReadReply(); agiReply = agiReader.ReadReply();
int status = agiReply.GetStatus(); 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()); 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()); 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(); 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(); throw new AGIHangupException();
return agiReply; return agiReply;
} }

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,10 +1,4 @@
using System; namespace AsterNET.Manager.Action
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AsterNET.Manager.Action
{ {
/// <summary> /// <summary>
/// This action lets you execute any AGI command through the Manager interface /// This action lets you execute any AGI command through the Manager interface
@ -12,17 +6,6 @@ namespace AsterNET.Manager.Action
/// </summary> /// </summary>
public class AgiAction : ManagerAction 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> /// <summary>
/// Creates a new empty AgiAction. /// Creates a new empty AgiAction.
/// </summary> /// </summary>
@ -32,6 +15,15 @@ namespace AsterNET.Manager.Action
Command = command; 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; namespace AsterNET.Manager.Action
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AsterNET.Manager.Action
{ {
public class AOCMessageAction : ManagerAction 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> /// <summary>
/// Generate an Advice of Charge message on a channel. /// Generate an Advice of Charge message on a channel.
/// </summary> /// </summary>
@ -47,22 +26,25 @@ namespace AsterNET.Manager.Action
/// <param name="chargingAssociationId"></param> /// <param name="chargingAssociationId"></param>
/// <param name="chargingAssociationNumber"></param> /// <param name="chargingAssociationNumber"></param>
/// <param name="chargingrAssociationPlan"></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; Channel = channel;
_channelPrefix = channelPrefix; ChannelPrefix = channelPrefix;
_msgType = msgType; MsgType = msgType;
_chargeType = chargeType; ChargeType = chargeType;
_unitAmount = unitAmount; UnitAmount = unitAmount;
_unitType = unitType; UnitType = unitType;
_currencyName = currencyName; CurrencyName = currencyName;
_currencyAmount = currencyAmount; CurrencyAmount = currencyAmount;
_currencyMultiplier = currencyMultiplier; CurrencyMultiplier = currencyMultiplier;
_totalType = totalType; TotalType = totalType;
_aocBillingId = aocBillingId; AocBillingId = aocBillingId;
_chargingAssociationId = chargingAssociationId; ChargingAssociationId = chargingAssociationId;
_chargingAssociationNumber = chargingAssociationNumber; ChargingAssociationNumber = chargingAssociationNumber;
_chargingrAssociationPlan = chargingrAssociationPlan; ChargingrAssociationPlan = chargingrAssociationPlan;
} }
public override string Action public override string Action
@ -70,88 +52,32 @@ namespace AsterNET.Manager.Action
get { return "AOCMessage"; } get { return "AOCMessage"; }
} }
public string Channel public string Channel { get; set; }
{
get { return _channel; }
set { _channel = value; }
}
public string ChannelPrefix public string ChannelPrefix { get; set; }
{
get { return _channelPrefix; }
set { _channelPrefix = value; }
}
public string MsgType public string MsgType { get; set; }
{
get { return _msgType; }
set { _msgType = value; }
}
public string ChargeType public string ChargeType { get; set; }
{
get { return _chargeType; }
set { _chargeType = value; }
}
public int UnitAmount public int UnitAmount { get; set; }
{
get { return _unitAmount; }
set { _unitAmount = value; }
}
public int UnitType public int UnitType { get; set; }
{
get { return _unitType; }
set { _unitType = value; }
}
public string CurrencyName public string CurrencyName { get; set; }
{
get { return _currencyName; }
set { _currencyName = value; }
}
public string CurrencyAmount public string CurrencyAmount { get; set; }
{
get { return _currencyAmount; }
set { _currencyAmount = value; }
}
public string CurrencyMultiplier public string CurrencyMultiplier { get; set; }
{
get { return _currencyMultiplier; }
set { _currencyMultiplier = value; }
}
public string TotalType public string TotalType { get; set; }
{
get { return _totalType; }
set { _totalType = value; }
}
public string AocBillingId public string AocBillingId { get; set; }
{
get { return _aocBillingId; }
set { _aocBillingId = value; }
}
public string ChargingAssociationId public string ChargingAssociationId { get; set; }
{
get { return _chargingAssociationId; }
set { _chargingAssociationId = value; }
}
public string ChargingAssociationNumber public string ChargingAssociationNumber { get; set; }
{
get { return _chargingAssociationNumber; }
set { _chargingAssociationNumber = value; }
}
public string ChargingrAssociationPlan public string ChargingrAssociationPlan { get; set; }
{
get { return _chargingrAssociationPlan; }
set { _chargingrAssociationPlan = value; }
}
} }
} }

View file

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

View file

@ -1,77 +1,16 @@
using System;
namespace AsterNET.Manager.Action namespace AsterNET.Manager.Action
{ {
/// <summary> /// <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 /// 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 /// 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 /// 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 /// Available since Asterisk 1.2
/// </summary> /// </summary>
public class AgentCallbackLoginAction : ManagerAction 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> /// <summary>
/// Creates a new empty AgentCallbackLoginAction. /// Creates a new empty AgentCallbackLoginAction.
/// </summary> /// </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> /// <param name="exten">the extension that is called to connect a queue member with this agent</param>
public AgentCallbackLoginAction(string agent, string exten) public AgentCallbackLoginAction(string agent, string exten)
{ {
this.agent = agent; Agent = agent;
this.exten = exten; Exten = exten;
} }
/// <summary> /// <summary>
@ -101,7 +40,46 @@ namespace AsterNET.Manager.Action
public AgentCallbackLoginAction(string agent, string exten, string context) public AgentCallbackLoginAction(string agent, string exten, string context)
: this(agent, exten) : 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 namespace AsterNET.Manager.Action
{ {
/// <summary> /// <summary>
@ -7,78 +5,68 @@ namespace AsterNET.Manager.Action
/// </summary> /// </summary>
public class AgentLogoffAction : ManagerAction public class AgentLogoffAction : ManagerAction
{ {
private string agent;
private bool soft;
#region Action #region Action
/// <summary> /// <summary>
/// Returns the name of this action, i.e. "AgentLogoff". /// Returns the name of this action, i.e. "AgentLogoff".
/// </summary> /// </summary>
/// <returns>the name of this action</returns> /// <returns>the name of this action</returns>
override public string Action public override string Action
{ {
get get { return "AgentLogoff"; }
{
return "AgentLogoff";
}
} }
#endregion #endregion
#region Agent #region Agent
/// <summary> /// <summary>
/// Returns the name of the agent to log off, for example "1002". /// Returns the name of the agent to log off, for example "1002".
/// </summary> /// </summary>
/// <returns>the name of the agent to log off</returns> /// <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. /// This is property is mandatory.
/// </summary> /// </summary>
/// <param name="agent">the name of the agent to log off</param> /// <param name="agent">the name of the agent to log off</param>
public string Agent public string Agent { get; set; }
{
get
{
return agent;
}
set
{
this.agent = value;
}
}
#endregion #endregion
#region Soft #region Soft
/// <summary> /// <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. /// Default is to hangup existing calls on logoff.
/// </summary> /// </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. /// <code>null</code> if default should be used.
/// </returns> /// </returns>
public bool Soft public bool Soft { get; set; }
{
get { return soft; }
set { this.soft = value; }
}
#endregion #endregion
#region Constructors - AgentLogoffAction() #region Constructors - AgentLogoffAction()
/// <summary> Creates a new empty AgentLogoffAction.</summary> /// <summary> Creates a new empty AgentLogoffAction.</summary>
public AgentLogoffAction() public AgentLogoffAction()
{ {
} }
/// <summary> /// <summary>
/// Creates a new AgentLogoffAction that logs off the given agent /// Creates a new AgentLogoffAction that logs off the given agent
/// </summary> /// </summary>
/// <param name="agent">the name of the agent to log off.</param> /// <param name="agent">the name of the agent to log off.</param>
public AgentLogoffAction(string agent) public AgentLogoffAction(string agent)
{ {
this.agent = agent; Agent = agent;
} }
#endregion #endregion
#region Constructors - AgentLogoffAction(string agent, bool soft) #region Constructors - AgentLogoffAction(string agent, bool soft)
/// <summary> /// <summary>
/// Creates a new AgentLogoffAction that logs off the given agent /// Creates a new AgentLogoffAction that logs off the given agent
/// </summary> /// </summary>
@ -87,8 +75,9 @@ namespace AsterNET.Manager.Action
public AgentLogoffAction(string agent, bool soft) public AgentLogoffAction(string agent, bool soft)
: this(agent) : this(agent)
{ {
this.soft = soft; Soft = soft;
} }
#endregion #endregion
} }
} }

View file

@ -1,11 +1,12 @@
using System; using System;
using AsterNET.Manager.Event;
namespace AsterNET.Manager.Action namespace AsterNET.Manager.Action
{ {
/// <summary> /// <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. /// 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 /// Available since Asterisk 1.2
/// </summary> /// </summary>
/// <seealso cref="AsterNET.Manager.Event.AgentsEvent" /> /// <seealso cref="AsterNET.Manager.Event.AgentsEvent" />
@ -13,29 +14,28 @@ namespace AsterNET.Manager.Action
public class AgentsAction : ManagerActionEvent public class AgentsAction : ManagerActionEvent
{ {
#region Action #region Action
/// <summary> /// <summary>
/// Get the name of this action, i.e. "Agents". /// Get the name of this action, i.e. "Agents".
/// </summary> /// </summary>
override public string Action public override string Action
{ {
get { return "Agents"; } get { return "Agents"; }
} }
#endregion #endregion
#region ActionCompleteEventClass #region ActionCompleteEventClass
public override Type ActionCompleteEventClass() public override Type ActionCompleteEventClass()
{ {
return typeof(Event.AgentsCompleteEvent); return typeof (AgentsCompleteEvent);
} }
#endregion #endregion
#region AgentsAction() #region AgentsAction()
/// <summary>
/// Creates a new AgentsAction.
/// </summary>
public AgentsAction()
{
}
#endregion #endregion
} }
} }

View file

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

View file

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

View file

@ -1,5 +1,3 @@
using System;
namespace AsterNET.Manager.Action namespace AsterNET.Manager.Action
{ {
/// <summary> /// <summary>
@ -7,34 +5,16 @@ namespace AsterNET.Manager.Action
/// in using challenge/response. Sending this action to the asterisk server /// in using challenge/response. Sending this action to the asterisk server
/// results in a ChallengeResponse being received from the server. /// results in a ChallengeResponse being received from the server.
/// </summary> /// </summary>
/// <seealso cref="Manager.Action.LoginAction"/> /// <seealso cref="Manager.Action.LoginAction" />
/// <seealso cref="Manager.Response.ChallengeResponse"/> /// <seealso cref="Manager.Response.ChallengeResponse" />
public class ChallengeAction : ManagerAction 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> /// <summary>
/// Creates a new empty ChallengeAction with MD5 algorithm /// Creates a new empty ChallengeAction with MD5 algorithm
/// </summary> /// </summary>
public ChallengeAction() public ChallengeAction()
{ {
this.authType = "MD5"; AuthType = "MD5";
} }
/// <summary> /// <summary>
@ -44,7 +24,20 @@ namespace AsterNET.Manager.Action
/// <param name="authType">the digest alogrithm to use.</param> /// <param name="authType">the digest alogrithm to use.</param>
public ChallengeAction(string authType) 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 namespace AsterNET.Manager.Action
{ {
/// <summary> /// <summary>
/// The ChangeMonitorAction changes the monitoring filename of a channel. /// 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> /// It is implemented in <code>res/res_monitor.c</code>
/// </summary> /// </summary>
public class ChangeMonitorAction : ManagerAction public class ChangeMonitorAction : ManagerAction
{ {
private string channel;
private string file;
#region Action #region Action
/// <summary> /// <summary>
/// Get the name of this action, i.e. "ChangeMonitor". /// Get the name of this action, i.e. "ChangeMonitor".
/// </summary> /// </summary>
override public string Action public override string Action
{ {
get { return "ChangeMonitor"; } get { return "ChangeMonitor"; }
} }
#endregion #endregion
#region Channel #region Channel
/// <summary> /// <summary>
/// Get/Set the name of the monitored channel.<br/> /// Get/Set the name of the monitored channel.<br />
/// This property is mandatory. /// This property is mandatory.
/// </summary> /// </summary>
public string Channel public string Channel { get; set; }
{
get { return this.channel; }
set { this.channel = value; }
}
#endregion #endregion
#region File #region File
/// <summary> /// <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. /// This property is mandatory.
/// </summary> /// </summary>
public string File public string File { get; set; }
{
get { return this.file; }
set { this.file = value; }
}
#endregion #endregion
#region ChangeMonitorAction() #region ChangeMonitorAction()
/// <summary> /// <summary>
/// Creates a new empty ChangeMonitorAction. /// Creates a new empty ChangeMonitorAction.
/// </summary> /// </summary>
public ChangeMonitorAction() public ChangeMonitorAction()
{ {
} }
#endregion #endregion
#region ChangeMonitorAction(string channel, string file) #region ChangeMonitorAction(string channel, string file)
/// <summary> /// <summary>
/// Creates a new ChangeMonitorAction that causes monitoring data for the /// Creates a new ChangeMonitorAction that causes monitoring data for the
/// given channel to be written to the given file(s). /// 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> /// <param name="file">the (base) name of the file(s) to which the voice data is written</param>
public ChangeMonitorAction(string channel, string file) public ChangeMonitorAction(string channel, string file)
{ {
this.channel = channel; Channel = channel;
this.file = file; File = file;
} }
#endregion #endregion
} }
} }

View file

@ -1,31 +1,13 @@
using System;
namespace AsterNET.Manager.Action namespace AsterNET.Manager.Action
{ {
/// <summary> /// <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. /// For a list of supported commands type <code>help</code> on asterisk's command line.
/// </summary> /// </summary>
public class CommandAction : ManagerAction public class CommandAction : ManagerAction
{ {
protected internal string command; 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> /// <summary>
/// Creates a new CommandAction. /// Creates a new CommandAction.
/// </summary> /// </summary>
@ -41,5 +23,22 @@ namespace AsterNET.Manager.Action
{ {
this.command = command; 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; namespace AsterNET.Manager.Action
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AsterNET.Manager.Action
{ {
public class ConfbridgeKickAction : ManagerAction public class ConfbridgeKickAction : ManagerAction
{ {
public string Conference { get; set; }
public string Channel { get; set; }
public override string Action
{
get { return "ConfbridgeKick"; }
}
/// <summary> /// <summary>
/// Removes a specified user from a specified conference. /// Removes a specified user from a specified conference.
/// </summary> /// </summary>
public ConfbridgeKickAction() public ConfbridgeKickAction()
{ } {
}
/// <summary> /// <summary>
/// Removes a specified user from a specified conference. /// Removes a specified user from a specified conference.
@ -29,8 +16,16 @@ namespace AsterNET.Manager.Action
/// <param name="channel"></param> /// <param name="channel"></param>
public ConfbridgeKickAction(string conference, string channel) public ConfbridgeKickAction(string conference, string channel)
{ {
this.Conference = conference; Conference = conference;
this.Channel = channel; 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;
using System.Collections.Generic; using AsterNET.Manager.Event;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AsterNET.Manager.Action namespace AsterNET.Manager.Action
{ {
/* /*
https://wiki.asterisk.org/wiki/display/AST/ConfBridge+10#ConfBridge10-ConfBridgeAsteriskManagerInterface%28AMI%29Events https://wiki.asterisk.org/wiki/display/AST/ConfBridge+10#ConfBridge10-ConfBridgeAsteriskManagerInterface%28AMI%29Events
Action: ConfbridgeList Action: ConfbridgeList
@ -19,17 +15,6 @@ namespace AsterNET.Manager.Action
/// </summary> /// </summary>
public class ConfbridgeListAction : ManagerActionEvent 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> /// <summary>
/// Lists all users in a particular ConfBridge conference. ConfbridgeList will follow as separate events, /// Lists all users in a particular ConfBridge conference. ConfbridgeList will follow as separate events,
/// followed by a final event called ConfbridgeListComplete /// followed by a final event called ConfbridgeListComplete
@ -37,7 +22,19 @@ namespace AsterNET.Manager.Action
/// <param name="conference"></param> /// <param name="conference"></param>
public ConfbridgeListAction(string conference) 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;
using System.Collections.Generic; using AsterNET.Manager.Event;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AsterNET.Manager.Action namespace AsterNET.Manager.Action
{ {
/// <summary> /// <summary>
/// Lists data about all active conferences. ConfbridgeListRooms will follow as separate events, /// Lists data about all active conferences. ConfbridgeListRooms will follow as separate events,
/// followed by a final event called ConfbridgeListRoomsComplete. /// followed by a final event called ConfbridgeListRoomsComplete.
/// </summary> /// </summary>
public class ConfbridgeListRoomsAction : ManagerActionEvent public class ConfbridgeListRoomsAction : ManagerActionEvent
{ {
public override string Action public override string Action
{ {
get { return "ConfbridgeListRooms"; } get { return "ConfbridgeListRooms"; }
} }
public override Type ActionCompleteEventClass() public override Type ActionCompleteEventClass()
{ {
return typeof(Event.ConfbridgeListRoomsCompleteEvent); return typeof (ConfbridgeListRoomsCompleteEvent);
}
/// <summary>
/// Lists data about all active conferences. ConfbridgeListRooms will follow as separate events,
/// followed by a final event called ConfbridgeListRoomsComplete.
/// </summary>
public ConfbridgeListRoomsAction()
{
} }
} }
} }

View file

@ -1,25 +1,13 @@
using System; namespace AsterNET.Manager.Action
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AsterNET.Manager.Action
{ {
public class ConfbridgeLockAction : ManagerAction public class ConfbridgeLockAction : ManagerAction
{ {
public string Conference { get; set; }
public override string Action
{
get { return "ConfbridgeLock"; }
}
/// <summary> /// <summary>
/// Locks a specified conference. /// Locks a specified conference.
/// </summary> /// </summary>
public ConfbridgeLockAction() public ConfbridgeLockAction()
{ } {
}
/// <summary> /// <summary>
/// Locks a specified conference. /// Locks a specified conference.
@ -27,7 +15,14 @@ namespace AsterNET.Manager.Action
/// <param name="conference"></param> /// <param name="conference"></param>
public ConfbridgeLockAction(string conference) 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; namespace AsterNET.Manager.Action
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AsterNET.Manager.Action
{ {
public class ConfbridgeMuteAction : ManagerAction public class ConfbridgeMuteAction : ManagerAction
{ {
public string Conference { get; set; }
public string Channel { get; set; }
public override string Action
{
get { return "ConfbridgeMute"; }
}
/// <summary> /// <summary>
/// Mutes a specified user in a specified conference. /// Mutes a specified user in a specified conference.
/// </summary> /// </summary>
public ConfbridgeMuteAction() public ConfbridgeMuteAction()
{ } {
}
/// <summary> /// <summary>
/// Mutes a specified user in a specified conference. /// Mutes a specified user in a specified conference.
@ -29,8 +16,16 @@ namespace AsterNET.Manager.Action
/// <param name="channel"></param> /// <param name="channel"></param>
public ConfbridgeMuteAction(string conference, string channel) public ConfbridgeMuteAction(string conference, string channel)
{ {
this.Conference = conference; Conference = conference;
this.Channel = channel; 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; namespace AsterNET.Manager.Action
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AsterNET.Manager.Action
{ {
public class ConfbridgeSetSingleVideoSrcAction : ManagerAction public class ConfbridgeSetSingleVideoSrcAction : ManagerAction
{ {
public string Conference { get; set; }
public string Channel { get; set; }
public override string Action
{
get { return "ConfbridgeSetSingleVideoSrc"; }
}
/// <summary> /// <summary>
/// Stops recording a specified conference. /// Stops recording a specified conference.
/// </summary> /// </summary>
public ConfbridgeSetSingleVideoSrcAction() public ConfbridgeSetSingleVideoSrcAction()
{ } {
}
/// <summary> /// <summary>
/// Stops recording a specified conference. /// Stops recording a specified conference.
@ -28,8 +15,16 @@ namespace AsterNET.Manager.Action
/// <param name="conference"></param> /// <param name="conference"></param>
public ConfbridgeSetSingleVideoSrcAction(string conference, string channel) public ConfbridgeSetSingleVideoSrcAction(string conference, string channel)
{ {
this.Conference = conference; Conference = conference;
this.Channel = channel; 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; namespace AsterNET.Manager.Action
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AsterNET.Manager.Action
{ {
public class ConfbridgeStartRecordAction : ManagerAction public class ConfbridgeStartRecordAction : ManagerAction
{ {
public string Conference { get; set; }
public override string Action
{
get { return "ConfbridgeStartRecord"; }
}
/// <summary> /// <summary>
/// Starts recording a specified conference, with an optional filename. /// Starts recording a specified conference, with an optional filename.
/// If recording is already in progress, an error will be returned. /// 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. /// If record_file is not specified, a file will automatically be generated in Asterisk's monitor directory.
/// </summary> /// </summary>
public ConfbridgeStartRecordAction() public ConfbridgeStartRecordAction()
{ } {
}
/// <summary> /// <summary>
/// Starts recording a specified conference, with an optional filename. /// Starts recording a specified conference, with an optional filename.
@ -33,7 +21,14 @@ namespace AsterNET.Manager.Action
/// <param name="conference"></param> /// <param name="conference"></param>
public ConfbridgeStartRecordAction(string conference) 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; namespace AsterNET.Manager.Action
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AsterNET.Manager.Action
{ {
public class ConfbridgeStopRecordAction : ManagerAction public class ConfbridgeStopRecordAction : ManagerAction
{ {
public string Conference { get; set; }
public override string Action
{
get { return "ConfbridgeStopRecord"; }
}
/// <summary> /// <summary>
/// Stops recording a specified conference. /// Stops recording a specified conference.
/// </summary> /// </summary>
public ConfbridgeStopRecordAction() public ConfbridgeStopRecordAction()
{ } {
}
/// <summary> /// <summary>
/// Stops recording a specified conference. /// Stops recording a specified conference.
@ -27,7 +15,14 @@ namespace AsterNET.Manager.Action
/// <param name="conference"></param> /// <param name="conference"></param>
public ConfbridgeStopRecordAction(string conference) 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; namespace AsterNET.Manager.Action
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AsterNET.Manager.Action
{ {
public class ConfbridgeUnlockAction : ManagerAction public class ConfbridgeUnlockAction : ManagerAction
{ {
public string Conference { get; set; }
public override string Action
{
get { return "ConfbridgeUnlock"; }
}
/// <summary> /// <summary>
/// Unlocks a specified conference. /// Unlocks a specified conference.
/// </summary> /// </summary>
public ConfbridgeUnlockAction() public ConfbridgeUnlockAction()
{ } {
}
/// <summary> /// <summary>
/// Unlocks a specified conference. /// Unlocks a specified conference.
@ -27,7 +15,14 @@ namespace AsterNET.Manager.Action
/// <param name="conference"></param> /// <param name="conference"></param>
public ConfbridgeUnlockAction(string conference) 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; namespace AsterNET.Manager.Action
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AsterNET.Manager.Action
{ {
public class ConfbridgeUnmuteAction : ManagerAction public class ConfbridgeUnmuteAction : ManagerAction
{ {
public string Conference { get; set; }
public string Channel { get; set; }
public override string Action
{
get { return "ConfbridgeUnmute"; }
}
/// <summary> /// <summary>
/// Unmutes a specified user in a specified conference. /// Unmutes a specified user in a specified conference.
/// </summary> /// </summary>
public ConfbridgeUnmuteAction() public ConfbridgeUnmuteAction()
{ } {
}
/// <summary> /// <summary>
/// Unmutes a specified user in a specified conference. /// Unmutes a specified user in a specified conference.
@ -29,8 +16,16 @@ namespace AsterNET.Manager.Action
/// <param name="channel"></param> /// <param name="channel"></param>
public ConfbridgeUnmuteAction(string conference, string channel) public ConfbridgeUnmuteAction(string conference, string channel)
{ {
this.Conference = conference; Conference = conference;
this.Channel = channel; 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; namespace AsterNET.Manager.Action
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AsterNET.Manager.Action
{ {
public class CoreSettingsAction : ManagerAction public class CoreSettingsAction : ManagerAction
{ {
/// <summary>
/// Show PBX core settings (version etc).
/// </summary>
public CoreSettingsAction()
{
}
public override string Action public override string Action
{ {
get { return "CoreSettings"; } get { return "CoreSettings"; }

View file

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

View file

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

View file

@ -1,18 +1,11 @@
using System; namespace AsterNET.Manager.Action
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AsterNET.Manager.Action
{ {
public class CreateConfigAction : ManagerAction public class CreateConfigAction : ManagerAction
{ {
private string _filename;
/// <summary> /// <summary>
/// Creates an empty file in the configuration directory. /// 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> /// </summary>
public CreateConfigAction() public CreateConfigAction()
{ {
@ -20,12 +13,13 @@ namespace AsterNET.Manager.Action
/// <summary> /// <summary>
/// Creates an empty file in the configuration directory. /// 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> /// </summary>
/// <param name="filename"></param> /// <param name="filename"></param>
public CreateConfigAction(string filename) public CreateConfigAction(string filename)
{ {
_filename = filename; Filename = filename;
} }
public override string Action public override string Action
@ -33,10 +27,6 @@ namespace AsterNET.Manager.Action
get { return "CreateConfig"; } get { return "CreateConfig"; }
} }
public string Filename public string Filename { get; set; }
{
get { return _filename; }
set { _filename = value; }
}
} }
} }

View file

@ -1,37 +1,9 @@
using System; namespace AsterNET.Manager.Action
namespace AsterNET.Manager.Action
{ {
/// <summary> /// <summary>
///
/// </summary> /// </summary>
public class DBDelAction : ManagerAction 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> /// <summary>
/// Creates a new empty DBDelAction. /// Creates a new empty DBDelAction.
/// </summary> /// </summary>
@ -47,8 +19,23 @@ namespace AsterNET.Manager.Action
/// <param name="key">the key of the entry to retrieve</param> /// <param name="key">the key of the entry to retrieve</param>
public DBDelAction(string family, string key) public DBDelAction(string family, string key)
{ {
this.family = family; Family = family;
this.key = key; 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>
///
/// </summary> /// </summary>
public class DBDelTreeAction : ManagerAction 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> /// <summary>
/// Creates a new empty DBDelTreeAction. /// Creates a new empty DBDelTreeAction.
/// </summary> /// </summary>
@ -47,8 +19,23 @@ namespace AsterNET.Manager.Action
/// <param name="key">the key of the entry to retrieve</param> /// <param name="key">the key of the entry to retrieve</param>
public DBDelTreeAction(string family, string key) public DBDelTreeAction(string family, string key)
{ {
this.family = family; Family = family;
this.key = key; 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 System;
using AsterNET.Manager.Event;
namespace AsterNET.Manager.Action namespace AsterNET.Manager.Action
{ {
/// <summary> /// <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 /// If an entry is found a DBGetResponseEvent is sent by Asterisk containing the
/// value, otherwise a ManagerError indicates that no entry matches. /// value, otherwise a ManagerError indicates that no entry matches.
/// </summary> /// </summary>
/// <seealso cref="AsterNET.Manager.Event.DBGetResponseEvent" /> /// <seealso cref="AsterNET.Manager.Event.DBGetResponseEvent" />
public class DBGetAction : ManagerActionEvent 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> /// <summary>
/// Creates a new empty DBGetAction. /// Creates a new empty DBGetAction.
/// </summary> /// </summary>
@ -60,8 +26,34 @@ namespace AsterNET.Manager.Action
/// <param name="key">the key of the entry to retrieve</param> /// <param name="key">the key of the entry to retrieve</param>
public DBGetAction(string family, string key) public DBGetAction(string family, string key)
{ {
this.family = family; Family = family;
this.key = key; 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 namespace AsterNET.Manager.Action
{ {
/// <summary> /// <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 /// Available since Asterisk 1.2
/// </summary> /// </summary>
public class DBPutAction : ManagerAction 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> /// <summary>
/// Creates a new empty DBPutAction. /// Creates a new empty DBPutAction.
/// </summary> /// </summary>
@ -56,9 +21,29 @@ namespace AsterNET.Manager.Action
/// <param name="val">the value to set</param> /// <param name="val">the value to set</param>
public DBPutAction(string family, string key, string val) public DBPutAction(string family, string key, string val)
{ {
this.family = family; Family = family;
this.key = key; Key = key;
this.val = val; 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 namespace AsterNET.Manager.Action
{ {
/// <summary> /// <summary>
@ -7,27 +5,6 @@ namespace AsterNET.Manager.Action
/// </summary> /// </summary>
public class EventsAction : ManagerAction 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> /// <summary>
/// Creates a new empty EventsAction. /// Creates a new empty EventsAction.
/// </summary> /// </summary>
@ -38,13 +15,30 @@ namespace AsterNET.Manager.Action
/// <summary> /// <summary>
/// Creates a new EventsAction that applies the given event mask to the current manager connection. /// Creates a new EventsAction that applies the given event mask to the current manager connection.
/// </summary> /// </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 /// 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. /// or a combination of "system", "call" and "log" (separated by ',') to specify what kind of events should be sent.
/// </param> /// </param>
public EventsAction(string eventMask) 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 namespace AsterNET.Manager.Action
{ {
/// <summary> /// <summary>
@ -7,37 +5,34 @@ namespace AsterNET.Manager.Action
/// </summary> /// </summary>
public class ExtensionStateAction : ManagerAction public class ExtensionStateAction : ManagerAction
{ {
private string exten;
private string context;
#region Action #region Action
/// <summary> /// <summary>
/// Get the name of this action, i.e. "ExtensionState". /// Get the name of this action, i.e. "ExtensionState".
/// </summary> /// </summary>
override public string Action public override string Action
{ {
get { return "ExtensionState"; } get { return "ExtensionState"; }
} }
#endregion #endregion
#region Exten #region Exten
/// <summary> /// <summary>
/// Get/Set the extension to query. /// Get/Set the extension to query.
/// </summary> /// </summary>
public string Exten public string Exten { get; set; }
{
get { return exten; }
set { this.exten = value; }
}
#endregion #endregion
#region Context #region Context
/// <summary> /// <summary>
/// Get/Set the name of the context that contains the extension to query. /// Get/Set the name of the context that contains the extension to query.
/// </summary> /// </summary>
public string Context public string Context { get; set; }
{
get { return context; }
set { this.context = value; }
}
#endregion #endregion
} }
} }

View file

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

View file

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

View file

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

View file

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

View file

@ -1,11 +1,9 @@
using System;
namespace AsterNET.Manager.Action namespace AsterNET.Manager.Action
{ {
/// <summary> /// <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 /// 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 /// An unsuccessful login results in an ManagerError being received from the
/// server with a message set to "Authentication failed" and the socket being /// server with a message set to "Authentication failed" and the socket being
/// closed by Asterisk. /// closed by Asterisk.
@ -14,66 +12,6 @@ namespace AsterNET.Manager.Action
/// <seealso cref="Manager.Response.ManagerError" /> /// <seealso cref="Manager.Response.ManagerError" />
public class LoginAction : ManagerAction 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> /// <summary>
/// Creates a new empty LoginAction. /// Creates a new empty LoginAction.
/// </summary> /// </summary>
@ -82,7 +20,7 @@ namespace AsterNET.Manager.Action
} }
/// <summary> /// <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. /// You should not use cleartext login if you are concerned about security and login with a password hash instead.
/// </summary> /// </summary>
/// <param name="username">the username as configured in Asterisk's <code>manager.conf</code></param> /// <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" /> /// <seealso cref="Manager.Action.ChallengeAction" />
public LoginAction(string username, string secret) public LoginAction(string username, string secret)
{ {
this.username = username; Username = username;
this.secret = secret; Secret = secret;
} }
/// <summary> /// <summary>
/// Creates a new LoginAction that performs a login via challenge/response. /// Creates a new LoginAction that performs a login via challenge/response.
/// </summary> /// </summary>
/// <param name="username">the username as configured in Asterisk's <code>manager.conf</code></param> /// <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="key">the hash of the user's password and the challenge</param>
public LoginAction(string username, string authType, string key) public LoginAction(string username, string authType, string key)
{ {
this.username = username; Username = username;
this.authType = authType; AuthType = authType;
this.key = key; Key = key;
} }
/// <summary> /// <summary>
/// Creates a new LoginAction that performs a login via challenge/response. /// Creates a new LoginAction that performs a login via challenge/response.
/// </summary> /// </summary>
/// <param name="username">the username as configured in Asterisk's <code>manager.conf</code></param> /// <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="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 /// 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. /// or a combination of "system", "call" and "log" (separated by ',') to specify what kind of events should be sent.
/// </param> /// </param>
public LoginAction(string username, string authType, string key, string events) public LoginAction(string username, string authType, string key, string events)
{ {
this.username = username; Username = username;
this.authType = authType; AuthType = authType;
this.key = key; Key = key;
this.events = events; 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 namespace AsterNET.Manager.Action
{ {
/// <summary> /// <summary>
@ -10,16 +8,9 @@ namespace AsterNET.Manager.Action
/// <summary> /// <summary>
/// Get the name of this action, i.e. "Logoff". /// Get the name of this action, i.e. "Logoff".
/// </summary> /// </summary>
override public string Action public override string Action
{ {
get { return "Logoff"; } get { return "Logoff"; }
} }
/// <summary>
/// Creates a new LogoffAction.
/// </summary>
public LogoffAction()
{
}
} }
} }

View file

@ -1,35 +1,12 @@
using System;
namespace AsterNET.Manager.Action namespace AsterNET.Manager.Action
{ {
/// <summary> /// <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. /// The MailboxCountAction returns a MailboxStatusResponse.
/// </summary> /// </summary>
/// <seealso cref="Manager.Response.MailboxCountResponse" /> /// <seealso cref="Manager.Response.MailboxCountResponse" />
public class MailboxCountAction : ManagerAction 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> /// <summary>
/// Creates a new empty MailboxCountAction. /// Creates a new empty MailboxCountAction.
/// </summary> /// </summary>
@ -41,14 +18,31 @@ namespace AsterNET.Manager.Action
/// Creates a new MailboxCountAction that queries the number of unread and /// Creates a new MailboxCountAction that queries the number of unread and
/// read messages in the given mailbox. /// read messages in the given mailbox.
/// </summary> /// </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 /// This can either be only the number of the mailbox or a string
/// of the form mailboxnumber@context.If no context is specified /// of the form mailboxnumber@context.If no context is specified
/// "default" is assumed. /// "default" is assumed.
/// </param> /// </param>
public MailboxCountAction(string mailbox) 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 namespace AsterNET.Manager.Action
{ {
/// <summary> /// <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. /// The MailboxStatusAction returns a MailboxStatusResponse.
/// </summary> /// </summary>
/// <seealso cref="Manager.Response.MailboxStatusResponse" /> /// <seealso cref="Manager.Response.MailboxStatusResponse" />
public class MailboxStatusAction : ManagerAction 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> /// <summary>
/// Creates a new empty MailboxStatusAction. /// Creates a new empty MailboxStatusAction.
/// </summary> /// </summary>
@ -44,14 +17,35 @@ namespace AsterNET.Manager.Action
/// <summary> /// <summary>
/// Creates a new MailboxStatusAction that checks for waiting messages in the given mailbox. /// Creates a new MailboxStatusAction that checks for waiting messages in the given mailbox.
/// </summary> /// </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 /// This can either be only the number of the mailbox or a string
/// of the form mailboxnumber@context.If no context is specified /// of the form mailboxnumber@context.If no context is specified
/// "default" is assumed. /// "default" is assumed.
/// </param> /// </param>
public MailboxStatusAction(string mailbox) 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 namespace AsterNET.Manager.Action
{ {
/// <summary> /// <summary>
@ -10,28 +7,28 @@ namespace AsterNET.Manager.Action
public abstract class ManagerAction public abstract class ManagerAction
{ {
private string actionId; private string actionId;
private string server;
private string proxyKey; private string proxyKey;
private string server;
/// <summary> /// <summary>
/// Manager API Action key. Also use as ProxyAction key to <see cref="ProxyAction">ProxyAction</see> actions. /// Manager API Action key. Also use as ProxyAction key to <see cref="ProxyAction">ProxyAction</see> actions.
/// </summary> /// </summary>
public abstract string Action public abstract string Action { get; }
{
get;
}
#region ActionId #region ActionId
public string ActionId public string ActionId
{ {
get { return this.actionId; } get { return this.actionId; }
set { this.actionId = value; } set { this.actionId = value; }
} }
#endregion #endregion
#region Server #region Server
/// <summary> /// <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. /// 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. /// If you do not specify a server, the proxy will pick the first one it finds -- fine in single-server configurations.
/// </summary> /// </summary>
@ -40,14 +37,16 @@ namespace AsterNET.Manager.Action
get { return this.server; } get { return this.server; }
set { this.server = value; } set { this.server = value; }
} }
#endregion #endregion
#region ProxyKey #region ProxyKey
/// <summary> /// <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, /// Rather than have to login with a username & password,
/// you can specify a <b>ProxyKey</b> that must be passed from /// 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 /// This is helpful in situations where you would like to authenticate and
/// execute an action in a single step. /// execute an action in a single step.
/// </summary> /// </summary>
@ -56,6 +55,7 @@ namespace AsterNET.Manager.Action
get { return this.proxyKey; } get { return this.proxyKey; }
set { this.proxyKey = value; } set { this.proxyKey = value; }
} }
#endregion #endregion
public override string ToString() public override string ToString()

View file

@ -4,17 +4,17 @@ namespace AsterNET.Manager.Action
{ {
/// <summary> /// <summary>
/// The ManagerActionEvent is implemented by ManagerActions that /// 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 /// The event type that indicates that Asterisk is finished is returned by the
/// ActionCompleteEventClass property. /// ActionCompleteEventClass property.
/// </summary> /// </summary>
/// <seealso cref="AsterNET.Manager.Event.ResponseEvent"/> /// <seealso cref="AsterNET.Manager.Event.ResponseEvent" />
public abstract class ManagerActionEvent : ManagerAction public abstract class ManagerActionEvent : ManagerAction
{ {
/// <summary> /// <summary>
/// Returns the event type that indicates that Asterisk is finished sending response events for this action. /// Returns the event type that indicates that Asterisk is finished sending response events for this action.
/// </summary> /// </summary>
/// <seealso cref="AsterNET.Manager.Event.ResponseEvent"/> /// <seealso cref="AsterNET.Manager.Event.ResponseEvent" />
public abstract Type ActionCompleteEventClass(); public abstract Type ActionCompleteEventClass();
} }
} }

View file

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

View file

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

View file

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

View file

@ -1,60 +1,11 @@
using System; namespace AsterNET.Manager.Action
namespace AsterNET.Manager.Action
{ {
/// <summary> /// <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 /// A successful login is the precondition for sending for that
/// </summary> /// </summary>
public class ParkAction : ManagerAction 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> /// <summary>
/// Creates a new ParkAction. /// Creates a new ParkAction.
/// </summary> /// </summary>
@ -63,13 +14,13 @@ namespace AsterNET.Manager.Action
/// <param name="timeout"></param> /// <param name="timeout"></param>
public ParkAction(string channel, string channel2, string timeout) public ParkAction(string channel, string channel2, string timeout)
{ {
this.channel = channel; this.Channel = channel;
this.channel2 = channel2; this.Channel2 = channel2;
this.timeout = timeout; this.Timeout = timeout;
} }
/// <summary> /// <summary>
/// Creates a new ParkAction.<br/> /// Creates a new ParkAction.<br />
/// </summary> /// </summary>
/// <param name="channel">Set the Channel which should be parked</param> /// <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> /// <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> /// <param name="parkinglot">Set the Parking lot.</param>
public ParkAction(string channel, string channel2, string timeout, string parkinglot) public ParkAction(string channel, string channel2, string timeout, string parkinglot)
{ {
this.channel = channel; this.Channel = channel;
this.channel2 = channel2; this.Channel2 = channel2;
this.timeout = timeout; this.Timeout = timeout;
this.parkinglot = parkinglot; 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 System;
using AsterNET.Manager.Event;
namespace AsterNET.Manager.Action namespace AsterNET.Manager.Action
{ {
/// <summary> /// <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 /// For each active channel a ParkedCallEvent is generated. After all parked
/// calls have been reported a ParkedCallsCompleteEvent is generated. /// calls have been reported a ParkedCallsCompleteEvent is generated.
/// </summary> /// </summary>
/// <seealso cref="AsterNET.Manager.Event.ParkedCallEvent"/> /// <seealso cref="AsterNET.Manager.Event.ParkedCallEvent" />
/// <seealso cref="AsterNET.Manager.Event.ParkedCallsCompleteEvent"/> /// <seealso cref="AsterNET.Manager.Event.ParkedCallsCompleteEvent" />
public class ParkedCallsAction : ManagerActionEvent public class ParkedCallsAction : ManagerActionEvent
{ {
/// <summary> Get the name of this action, i.e. "ParkedCalls".</summary> /// <summary> Get the name of this action, i.e. "ParkedCalls".</summary>
@ -19,14 +20,7 @@ namespace AsterNET.Manager.Action
public override Type ActionCompleteEventClass() public override Type ActionCompleteEventClass()
{ {
return typeof(Event.ParkedCallsCompleteEvent); return typeof (ParkedCallsCompleteEvent);
}
/// <summary>
/// Creates a new ParkedCallsAction.
/// </summary>
public ParkedCallsAction()
{
} }
} }
} }

View file

@ -1,5 +1,3 @@
using System;
namespace AsterNET.Manager.Action namespace AsterNET.Manager.Action
{ {
/// <summary> /// <summary>
@ -11,16 +9,9 @@ namespace AsterNET.Manager.Action
/// <summary> /// <summary>
/// Get the name of this action, i.e. "Ping". /// Get the name of this action, i.e. "Ping".
/// </summary> /// </summary>
override public string Action public override string Action
{ {
get { return "Ping"; } 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 namespace AsterNET.Manager.Action
{ {
public abstract class ProxyAction : ManagerAction public abstract class ProxyAction : ManagerAction

View file

@ -1,72 +1,11 @@
using System;
namespace AsterNET.Manager.Action namespace AsterNET.Manager.Action
{ {
/// <summary> /// <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> /// It is implemented in <code>apps/app_queue.c</code>
/// </summary> /// </summary>
public class QueueAddAction : ManagerAction 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> /// <summary>
/// Creates a new empty QueueAddAction. /// Creates a new empty QueueAddAction.
/// </summary> /// </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> /// <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) public QueueAddAction(string queue, string iface)
{ {
this.queue = queue; this.Queue = queue;
this.iface = iface; this.Interface = iface;
} }
/// <summary> /// <summary>
@ -93,9 +32,9 @@ namespace AsterNET.Manager.Action
/// <param name="memberName">the name of the the new member will be added to</param> /// <param name="memberName">the name of the the new member will be added to</param>
public QueueAddAction(string queue, string iface, string memberName) public QueueAddAction(string queue, string iface, string memberName)
{ {
this.queue = queue; this.Queue = queue;
this.iface = iface; this.Interface = iface;
this.memberName = memberName; this.MemberName = memberName;
} }
/// <summary> /// <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="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="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="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 /// The penalty must be a positive integer or 0 for no penalty. When calls are
/// distributed members with higher penalties are considered last. /// distributed members with higher penalties are considered last.
/// </param> /// </param>
public QueueAddAction(string queue, string iface, string memberName, int penalty) public QueueAddAction(string queue, string iface, string memberName, int penalty)
{ {
this.queue = queue; this.Queue = queue;
this.iface = iface; this.Interface = iface;
this.memberName = memberName; this.MemberName = memberName;
this.penalty = penalty; 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; namespace AsterNET.Manager.Action
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AsterNET.Manager.Action
{ {
public class QueueLogAction : ManagerAction public class QueueLogAction : ManagerAction
{ {
private string _queue;
private string _event;
private string _uniqueid;
private string _interface;
private string _message;
/// <summary> /// <summary>
/// Adds custom entry in queue_log. /// Adds custom entry in queue_log.
/// </summary> /// </summary>
@ -31,11 +19,11 @@ namespace AsterNET.Manager.Action
/// <param name="message"></param> /// <param name="message"></param>
public QueueLogAction(string queue, string @event, string uniqueid, string @interface, string message) public QueueLogAction(string queue, string @event, string uniqueid, string @interface, string message)
{ {
_queue = queue; Queue = queue;
_event = @event; Event = @event;
_uniqueid = uniqueid; Uniqueid = uniqueid;
_interface = @interface; Interface = @interface;
_message = message; Message = message;
} }
public override string Action public override string Action
@ -43,34 +31,14 @@ namespace AsterNET.Manager.Action
get { return "QueueLog"; } get { return "QueueLog"; }
} }
public string Queue public string Queue { get; set; }
{
get { return _queue; }
set { _queue = value; }
}
public string Event public string Event { get; set; }
{
get { return _event; }
set { _event = value; }
}
public string Uniqueid public string Uniqueid { get; set; }
{
get { return _uniqueid; }
set { _uniqueid = value; }
}
public string Interface public string Interface { get; set; }
{
get { return _interface; }
set { _interface = value; }
}
public string Message public string Message { get; set; }
{
get { return _message; }
set { _message = value; }
}
} }
} }

View file

@ -1,57 +1,12 @@
using System;
namespace AsterNET.Manager.Action namespace AsterNET.Manager.Action
{ {
/// <summary> /// <summary>
/// The QueuePauseAction makes a queue member temporarily unavailabe (or available again).<br/> /// The QueuePauseAction makes a queue member temporarily unavailabe (or available again).<br />
/// It is implemented in <code>apps/app_queue.c</code><br/> /// It is implemented in <code>apps/app_queue.c</code><br />
/// Available since Asterisk 1.2. /// Available since Asterisk 1.2.
/// </summary> /// </summary>
public class QueuePauseAction : ManagerAction 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> /// <summary>
/// Creates a new empty QueuePauseAction. /// Creates a new empty QueuePauseAction.
/// </summary> /// </summary>
@ -66,8 +21,8 @@ namespace AsterNET.Manager.Action
/// <param name="iface">the interface of the member to make unavailable</param> /// <param name="iface">the interface of the member to make unavailable</param>
public QueuePauseAction(string iface) public QueuePauseAction(string iface)
{ {
this.iface = iface; this.Interface = iface;
this.paused = true; Paused = true;
} }
/// <summary> /// <summary>
@ -78,9 +33,9 @@ namespace AsterNET.Manager.Action
/// <param name="queue">the queue the member is made unvailable on</param> /// <param name="queue">the queue the member is made unvailable on</param>
public QueuePauseAction(string iface, string queue) public QueuePauseAction(string iface, string queue)
{ {
this.iface = iface; this.Interface = iface;
this.queue = queue; this.Queue = queue;
this.paused = true; Paused = true;
} }
/// <summary> /// <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> /// <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) public QueuePauseAction(string iface, bool paused)
{ {
this.iface = iface; this.Interface = iface;
this.paused = paused; this.Paused = paused;
} }
/// <summary> /// <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> /// <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) public QueuePauseAction(string iface, string queue, bool paused)
{ {
this.iface = iface; this.Interface = iface;
this.queue = queue; this.Queue = queue;
this.paused = paused; 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; namespace AsterNET.Manager.Action
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AsterNET.Manager.Action
{ {
public class QueuePenaltyAction : ManagerAction public class QueuePenaltyAction : ManagerAction
{ {
private string _interface;
private string _penalty;
private string _queue;
/// <summary> /// <summary>
/// Set the penalty for a queue member. /// Set the penalty for a queue member.
/// </summary> /// </summary>
@ -27,9 +17,9 @@ namespace AsterNET.Manager.Action
/// <param name="queue"></param> /// <param name="queue"></param>
public QueuePenaltyAction(string @interface, string penalty, string queue) public QueuePenaltyAction(string @interface, string penalty, string queue)
{ {
_interface = @interface; Interface = @interface;
_penalty = penalty; Penalty = penalty;
_queue = queue; Queue = queue;
} }
public override string Action public override string Action
@ -37,22 +27,10 @@ namespace AsterNET.Manager.Action
get { return "QueuePenalty"; } get { return "QueuePenalty"; }
} }
public string Interface public string Interface { get; set; }
{
get { return _interface; }
set { _interface = value; }
}
public string Penalty public string Penalty { get; set; }
{
get { return _penalty; }
set { _penalty = value; }
}
public string Queue public string Queue { get; set; }
{
get { return _queue; }
set { _queue = value; }
}
} }
} }

View file

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

View file

@ -1,46 +1,11 @@
using System;
namespace AsterNET.Manager.Action namespace AsterNET.Manager.Action
{ {
/// <summary> /// <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> /// It is implemented in <code>apps/app_queue.c</code>
/// </summary> /// </summary>
public class QueueRemoveAction : ManagerAction 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> /// <summary>
/// Creates a new empty QueueRemoveAction. /// Creates a new empty QueueRemoveAction.
/// </summary> /// </summary>
@ -55,8 +20,27 @@ namespace AsterNET.Manager.Action
/// <param name="iface">the interface of the member to remove</param> /// <param name="iface">the interface of the member to remove</param>
public QueueRemoveAction(string queue, string iface) public QueueRemoveAction(string queue, string iface)
{ {
this.queue = queue; this.Queue = queue;
this.iface = iface; 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; namespace AsterNET.Manager.Action
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AsterNET.Manager.Action
{ {
public class QueueResetAction : ManagerAction public class QueueResetAction : ManagerAction
{ {
private string _queue;
/// <summary> /// <summary>
/// Reset queue statistics. /// Reset queue statistics.
/// </summary> /// </summary>
@ -23,7 +15,7 @@ namespace AsterNET.Manager.Action
/// <param name="queue"></param> /// <param name="queue"></param>
public QueueResetAction(string queue) public QueueResetAction(string queue)
{ {
_queue = queue; Queue = queue;
} }
public override string Action public override string Action
@ -31,10 +23,6 @@ namespace AsterNET.Manager.Action
get { return "QueueReset"; } get { return "QueueReset"; }
} }
public string Queue public string Queue { get; set; }
{
get { return _queue; }
set { _queue = value; }
}
} }
} }

View file

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

View file

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

View file

@ -1,5 +1,3 @@
using System;
namespace AsterNET.Manager.Action namespace AsterNET.Manager.Action
{ {
/// <summary> /// <summary>
@ -7,59 +5,6 @@ namespace AsterNET.Manager.Action
/// </summary> /// </summary>
public class RedirectAction : ManagerAction 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> /// <summary>
/// Creates a new empty RedirectAction. /// Creates a new empty RedirectAction.
/// </summary> /// </summary>
@ -76,10 +21,10 @@ namespace AsterNET.Manager.Action
/// <param name="priority">the destination priority</param> /// <param name="priority">the destination priority</param>
public RedirectAction(string channel, string context, string exten, int priority) public RedirectAction(string channel, string context, string exten, int priority)
{ {
this.channel = channel; this.Channel = channel;
this.context = context; this.Context = context;
this.exten = exten; this.Exten = exten;
this.priority = priority; this.Priority = priority;
} }
/// <summary> /// <summary>
@ -92,11 +37,43 @@ namespace AsterNET.Manager.Action
/// <param name="priority">the destination priority</param> /// <param name="priority">the destination priority</param>
public RedirectAction(string channel, string extraChannel, string context, string exten, int priority) public RedirectAction(string channel, string extraChannel, string context, string exten, int priority)
{ {
this.channel = channel; this.Channel = channel;
this.extraChannel = extraChannel; this.ExtraChannel = extraChannel;
this.context = context; this.Context = context;
this.exten = exten; this.Exten = exten;
this.priority = priority; 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 System;
using AsterNET.Manager.Event;
namespace AsterNET.Manager.Action namespace AsterNET.Manager.Action
{ {
/// <summary> /// <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 /// 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 /// Available since Asterisk 1.2
/// </summary> /// </summary>
/// <seealso cref="Manager.event.PeerEntryEvent" /> /// <seealso cref="Manager.event.PeerEntryEvent" />
@ -16,16 +17,10 @@ namespace AsterNET.Manager.Action
{ {
get { return "SIPPeers"; } get { return "SIPPeers"; }
} }
public override Type ActionCompleteEventClass() public override Type ActionCompleteEventClass()
{ {
return typeof(Event.PeerlistCompleteEvent); return typeof (PeerlistCompleteEvent);
}
/// <summary>
/// Creates a new SIPPeersAction.
/// </summary>
public SIPPeersAction()
{
} }
} }
} }

View file

@ -1,37 +1,18 @@
using System; using System;
using AsterNET.Manager.Event;
namespace AsterNET.Manager.Action namespace AsterNET.Manager.Action
{ {
/// <summary> /// <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 /// 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 /// Available since Asterisk 1.2
/// </summary> /// </summary>
/// <seealso cref="Manager.event.PeerEntryEvent" /> /// <seealso cref="Manager.event.PeerEntryEvent" />
/// <seealso cref="Manager.event.PeerlistCompleteEvent" /> /// <seealso cref="Manager.event.PeerlistCompleteEvent" />
public class SIPShowPeerAction : ManagerActionEvent 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> /// <summary> Creates a new empty SIPShowPeerAction.</summary>
public SIPShowPeerAction() public SIPShowPeerAction()
{ {
@ -42,7 +23,23 @@ namespace AsterNET.Manager.Action
/// </summary> /// </summary>
public SIPShowPeerAction(string peer) 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 namespace AsterNET.Manager.Action
{ {
/// <summary> /// <summary>
/// The SetCDRUserFieldAction causes the user field of the call detail record for the given channel to be changed.<br/> /// The SetCDRUserFieldAction causes the user field of the call detail record for the given channel to be changed.
/// Depending on the value of the append property the value is appended or overwritten.<br/> /// <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> /// The SetCDRUserFieldAction is implemented in <code>apps/app_setcdruserfield.c</code>
/// </summary> /// </summary>
public class SetCDRUserFieldAction : ManagerAction 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> /// <summary>
/// Creates a new empty SetCDRUserFieldAction. /// Creates a new empty SetCDRUserFieldAction.
/// </summary> /// </summary>
@ -55,27 +16,55 @@ namespace AsterNET.Manager.Action
} }
/// <summary> /// <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> /// </summary>
/// <param name="channel">the name of the channel</param> /// <param name="channel">the name of the channel</param>
/// <param name="userField">the new value of the userfield</param> /// <param name="userField">the new value of the userfield</param>
public SetCDRUserFieldAction(string channel, string userField) public SetCDRUserFieldAction(string channel, string userField)
{ {
this.channel = channel; this.Channel = channel;
this.userField = userField; this.UserField = userField;
} }
/// <summary> /// <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> /// </summary>
/// <param name="channel">the name of the channel</param> /// <param name="channel">the name of the channel</param>
/// <param name="userField">the new value of the userfield</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> /// <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) public SetCDRUserFieldAction(string channel, string userField, bool append)
{ {
this.channel = channel; this.Channel = channel;
this.userField = userField; this.UserField = userField;
this.append = append; 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 namespace AsterNET.Manager.Action
{ {
/// <summary> /// <summary>
@ -9,43 +7,13 @@ namespace AsterNET.Manager.Action
{ {
/// <summary> The channel on which to set the variable.</summary> /// <summary> The channel on which to set the variable.</summary>
public string channel; public string channel;
/// <summary> The name of the variable to set.</summary> /// <summary> The name of the variable to set.</summary>
public string varName; public string varName;
/// <summary> The value to store.</summary> /// <summary> The value to store.</summary>
public string varValue; 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> /// <summary>
/// Creates a new empty SetVarAction. /// Creates a new empty SetVarAction.
/// </summary> /// </summary>
@ -60,8 +28,8 @@ namespace AsterNET.Manager.Action
/// <param name="value">the new value</param> /// <param name="value">the new value</param>
public SetVarAction(string variable, string value) public SetVarAction(string variable, string value)
{ {
this.varName = variable; varName = variable;
this.varValue = value; varValue = value;
} }
/// <summary> /// <summary>
@ -74,8 +42,43 @@ namespace AsterNET.Manager.Action
public SetVarAction(string channel, string variable, string value) public SetVarAction(string channel, string variable, string value)
{ {
this.channel = channel; this.channel = channel;
this.varName = variable; varName = variable;
this.varValue = value; 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 System;
using AsterNET.Manager.Event;
namespace AsterNET.Manager.Action namespace AsterNET.Manager.Action
{ {
/// <summary> /// <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 /// For each active channel a StatusEvent is generated. After the state of all
/// channels has been reported a StatusCompleteEvent is generated. /// channels has been reported a StatusCompleteEvent is generated.
/// </summary> /// </summary>
@ -18,16 +19,10 @@ namespace AsterNET.Manager.Action
{ {
get { return "Status"; } get { return "Status"; }
} }
public override Type ActionCompleteEventClass() public override Type ActionCompleteEventClass()
{ {
return typeof(Event.StatusCompleteEvent); return typeof (StatusCompleteEvent);
}
/// <summary>
/// Creates a new StatusAction.
/// </summary>
public StatusAction()
{
} }
} }
} }

View file

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

View file

@ -1,6 +1,5 @@
using System;
using AsterNET.Manager.Response;
using System.Collections.Generic; using System.Collections.Generic;
using AsterNET.Manager.Response;
namespace AsterNET.Manager.Action 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 /// 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 /// 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 /// ACTION_* fields provided by this action to specify what action you would like
/// to take, while avoiding handling the strings required. Plain fields:<br/> /// to take, while avoiding handling the strings required. Plain fields:<br />
/// SrcFilename: Configuration filename to read(e.g. foo.conf)<br/> /// SrcFilename: Configuration filename to read(e.g. foo.conf)<br />
/// DstFilename: Configuration filename to write(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/> /// Reload: Whether or not a reload should take place (or name of specific module)<br />
/// Repeatable fields:<br/> /// Repeatable fields:<br />
/// Action-XXXXXX: Action to Take (NewCat,RenameCat,DelCat,Update,Delete,Append)<br/> /// Action-XXXXXX: Action to Take (NewCat,RenameCat,DelCat,Update,Delete,Append)<br />
/// Cat-XXXXXX: Category to operate on<br/> /// Cat-XXXXXX: Category to operate on<br />
/// Var-XXXXXX: Variable to work on<br/> /// Var-XXXXXX: Variable to work on<br />
/// Value-XXXXXX: Value to work on<br/> /// Value-XXXXXX: Value to work on<br />
/// Match-XXXXXX: Extra match required to match line /// Match-XXXXXX: Extra match required to match line
/// </summary> /// </summary>
public class UpdateConfigAction : ManagerActionResponse public class UpdateConfigAction : ManagerActionResponse
@ -32,20 +31,16 @@ namespace AsterNET.Manager.Action
public const string ACTION_DELETE = "delete"; public const string ACTION_DELETE = "delete";
public const string ACTION_APPEND = "append"; public const string ACTION_APPEND = "append";
private string reload; private readonly Dictionary<string, string> actions;
private string srcFileName;
private string dstFileName;
private int actionCounter; private int actionCounter;
private Dictionary<string, string> actions;
/// <summary> /// <summary>
/// Creates a new UpdateConfigAction. /// Creates a new UpdateConfigAction.
/// </summary> /// </summary>
public UpdateConfigAction() public UpdateConfigAction()
: base()
{ {
actionCounter = 0; actionCounter = 0;
actions = new Dictionary<string,string>(); actions = new Dictionary<string, string>();
} }
/// <summary> /// <summary>
@ -54,9 +49,9 @@ namespace AsterNET.Manager.Action
public UpdateConfigAction(string srcFilename, string dstFilename, string reload) public UpdateConfigAction(string srcFilename, string dstFilename, string reload)
: this() : this()
{ {
this.srcFileName = srcFilename; SrcFileName = srcFilename;
this.dstFileName = dstFilename; DstFileName = dstFilename;
this.reload = reload; this.Reload = reload;
} }
/// <summary> /// <summary>
@ -65,9 +60,9 @@ namespace AsterNET.Manager.Action
public UpdateConfigAction(string srcFilename, string dstFilename, bool reload) public UpdateConfigAction(string srcFilename, string dstFilename, bool reload)
: this() : this()
{ {
this.srcFileName = srcFilename; SrcFileName = srcFilename;
this.dstFileName = dstFilename; DstFileName = dstFilename;
this.reload = (reload ? "true" : ""); this.Reload = (reload ? "true" : "");
} }
/// <summary> /// <summary>
@ -76,38 +71,26 @@ namespace AsterNET.Manager.Action
public UpdateConfigAction(string srcFilename, string dstFilename) public UpdateConfigAction(string srcFilename, string dstFilename)
: this() : this()
{ {
this.srcFileName = srcFilename; SrcFileName = srcFilename;
this.dstFileName = dstFilename; DstFileName = dstFilename;
this.reload = ""; Reload = "";
} }
/// <summary> /// <summary>
/// Get/Set the destination filename. /// Get/Set the destination filename.
/// </summary> /// </summary>
public string DstFileName public string DstFileName { get; set; }
{
get { return dstFileName; }
set { dstFileName = value; }
}
/// <summary> /// <summary>
/// Get/Set the source filename. /// Get/Set the source filename.
/// </summary> /// </summary>
public string SrcFileName public string SrcFileName { get; set; }
{
get { return srcFileName; }
set { srcFileName = value; }
}
/// <summary> /// <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. /// Set to empty string to update without reload.
/// </summary> /// </summary>
public string Reload public string Reload { get; set; }
{
get { return reload; }
set { reload = value; }
}
/// <summary> /// <summary>
/// Get the name of this action. /// Get the name of this action.
@ -118,6 +101,7 @@ namespace AsterNET.Manager.Action
} }
#region AddCommand(...) #region AddCommand(...)
/// <summary> /// <summary>
/// Adds a command to update a config file while sparing you the details of /// 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 /// 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); AddCommand(null, null, null, null, null);
} }
#endregion #endregion
#region Actions #region Actions
/// <summary> /// <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. /// 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> /// </summary>
public Dictionary<string, string> Actions public Dictionary<string, string> Actions
{ {
get { return actions; } get { return actions; }
} }
#endregion #endregion
public override object ActionCompleteResponseClass() public override object ActionCompleteResponseClass()
{ {
return new ManagerResponse(); return new ManagerResponse();
} }
} }
} }

View file

@ -1,5 +1,3 @@
using System;
namespace AsterNET.Manager.Action namespace AsterNET.Manager.Action
{ {
/// <summary> /// <summary>
@ -7,36 +5,33 @@ namespace AsterNET.Manager.Action
/// </summary> /// </summary>
public class ZapDNDOffAction : ManagerAction 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> /// <summary>
/// Creates a new empty ZapDNDOffAction. /// Creates a new empty ZapDNDOffAction.
/// </summary> /// </summary>
public ZapDNDOffAction() public ZapDNDOffAction()
{ {
} }
/// <summary> /// <summary>
/// Creates a new ZapDNDOffAction that disables "Do Not Disturb" status for the given zap channel. /// Creates a new ZapDNDOffAction that disables "Do Not Disturb" status for the given zap channel.
/// </summary> /// </summary>
public ZapDNDOffAction(int zapChannel) 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 namespace AsterNET.Manager.Action
{ {
/// <summary> /// <summary>
@ -7,24 +5,6 @@ namespace AsterNET.Manager.Action
/// </summary> /// </summary>
public class ZapDNDOnAction : ManagerAction 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> /// <summary>
/// Creates a new empty ZapDNDOnAction. /// Creates a new empty ZapDNDOnAction.
/// </summary> /// </summary>
@ -37,7 +17,21 @@ namespace AsterNET.Manager.Action
/// </summary> /// </summary>
public ZapDNDOnAction(int zapChannel) 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 namespace AsterNET.Manager.Action
{ {
/// <summary> /// <summary>
@ -7,35 +5,6 @@ namespace AsterNET.Manager.Action
/// </summary> /// </summary>
public class ZapDialOffhookAction : ManagerAction 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> /// <summary> Creates a new empty ZapDialOffhookAction.</summary>
public ZapDialOffhookAction() public ZapDialOffhookAction()
{ {
@ -46,8 +15,28 @@ namespace AsterNET.Manager.Action
/// </summary> /// </summary>
public ZapDialOffhookAction(int zapChannel, string number) public ZapDialOffhookAction(int zapChannel, string number)
{ {
this.zapChannel = zapChannel; this.ZapChannel = zapChannel;
this.number = number; 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 namespace AsterNET.Manager.Action
{ {
/// <summary> /// <summary>
@ -7,25 +5,6 @@ namespace AsterNET.Manager.Action
/// </summary> /// </summary>
public class ZapHangupAction : ManagerAction 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> /// <summary>
/// Creates a new empty ZapHangupAction. /// Creates a new empty ZapHangupAction.
/// </summary> /// </summary>
@ -38,7 +17,21 @@ namespace AsterNET.Manager.Action
/// </summary> /// </summary>
public ZapHangupAction(int zapChannel) 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 System;
using AsterNET.Manager.Event;
namespace AsterNET.Manager.Action namespace AsterNET.Manager.Action
{ {
/// <summary> /// <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 /// For each zap channel a ZapShowChannelsEvent is generated. After all zap
/// channels have been listed a ZapShowChannelsCompleteEvent is generated. /// channels have been listed a ZapShowChannelsCompleteEvent is generated.
/// </summary> /// </summary>
@ -17,16 +19,10 @@ namespace AsterNET.Manager.Action
{ {
get { return "ZapShowChannels"; } get { return "ZapShowChannels"; }
} }
public override Type ActionCompleteEventClass() public override Type ActionCompleteEventClass()
{ {
return typeof(Event.ZapShowChannelsCompleteEvent); return typeof (ZapShowChannelsCompleteEvent);
}
/// <summary>
/// Creates a new ZapShowChannelsAction.
/// </summary>
public ZapShowChannelsAction()
{
} }
} }
} }

View file

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

View file

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

View file

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

View file

@ -5,38 +5,24 @@ namespace AsterNET.Manager.Event
/// </summary> /// </summary>
public abstract class AbstractAgentEvent : AbstractAgentVariables public abstract class AbstractAgentEvent : AbstractAgentVariables
{ {
private string queue; public AbstractAgentEvent(ManagerConnection source)
private string member; : base(source)
private string memberName; {
}
/// <summary> /// <summary>
/// Get/Set the name of the queue. /// Get/Set the name of the queue.
/// </summary> /// </summary>
public string Queue public string Queue { get; set; }
{
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; }
}
/// <summary> /// <summary>
/// Get/Set the name of the member's interface. /// Get/Set the name of the member's interface.
/// </summary> /// </summary>
public string MemberName public string Member { get; set; }
{
get { return memberName; }
set { this.memberName = value; }
}
public AbstractAgentEvent(ManagerConnection source) /// <summary>
: base(source) /// 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> /// </summary>
public abstract class AbstractMeetmeEvent : ManagerEvent 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) public AbstractMeetmeEvent(ManagerConnection source)
: base(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> /// </summary>
public abstract class AbstractParkedCallEvent : ManagerEvent public abstract class AbstractParkedCallEvent : ManagerEvent
{ {
private string exten; public AbstractParkedCallEvent(ManagerConnection source)
private string callerId; : base(source)
private string callerIdNum; {
private string callerIdName; }
/// <summary> /// <summary>
/// Get/Set the extension the channel is or was parked at. /// Get/Set the extension the channel is or was parked at.
/// </summary> /// </summary>
public string Exten public string Exten { get; set; }
{
get { return this.exten; }
set { this.exten = value; }
}
/// <summary> /// <summary>
/// Get/Set the Caller*ID number of the parked channel. /// Get/Set the Caller*ID number of the parked channel.
/// </summary> /// </summary>
public string CallerId public string CallerId { get; set; }
{
get { return this.callerId; }
set { this.callerId = value; }
}
/// <summary> /// <summary>
/// Get/Set the Caller*ID number of the parked channel. /// Get/Set the Caller*ID number of the parked channel.
/// </summary> /// </summary>
public string CallerIdNum public string CallerIdNum { get; set; }
{
get { return this.callerIdNum; }
set { this.callerIdNum = value; }
}
/// <summary> /// <summary>
/// Get/Set the Caller*ID name of the parked channel. /// Get/Set the Caller*ID name of the parked channel.
/// </summary> /// </summary>
public string CallerIdName public string CallerIdName { get; set; }
{
get { return this.callerIdName; }
set { this.callerIdName = value; }
}
public AbstractParkedCallEvent(ManagerConnection source)
: base(source)
{ }
} }
} }

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -5,40 +5,24 @@ namespace AsterNET.Manager.Event
/// </summary> /// </summary>
public class AgentConnectEvent : AbstractAgentEvent 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) public AgentConnectEvent(ManagerConnection source)
: base(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 namespace AsterNET.Manager.Event
{ {
/// <summary> /// <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> /// It is implemented in <code>channels/chan_agent.c</code>
/// </summary> /// </summary>
/// <seealso cref="Manager.event.AgentLogoffEvent" /> /// <seealso cref="Manager.event.AgentLogoffEvent" />
public class AgentLoginEvent : ManagerEvent 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) public AgentLoginEvent(ManagerConnection source)
: base(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 namespace AsterNET.Manager.Event
{ {
/// <summary> /// <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> /// It is implemented in <code>channels/chan_agent.c</code>
/// </summary> /// </summary>
/// <seealso cref="Manager.event.AgentLoginEvent" /> /// <seealso cref="Manager.event.AgentLoginEvent" />
public class AgentLogoffEvent : ManagerEvent 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) public AgentLogoffEvent(ManagerConnection source)
: base(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 namespace AsterNET.Manager.Event
{ {
/// <summary> /// <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 /// Available since Asterisk 1.2
/// </summary> /// </summary>
/// <seealso cref="Manager.Action.AgentsAction" /> /// <seealso cref="Manager.Action.AgentsAction" />
public class AgentsEvent : ResponseEvent public class AgentsEvent : ResponseEvent
{ {
private string agent; public AgentsEvent(ManagerConnection source)
private string name; : base(source)
private string status; {
private string loggedInChan; }
private string talkingTo;
private long loggedInTime;
/// <summary> /// <summary>
/// Get/Set the agentid. /// Get/Set the agentid.
/// </summary> /// </summary>
public string Agent public string Agent { get; set; }
{
get { return this.agent; }
set { this.agent = value; }
}
/// <summary> /// <summary>
/// Get/Set the name of this agent. /// Get/Set the name of this agent.
/// </summary> /// </summary>
public string Name public string Name { get; set; }
{
get { return this.name; }
set { this.name = value; }
}
/// <summary> /// <summary>
/// Get/Set the status of this agent.<br/> /// Get/Set the status of this agent.<br />
/// This is one of /// This is one of
/// <dl> /// <dl>
/// <dt>"AGENT_LOGGEDOFF"</dt> /// <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> /// <dd>Don't know anything about agent. Shouldn't ever get this.</dd>
/// </dl> /// </dl>
/// </summary> /// </summary>
public string Status public string Status { get; set; }
{
get { return this.status; }
set { this.status = value; }
}
/// <summary> /// <summary>
/// Get/Set the name of channel this agent logged in from or "n/a" if the agent is not logged in. /// Get/Set the name of channel this agent logged in from or "n/a" if the agent is not logged in.
/// </summary> /// </summary>
public string LoggedInChan public string LoggedInChan { get; set; }
{
get { return this.loggedInChan; }
set { this.loggedInChan = value; }
}
/// <summary> /// <summary>
/// Get/Set the time (in seconds since 01/01/1970) when the agent logged in or 0 if the user is not logged. /// Get/Set the time (in seconds since 01/01/1970) when the agent logged in or 0 if the user is not logged.
/// </summary> /// </summary>
public long LoggedInTime public long LoggedInTime { get; set; }
{
get { return this.loggedInTime; }
set { this.loggedInTime = value; }
}
/// <summary> /// <summary>
/// Get/Set the numerical Caller*ID of the channel this agent is talking toor "n/a" if this agent is talking to nobody. /// Get/Set the numerical Caller*ID of the channel this agent is talking toor "n/a" if this agent is talking to nobody.
/// </summary> /// </summary>
public string TalkingTo public string TalkingTo { get; set; }
{
get { return this.talkingTo; }
set { this.talkingTo = value; }
}
public AgentsEvent(ManagerConnection source)
: base(source)
{
}
} }
} }

View file

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

View file

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

View file

@ -1,114 +1,48 @@
namespace AsterNET.Manager.Event namespace AsterNET.Manager.Event
{ {
/// <summary> /// <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 /// 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> /// This event is implemented in <code>cdr/cdr_manager.c</code>
/// </summary> /// </summary>
public class CdrEvent : ManagerEvent 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) public CdrEvent(ManagerConnection source)
: base(source) : base(source)
{ {
} }
public string AccountCode public string AccountCode { get; set; }
{
get { return accountCode; } public string Src { get; set; }
set { this.accountCode = value; }
} public string Destination { get; set; }
public string Src
{ public string DestinationContext { get; set; }
get { return src; }
set { this.src = value; } public string CallerId { get; set; }
}
public string Destination public string DestinationChannel { get; set; }
{
get { return destination; } public string LastApplication { get; set; }
set { this.destination = value; }
} public string LastData { get; set; }
public string DestinationContext
{ public string StartTime { get; set; }
get { return destinationContext; }
set { this.destinationContext = value; } public string AnswerTime { get; set; }
}
public string CallerId public string EndTime { get; set; }
{
get { return callerId; } public long Duration { get; set; }
set { this.callerId = value; }
} public long BillableSeconds { get; set; }
public string DestinationChannel
{ public string Disposition { get; set; }
get { return destinationChannel; }
set { this.destinationChannel = value; } public string AmaFlags { get; set; }
}
public string LastApplication public string UserField { get; set; }
{
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; }
}
} }
} }

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