diff --git a/Asterisk.2013/Asterisk.NET.Test/Asterisk.NET.Test/Program.cs b/Asterisk.2013/Asterisk.NET.Test/Asterisk.NET.Test/Program.cs index e47cda1..bec6da2 100644 --- a/Asterisk.2013/Asterisk.NET.Test/Asterisk.NET.Test/Program.cs +++ b/Asterisk.2013/Asterisk.NET.Test/Asterisk.NET.Test/Program.cs @@ -138,13 +138,13 @@ Ctrl-C to exit"); manager.RegisterUserEventClass(typeof(UserAgentLoginEvent)); // Add or Remove events - manager.UserEvents += new UserEventHandler(dam_UserEvents); + manager.UserEvents += new EventHandler(dam_UserEvents); // Dont't display this event - manager.NewExten += new NewExtenEventHandler(manager_IgnoreEvent); + manager.NewExten += new EventHandler(manager_IgnoreEvent); // Display all other - manager.UnhandledEvent += new ManagerEventHandler(dam_Events); + manager.UnhandledEvent += new EventHandler(dam_Events); // +++ Only to debug purpose manager.FireAllEvents = true; @@ -288,7 +288,7 @@ Ctrl-C to exit"); Console.WriteLine("Redirect Call from " + ORIGINATE_CHANNEL + " to " + ORIGINATE_EXTRA_CHANNEL + " or press ESC."); // Wait for Dial Event from ORIGINATE_CHANNEL - DialEventHandler de = new DialEventHandler(dam_Dial); + EventHandler de = new EventHandler(dam_Dial); manager.Dial += de; while (transferChannel == null) { @@ -323,7 +323,7 @@ Ctrl-C to exit"); // Link event used to define monitor channel Console.WriteLine("Monitor call. Please call " + ORIGINATE_CHANNEL + " and answer or press ESC."); // Wait for Link event - LinkEventHandler le = new LinkEventHandler(dam_Link); + EventHandler le = new EventHandler(dam_Link); manager.Link += le; while (monitorChannel == null) { diff --git a/Asterisk.2013/Asterisk.NET.WinForm/FormMain.cs b/Asterisk.2013/Asterisk.NET.WinForm/FormMain.cs index 0ebcbb5..6ac81b2 100644 --- a/Asterisk.2013/Asterisk.NET.WinForm/FormMain.cs +++ b/Asterisk.2013/Asterisk.NET.WinForm/FormMain.cs @@ -28,7 +28,7 @@ namespace AsterNET.WinForm btnConnect.Enabled = false; manager = new ManagerConnection(address, port, user, password); - manager.UnhandledEvent += new ManagerEventHandler(manager_Events); + manager.UnhandledEvent += new EventHandler(manager_Events); try { // Uncomment next 2 line comments to Disable timeout (debug mode) diff --git a/Asterisk.2013/Asterisk.NET/AsterNET.csproj b/Asterisk.2013/Asterisk.NET/AsterNET.csproj index 1a101cb..cf51e8c 100644 --- a/Asterisk.2013/Asterisk.NET/AsterNET.csproj +++ b/Asterisk.2013/Asterisk.NET/AsterNET.csproj @@ -167,6 +167,7 @@ + @@ -195,6 +196,7 @@ + @@ -256,6 +258,7 @@ + diff --git a/Asterisk.2013/Asterisk.NET/Helper.cs b/Asterisk.2013/Asterisk.NET/Helper.cs index 80c9830..e6fc507 100644 --- a/Asterisk.2013/Asterisk.NET/Helper.cs +++ b/Asterisk.2013/Asterisk.NET/Helper.cs @@ -874,12 +874,13 @@ namespace AsterNET #region RegisterEventHandler(Dictionary list, int index, Type eventType) - internal static void RegisterEventHandler(Dictionary list, int index, Type eventType) + internal static void RegisterEventHandler(Dictionary> list, Type eventType, Func action) { - int eventHash = eventType.Name.GetHashCode(); + var eventTypeName = eventType.Name; + int eventHash = eventTypeName.GetHashCode(); if (list.ContainsKey(eventHash)) - throw new ArgumentException("Event class already registered : " + eventType.Name); - list.Add(eventHash, index); + throw new ArgumentException("Event class already registered : " + eventTypeName); + list.Add(eventHash, action); } #endregion diff --git a/Asterisk.2013/Asterisk.NET/Manager/Action/FilterAction.cs b/Asterisk.2013/Asterisk.NET/Manager/Action/FilterAction.cs new file mode 100644 index 0000000..b5369df --- /dev/null +++ b/Asterisk.2013/Asterisk.NET/Manager/Action/FilterAction.cs @@ -0,0 +1,57 @@ +namespace AsterNET.Manager.Action +{ + /// + /// Dynamically add filters for the current manager session + /// The filters added are only used for the current session. Once the connection is closed the filters are removed. + /// This comand requires the system permission because this command can be used to create filters that may bypass filters defined in manager.conf + /// + public class FilterAction : ManagerAction + { + #region Action + + /// + /// Get the name of this action, i.e. "Filter". + /// + public override string Action + { + get { return "Filter"; } + } + + #endregion + + #region Operation + + /// + /// Add - Add a filter + /// + public string Operation { get; set; } + + #endregion + + #region Filter + + /// + /// Filters can be whitelist or blacklist + /// Example whitelist filter: "Event: Newchannel" + /// Example blacklist filter: "!Channel: DAHDI.*" + /// + public string Filter { get; set; } + + #endregion + + #region FilterAction(string filter) + + /// + /// Add - Add a filter + /// + /// Add a filter + /// Filters can be whitelist or blacklist + public FilterAction(string filter, string operation = "Add") + { + Filter = filter; + Operation = operation; + } + + #endregion + } +} diff --git a/Asterisk.2013/Asterisk.NET/Manager/Action/QueueSummaryAction.cs b/Asterisk.2013/Asterisk.NET/Manager/Action/QueueSummaryAction.cs new file mode 100644 index 0000000..703daae --- /dev/null +++ b/Asterisk.2013/Asterisk.NET/Manager/Action/QueueSummaryAction.cs @@ -0,0 +1,51 @@ +using AsterNET.Manager.Event; +using System; + +namespace AsterNET.Manager.Action +{ + /// + /// Show queue summary + /// + /// + public class QueueSummaryAction : ManagerActionEvent + { + #region Action + + /// + /// Get the name of this action, i.e. "Filter". + /// + public override string Action + { + get { return "QueueSummary"; } + } + + #endregion + + #region MyRegion + + /// + /// Name of queue + /// + public string Queue { get; set; } + + #endregion + + #region QueueSummaryAction(string queue) + + public QueueSummaryAction(string queue) + { + Queue = queue; + } + + #endregion + + #region ActionCompleteEventClass() + + public override Type ActionCompleteEventClass() + { + return typeof(QueueSummaryEvent); + } + + #endregion + } +} diff --git a/Asterisk.2013/Asterisk.NET/Manager/Event/ChallengeSentEvent.cs b/Asterisk.2013/Asterisk.NET/Manager/Event/ChallengeSentEvent.cs index df155dc..3107bbe 100644 --- a/Asterisk.2013/Asterisk.NET/Manager/Event/ChallengeSentEvent.cs +++ b/Asterisk.2013/Asterisk.NET/Manager/Event/ChallengeSentEvent.cs @@ -1,16 +1,16 @@ -namespace AsterNET.Manager.Event -{ - - /// - /// Raised when an Asterisk service sends an authentication challenge to a request..
- ///
- public class ChallengeSentEvent : ManagerEvent - { - public ChallengeSentEvent(ManagerConnection source) - : base(source) - { - } - - public string Status { get; set; } - } +namespace AsterNET.Manager.Event +{ + + /// + /// Raised when an Asterisk service sends an authentication challenge to a request..
+ ///
+ public class ChallengeSentEvent : ManagerEvent + { + public ChallengeSentEvent(ManagerConnection source) + : base(source) + { + } + + public string Status { get; set; } + } } \ No newline at end of file diff --git a/Asterisk.2013/Asterisk.NET/Manager/Event/DeviceStateChangeEvent.cs b/Asterisk.2013/Asterisk.NET/Manager/Event/DeviceStateChangeEvent.cs index 415b3e1..3ffb3df 100644 --- a/Asterisk.2013/Asterisk.NET/Manager/Event/DeviceStateChangeEvent.cs +++ b/Asterisk.2013/Asterisk.NET/Manager/Event/DeviceStateChangeEvent.cs @@ -1,17 +1,17 @@ -namespace AsterNET.Manager.Event -{ - - /// - /// Raised when a device state changes.
- /// This differs from the ExtensionStatus event because this event is raised for all device state changes, not only for changes that affect dialplan hints. - ///
- public class DeviceStateChangeEvent : ManagerEvent - { - public DeviceStateChangeEvent(ManagerConnection source) - : base(source) - { - } - - public string Status { get; set; } - } +namespace AsterNET.Manager.Event +{ + + /// + /// Raised when a device state changes.
+ /// This differs from the ExtensionStatus event because this event is raised for all device state changes, not only for changes that affect dialplan hints. + ///
+ public class DeviceStateChangeEvent : ManagerEvent + { + public DeviceStateChangeEvent(ManagerConnection source) + : base(source) + { + } + + public string Status { get; set; } + } } \ No newline at end of file diff --git a/Asterisk.2013/Asterisk.NET/Manager/Event/InvalidAccountIDEvent.cs b/Asterisk.2013/Asterisk.NET/Manager/Event/InvalidAccountIDEvent.cs index 44154dc..9971054 100644 --- a/Asterisk.2013/Asterisk.NET/Manager/Event/InvalidAccountIDEvent.cs +++ b/Asterisk.2013/Asterisk.NET/Manager/Event/InvalidAccountIDEvent.cs @@ -1,16 +1,16 @@ -namespace AsterNET.Manager.Event -{ - - /// - /// Raised when a request fails an authentication check due to an invalid account ID.
- ///
- public class InvalidAccountIDEvent : ManagerEvent - { - public InvalidAccountIDEvent(ManagerConnection source) - : base(source) - { - } - - public string Status { get; set; } - } +namespace AsterNET.Manager.Event +{ + + /// + /// Raised when a request fails an authentication check due to an invalid account ID.
+ ///
+ public class InvalidAccountIDEvent : ManagerEvent + { + public InvalidAccountIDEvent(ManagerConnection source) + : base(source) + { + } + + public string Status { get; set; } + } } \ No newline at end of file diff --git a/Asterisk.2013/Asterisk.NET/Manager/Event/QueueSummaryEvent.cs b/Asterisk.2013/Asterisk.NET/Manager/Event/QueueSummaryEvent.cs new file mode 100644 index 0000000..9f48db6 --- /dev/null +++ b/Asterisk.2013/Asterisk.NET/Manager/Event/QueueSummaryEvent.cs @@ -0,0 +1,48 @@ +namespace AsterNET.Manager.Event +{ + /// + /// + /// + public class QueueSummaryEvent : ManagerEvent + { + public QueueSummaryEvent(ManagerConnection source) + : base(source) + { + } + + /// + /// Queue name + /// + public string Queue { get; set; } + + /// + /// Logged operators count in queue + /// + public int LoggedIn { get; set; } + + /// + /// Available operators in queue + /// + public int Available { get; set; } + + /// + /// Calls count + /// + public int Callers { get; set; } + + /// + /// + /// + public int HoldTime { get; set; } + + /// + /// Total talk time + /// + public int TalkTime { get; set; } + + /// + /// + /// + public int LongestHoldTime { get; set; } + } +} diff --git a/Asterisk.2013/Asterisk.NET/Manager/Event/SuccessfulAuthEvent.cs b/Asterisk.2013/Asterisk.NET/Manager/Event/SuccessfulAuthEvent.cs index c87a9e0..32f7570 100644 --- a/Asterisk.2013/Asterisk.NET/Manager/Event/SuccessfulAuthEvent.cs +++ b/Asterisk.2013/Asterisk.NET/Manager/Event/SuccessfulAuthEvent.cs @@ -1,16 +1,16 @@ -namespace AsterNET.Manager.Event -{ - - /// - /// Raised when a request successfully authenticates with a service..
- ///
- public class SuccessfulAuthEvent : ManagerEvent - { - public SuccessfulAuthEvent(ManagerConnection source) - : base(source) - { - } - - public string Status { get; set; } - } +namespace AsterNET.Manager.Event +{ + + /// + /// Raised when a request successfully authenticates with a service..
+ ///
+ public class SuccessfulAuthEvent : ManagerEvent + { + public SuccessfulAuthEvent(ManagerConnection source) + : base(source) + { + } + + public string Status { get; set; } + } } \ No newline at end of file diff --git a/Asterisk.2013/Asterisk.NET/Manager/ManagerConnection.cs b/Asterisk.2013/Asterisk.NET/Manager/ManagerConnection.cs index daf82bb..d1fe667 100644 --- a/Asterisk.2013/Asterisk.NET/Manager/ManagerConnection.cs +++ b/Asterisk.2013/Asterisk.NET/Manager/ManagerConnection.cs @@ -1,5 +1,4 @@ using System; -using System.IO; using System.Threading; using System.Collections; using AsterNET.Manager.Action; @@ -7,1645 +6,957 @@ using AsterNET.Manager.Event; using AsterNET.Manager.Response; using System.Text.RegularExpressions; using System.Text; -using System.Net.Sockets; using System.Collections.Generic; using System.Reflection; using AsterNET.IO; -using AsterNET.Util; namespace AsterNET.Manager { - #region Event delegate - - public delegate void ManagerEventHandler(object sender, ManagerEvent e); - public delegate void AgentCallbackLoginEventHandler(object sender, Event.AgentCallbackLoginEvent e); - public delegate void AgentCallbackLogoffEventHandler(object sender, Event.AgentCallbackLogoffEvent e); - public delegate void AgentCalledEventHandler(object sender, Event.AgentCalledEvent e); - public delegate void AgentCompleteEventHandler(object sender, Event.AgentCompleteEvent e); - public delegate void AgentConnectEventHandler(object sender, Event.AgentConnectEvent e); - public delegate void AgentDumpEventHandler(object sender, Event.AgentDumpEvent e); - public delegate void AgentLoginEventHandler(object sender, Event.AgentLoginEvent e); - public delegate void AgentLogoffEventHandler(object sender, Event.AgentLogoffEvent e); - public delegate void AgentsCompleteEventHandler(object sender, Event.AgentsCompleteEvent e); - public delegate void AgentsEventHandler(object sender, Event.AgentsEvent e); - public delegate void AlarmClearEventHandler(object sender, Event.AlarmClearEvent e); - public delegate void AlarmEventHandler(object sender, Event.AlarmEvent e); - public delegate void BridgeEventHandler(object sender, Event.BridgeEvent e); - public delegate void CdrEventHandler(object sender, Event.CdrEvent e); - public delegate void DBGetResponseEventHandler(object sender, Event.DBGetResponseEvent e); - public delegate void DialEventHandler(object sender, Event.DialEvent e); - public delegate void DTMFEventHandler(object sender, Event.DTMFEvent e); - public delegate void DNDStateEventHandler(object sender, Event.DNDStateEvent e); - public delegate void ExtensionStatusEventHandler(object sender, Event.ExtensionStatusEvent e); - public delegate void HangupEventHandler(object sender, Event.HangupEvent e); - public delegate void HoldedCallEventHandler(object sender, Event.HoldedCallEvent e); - public delegate void HoldEventHandler(object sender, Event.HoldEvent e); - public delegate void JoinEventHandler(object sender, Event.JoinEvent e); - public delegate void LeaveEventHandler(object sender, Event.LeaveEvent e); - public delegate void LinkEventHandler(object sender, Event.LinkEvent e); - public delegate void LogChannelEventHandler(object sender, Event.LogChannelEvent e); - public delegate void MeetMeJoinEventHandler(object sender, Event.MeetmeJoinEvent e); - public delegate void MeetMeLeaveEventHandler(object sender, Event.MeetmeLeaveEvent e); - public delegate void MeetMeTalkingEventHandler(object sender, Event.MeetmeTalkingEvent e); - - public delegate void MessageWaitingEventHandler(object sender, Event.MessageWaitingEvent e); - public delegate void NewCallerIdEventHandler(object sender, Event.NewCallerIdEvent e); - public delegate void NewChannelEventHandler(object sender, Event.NewChannelEvent e); - public delegate void NewExtenEventHandler(object sender, Event.NewExtenEvent e); - public delegate void NewStateEventHandler(object sender, Event.NewStateEvent e); - public delegate void OriginateResponseEventHandler(object sender, Event.OriginateResponseEvent e); - public delegate void ParkedCallEventHandler(object sender, Event.ParkedCallEvent e); - public delegate void ParkedCallGiveUpEventHandler(object sender, Event.ParkedCallGiveUpEvent e); - public delegate void ParkedCallsCompleteEventHandler(object sender, Event.ParkedCallsCompleteEvent e); - public delegate void ParkedCallTimeOutEventHandler(object sender, Event.ParkedCallTimeOutEvent e); - public delegate void PeerEntryEventHandler(object sender, Event.PeerEntryEvent e); - public delegate void PeerlistCompleteEventHandler(object sender, Event.PeerlistCompleteEvent e); - public delegate void PeerStatusEventHandler(object sender, Event.PeerStatusEvent e); - public delegate void QueueEntryEventHandler(object sender, Event.QueueEntryEvent e); - public delegate void QueueMemberAddedEventHandler(object sender, Event.QueueMemberAddedEvent e); - public delegate void QueueMemberEventHandler(object sender, Event.QueueMemberEvent e); - public delegate void QueueMemberPausedEventHandler(object sender, Event.QueueMemberPausedEvent e); - public delegate void QueueMemberRemovedEventHandler(object sender, Event.QueueMemberRemovedEvent e); - public delegate void QueueMemberStatusEventHandler(object sender, Event.QueueMemberStatusEvent e); - public delegate void QueueParamsEventHandler(object sender, Event.QueueParamsEvent e); - public delegate void QueueStatusCompleteEventHandler(object sender, Event.QueueStatusCompleteEvent e); - public delegate void RegistryEventHandler(object sender, Event.RegistryEvent e); - public delegate void RenameEventHandler(object sender, Event.RenameEvent e); - public delegate void TransferEventHandler(object sender, Event.TransferEvent e); - public delegate void StatusCompleteEventHandler(object sender, Event.StatusCompleteEvent e); - public delegate void StatusEventHandler(object sender, Event.StatusEvent e); - public delegate void UnholdEventHandler(object sender, Event.UnholdEvent e); - public delegate void UnlinkEventHandler(object sender, Event.UnlinkEvent e); - public delegate void UnparkedCallEventHandler(object sender, Event.UnparkedCallEvent e); - public delegate void UserEventHandler(object sender, Event.UserEvent e); - public delegate void QueueCallerAbandonEventHandler(object sender, Event.QueueCallerAbandonEvent e); - public delegate void ZapShowChannelsCompleteEventHandler(object sender, Event.ZapShowChannelsCompleteEvent e); - public delegate void ZapShowChannelsEventHandler(object sender, Event.ZapShowChannelsEvent e); - public delegate void ConnectionStateEventHandler(object sender, Event.ConnectionStateEvent e); - public delegate void VarSetEventHandler(object sender, Event.VarSetEvent e); - public delegate void AGIExecHandler(object sender, Event.AGIExecEvent e); - public delegate void ConfbridgeStartEventHandler(object sender, Event.ConfbridgeStartEvent e); - public delegate void ConfbridgeJoinEventHandler(object sender, Event.ConfbridgeJoinEvent e); - public delegate void ConfbridgeLeaveEventHandler(object sender, Event.ConfbridgeLeaveEvent e); - public delegate void ConfbridgeEndEventHandler(object sender, Event.ConfbridgeEndEvent e); - public delegate void ConfbridgeTalkingEventHandler(object sender, Event.ConfbridgeTalkingEvent e); - public delegate void FailedACLEventHandler(object sender, Event.FailedACLEvent e); - public delegate void AttendedTransferEventHandler(object sender, Event.AttendedTransferEvent e); - public delegate void BlindTransferEventHandler(object sender, Event.BlindTransferEvent e); - public delegate void BridgeCreateEventHandler(object sender, Event.BridgeCreateEvent e); - public delegate void BridgeDestroyEventHandler(object sender, Event.BridgeDestroyEvent e); - public delegate void BridgeEnterEventHandler(object sender, Event.BridgeEnterEvent e); - public delegate void BridgeLeaveEventHandler(object sender, Event.BridgeLeaveEvent e); - public delegate void DialBeginEventHandler(object sender, Event.DialBeginEvent e); - public delegate void DialEndEventHandler(object sender, Event.DialEndEvent e); - public delegate void QueueCallerJoinEventHandler(object sender, Event.QueueCallerJoinEvent e); - public delegate void QueueCallerLeaveEventHandler(object sender, Event.QueueCallerLeaveEvent e); - public delegate void QueueMemberPauseEventHandler(object sender, Event.QueueMemberPauseEvent e); - public delegate void ChallengeResponseFailedEventHandler(object sender, Event.ChallengeResponseFailedEvent e); - public delegate void InvalidAccountIDEventHandler(object sender, Event.InvalidAccountIDEvent e); - public delegate void DeviceStateChangedEventHandler(object sender, Event.DeviceStateChangeEvent e); - public delegate void ChallengeSentEventHandler(object sender, Event.ChallengeSentEvent e); - public delegate void SuccessfulAuthEventHandler(object sender, Event.SuccessfulAuthEvent e); - - - #endregion - /// /// Default implemention of the ManagerConnection interface. /// public class ManagerConnection - { - #region Variables + { + #region Variables #if LOGGER - private Logger logger = Logger.Instance(); + private Logger logger = Logger.Instance(); #endif - private long actionIdCount = 0; - private string hostname; - private int port; - private string username; - private string password; + private long actionIdCount = 0; + private string hostname; + private int port; + private string username; + private string password; - private SocketConnection mrSocket; - private Thread mrReaderThread; - private ManagerReader mrReader; + private SocketConnection mrSocket; + private Thread mrReaderThread; + private ManagerReader mrReader; - private int defaultResponseTimeout = 2000; - private int defaultEventTimeout = 5000; - private int sleepTime = 50; - private bool keepAlive = true; - private bool keepAliveAfterAuthenticationFailure = false; - private string protocolIdentifier; - private AsteriskVersion asteriskVersion; - private Dictionary responseHandlers; - private Dictionary pingHandlers; - private Dictionary responseEventHandlers; - private int pingInterval = 10000; + private int defaultResponseTimeout = 2000; + private int defaultEventTimeout = 5000; + private int sleepTime = 50; + private bool keepAlive = true; + private bool keepAliveAfterAuthenticationFailure = false; + private string protocolIdentifier; + private AsteriskVersion asteriskVersion; + private Dictionary responseHandlers; + private Dictionary pingHandlers; + private Dictionary responseEventHandlers; + private int pingInterval = 10000; - private object lockSocket = new object(); - private object lockHandlers = new object(); + private object lockSocket = new object(); + private object lockHandlers = new object(); - private bool enableEvents = true; - private string version = string.Empty; - private Encoding socketEncoding = Encoding.ASCII; - private bool reconnected = false; - private bool reconnectEnable = false; - private int reconnectCount; + private bool enableEvents = true; + private string version = string.Empty; + private Encoding socketEncoding = Encoding.ASCII; + private bool reconnected = false; + private bool reconnectEnable = false; + private int reconnectCount; - private Dictionary registeredEventClasses; - private Dictionary registeredEventHandlers; - private event ManagerEventHandler internalEvent; - private bool fireAllEvents = false; - private Thread callerThread; + private Dictionary registeredEventClasses; + private Dictionary> registeredEventHandlers; + private event EventHandler internalEvent; + private bool fireAllEvents = false; + private Thread callerThread; - /// Default Fast Reconnect retry counter. - private int reconnectRetryFast = 5; - /// Default Maximum Reconnect retry counter. - private int reconnectRetryMax = 10; - /// Default Fast Reconnect interval in milliseconds. - private int reconnectIntervalFast = 5000; - /// Default Slow Reconnect interval in milliseconds. - private int reconnectIntervalMax = 10000; + /// Default Fast Reconnect retry counter. + private int reconnectRetryFast = 5; + /// Default Maximum Reconnect retry counter. + private int reconnectRetryMax = 10; + /// Default Fast Reconnect interval in milliseconds. + private int reconnectIntervalFast = 5000; + /// Default Slow Reconnect interval in milliseconds. + private int reconnectIntervalMax = 10000; public char[] VAR_DELIMITER = { '|' }; - #endregion + #endregion /// /// Allows you to specifiy how events are fired. If false (default) then /// events will be fired in order. Otherwise events will be fired as they arrive and /// control logic in your application will need to handle synchronization. /// - public bool UseASyncEvents = false; + public bool UseASyncEvents = false; - #region Events + #region Events - /// - /// An UnhandledEvent is triggered on unknown event. - /// - public event ManagerEventHandler UnhandledEvent; - /// - /// An AgentCallbackLogin is triggered when an agent is successfully logged in. - /// - public event AgentCallbackLoginEventHandler AgentCallbackLogin; - /// - /// An AgentCallbackLogoff is triggered when an agent that previously logged in is logged of.
- ///
- public event AgentCallbackLogoffEventHandler AgentCallbackLogoff; - /// - /// An AgentCalled is triggered when an agent is ring.
- /// To enable AgentCalled you have to set eventwhencalled = yes in queues.conf.
- ///
- public event AgentCalledEventHandler AgentCalled; - /// - /// An AgentCompleteEvent is triggered when at the end of a call if the caller was connected to an agent. - /// - public event AgentCompleteEventHandler AgentComplete; - /// - /// An AgentConnectEvent is triggered when a caller is connected to an agent. - /// - public event AgentConnectEventHandler AgentConnect; - /// - /// An AgentDumpEvent is triggered when an agent dumps the caller while listening to the queue announcement. - /// - public event AgentDumpEventHandler AgentDump; - /// - /// An AgentLoginEvent is triggered when an agent is successfully logged in using AgentLogin. - /// - public event AgentLoginEventHandler AgentLogin; - /// - /// An AgentCallbackLogoffEvent is triggered when an agent that previously logged in using AgentLogin is logged of. - /// - public event AgentLogoffEventHandler AgentLogoff; - /// - /// An AgentsCompleteEvent is triggered after the state of all agents has been reported in response to an AgentsAction. - /// - public event AgentsCompleteEventHandler AgentsComplete; - /// - /// An AgentsEvent is triggered for each agent in response to an AgentsAction. - /// - public event AgentsEventHandler Agents; - /// - /// An AlarmEvent is triggered when a Zap channel leaves alarm state. - /// - public event AlarmClearEventHandler AlarmClear; - /// - /// - /// - public event BridgeEventHandler Bridge; - /// - /// An AlarmEvent is triggered when a Zap channel enters or changes alarm state. - /// - public event AlarmEventHandler Alarm; - /// - /// A CdrEvent is triggered when a call detail record is generated, usually at the end of a call. - /// - public event CdrEventHandler Cdr; - public event DBGetResponseEventHandler DBGetResponse; - /// - /// A Dial is triggered whenever a phone attempts to dial someone.
- ///
- public event DialEventHandler Dial; - public event DTMFEventHandler DTMF; - /// - /// A DNDStateEvent is triggered by the Zap channel driver when a channel enters or leaves DND (do not disturb) state. - /// - public event DNDStateEventHandler DNDState; - /// - /// An ExtensionStatus is triggered when the state of an extension changes.
- ///
- public event ExtensionStatusEventHandler ExtensionStatus; - /// - /// A Hangup is triggered when a channel is hung up.
- ///
- public event HangupEventHandler Hangup; - /// - /// A HoldedCall is triggered when a channel is put on hold.
- ///
- public event HoldedCallEventHandler HoldedCall; - /// - /// A Hold is triggered by the SIP channel driver when a channel is put on hold.
- ///
- public event HoldEventHandler Hold; - /// - /// A Join is triggered when a channel joines a queue.
- ///
- public event JoinEventHandler Join; - /// - /// A Leave is triggered when a channel leaves a queue.
- ///
- public event LeaveEventHandler Leave; - /// - /// A Link is triggered when two voice channels are linked together and voice data exchange commences.
- /// Several Link events may be seen for a single call. This can occur when Asterisk fails to setup a - /// native bridge for the call.This is when Asterisk must sit between two telephones and perform - /// CODEC conversion on their behalf. - ///
- public event LinkEventHandler Link; - /// - /// A LogChannel is triggered when logging is turned on or off.
- ///
- public event LogChannelEventHandler LogChannel; - /// - /// A MeetMeJoin is triggered if a channel joins a meet me conference.
- ///
- public event MeetMeJoinEventHandler MeetMeJoin; - /// - /// A MeetMeLeave is triggered if a channel leaves a meet me conference.
- ///
- public event MeetMeLeaveEventHandler MeetMeLeave; - // public event MeetMeStopTalkingEventHandler MeetMeStopTalking; - /// - /// A MeetMeTalkingEvent is triggered when a user starts talking in a meet me conference.
- /// To enable talker detection you must pass the option 'T' to the MeetMe application. - ///
- public event MeetMeTalkingEventHandler MeetMeTalking; - /// - /// A MessageWaiting is triggered when someone leaves voicemail.
- ///
- public event MessageWaitingEventHandler MessageWaiting; - /// - /// A NewCallerId is triggered when the caller id of a channel changes.
- ///
- public event NewCallerIdEventHandler NewCallerId; - /// - /// A NewChannel is triggered when a new channel is created.
- ///
- public event NewChannelEventHandler NewChannel; - /// - /// A NewExten is triggered when a channel is connected to a new extension.
- ///
- public event NewExtenEventHandler NewExten; - /// - /// A NewState is triggered when the state of a channel has changed.
- ///
- public event NewStateEventHandler NewState; - // public event OriginateEventHandler Originate; - /// - /// An OriginateFailure is triggered when the execution of an OriginateAction failed. - /// - // public event OriginateFailureEventHandler OriginateFailure; - /// - /// An OriginateSuccess is triggered when the execution of an OriginateAction succeeded. - /// - // public event OriginateSuccessEventHandler OriginateSuccess; - /// - /// An OriginateResponse is triggered when the execution of an Originate. - /// - public event OriginateResponseEventHandler OriginateResponse; - /// - /// A ParkedCall is triggered when a channel is parked (in this case no - /// action id is set) and in response to a ParkedCallsAction.
- ///
- public event ParkedCallEventHandler ParkedCall; - /// - /// A ParkedCallGiveUp is triggered when a channel that has been parked is hung up.
- ///
- public event ParkedCallGiveUpEventHandler ParkedCallGiveUp; - /// - /// A ParkedCallsComplete is triggered after all parked calls have been reported in response to a ParkedCallsAction. - /// - public event ParkedCallsCompleteEventHandler ParkedCallsComplete; - /// - /// A ParkedCallTimeOut is triggered when call parking times out for a given channel.
- ///
- public event ParkedCallTimeOutEventHandler ParkedCallTimeOut; - /// - /// A PeerEntry is triggered in response to a SIPPeersAction or SIPShowPeerAction and contains information about a peer.
- ///
- public event PeerEntryEventHandler PeerEntry; - /// - /// A PeerlistComplete is triggered after the details of all peers has been reported in response to an SIPPeersAction or SIPShowPeerAction.
- ///
- public event PeerlistCompleteEventHandler PeerlistComplete; - /// - /// A PeerStatus is triggered when a SIP or IAX client attempts to registrer at this asterisk server.
- ///
- public event PeerStatusEventHandler PeerStatus; - /// - /// A QueueEntryEvent is triggered in response to a QueueStatusAction and contains information about an entry in a queue. - /// - public event QueueCallerAbandonEventHandler QueueCallerAbandon; - /// - /// A QueueEntryEvent is triggered in response to a QueueStatusAction and contains information about an entry in a queue. - /// - public event QueueEntryEventHandler QueueEntry; - /// - /// A QueueMemberAddedEvent is triggered when a queue member is added to a queue. - /// - public event QueueMemberAddedEventHandler QueueMemberAdded; - /// - /// A QueueMemberEvent is triggered in response to a QueueStatusAction and contains information about a member of a queue. - /// - public event QueueMemberEventHandler QueueMember; + /// + /// An UnhandledEvent is triggered on unknown event. + /// + public event EventHandler UnhandledEvent; + /// + /// An AgentCallbackLogin is triggered when an agent is successfully logged in. + /// + public event EventHandler AgentCallbackLogin; + /// + /// An AgentCallbackLogoff is triggered when an agent that previously logged in is logged of.
+ ///
+ public event EventHandler AgentCallbackLogoff; + /// + /// An AgentCalled is triggered when an agent is ring.
+ /// To enable AgentCalled you have to set eventwhencalled = yes in queues.conf.
+ ///
+ public event EventHandler AgentCalled; + /// + /// An AgentCompleteEvent is triggered when at the end of a call if the caller was connected to an agent. + /// + public event EventHandler AgentComplete; + /// + /// An AgentConnectEvent is triggered when a caller is connected to an agent. + /// + public event EventHandler AgentConnect; + /// + /// An AgentDumpEvent is triggered when an agent dumps the caller while listening to the queue announcement. + /// + public event EventHandler AgentDump; + /// + /// An AgentLoginEvent is triggered when an agent is successfully logged in using AgentLogin. + /// + public event EventHandler AgentLogin; + /// + /// An AgentCallbackLogoffEvent is triggered when an agent that previously logged in using AgentLogin is logged of. + /// + public event EventHandler AgentLogoff; + /// + /// An AgentsCompleteEvent is triggered after the state of all agents has been reported in response to an AgentsAction. + /// + public event EventHandler AgentsComplete; + /// + /// An AgentsEvent is triggered for each agent in response to an AgentsAction. + /// + public event EventHandler Agents; + /// + /// An AlarmEvent is triggered when a Zap channel leaves alarm state. + /// + public event EventHandler AlarmClear; + /// + /// + /// + public event EventHandler Bridge; + /// + /// An AlarmEvent is triggered when a Zap channel enters or changes alarm state. + /// + public event EventHandler Alarm; + /// + /// A CdrEvent is triggered when a call detail record is generated, usually at the end of a call. + /// + public event EventHandler Cdr; + public event EventHandler DBGetResponse; + /// + /// A Dial is triggered whenever a phone attempts to dial someone.
+ ///
+ public event EventHandler Dial; + public event EventHandler DTMF; + /// + /// A DNDStateEvent is triggered by the Zap channel driver when a channel enters or leaves DND (do not disturb) state. + /// + public event EventHandler DNDState; + /// + /// An ExtensionStatus is triggered when the state of an extension changes.
+ ///
+ public event EventHandler ExtensionStatus; + /// + /// A Hangup is triggered when a channel is hung up.
+ ///
+ public event EventHandler Hangup; + /// + /// A HoldedCall is triggered when a channel is put on hold.
+ ///
+ public event EventHandler HoldedCall; + /// + /// A Hold is triggered by the SIP channel driver when a channel is put on hold.
+ ///
+ public event EventHandler Hold; + /// + /// A Join is triggered when a channel joines a queue.
+ ///
+ public event EventHandler Join; + /// + /// A Leave is triggered when a channel leaves a queue.
+ ///
+ public event EventHandler Leave; + /// + /// A Link is triggered when two voice channels are linked together and voice data exchange commences.
+ /// Several Link events may be seen for a single call. This can occur when Asterisk fails to setup a + /// native bridge for the call.This is when Asterisk must sit between two telephones and perform + /// CODEC conversion on their behalf. + ///
+ public event EventHandler Link; + /// + /// A LogChannel is triggered when logging is turned on or off.
+ ///
+ public event EventHandler LogChannel; + /// + /// A MeetMeJoin is triggered if a channel joins a meet me conference.
+ ///
+ public event EventHandler MeetMeJoin; + /// + /// A MeetMeLeave is triggered if a channel leaves a meet me conference.
+ ///
+ public event EventHandler MeetMeLeave; + // public event EventHandler MeetMeStopTalking; + /// + /// A MeetMeTalkingEvent is triggered when a user starts talking in a meet me conference.
+ /// To enable talker detection you must pass the option 'T' to the MeetMe application. + ///
+ public event EventHandler MeetMeTalking; + /// + /// A MessageWaiting is triggered when someone leaves voicemail.
+ ///
+ public event EventHandler MessageWaiting; + /// + /// A NewCallerId is triggered when the caller id of a channel changes.
+ ///
+ public event EventHandler NewCallerId; + /// + /// A NewChannel is triggered when a new channel is created.
+ ///
+ public event EventHandler NewChannel; + /// + /// A NewExten is triggered when a channel is connected to a new extension.
+ ///
+ public event EventHandler NewExten; + /// + /// A NewState is triggered when the state of a channel has changed.
+ ///
+ public event EventHandler NewState; + // public event EventHandler Originate; + /// + /// An OriginateFailure is triggered when the execution of an OriginateAction failed. + /// + // public event EventHandler OriginateFailure; + /// + /// An OriginateSuccess is triggered when the execution of an OriginateAction succeeded. + /// + // public event EventHandler OriginateSuccess; + /// + /// An OriginateResponse is triggered when the execution of an Originate. + /// + public event EventHandler OriginateResponse; + /// + /// A ParkedCall is triggered when a channel is parked (in this case no + /// action id is set) and in response to a ParkedCallsAction.
+ ///
+ public event EventHandler ParkedCall; + /// + /// A ParkedCallGiveUp is triggered when a channel that has been parked is hung up.
+ ///
+ public event EventHandler ParkedCallGiveUp; + /// + /// A ParkedCallsComplete is triggered after all parked calls have been reported in response to a ParkedCallsAction. + /// + public event EventHandler ParkedCallsComplete; + /// + /// A ParkedCallTimeOut is triggered when call parking times out for a given channel.
+ ///
+ public event EventHandler ParkedCallTimeOut; + /// + /// A PeerEntry is triggered in response to a SIPPeersAction or SIPShowPeerAction and contains information about a peer.
+ ///
+ public event EventHandler PeerEntry; + /// + /// A PeerlistComplete is triggered after the details of all peers has been reported in response to an SIPPeersAction or SIPShowPeerAction.
+ ///
+ public event EventHandler PeerlistComplete; + /// + /// A PeerStatus is triggered when a SIP or IAX client attempts to registrer at this asterisk server.
+ ///
+ public event EventHandler PeerStatus; + /// + /// A QueueEntryEvent is triggered in response to a QueueStatusAction and contains information about an entry in a queue. + /// + public event EventHandler QueueCallerAbandon; + /// + /// A QueueEntryEvent is triggered in response to a QueueStatusAction and contains information about an entry in a queue. + /// + public event EventHandler QueueEntry; + /// + /// A QueueMemberAddedEvent is triggered when a queue member is added to a queue. + /// + public event EventHandler QueueMemberAdded; + /// + /// A QueueMemberEvent is triggered in response to a QueueStatusAction and contains information about a member of a queue. + /// + public event EventHandler QueueMember; /// /// A QueueMemberPausedEvent is triggered when a queue member is paused or unpaused. /// Replaced by : since Asterisk 12.
/// Removed since : Asterisk 13.
///
- public event QueueMemberPausedEventHandler QueueMemberPaused; - /// - /// A QueueMemberRemovedEvent is triggered when a queue member is removed from a queue. - /// - public event QueueMemberRemovedEventHandler QueueMemberRemoved; - /// - /// A QueueMemberStatusEvent shows the status of a QueueMemberEvent. - /// - public event QueueMemberStatusEventHandler QueueMemberStatus; - /// - /// A QueueParamsEvent is triggered in response to a QueueStatusAction and contains the parameters of a queue. - /// - public event QueueParamsEventHandler QueueParams; - /// - /// A QueueStatusCompleteEvent is triggered after the state of all queues has been reported in response to a QueueStatusAction. - /// - public event QueueStatusCompleteEventHandler QueueStatusComplete; - /// - /// A Registry is triggered when this asterisk server attempts to register - /// as a client at another SIP or IAX server.
- ///
- public event RegistryEventHandler Registry; - /// - /// A RenameEvent is triggered when the name of a channel is changed. - /// - public event RenameEventHandler Rename; - /// - /// A StatusCompleteEvent is triggered after the state of all channels has been reported in response to a StatusAction. - /// - public event StatusCompleteEventHandler StatusComplete; - /// - /// A StatusEvent is triggered for each active channel in response to a StatusAction. - /// - public event StatusEventHandler Status; - /// - /// - /// - public event TransferEventHandler Transfer; - /// - /// An UnholdEvent is triggered by the SIP channel driver when a channel is no longer put on hold. - /// - public event UnholdEventHandler Unhold; - /// - /// An UnlinkEvent is triggered when a link between two voice channels is discontinued, for example, just before call completion. - /// - public event UnlinkEventHandler Unlink; - /// - /// A UnparkedCallEvent is triggered when a channel that has been parked is resumed. - /// - public event UnparkedCallEventHandler UnparkedCall; - /// - /// A ZapShowChannelsEvent is triggered on UserEvent in dialplan. - /// - public event UserEventHandler UserEvents; - /// - /// A ZapShowChannelsCompleteEvent is triggered after the state of all zap channels has been reported in response to a ZapShowChannelsAction. - /// - public event ZapShowChannelsCompleteEventHandler ZapShowChannelsComplete; - /// - /// A ZapShowChannelsEvent is triggered in response to a ZapShowChannelsAction and shows the state of a zap channel. - /// - public event ZapShowChannelsEventHandler ZapShowChannels; - /// - /// A ConnectionState is triggered after Connect/Disconnect/Reload/Shutdown events. - /// - public event ConnectionStateEventHandler ConnectionState; + public event EventHandler QueueMemberPaused; + /// + /// A QueueMemberRemovedEvent is triggered when a queue member is removed from a queue. + /// + public event EventHandler QueueMemberRemoved; + /// + /// A QueueMemberStatusEvent shows the status of a QueueMemberEvent. + /// + public event EventHandler QueueMemberStatus; + /// + /// A QueueParamsEvent is triggered in response to a QueueStatusAction and contains the parameters of a queue. + /// + public event EventHandler QueueParams; + /// + /// A QueueStatusCompleteEvent is triggered after the state of all queues has been reported in response to a QueueStatusAction. + /// + public event EventHandler QueueStatusComplete; + /// + /// A Registry is triggered when this asterisk server attempts to register + /// as a client at another SIP or IAX server.
+ ///
+ public event EventHandler Registry; + /// + /// A RenameEvent is triggered when the name of a channel is changed. + /// + public event EventHandler Rename; + /// + /// A StatusCompleteEvent is triggered after the state of all channels has been reported in response to a StatusAction. + /// + public event EventHandler StatusComplete; + /// + /// A StatusEvent is triggered for each active channel in response to a StatusAction. + /// + public event EventHandler Status; + /// + /// + /// + public event EventHandler Transfer; + /// + /// An UnholdEvent is triggered by the SIP channel driver when a channel is no longer put on hold. + /// + public event EventHandler Unhold; + /// + /// An UnlinkEvent is triggered when a link between two voice channels is discontinued, for example, just before call completion. + /// + public event EventHandler Unlink; + /// + /// A UnparkedCallEvent is triggered when a channel that has been parked is resumed. + /// + public event EventHandler UnparkedCall; + /// + /// A ZapShowChannelsEvent is triggered on UserEvent in dialplan. + /// + public event EventHandler UserEvents; + /// + /// A ZapShowChannelsCompleteEvent is triggered after the state of all zap channels has been reported in response to a ZapShowChannelsAction. + /// + public event EventHandler ZapShowChannelsComplete; + /// + /// A ZapShowChannelsEvent is triggered in response to a ZapShowChannelsAction and shows the state of a zap channel. + /// + public event EventHandler ZapShowChannels; + /// + /// A ConnectionState is triggered after Connect/Disconnect/Reload/Shutdown events. + /// + public event EventHandler ConnectionState; - /// - /// When a variable is set - /// - public event VarSetEventHandler VarSet; + /// + /// When a variable is set + /// + public event EventHandler VarSet; - /// - /// AgiExec is execute - /// - public event AGIExecHandler AGIExec; + /// + /// AgiExec is execute + /// + public event EventHandler AGIExec; - /// - /// This event is sent when the first user requests a conference and it is instantiated - /// - public event ConfbridgeStartEventHandler ConfbridgeStart; + /// + /// This event is sent when the first user requests a conference and it is instantiated + /// + public event EventHandler ConfbridgeStart; - /// - /// This event is sent when a user joins a conference - either one already in progress or as the first user to join a newly instantiated bridge. - /// - public event ConfbridgeJoinEventHandler ConfbridgeJoin; + /// + /// This event is sent when a user joins a conference - either one already in progress or as the first user to join a newly instantiated bridge. + /// + public event EventHandler ConfbridgeJoin; - /// - /// This event is sent when a user leaves a conference. - /// - public event ConfbridgeLeaveEventHandler ConfbridgeLeave; + /// + /// This event is sent when a user leaves a conference. + /// + public event EventHandler ConfbridgeLeave; - /// - /// This event is sent when the last user leaves a conference and it is torn down. - /// - public event ConfbridgeEndEventHandler ConfbridgeEnd; + /// + /// This event is sent when the last user leaves a conference and it is torn down. + /// + public event EventHandler ConfbridgeEnd; - /// - /// This event is sent when the conference detects that a user has either begin or stopped talking. - /// - public event ConfbridgeTalkingEventHandler ConfbridgeTalking; + /// + /// This event is sent when the conference detects that a user has either begin or stopped talking. + /// + public event EventHandler ConfbridgeTalking; /// /// /// - public event FailedACLEventHandler FailedACL; + public event EventHandler FailedACL; - public event AttendedTransferEventHandler AttendedTransfer; - public event BlindTransferEventHandler BlindTransfer; + public event EventHandler AttendedTransfer; + public event EventHandler BlindTransfer; - public event BridgeCreateEventHandler BridgeCreate; - public event BridgeDestroyEventHandler BridgeDestroy; - public event BridgeEnterEventHandler BridgeEnter; - public event BridgeLeaveEventHandler BridgeLeave; + public event EventHandler BridgeCreate; + public event EventHandler BridgeDestroy; + public event EventHandler BridgeEnter; + public event EventHandler BridgeLeave; /// /// Raised when a dial action has started.
///
- public event DialBeginEventHandler DialBegin; + public event EventHandler DialBegin; /// /// Raised when a dial action has completed.
///
- public event DialEndEventHandler DialEnd; + public event EventHandler DialEnd; /// /// Raised when a caller joins a Queue.
///
- public event QueueCallerJoinEventHandler QueueCallerJoin; + public event EventHandler QueueCallerJoin; /// /// Raised when a caller leaves a Queue.
///
- public event QueueCallerLeaveEventHandler QueueCallerLeave; + public event EventHandler QueueCallerLeave; /// /// A QueueMemberPauseEvent is triggered when a queue member is paused or unpaused.
/// Available since : Asterisk 12. ///
- public event QueueMemberPauseEventHandler QueueMemberPause; - - /// - /// A ChallengeResponseFailed is triggered when a request's attempt to authenticate has been challenged, and the request failed the authentication challenge. - /// - public event ChallengeResponseFailedEventHandler ChallengeResponseFailed; + public event EventHandler QueueMemberPause; /// - /// A InvalidAccountID is triggered when a request fails an authentication check due to an invalid account ID. - /// - public event InvalidAccountIDEventHandler InvalidAccountID; + /// A ChallengeResponseFailed is triggered when a request's attempt to authenticate has been challenged, and the request failed the authentication challenge. + /// + public event EventHandler ChallengeResponseFailed; /// - /// A DeviceStateChanged is triggered when a device state changes. - /// - public event DeviceStateChangedEventHandler DeviceStateChanged; + /// A InvalidAccountID is triggered when a request fails an authentication check due to an invalid account ID. + /// + public event EventHandler InvalidAccountID; /// - /// A ChallengeSent is triggered when an Asterisk service sends an authentication challenge to a request.. - /// - public event ChallengeSentEventHandler ChallengeSent; + /// A DeviceStateChanged is triggered when a device state changes. + /// + public event EventHandler DeviceStateChanged; /// - /// A SuccessfulAuth is triggered when a request successfully authenticates with a service. - /// - public event SuccessfulAuthEventHandler SuccessfulAuth; + /// A ChallengeSent is triggered when an Asterisk service sends an authentication challenge to a request.. + /// + public event EventHandler ChallengeSent; + + /// + /// A SuccessfulAuth is triggered when a request successfully authenticates with a service. + /// + public event EventHandler SuccessfulAuth; + + /// + /// Raised when call queue summary + /// + public event EventHandler QueueSummary; #endregion #region Constructor - ManagerConnection() /// Creates a new instance. public ManagerConnection() - { - callerThread = Thread.CurrentThread; + { + callerThread = Thread.CurrentThread; - socketEncoding = Encoding.ASCII; + socketEncoding = Encoding.ASCII; - responseHandlers = new Dictionary(); - pingHandlers = new Dictionary(); - responseEventHandlers = new Dictionary(); - registeredEventClasses = new Dictionary(); + responseHandlers = new Dictionary(); + pingHandlers = new Dictionary(); + responseEventHandlers = new Dictionary(); + registeredEventClasses = new Dictionary(); - Helper.RegisterBuiltinEventClasses(registeredEventClasses); + Helper.RegisterBuiltinEventClasses(registeredEventClasses); - registeredEventHandlers = new Dictionary(); + registeredEventHandlers = new Dictionary>(); - #region Event mapping table - Helper.RegisterEventHandler(registeredEventHandlers, 0, typeof(AgentCallbackLoginEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 1, typeof(AgentCallbackLogoffEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 2, typeof(AgentCalledEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 3, typeof(AgentCompleteEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 4, typeof(AgentConnectEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 5, typeof(AgentDumpEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 6, typeof(AgentLoginEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 7, typeof(AgentLogoffEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 8, typeof(AgentsCompleteEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 9, typeof(AgentsEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 10, typeof(AlarmClearEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 11, typeof(AlarmEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 12, typeof(CdrEvent)); + #region Event mapping table + Helper.RegisterEventHandler(registeredEventHandlers, typeof(AgentCallbackLoginEvent), arg => fireEvent(AgentCallbackLogin, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(AgentCallbackLogoffEvent), arg => fireEvent(AgentCallbackLogoff, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(AgentCalledEvent), arg => fireEvent(AgentCalled, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(AgentCompleteEvent), arg => fireEvent(AgentComplete, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(AgentConnectEvent), arg => fireEvent(AgentConnect, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(AgentDumpEvent), arg => fireEvent(AgentDump, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(AgentLoginEvent), arg => fireEvent(AgentLogin, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(AgentLogoffEvent), arg => fireEvent(AgentLogoff, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(AgentsCompleteEvent), arg => fireEvent(AgentsComplete, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(AgentsEvent), arg => fireEvent(Agents, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(AlarmClearEvent), arg => fireEvent(AlarmClear, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(AlarmEvent), arg => fireEvent(Alarm, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(CdrEvent), arg => fireEvent(Cdr, arg)); - Helper.RegisterEventHandler(registeredEventHandlers, 14, typeof(DBGetResponseEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 15, typeof(DialEvent)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(DBGetResponseEvent), arg => fireEvent(DBGetResponse, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(DialEvent), arg => fireEvent(Dial, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(DNDStateEvent), arg => fireEvent(DNDState, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(ExtensionStatusEvent), arg => fireEvent(ExtensionStatus, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(HangupEvent), arg => fireEvent(Hangup, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(HoldedCallEvent), arg => fireEvent(HoldedCall, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(HoldEvent), arg => fireEvent(Hold, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(JoinEvent), arg => fireEvent(Join, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(LeaveEvent), arg => fireEvent(Leave, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(LinkEvent), arg => fireEvent(Link, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(LogChannelEvent), arg => fireEvent(LogChannel, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(MeetmeJoinEvent), arg => fireEvent(MeetMeJoin, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(MeetmeLeaveEvent), arg => fireEvent(MeetMeLeave, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(MeetmeTalkingEvent), arg => fireEvent(MeetMeTalking, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(MessageWaitingEvent), arg => fireEvent(MessageWaiting, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(NewCallerIdEvent), arg => fireEvent(NewCallerId, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(NewChannelEvent), arg => fireEvent(NewChannel, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(NewExtenEvent), arg => fireEvent(NewExten, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(NewStateEvent), arg => fireEvent(NewState, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(OriginateResponseEvent), arg => fireEvent(OriginateResponse, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(ParkedCallEvent), arg => fireEvent(ParkedCall, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(ParkedCallGiveUpEvent), arg => fireEvent(ParkedCallGiveUp, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(ParkedCallsCompleteEvent), arg => fireEvent(ParkedCallsComplete, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(ParkedCallTimeOutEvent), arg => fireEvent(ParkedCallTimeOut, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(PeerEntryEvent), arg => fireEvent(PeerEntry, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(PeerlistCompleteEvent), arg => fireEvent(PeerlistComplete, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(PeerStatusEvent), arg => fireEvent(PeerStatus, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(QueueEntryEvent), arg => fireEvent(QueueEntry, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(QueueMemberAddedEvent), arg => fireEvent(QueueMemberAdded, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(QueueMemberEvent), arg => fireEvent(QueueMember, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(QueueMemberPausedEvent), arg => fireEvent(QueueMemberPaused, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(QueueMemberRemovedEvent), arg => fireEvent(QueueMemberRemoved, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(QueueMemberStatusEvent), arg => fireEvent(QueueMemberStatus, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(QueueParamsEvent), arg => fireEvent(QueueParams, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(QueueStatusCompleteEvent), arg => fireEvent(QueueStatusComplete, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(RegistryEvent), arg => fireEvent(Registry, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(QueueCallerAbandonEvent), arg => fireEvent(QueueCallerAbandon, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(RenameEvent), arg => fireEvent(Rename, arg)); - Helper.RegisterEventHandler(registeredEventHandlers, 17, typeof(DNDStateEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 18, typeof(ExtensionStatusEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 19, typeof(HangupEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 20, typeof(HoldedCallEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 21, typeof(HoldEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 22, typeof(JoinEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 23, typeof(LeaveEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 24, typeof(LinkEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 25, typeof(LogChannelEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 26, typeof(MeetmeJoinEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 27, typeof(MeetmeLeaveEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 28, typeof(MeetmeTalkingEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 29, typeof(MessageWaitingEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 30, typeof(NewCallerIdEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 31, typeof(NewChannelEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 32, typeof(NewExtenEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 33, typeof(NewStateEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 34, typeof(OriginateResponseEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 35, typeof(ParkedCallEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 36, typeof(ParkedCallGiveUpEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 37, typeof(ParkedCallsCompleteEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 38, typeof(ParkedCallTimeOutEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 39, typeof(PeerEntryEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 40, typeof(PeerlistCompleteEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 41, typeof(PeerStatusEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 42, typeof(QueueEntryEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 43, typeof(QueueMemberAddedEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 44, typeof(QueueMemberEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 45, typeof(QueueMemberPausedEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 46, typeof(QueueMemberRemovedEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 47, typeof(QueueMemberStatusEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 48, typeof(QueueParamsEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 49, typeof(QueueStatusCompleteEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 50, typeof(RegistryEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 51, typeof(QueueCallerAbandonEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 52, typeof(RenameEvent)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(StatusCompleteEvent), arg => fireEvent(StatusComplete, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(StatusEvent), arg => fireEvent(Status, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(UnholdEvent), arg => fireEvent(Unhold, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(UnlinkEvent), arg => fireEvent(Unlink, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(UnparkedCallEvent), arg => fireEvent(UnparkedCall, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(UserEvent), arg => fireEvent(UserEvents, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(ZapShowChannelsCompleteEvent), arg => fireEvent(ZapShowChannelsComplete, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(ZapShowChannelsEvent), arg => fireEvent(ZapShowChannels, arg)); - Helper.RegisterEventHandler(registeredEventHandlers, 54, typeof(StatusCompleteEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 55, typeof(StatusEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 56, typeof(UnholdEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 57, typeof(UnlinkEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 58, typeof(UnparkedCallEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 59, typeof(UserEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 60, typeof(ZapShowChannelsCompleteEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 61, typeof(ZapShowChannelsEvent)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(ConnectEvent), arg => fireEvent(ConnectionState, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(DisconnectEvent), arg => fireEvent(ConnectionState, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(ReloadEvent), arg => fireEvent(ConnectionState, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(ShutdownEvent), arg => fireEvent(ConnectionState, arg)); - Helper.RegisterEventHandler(registeredEventHandlers, 62, typeof(ConnectEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 62, typeof(DisconnectEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 62, typeof(ReloadEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 62, typeof(ShutdownEvent)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(BridgeEvent), arg => fireEvent(Bridge, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(TransferEvent), arg => fireEvent(Transfer, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(DTMFEvent), arg => fireEvent(DTMF, arg)); - Helper.RegisterEventHandler(registeredEventHandlers, 63, typeof(BridgeEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 64, typeof(TransferEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 65, typeof(DTMFEvent)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(VarSetEvent), arg => fireEvent(VarSet, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(AGIExecEvent), arg => fireEvent(AGIExec, arg)); - Helper.RegisterEventHandler(registeredEventHandlers, 70, typeof(VarSetEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 80, typeof(AGIExecEvent)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(ConfbridgeStartEvent), arg => fireEvent(ConfbridgeStart, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(ConfbridgeJoinEvent), arg => fireEvent(ConfbridgeJoin, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(ConfbridgeLeaveEvent), arg => fireEvent(ConfbridgeLeave, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(ConfbridgeEndEvent), arg => fireEvent(ConfbridgeEnd, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(ConfbridgeTalkingEvent), arg => fireEvent(ConfbridgeTalking, arg)); - Helper.RegisterEventHandler(registeredEventHandlers, 81, typeof(ConfbridgeStartEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 82, typeof(ConfbridgeJoinEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 83, typeof(ConfbridgeLeaveEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 84, typeof(ConfbridgeEndEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 85, typeof(ConfbridgeTalkingEvent)); - - Helper.RegisterEventHandler(registeredEventHandlers, 86, typeof(FailedACLEvent)); - - Helper.RegisterEventHandler(registeredEventHandlers, 87, typeof(AttendedTransferEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 88, typeof(BridgeCreateEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 89, typeof(BridgeDestroyEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 90, typeof(BridgeEnterEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 91, typeof(BridgeLeaveEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 92, typeof(BlindTransferEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 93, typeof(DialBeginEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 94, typeof(DialEndEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 95, typeof(QueueCallerJoinEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 96, typeof(QueueCallerLeaveEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 97, typeof(QueueMemberPauseEvent)); - - Helper.RegisterEventHandler(registeredEventHandlers, 98, typeof(ChallengeResponseFailedEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 99, typeof(InvalidAccountIDEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 100, typeof(DeviceStateChangeEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 101, typeof(ChallengeSentEvent)); - Helper.RegisterEventHandler(registeredEventHandlers, 102, typeof(SuccessfulAuthEvent)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(FailedACLEvent), arg => fireEvent(FailedACL, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(AttendedTransferEvent), arg => fireEvent(AttendedTransfer, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(BridgeCreateEvent), arg => fireEvent(BridgeCreate, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(BridgeDestroyEvent), arg => fireEvent(BridgeDestroy, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(BridgeEnterEvent), arg => fireEvent(BridgeEnter, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(BridgeLeaveEvent), arg => fireEvent(BridgeLeave, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(BlindTransferEvent), arg => fireEvent(BlindTransfer, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(DialBeginEvent), arg => fireEvent(DialBegin, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(DialEndEvent), arg => fireEvent(DialEnd, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(QueueCallerJoinEvent), arg => fireEvent(QueueCallerJoin, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(QueueCallerLeaveEvent), arg => fireEvent(QueueCallerLeave, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(QueueMemberPauseEvent), arg => fireEvent(QueueMemberPause, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(ChallengeResponseFailedEvent), arg => fireEvent(ChallengeResponseFailed, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(InvalidAccountIDEvent), arg => fireEvent(InvalidAccountID, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(DeviceStateChangeEvent), arg => fireEvent(DeviceStateChanged, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(ChallengeSentEvent), arg => fireEvent(ChallengeSent, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(SuccessfulAuthEvent), arg => fireEvent(SuccessfulAuth, arg)); + Helper.RegisterEventHandler(registeredEventHandlers, typeof(QueueSummaryEvent), arg => fireEvent(QueueSummary, arg)); + #endregion - this.internalEvent += new ManagerEventHandler(internalEventHandler); - } - #endregion + this.internalEvent += new EventHandler(internalEventHandler); + } + #endregion - #region Constructor - ManagerConnection(hostname, port, username, password) - /// - /// Creates a new instance with the given connection parameters. - /// - /// the hosname of the Asterisk server to connect to. - /// the port where Asterisk listens for incoming Manager API connections, usually 5038. - /// the username to use for login - /// the password to use for login - public ManagerConnection(string hostname, int port, string username, string password) - : this() - { - this.hostname = hostname; - this.port = port; - this.username = username; - this.password = password; - } - #endregion + #region Constructor - ManagerConnection(hostname, port, username, password) + /// + /// Creates a new instance with the given connection parameters. + /// + /// the hosname of the Asterisk server to connect to. + /// the port where Asterisk listens for incoming Manager API connections, usually 5038. + /// the username to use for login + /// the password to use for login + public ManagerConnection(string hostname, int port, string username, string password) + : this() + { + this.hostname = hostname; + this.port = port; + this.username = username; + this.password = password; + } + #endregion - #region Constructor - ManagerConnection(hostname, port, username, password, Encoding socketEncoding) - /// - /// Creates a new instance with the given connection parameters. - /// - /// the hosname of the Asterisk server to connect to. - /// the port where Asterisk listens for incoming Manager API connections, usually 5038. - /// the username to use for login - /// the password to use for login - /// text encoding to asterisk input/output stream - public ManagerConnection(string hostname, int port, string username, string password, Encoding encoding) - : this() - { - this.hostname = hostname; - this.port = port; - this.username = username; - this.password = password; - this.socketEncoding = encoding; - } - #endregion + #region Constructor - ManagerConnection(hostname, port, username, password, Encoding socketEncoding) + /// + /// Creates a new instance with the given connection parameters. + /// + /// the hosname of the Asterisk server to connect to. + /// the port where Asterisk listens for incoming Manager API connections, usually 5038. + /// the username to use for login + /// the password to use for login + /// text encoding to asterisk input/output stream + public ManagerConnection(string hostname, int port, string username, string password, Encoding encoding) + : this() + { + this.hostname = hostname; + this.port = port; + this.username = username; + this.password = password; + this.socketEncoding = encoding; + } + #endregion - /// - /// Default Fast Reconnect retry counter. - /// - public int ReconnectRetryFast - { - get { return reconnectRetryFast; } - set { reconnectRetryFast = value; } - } - /// Default Maximum Reconnect retry counter. - public int ReconnectRetryMax - { - get { return reconnectRetryMax; } - set { reconnectRetryMax = value; } - } - /// Default Fast Reconnect interval in milliseconds. - public int ReconnectIntervalFast - { - get { return reconnectIntervalFast; } - set { reconnectIntervalFast = value; } - } - /// Default Slow Reconnect interval in milliseconds. - public int ReconnectIntervalMax - { - get { return reconnectIntervalMax; } - set { reconnectIntervalMax = value; } - } + /// + /// Default Fast Reconnect retry counter. + /// + public int ReconnectRetryFast + { + get { return reconnectRetryFast; } + set { reconnectRetryFast = value; } + } + /// Default Maximum Reconnect retry counter. + public int ReconnectRetryMax + { + get { return reconnectRetryMax; } + set { reconnectRetryMax = value; } + } + /// Default Fast Reconnect interval in milliseconds. + public int ReconnectIntervalFast + { + get { return reconnectIntervalFast; } + set { reconnectIntervalFast = value; } + } + /// Default Slow Reconnect interval in milliseconds. + public int ReconnectIntervalMax + { + get { return reconnectIntervalMax; } + set { reconnectIntervalMax = value; } + } - #region CallerThread - internal Thread CallerThread - { - get { return callerThread; } - } - #endregion + #region CallerThread + internal Thread CallerThread + { + get { return callerThread; } + } + #endregion - #region internalEventHandler(object sender, ManagerEvent e) - private void internalEventHandler(object sender, ManagerEvent e) - { - int eventHash = e.GetType().Name.GetHashCode(); - if (registeredEventHandlers.ContainsKey(eventHash)) - { - switch (registeredEventHandlers[eventHash]) - { - #region A-C - case 0: - if (AgentCallbackLogin != null) - { - AgentCallbackLogin(this, (AgentCallbackLoginEvent)e); - return; - } - break; - case 1: - if (AgentCallbackLogoff != null) - { - AgentCallbackLogoff(this, (AgentCallbackLogoffEvent)e); - return; - } - break; - case 2: - if (AgentCalled != null) - { - AgentCalled(this, (Event.AgentCalledEvent)e); - return; - } - break; - case 3: - if (AgentComplete != null) - { - AgentComplete(this, (Event.AgentCompleteEvent)e); - return; - } - break; - case 4: - if (AgentConnect != null) - { - AgentConnect(this, (Event.AgentConnectEvent)e); - return; - } - break; - case 5: - if (AgentDump != null) - { - AgentDump(this, (Event.AgentDumpEvent)e); - return; - } - break; - case 6: - if (AgentLogin != null) - { - AgentLogin(this, (Event.AgentLoginEvent)e); - return; - } - break; - case 7: - if (AgentLogoff != null) - { - AgentLogoff(this, (Event.AgentLogoffEvent)e); - return; - } - break; - case 8: - if (AgentsComplete != null) - { - AgentsComplete(this, (AgentsCompleteEvent)e); - return; - } - break; - case 9: - if (Agents != null) - { - Agents(this, (AgentsEvent)e); - return; - } - break; - case 10: - if (AlarmClear != null) - { - AlarmClear(this, (AlarmClearEvent)e); - return; - } - break; - case 11: - if (Alarm != null) - { - Alarm(this, (AlarmEvent)e); - return; - } - break; - case 12: - if (Cdr != null) - { - Cdr(this, (CdrEvent)e); - return; - } - break; - #endregion - #region D-L - case 14: - if (DBGetResponse != null) - { - DBGetResponse(this, (DBGetResponseEvent)e); - return; - } - break; - case 15: - if (Dial != null) - { - Dial(this, (DialEvent)e); - return; - } - break; - case 17: - if (DNDState != null) - { - DNDState(this, (DNDStateEvent)e); - return; - } - break; - case 18: - if (ExtensionStatus != null) - { - ExtensionStatus(this, (ExtensionStatusEvent)e); - return; - } - break; - case 19: - if (Hangup != null) - { - Hangup(this, (HangupEvent)e); - return; - } - break; - case 20: - if (HoldedCall != null) - { - HoldedCall(this, (HoldedCallEvent)e); - return; - } - break; - case 21: - if (Hold != null) - { - Hold(this, (HoldEvent)e); - return; - } - break; - case 22: - if (Join != null) - { - Join(this, (JoinEvent)e); - return; - } - break; - case 23: - if (Leave != null) - { - Leave(this, (LeaveEvent)e); - return; - } - break; - case 24: - if (Link != null) - { - Link(this, (LinkEvent)e); - return; - } - break; - case 25: - if (LogChannel != null) - { - LogChannel(this, (LogChannelEvent)e); - return; - } - break; - #endregion - #region M-P - case 26: - if (MeetMeJoin != null) - { - MeetMeJoin(this, (MeetmeJoinEvent)e); - return; - } - break; - case 27: - if (MeetMeLeave != null) - { - MeetMeLeave(this, (MeetmeLeaveEvent)e); - return; - } - break; - case 28: - if (MeetMeTalking != null) - { - MeetMeTalking(this, (MeetmeTalkingEvent)e); - return; - } - break; - case 29: - if (MessageWaiting != null) - { - MessageWaiting(this, (MessageWaitingEvent)e); - return; - } - break; - case 30: - if (NewCallerId != null) - { - NewCallerId(this, (NewCallerIdEvent)e); - return; - } - break; - case 31: - if (NewChannel != null) - { - NewChannel(this, (NewChannelEvent)e); - return; - } - break; - case 32: - if (NewExten != null) - { - NewExten(this, (NewExtenEvent)e); - return; - } - break; - case 33: - if (NewState != null) - { - NewState(this, (NewStateEvent)e); - return; - } - break; - case 34: - if (OriginateResponse != null) - { - OriginateResponse(this, (OriginateResponseEvent)e); - return; - } - break; - case 35: - if (ParkedCall != null) - { - ParkedCall(this, (ParkedCallEvent)e); - return; - } - break; - case 36: - if (ParkedCallGiveUp != null) - { - ParkedCallGiveUp(this, (ParkedCallGiveUpEvent)e); - return; - } - break; - case 37: - if (ParkedCallsComplete != null) - { - ParkedCallsComplete(this, (ParkedCallsCompleteEvent)e); - return; - } - break; - case 38: - if (ParkedCallTimeOut != null) - { - ParkedCallTimeOut(this, (ParkedCallTimeOutEvent)e); - return; - } - break; - case 39: - if (PeerEntry != null) - { - PeerEntry(this, (PeerEntryEvent)e); - return; - } - break; - case 40: - if (PeerlistComplete != null) - { - PeerlistComplete(this, (PeerlistCompleteEvent)e); - return; - } - break; - case 41: - if (PeerStatus != null) - { - PeerStatus(this, (PeerStatusEvent)e); - return; - } - break; - #endregion - #region Q-Z - case 42: - if (QueueEntry != null) - { - QueueEntry(this, (QueueEntryEvent)e); - return; - } - break; - case 43: - if (QueueMemberAdded != null) - { - QueueMemberAdded(this, (QueueMemberAddedEvent)e); - return; - } - break; - case 44: - if (QueueMember != null) - { - QueueMember(this, (QueueMemberEvent)e); - return; - } - break; - case 45: - if (QueueMemberPaused != null) - { - QueueMemberPaused(this, (QueueMemberPausedEvent)e); - return; - } - break; - case 46: - if (QueueMemberRemoved != null) - { - QueueMemberRemoved(this, (QueueMemberRemovedEvent)e); - return; - } - break; - case 47: - if (QueueMemberStatus != null) - { - QueueMemberStatus(this, (QueueMemberStatusEvent)e); - return; - } - break; - case 48: - if (QueueParams != null) - { - QueueParams(this, (QueueParamsEvent)e); - return; - } - break; - case 49: - if (QueueStatusComplete != null) - { - QueueStatusComplete(this, (QueueStatusCompleteEvent)e); - return; - } - break; - case 50: - if (Registry != null) - { - Registry(this, (RegistryEvent)e); - return; - } - break; - case 51: - if (QueueCallerAbandon != null) - { - QueueCallerAbandon(this, (QueueCallerAbandonEvent)e); - return; - } - break; - case 52: - if (Rename != null) - { - Rename(this, (RenameEvent)e); - return; - } - break; - case 54: - if (StatusComplete != null) - { - StatusComplete(this, (StatusCompleteEvent)e); - return; - } - break; - case 55: - if (Status != null) - { - Status(this, (StatusEvent)e); - return; - } - break; - case 56: - if (Unhold != null) - { - Unhold(this, (UnholdEvent)e); - return; - } - break; - case 57: - if (Unlink != null) - { - Unlink(this, (UnlinkEvent)e); - return; - } - break; - case 58: - if (UnparkedCall != null) - { - UnparkedCall(this, (UnparkedCallEvent)e); - return; - } - break; - case 59: - if (UserEvents != null) - { - UserEvents(this, (UserEvent)e); - return; - } - break; - case 60: - if (ZapShowChannelsComplete != null) - { - ZapShowChannelsComplete(this, (ZapShowChannelsCompleteEvent)e); - return; - } - break; - case 61: - if (ZapShowChannels != null) - { - ZapShowChannels(this, (ZapShowChannelsEvent)e); - return; - } - break; - #endregion + #region internalEventHandler(object sender, ManagerEvent e) + private void internalEventHandler(object sender, ManagerEvent e) + { + int eventHash = e.GetType().Name.GetHashCode(); + if (registeredEventHandlers.ContainsKey(eventHash)) + { + var currentEvent = registeredEventHandlers[eventHash]; + if (currentEvent(e)) + { + return; + } + } - case 62: - if (ConnectionState != null) - { - ConnectionState(this, (ConnectionStateEvent)e); - return; - } - break; - case 63: - if (Bridge != null) - { - Bridge(this, (BridgeEvent)e); - } - break; - case 64: - if (Transfer != null) - { - Transfer(this, (TransferEvent)e); - } - break; - case 65: - if (DTMF != null) - { - DTMF(this, (DTMFEvent)e); - } - break; - case 70: - if (VarSet != null) - { - VarSet(this, (VarSetEvent)e); - } - break; - case 80: - if (AGIExec != null) - { - AGIExec(this, (AGIExecEvent)e); - } - break; - case 81: - if (ConfbridgeStart != null) - { - ConfbridgeStart(this, (ConfbridgeStartEvent)e); - } - break; - case 82: - if (ConfbridgeJoin != null) - { - ConfbridgeJoin(this, (ConfbridgeJoinEvent)e); - } - break; - case 83: - if (ConfbridgeLeave != null) - { - ConfbridgeLeave(this, (ConfbridgeLeaveEvent)e); - } - break; - case 84: - if (ConfbridgeEnd != null) - { - ConfbridgeEnd(this, (ConfbridgeEndEvent)e); - } - break; - case 85: - if (ConfbridgeTalking != null) - { - ConfbridgeTalking(this, (ConfbridgeTalkingEvent)e); - } - break; - case 86: - if (FailedACL != null) - { - FailedACL(this, (FailedACLEvent)e); - } - break; - case 87: - if (AttendedTransfer != null) - { - AttendedTransfer(this, (AttendedTransferEvent) e); - } - break; - case 88: - if (BridgeCreate != null) - { - BridgeCreate(this, (BridgeCreateEvent) e); - } - break; - case 89: - if (BridgeDestroy != null) - { - BridgeDestroy(this, (BridgeDestroyEvent)e); - } - break; - case 90: - if (BridgeEnter != null) - { - BridgeEnter(this, (BridgeEnterEvent)e); - } - break; - case 91: - if (BridgeLeave != null) - { - BridgeLeave(this, (BridgeLeaveEvent)e); - } - break; - case 92: - if (BlindTransfer != null) - { - BlindTransfer(this, (BlindTransferEvent)e); - } - break; - case 93: - if (DialBegin != null) - { - DialBegin(this, (DialBeginEvent)e); - } - break; - case 94: - if (DialEnd != null) - { - DialEnd(this, (DialEndEvent)e); - } - break; - case 95: - if (QueueCallerJoin != null) - { - QueueCallerJoin(this, (QueueCallerJoinEvent)e); - } - break; - case 96: - if (QueueCallerLeave != null) - { - QueueCallerLeave(this, (QueueCallerLeaveEvent)e); - } - break; - case 97: - if (QueueMemberPause != null) - { - QueueMemberPause(this, (QueueMemberPauseEvent)e); - } - break; - case 98: - if (ChallengeResponseFailed != null) - { - ChallengeResponseFailed(this, (ChallengeResponseFailedEvent)e); - return; - } - break; - case 99: - if (InvalidAccountID != null) - { - InvalidAccountID(this, (InvalidAccountIDEvent)e); - return; - } - break; - case 100: - if (DeviceStateChanged != null) - { - DeviceStateChanged(this, (DeviceStateChangeEvent)e); - return; - } - break; - case 101: - if (ChallengeSent != null) - { - ChallengeSent(this, (ChallengeSentEvent)e); - return; - } - break; - case 102: - if (SuccessfulAuth != null) - { - SuccessfulAuth(this, (SuccessfulAuthEvent)e); - return; - } - break; - default: - if (UnhandledEvent != null) - UnhandledEvent(this, e); - return; - } - } - if (fireAllEvents && UnhandledEvent != null) - UnhandledEvent(this, e); - } - #endregion + if (fireAllEvents) + { + fireEvent(UnhandledEvent, e); + } + } + #endregion - #region FireAllEvents - /// - /// If this property set to true then ManagerConnection send all unassigned events to UnhandledEvent handler,
- /// if set to false then all unassgned events lost and send only UnhandledEvent.
- /// Default: false - ///
- public bool FireAllEvents - { - get { return this.fireAllEvents; } - set { this.fireAllEvents = value; } - } - #endregion + #region FireAllEvents + /// + /// If this property set to true then ManagerConnection send all unassigned events to UnhandledEvent handler,
+ /// if set to false then all unassgned events lost and send only UnhandledEvent.
+ /// Default: false + ///
+ public bool FireAllEvents + { + get { return this.fireAllEvents; } + set { this.fireAllEvents = value; } + } + #endregion - #region PingInterval - /// - /// Timeout from Ping to Pong. If no Pong received send Disconnect event. Set to zero to disable. - /// - public int PingInterval - { - get { return pingInterval; } - set { pingInterval = value; } - } - #endregion + #region PingInterval + /// + /// Timeout from Ping to Pong. If no Pong received send Disconnect event. Set to zero to disable. + /// + public int PingInterval + { + get { return pingInterval; } + set { pingInterval = value; } + } + #endregion - #region Hostname - /// Sets the hostname of the asterisk server to connect to.
- /// Default is localhost. - ///
- public string Hostname - { - get { return hostname; } - set { hostname = value; } - } - #endregion + #region Hostname + /// Sets the hostname of the asterisk server to connect to.
+ /// Default is localhost. + ///
+ public string Hostname + { + get { return hostname; } + set { hostname = value; } + } + #endregion - #region Port - /// - /// Sets the port to use to connect to the asterisk server. This is the port - /// specified in asterisk's manager.conf file.
- /// Default is 5038. - ///
- public int Port - { - get { return port; } - set { port = value; } - } - #endregion + #region Port + /// + /// Sets the port to use to connect to the asterisk server. This is the port + /// specified in asterisk's manager.conf file.
+ /// Default is 5038. + ///
+ public int Port + { + get { return port; } + set { port = value; } + } + #endregion - #region UserName - /// - /// Sets the username to use to connect to the asterisk server. This is the - /// username specified in asterisk's manager.conf file. - /// - public string Username - { - get { return username; } - set { username = value; } - } - #endregion + #region UserName + /// + /// Sets the username to use to connect to the asterisk server. This is the + /// username specified in asterisk's manager.conf file. + /// + public string Username + { + get { return username; } + set { username = value; } + } + #endregion - #region Password - /// - /// Sets the password to use to connect to the asterisk server. This is the - /// password specified in asterisk's manager.conf file. - /// - public string Password - { - get { return password; } - set { password = value; } - } - #endregion + #region Password + /// + /// Sets the password to use to connect to the asterisk server. This is the + /// password specified in asterisk's manager.conf file. + /// + public string Password + { + get { return password; } + set { password = value; } + } + #endregion - #region DefaultResponseTimeout - /// Sets the time in milliseconds the synchronous method - /// will wait for a response before throwing a TimeoutException.
- /// Default is 2000. - ///
- public int DefaultResponseTimeout - { - get { return defaultResponseTimeout; } - set { defaultResponseTimeout = value; } - } - #endregion + #region DefaultResponseTimeout + /// Sets the time in milliseconds the synchronous method + /// will wait for a response before throwing a TimeoutException.
+ /// Default is 2000. + ///
+ public int DefaultResponseTimeout + { + get { return defaultResponseTimeout; } + set { defaultResponseTimeout = value; } + } + #endregion - #region DefaultEventTimeout - /// Sets the time in milliseconds the synchronous method - /// will wait for a response and the last response event before throwing a TimeoutException.
- /// Default is 5000. - ///
- public int DefaultEventTimeout - { - get { return defaultEventTimeout; } - set { defaultEventTimeout = value; } - } - #endregion + #region DefaultEventTimeout + /// Sets the time in milliseconds the synchronous method + /// will wait for a response and the last response event before throwing a TimeoutException.
+ /// Default is 5000. + ///
+ public int DefaultEventTimeout + { + get { return defaultEventTimeout; } + set { defaultEventTimeout = value; } + } + #endregion - #region SleepTime - /// Sets the time in milliseconds the synchronous methods - /// SendAction(Action.ManagerAction) and - /// SendAction(Action.ManagerAction, long) will sleep between two checks - /// for the arrival of a response. This value should be rather small.
- /// The sleepTime attribute is also used when checking for the protocol - /// identifer.
- /// Default is 50. - ///
- /// this has been replaced by an interrupt based response checking approach. - public int SleepTime - { - get { return sleepTime; } - set { sleepTime = value; } - } - #endregion + #region SleepTime + /// Sets the time in milliseconds the synchronous methods + /// SendAction(Action.ManagerAction) and + /// SendAction(Action.ManagerAction, long) will sleep between two checks + /// for the arrival of a response. This value should be rather small.
+ /// The sleepTime attribute is also used when checking for the protocol + /// identifer.
+ /// Default is 50. + ///
+ /// this has been replaced by an interrupt based response checking approach. + public int SleepTime + { + get { return sleepTime; } + set { sleepTime = value; } + } + #endregion - #region KeepAliveAfterAuthenticationFailure - /// Set to true to try reconnecting to ther asterisk serve - /// even if the reconnection attempt threw an AuthenticationFailedException.
- /// Default is false. - ///
- public bool KeepAliveAfterAuthenticationFailure - { - set { keepAliveAfterAuthenticationFailure = value; } - get { return keepAliveAfterAuthenticationFailure; } - } - #endregion + #region KeepAliveAfterAuthenticationFailure + /// Set to true to try reconnecting to ther asterisk serve + /// even if the reconnection attempt threw an AuthenticationFailedException.
+ /// Default is false. + ///
+ public bool KeepAliveAfterAuthenticationFailure + { + set { keepAliveAfterAuthenticationFailure = value; } + get { return keepAliveAfterAuthenticationFailure; } + } + #endregion - #region KeepAlive - /// - /// Should we attempt to reconnect when the connection is lost?
- /// This is set to true after successful login and to false after logoff or after an authentication failure when keepAliveAfterAuthenticationFailure is false. - ///
- public bool KeepAlive - { - get { return keepAlive; } - set { keepAlive = value; } - } - #endregion + #region KeepAlive + /// + /// Should we attempt to reconnect when the connection is lost?
+ /// This is set to true after successful login and to false after logoff or after an authentication failure when keepAliveAfterAuthenticationFailure is false. + ///
+ public bool KeepAlive + { + get { return keepAlive; } + set { keepAlive = value; } + } + #endregion - #region SocketEncoding - /// - /// Socket Encoding - default ASCII - /// - public Encoding SocketEncoding - { - get { return socketEncoding; } - set { socketEncoding = value; } - } - #endregion + #region SocketEncoding + /// + /// Socket Encoding - default ASCII + /// + public Encoding SocketEncoding + { + get { return socketEncoding; } + set { socketEncoding = value; } + } + #endregion - #region Version - public string Version - { - get { return version; } - } - #endregion + #region Version + public string Version + { + get { return version; } + } + #endregion - #region AsteriskVersion - public AsteriskVersion AsteriskVersion - { - get { return asteriskVersion; } - } - #endregion + #region AsteriskVersion + public AsteriskVersion AsteriskVersion + { + get { return asteriskVersion; } + } + #endregion - #region login(timeout) - /// - /// Does the real login, following the steps outlined below.
- /// Connects to the asterisk server by calling connect() if not already connected
- /// Waits until the protocol identifier is received. This is checked every sleepTime ms but not longer than timeout ms in total.
- /// Sends a ChallengeAction requesting a challenge for authType MD5.
- /// When the ChallengeResponse is received a LoginAction is sent using the calculated key (MD5 hash of the password appended to the received challenge).
- ///
- /// the maximum time to wait for the protocol identifier (in ms) - /// - /// AuthenticationFailedException if username or password are incorrect and the login action returns an error or if the MD5 - /// hash cannot be computed. The connection is closed in this case. - /// - /// - /// TimeoutException if a timeout occurs either while waiting for the - /// protocol identifier or when sending the challenge or login - /// action. The connection is closed in this case. - /// - private void login(int timeout) - { - enableEvents = false; - if (reconnected) - { + #region login(timeout) + /// + /// Does the real login, following the steps outlined below.
+ /// Connects to the asterisk server by calling connect() if not already connected
+ /// Waits until the protocol identifier is received. This is checked every sleepTime ms but not longer than timeout ms in total.
+ /// Sends a ChallengeAction requesting a challenge for authType MD5.
+ /// When the ChallengeResponse is received a LoginAction is sent using the calculated key (MD5 hash of the password appended to the received challenge).
+ ///
+ /// the maximum time to wait for the protocol identifier (in ms) + /// + /// AuthenticationFailedException if username or password are incorrect and the login action returns an error or if the MD5 + /// hash cannot be computed. The connection is closed in this case. + /// + /// + /// TimeoutException if a timeout occurs either while waiting for the + /// protocol identifier or when sending the challenge or login + /// action. The connection is closed in this case. + /// + private void login(int timeout) + { + enableEvents = false; + if (reconnected) + { #if LOGGER - logger.Error("Login during reconnect state."); + logger.Error("Login during reconnect state."); #endif - throw new AuthenticationFailedException("Unable login during reconnect state."); - } + throw new AuthenticationFailedException("Unable login during reconnect state."); + } - reconnectEnable = false; - DateTime start = DateTime.Now; - do - { - if (connect()) - { - // Increase delay after connection up to 500 ms - Thread.Sleep(10 * sleepTime); // 200 milliseconds delay - } - try - { - Thread.Sleep(4 * sleepTime); // 200 milliseconds delay - } - catch - { } + reconnectEnable = false; + DateTime start = DateTime.Now; + do + { + if (connect()) + { + // Increase delay after connection up to 500 ms + Thread.Sleep(10 * sleepTime); // 200 milliseconds delay + } + try + { + Thread.Sleep(4 * sleepTime); // 200 milliseconds delay + } + catch + { } - if (string.IsNullOrEmpty(protocolIdentifier) && timeout > 0 && Helper.GetMillisecondsFrom(start) > timeout) - { - disconnect(true); - throw new TimeoutException("Timeout waiting for protocol identifier"); - } - } while (string.IsNullOrEmpty(protocolIdentifier)); + if (string.IsNullOrEmpty(protocolIdentifier) && timeout > 0 && Helper.GetMillisecondsFrom(start) > timeout) + { + disconnect(true); + throw new TimeoutException("Timeout waiting for protocol identifier"); + } + } while (string.IsNullOrEmpty(protocolIdentifier)); - ChallengeAction challengeAction = new ChallengeAction(); - Response.ManagerResponse response = SendAction(challengeAction, defaultResponseTimeout * 2); - if (response is ChallengeResponse) - { - ChallengeResponse challengeResponse = (ChallengeResponse)response; - string key, challenge = challengeResponse.Challenge; - try - { - Util.MD5Support md = Util.MD5Support.GetInstance(); - if (challenge != null) - md.Update(UTF8Encoding.UTF8.GetBytes(challenge)); - if (password != null) - md.Update(UTF8Encoding.UTF8.GetBytes(password)); - key = Helper.ToHexString(md.DigestData); - } - catch (Exception ex) - { - disconnect(true); + ChallengeAction challengeAction = new ChallengeAction(); + Response.ManagerResponse response = SendAction(challengeAction, defaultResponseTimeout * 2); + if (response is ChallengeResponse) + { + ChallengeResponse challengeResponse = (ChallengeResponse)response; + string key, challenge = challengeResponse.Challenge; + try + { + Util.MD5Support md = Util.MD5Support.GetInstance(); + if (challenge != null) + md.Update(UTF8Encoding.UTF8.GetBytes(challenge)); + if (password != null) + md.Update(UTF8Encoding.UTF8.GetBytes(password)); + key = Helper.ToHexString(md.DigestData); + } + catch (Exception ex) + { + disconnect(true); #if LOGGER - logger.Error("Unable to create login key using MD5 Message Digest.", ex); + logger.Error("Unable to create login key using MD5 Message Digest.", ex); #endif - throw new AuthenticationFailedException("Unable to create login key using MD5 Message Digest.", ex); - } + throw new AuthenticationFailedException("Unable to create login key using MD5 Message Digest.", ex); + } - Action.LoginAction loginAction = new Action.LoginAction(username, "MD5", key); - Response.ManagerResponse loginResponse = SendAction(loginAction); - if (loginResponse is Response.ManagerError) - { - disconnect(true); - throw new AuthenticationFailedException(loginResponse.Message); - } + Action.LoginAction loginAction = new Action.LoginAction(username, "MD5", key); + Response.ManagerResponse loginResponse = SendAction(loginAction); + if (loginResponse is Response.ManagerError) + { + disconnect(true); + throw new AuthenticationFailedException(loginResponse.Message); + } - // successfully logged in so assure that we keep trying to reconnect when disconnected - reconnectEnable = keepAlive; + // successfully logged in so assure that we keep trying to reconnect when disconnected + reconnectEnable = keepAlive; #if LOGGER - logger.Info("Successfully logged in"); + logger.Info("Successfully logged in"); #endif - asteriskVersion = determineVersion(); + asteriskVersion = determineVersion(); #if LOGGER - logger.Info("Determined Asterisk version: " + asteriskVersion); + logger.Info("Determined Asterisk version: " + asteriskVersion); #endif - enableEvents = true; - ConnectEvent ce = new ConnectEvent(this); - ce.ProtocolIdentifier = this.protocolIdentifier; - DispatchEvent(ce); - } - else if (response is ManagerError) - throw new ManagerException("Unable login to Asterisk - " + response.Message); - else - throw new ManagerException("Unknown response during login to Asterisk - " + response.GetType().Name + " with message " + response.Message); + enableEvents = true; + ConnectEvent ce = new ConnectEvent(this); + ce.ProtocolIdentifier = this.protocolIdentifier; + DispatchEvent(ce); + } + else if (response is ManagerError) + throw new ManagerException("Unable login to Asterisk - " + response.Message); + else + throw new ManagerException("Unknown response during login to Asterisk - " + response.GetType().Name + " with message " + response.Message); - } - #endregion + } + #endregion - #region determineVersion() - protected internal AsteriskVersion determineVersion() - { - Response.ManagerResponse response; - response = SendAction(new Action.CommandAction("core show version"), defaultResponseTimeout * 2); - if (response is Response.CommandResponse) - { - foreach (string line in ((Response.CommandResponse)response).Result) - { - foreach (Match m in Common.ASTERISK_VERSION.Matches(line)) - { - if (m.Groups.Count >= 2) - { - version = m.Groups[1].Value; + #region determineVersion() + protected internal AsteriskVersion determineVersion() + { + Response.ManagerResponse response; + response = SendAction(new Action.CommandAction("core show version"), defaultResponseTimeout * 2); + if (response is Response.CommandResponse) + { + foreach (string line in ((Response.CommandResponse)response).Result) + { + foreach (Match m in Common.ASTERISK_VERSION.Matches(line)) + { + if (m.Groups.Count >= 2) + { + version = m.Groups[1].Value; if (version.StartsWith("1.4.")) { VAR_DELIMITER = new char[] { '|' }; @@ -1683,56 +994,56 @@ namespace AsterNET.Manager } else throw new ManagerException("Unknown Asterisk version " + version); - } - } - } - } + } + } + } + } - Response.ManagerResponse showVersionFilesResponse = SendAction(new Action.CommandAction("show version files"), defaultResponseTimeout * 2); - if (showVersionFilesResponse is Response.CommandResponse) - { - IList showVersionFilesResult = ((Response.CommandResponse)showVersionFilesResponse).Result; - if (showVersionFilesResult != null && showVersionFilesResult.Count > 0) - { - string line1; - line1 = (string)showVersionFilesResult[0]; - if (line1 != null && line1.StartsWith("File")) - return AsteriskVersion.ASTERISK_1_2; - } - } - return AsteriskVersion.ASTERISK_1_0; - } + Response.ManagerResponse showVersionFilesResponse = SendAction(new Action.CommandAction("show version files"), defaultResponseTimeout * 2); + if (showVersionFilesResponse is Response.CommandResponse) + { + IList showVersionFilesResult = ((Response.CommandResponse)showVersionFilesResponse).Result; + if (showVersionFilesResult != null && showVersionFilesResult.Count > 0) + { + string line1; + line1 = (string)showVersionFilesResult[0]; + if (line1 != null && line1.StartsWith("File")) + return AsteriskVersion.ASTERISK_1_2; + } + } + return AsteriskVersion.ASTERISK_1_0; + } - #endregion + #endregion - #region connect() - protected internal bool connect() - { - bool result = false; - bool startReader = false; + #region connect() + protected internal bool connect() + { + bool result = false; + bool startReader = false; - lock (lockSocket) - { - if (mrSocket == null) - { + lock (lockSocket) + { + if (mrSocket == null) + { #if LOGGER - logger.Info("Connecting to {0}:{1}", hostname, port); + logger.Info("Connecting to {0}:{1}", hostname, port); #endif - try - { - mrSocket = new SocketConnection(hostname, port, socketEncoding); - result = mrSocket.IsConnected; - } + try + { + mrSocket = new SocketConnection(hostname, port, socketEncoding); + result = mrSocket.IsConnected; + } #if LOGGER - catch (Exception ex) - { - logger.Info("Connect - Exception : {0}", ex.Message); + catch (Exception ex) + { + logger.Info("Connect - Exception : {0}", ex.Message); #else catch { #endif - result = false; - } + result = false; + } if (result) { if (mrReader == null) @@ -1753,862 +1064,879 @@ namespace AsterNET.Manager { mrSocket = null; } - } - } + } + } if (startReader) { mrReaderThread.Start(); } - return IsConnected(); - } - #endregion + return IsConnected(); + } + #endregion - #region disconnect() - /// Closes the socket connection. - private void disconnect(bool withDie) - { - lock (lockSocket) - { - if (withDie) - { - reconnectEnable = false; - reconnected = false; - enableEvents = true; - } + #region disconnect() + /// Closes the socket connection. + private void disconnect(bool withDie) + { + lock (lockSocket) + { + if (withDie) + { + reconnectEnable = false; + reconnected = false; + enableEvents = true; + } - if (mrReader != null) - { - if (withDie) - { - mrReader.Die = true; - mrReader = null; - } - else - mrReader.Socket = null; - } + if (mrReader != null) + { + if (withDie) + { + mrReader.Die = true; + mrReader = null; + } + else + mrReader.Socket = null; + } - if (this.mrSocket != null) - { - mrSocket.Close(); - mrSocket = null; - } + if (this.mrSocket != null) + { + mrSocket.Close(); + mrSocket = null; + } - responseEventHandlers.Clear(); - responseHandlers.Clear(); - pingHandlers.Clear(); - } - } - #endregion + responseEventHandlers.Clear(); + responseHandlers.Clear(); + pingHandlers.Clear(); + } + } + #endregion - #region reconnect(bool init) - /// - /// Reconnects to the asterisk server when the connection is lost.
- /// While keepAlive is true we will try to reconnect. - /// Reconnection attempts will be stopped when the logoff() method - /// is called or when the login after a successful reconnect results in an - /// AuthenticationFailedException suggesting that the manager - /// credentials have changed and keepAliveAfterAuthenticationFailure is not set.
- /// This method is called when a DisconnectEvent is received from the reader. - ///
- private void reconnect(bool init) - { + #region reconnect(bool init) + /// + /// Reconnects to the asterisk server when the connection is lost.
+ /// While keepAlive is true we will try to reconnect. + /// Reconnection attempts will be stopped when the logoff() method + /// is called or when the login after a successful reconnect results in an + /// AuthenticationFailedException suggesting that the manager + /// credentials have changed and keepAliveAfterAuthenticationFailure is not set.
+ /// This method is called when a DisconnectEvent is received from the reader. + ///
+ private void reconnect(bool init) + { #if LOGGER - logger.Warning("reconnect (init: {0}), reconnectCount:{1}", init, reconnectCount); + logger.Warning("reconnect (init: {0}), reconnectCount:{1}", init, reconnectCount); #endif - if (init) - reconnectCount = 0; - else if (reconnectCount++ > reconnectRetryMax) - reconnectEnable = false; + if (init) + reconnectCount = 0; + else if (reconnectCount++ > reconnectRetryMax) + reconnectEnable = false; - if (reconnectEnable) - { + if (reconnectEnable) + { #if LOGGER - logger.Warning("Try reconnect."); + logger.Warning("Try reconnect."); #endif - enableEvents = false; - reconnected = true; - disconnect(false); + enableEvents = false; + reconnected = true; + disconnect(false); - int retryCount = 0; - while (reconnectEnable && !mrReader.Die) - { - if (retryCount >= reconnectRetryMax) - reconnectEnable = false; - else - { - try - { - if (retryCount < reconnectRetryFast) - { - // Try to reconnect quite fast for the first times - // this succeeds if the server has just been restarted + int retryCount = 0; + while (reconnectEnable && !mrReader.Die) + { + if (retryCount >= reconnectRetryMax) + reconnectEnable = false; + else + { + try + { + if (retryCount < reconnectRetryFast) + { + // Try to reconnect quite fast for the first times + // this succeeds if the server has just been restarted #if LOGGER - logger.Info("Reconnect delay : {0}, retry : {1}", reconnectIntervalFast, retryCount); + logger.Info("Reconnect delay : {0}, retry : {1}", reconnectIntervalFast, retryCount); #endif - Thread.Sleep(reconnectIntervalFast); - } - else - { - // slow down after unsuccessful attempts assuming a shutdown of the server + Thread.Sleep(reconnectIntervalFast); + } + else + { + // slow down after unsuccessful attempts assuming a shutdown of the server #if LOGGER - logger.Info("Reconnect delay : {0}, retry : {1}", reconnectIntervalMax, retryCount); + logger.Info("Reconnect delay : {0}, retry : {1}", reconnectIntervalMax, retryCount); #endif - Thread.Sleep(reconnectIntervalMax); - } - } - catch (ThreadInterruptedException) - { - continue; - } + Thread.Sleep(reconnectIntervalMax); + } + } + catch (ThreadInterruptedException) + { + continue; + } #if LOGGER - catch (Exception ex) - { - logger.Info("Reconnect delay exception : ", ex.Message); + catch (Exception ex) + { + logger.Info("Reconnect delay exception : ", ex.Message); #else catch { #endif - continue; - } + continue; + } - try - { + try + { #if LOGGER - logger.Info("Try connect."); + logger.Info("Try connect."); #endif - if (connect()) - break; - } + if (connect()) + break; + } #if LOGGER - catch(Exception ex) - { - logger.Info("Connect exception : ", ex.Message); + catch (Exception ex) + { + logger.Info("Connect exception : ", ex.Message); #else catch { #endif - } - retryCount++; - } - } - } + } + retryCount++; + } + } + } - if (!reconnectEnable) - { + if (!reconnectEnable) + { #if LOGGER - logger.Info("Can't reconnect."); + logger.Info("Can't reconnect."); #endif - enableEvents = true; - reconnected = false; - disconnect(true); - fireEvent(new DisconnectEvent(this)); - } - } - #endregion + enableEvents = true; + reconnected = false; + disconnect(true); + fireEvent(new DisconnectEvent(this)); + } + } + #endregion - #region createInternalActionId() - /// - /// Creates a new unique internal action id based on the hash code of this connection and a sequence. - /// - private string createInternalActionId() - { - return this.GetHashCode() + "_" + (this.actionIdCount++); - } - #endregion + #region createInternalActionId() + /// + /// Creates a new unique internal action id based on the hash code of this connection and a sequence. + /// + private string createInternalActionId() + { + return this.GetHashCode() + "_" + (this.actionIdCount++); + } + #endregion - #region Login() - /// - /// Logs in to the Asterisk manager using asterisk's MD5 based - /// challenge/response protocol. The login is delayed until the protocol - /// identifier has been received by the reader. - /// - /// AuthenticationFailedException if the username and/or password are incorrect - /// TimeoutException if no response is received within the specified timeout period - /// - /// - public void Login() - { - login(defaultResponseTimeout); - } - /// - /// Log in to the Asterisk manager using asterisk's MD5 based - /// challenge/response protocol. The login is delayed until the protocol - /// identifier has been received by the reader. - /// - /// Timeout in milliseconds to login. - public void Login(int timeout) - { - login(timeout); - } - #endregion + #region Login() + /// + /// Logs in to the Asterisk manager using asterisk's MD5 based + /// challenge/response protocol. The login is delayed until the protocol + /// identifier has been received by the reader. + /// + /// AuthenticationFailedException if the username and/or password are incorrect + /// TimeoutException if no response is received within the specified timeout period + /// + /// + public void Login() + { + login(defaultResponseTimeout); + } + /// + /// Log in to the Asterisk manager using asterisk's MD5 based + /// challenge/response protocol. The login is delayed until the protocol + /// identifier has been received by the reader. + /// + /// Timeout in milliseconds to login. + public void Login(int timeout) + { + login(timeout); + } + #endregion - #region IsConnected() - /// Returns true if there is a socket connection to the - /// asterisk server, false otherwise. - /// - /// - /// true if there is a socket connection to the - /// asterisk server, false otherwise. - /// - public bool IsConnected() - { - bool result = false; - lock (lockSocket) - result = mrSocket != null && mrSocket.IsConnected; - return result; - } - #endregion + #region IsConnected() + /// Returns true if there is a socket connection to the + /// asterisk server, false otherwise. + /// + /// + /// true if there is a socket connection to the + /// asterisk server, false otherwise. + /// + public bool IsConnected() + { + bool result = false; + lock (lockSocket) + result = mrSocket != null && mrSocket.IsConnected; + return result; + } + #endregion - #region Logoff() - /// - /// Sends a LogoffAction and disconnects from the server. - /// - public void Logoff() - { - lock (lockSocket) - { - // stop reconnecting when we got disconnected - reconnectEnable = false; - if (mrReader != null && mrSocket != null) - try - { - mrReader.IsLogoff = true; - SendAction(new Action.LogoffAction()); - } - catch - { } - } - disconnect(true); - } - #endregion + #region Logoff() + /// + /// Sends a LogoffAction and disconnects from the server. + /// + public void Logoff() + { + lock (lockSocket) + { + // stop reconnecting when we got disconnected + reconnectEnable = false; + if (mrReader != null && mrSocket != null) + try + { + mrReader.IsLogoff = true; + SendAction(new Action.LogoffAction()); + } + catch + { } + } + disconnect(true); + } + #endregion - #region SendAction(action) - /// - /// Send Action with default timeout. - /// - /// - /// - public Response.ManagerResponse SendAction(Action.ManagerAction action) - { - return SendAction(action, defaultResponseTimeout); - } - #endregion + #region SendAction(action) + /// + /// Send Action with default timeout. + /// + /// + /// + public Response.ManagerResponse SendAction(Action.ManagerAction action) + { + return SendAction(action, defaultResponseTimeout); + } + #endregion - #region SendAction(action, timeout) - /// - /// Send action ans with timeout (milliseconds) - /// - /// action to send - /// timeout in milliseconds - /// - public Response.ManagerResponse SendAction(ManagerAction action, int timeOut) - { - AutoResetEvent autoEvent = new AutoResetEvent(false); - ResponseHandler handler = new ResponseHandler(action, autoEvent); + #region SendAction(action, timeout) + /// + /// Send action ans with timeout (milliseconds) + /// + /// action to send + /// timeout in milliseconds + /// + public Response.ManagerResponse SendAction(ManagerAction action, int timeOut) + { + AutoResetEvent autoEvent = new AutoResetEvent(false); + ResponseHandler handler = new ResponseHandler(action, autoEvent); - int hash = SendAction(action, handler); - bool result = autoEvent.WaitOne(timeOut <= 0 ? -1 : timeOut, true); + int hash = SendAction(action, handler); + bool result = autoEvent.WaitOne(timeOut <= 0 ? -1 : timeOut, true); - RemoveResponseHandler(handler); + RemoveResponseHandler(handler); - if (result) - return handler.Response; - throw new TimeoutException("Timeout waiting for response to " + action.Action); - } - #endregion + if (result) + return handler.Response; + throw new TimeoutException("Timeout waiting for response to " + action.Action); + } + #endregion - #region SendAction(action, responseHandler) - public int SendAction(ManagerAction action, ResponseHandler responseHandler) - { - if (action == null) - throw new ArgumentException("Unable to send action: action is null."); + #region SendAction(action, responseHandler) + public int SendAction(ManagerAction action, ResponseHandler responseHandler) + { + if (action == null) + throw new ArgumentException("Unable to send action: action is null."); - if (mrSocket == null) - throw new SystemException("Unable to send " + action.Action + " action: not connected."); + if (mrSocket == null) + throw new SystemException("Unable to send " + action.Action + " action: not connected."); - // if the responseHandler is null the user is obviously not interested in the response, thats fine. - string internalActionId = string.Empty; - if (responseHandler != null) - { - internalActionId = createInternalActionId(); - responseHandler.Hash = internalActionId.GetHashCode(); - AddResponseHandler(responseHandler); - } + // if the responseHandler is null the user is obviously not interested in the response, thats fine. + string internalActionId = string.Empty; + if (responseHandler != null) + { + internalActionId = createInternalActionId(); + responseHandler.Hash = internalActionId.GetHashCode(); + AddResponseHandler(responseHandler); + } - SendToAsterisk(action, internalActionId); + SendToAsterisk(action, internalActionId); - return responseHandler != null ? responseHandler.Hash : 0; - } - #endregion + return responseHandler != null ? responseHandler.Hash : 0; + } + #endregion - #region SendEventGeneratingAction(action) - public ResponseEvents SendEventGeneratingAction(ManagerActionEvent action) - { - return SendEventGeneratingAction(action, defaultEventTimeout); - } - #endregion + #region SendEventGeneratingAction(action) + public ResponseEvents SendEventGeneratingAction(ManagerActionEvent action) + { + return SendEventGeneratingAction(action, defaultEventTimeout); + } + #endregion - #region SendEventGeneratingAction(action, timeout) - /// - /// - /// - /// - /// wait timeout in milliseconds - /// - public ResponseEvents SendEventGeneratingAction(ManagerActionEvent action, int timeout) - { - if (action == null) - throw new ArgumentException("Unable to send action: action is null."); - else if (action.ActionCompleteEventClass() == null) - throw new ArgumentException("Unable to send action: ActionCompleteEventClass is null."); - else if (!typeof(ResponseEvent).IsAssignableFrom(action.ActionCompleteEventClass())) - throw new ArgumentException("Unable to send action: ActionCompleteEventClass is not a ResponseEvent."); + #region SendEventGeneratingAction(action, timeout) + /// + /// + /// + /// + /// wait timeout in milliseconds + /// + public ResponseEvents SendEventGeneratingAction(ManagerActionEvent action, int timeout) + { + if (action == null) + throw new ArgumentException("Unable to send action: action is null."); + else if (action.ActionCompleteEventClass() == null) + throw new ArgumentException("Unable to send action: ActionCompleteEventClass is null."); + else if (!typeof(ResponseEvent).IsAssignableFrom(action.ActionCompleteEventClass())) + throw new ArgumentException("Unable to send action: ActionCompleteEventClass is not a ResponseEvent."); - if (mrSocket == null) - throw new SystemException("Unable to send " + action.Action + " action: not connected."); + if (mrSocket == null) + throw new SystemException("Unable to send " + action.Action + " action: not connected."); - AutoResetEvent autoEvent = new AutoResetEvent(false); - ResponseEventHandler handler = new ResponseEventHandler(this, action, autoEvent); + AutoResetEvent autoEvent = new AutoResetEvent(false); + ResponseEventHandler handler = new ResponseEventHandler(this, action, autoEvent); - string internalActionId = createInternalActionId(); - handler.Hash = internalActionId.GetHashCode(); - AddResponseHandler(handler); - AddResponseEventHandler(handler); + string internalActionId = createInternalActionId(); + handler.Hash = internalActionId.GetHashCode(); + AddResponseHandler(handler); + AddResponseEventHandler(handler); - SendToAsterisk(action, internalActionId); + SendToAsterisk(action, internalActionId); - bool result = autoEvent.WaitOne(timeout <= 0 ? -1 : timeout, true); + bool result = autoEvent.WaitOne(timeout <= 0 ? -1 : timeout, true); - RemoveResponseHandler(handler); - RemoveResponseEventHandler(handler); + RemoveResponseHandler(handler); + RemoveResponseEventHandler(handler); - if (result) - return handler.ResponseEvents; + if (result) + return handler.ResponseEvents; - throw new EventTimeoutException("Timeout waiting for response or response events to " + action.Action, handler.ResponseEvents); - } - #endregion + throw new EventTimeoutException("Timeout waiting for response or response events to " + action.Action, handler.ResponseEvents); + } + #endregion - #region Response Handler helpers - private void AddResponseHandler(IResponseHandler handler) - { - lock (lockHandlers) - { - if (handler.Action is PingAction) - pingHandlers[handler.Hash] = handler; - else - responseHandlers[handler.Hash] = handler; - } - } + #region Response Handler helpers + private void AddResponseHandler(IResponseHandler handler) + { + lock (lockHandlers) + { + if (handler.Action is PingAction) + pingHandlers[handler.Hash] = handler; + else + responseHandlers[handler.Hash] = handler; + } + } - private void AddResponseEventHandler(IResponseHandler handler) - { - lock (lockHandlers) - responseEventHandlers[handler.Hash] = handler; - } + private void AddResponseEventHandler(IResponseHandler handler) + { + lock (lockHandlers) + responseEventHandlers[handler.Hash] = handler; + } - internal void RemoveResponseHandler(IResponseHandler handler) - { - int hash = handler.Hash; - if (hash != 0) - lock (lockHandlers) - if (responseHandlers.ContainsKey(hash)) - responseHandlers.Remove(hash); - } + internal void RemoveResponseHandler(IResponseHandler handler) + { + int hash = handler.Hash; + if (hash != 0) + lock (lockHandlers) + if (responseHandlers.ContainsKey(hash)) + responseHandlers.Remove(hash); + } - internal void RemoveResponseEventHandler(IResponseHandler handler) - { - int hash = handler.Hash; - if (hash != 0) - lock (lockHandlers) - if (responseEventHandlers.ContainsKey(hash)) - responseEventHandlers.Remove(hash); - } + internal void RemoveResponseEventHandler(IResponseHandler handler) + { + int hash = handler.Hash; + if (hash != 0) + lock (lockHandlers) + if (responseEventHandlers.ContainsKey(hash)) + responseEventHandlers.Remove(hash); + } - private IResponseHandler GetRemoveResponseHandler(int hash) - { - IResponseHandler handler = null; - if (hash != 0) - lock (lockHandlers) - if (responseHandlers.ContainsKey(hash)) - { - handler = responseHandlers[hash]; - responseHandlers.Remove(hash); - } - return handler; - } + private IResponseHandler GetRemoveResponseHandler(int hash) + { + IResponseHandler handler = null; + if (hash != 0) + lock (lockHandlers) + if (responseHandlers.ContainsKey(hash)) + { + handler = responseHandlers[hash]; + responseHandlers.Remove(hash); + } + return handler; + } - private IResponseHandler GetRemoveResponseEventHandler(int hash) - { - IResponseHandler handler = null; - if (hash != 0) - lock (lockHandlers) - if (responseEventHandlers.ContainsKey(hash)) - { - handler = responseEventHandlers[hash]; - responseEventHandlers.Remove(hash); - } - return handler; - } + private IResponseHandler GetRemoveResponseEventHandler(int hash) + { + IResponseHandler handler = null; + if (hash != 0) + lock (lockHandlers) + if (responseEventHandlers.ContainsKey(hash)) + { + handler = responseEventHandlers[hash]; + responseEventHandlers.Remove(hash); + } + return handler; + } - private IResponseHandler GetResponseHandler(int hash) - { - IResponseHandler handler = null; - if (hash != 0) - lock (lockHandlers) - if (responseHandlers.ContainsKey(hash)) - handler = responseHandlers[hash]; - return handler; - } + private IResponseHandler GetResponseHandler(int hash) + { + IResponseHandler handler = null; + if (hash != 0) + lock (lockHandlers) + if (responseHandlers.ContainsKey(hash)) + handler = responseHandlers[hash]; + return handler; + } - private IResponseHandler GetResponseEventHandler(int hash) - { - IResponseHandler handler = null; - if (hash != 0) - lock (lockHandlers) - if (responseEventHandlers.ContainsKey(hash)) - handler = responseEventHandlers[hash]; - return handler; - } - #endregion + private IResponseHandler GetResponseEventHandler(int hash) + { + IResponseHandler handler = null; + if (hash != 0) + lock (lockHandlers) + if (responseEventHandlers.ContainsKey(hash)) + handler = responseEventHandlers[hash]; + return handler; + } + #endregion - #region SendToAsterisk(ManagerAction action, string internalActionId) + #region SendToAsterisk(ManagerAction action, string internalActionId) - internal void SendToAsterisk(ManagerAction action, string internalActionId) - { - if (mrSocket == null) - throw new SystemException("Unable to send action: socket is null"); + internal void SendToAsterisk(ManagerAction action, string internalActionId) + { + if (mrSocket == null) + throw new SystemException("Unable to send action: socket is null"); - string buffer = BuildAction(action, internalActionId); + string buffer = BuildAction(action, internalActionId); #if LOGGER - logger.Debug("Sent action : '{0}' : {1}", internalActionId, action); + logger.Debug("Sent action : '{0}' : {1}", internalActionId, action); #endif - if (sa == null) - sa = new SendToAsteriskDelegate(sendToAsterisk); - sa.Invoke(buffer); - } + if (sa == null) + sa = new SendToAsteriskDelegate(sendToAsterisk); + sa.Invoke(buffer); + } - private delegate void SendToAsteriskDelegate(string buffer); - private SendToAsteriskDelegate sa = null; + private delegate void SendToAsteriskDelegate(string buffer); + private SendToAsteriskDelegate sa = null; - private void sendToAsterisk(string buffer) - { - mrSocket.Write(buffer); - } + private void sendToAsterisk(string buffer) + { + mrSocket.Write(buffer); + } - #endregion + #endregion - #region BuildAction(action) - public string BuildAction(Action.ManagerAction action) - { - return BuildAction(action, null); - } - #endregion + #region BuildAction(action) + public string BuildAction(Action.ManagerAction action) + { + return BuildAction(action, null); + } + #endregion - #region BuildAction(action, internalActionId) - public string BuildAction(ManagerAction action, string internalActionId) - { - MethodInfo getter; - object value; - StringBuilder sb = new StringBuilder(); - string valueAsString = string.Empty; + #region BuildAction(action, internalActionId) + public string BuildAction(ManagerAction action, string internalActionId) + { + MethodInfo getter; + object value; + StringBuilder sb = new StringBuilder(); + string valueAsString = string.Empty; - if (typeof(Action.ProxyAction).IsAssignableFrom(action.GetType())) - sb.Append(string.Concat("ProxyAction: ", action.Action, Common.LINE_SEPARATOR)); - else - sb.Append(string.Concat("Action: ", action.Action, Common.LINE_SEPARATOR)); + if (typeof(Action.ProxyAction).IsAssignableFrom(action.GetType())) + sb.Append(string.Concat("ProxyAction: ", action.Action, Common.LINE_SEPARATOR)); + else + sb.Append(string.Concat("Action: ", action.Action, Common.LINE_SEPARATOR)); - if (string.IsNullOrEmpty(internalActionId)) - valueAsString = action.ActionId; - else - valueAsString = string.Concat(internalActionId, Common.INTERNAL_ACTION_ID_DELIMITER, action.ActionId); + if (string.IsNullOrEmpty(internalActionId)) + valueAsString = action.ActionId; + else + valueAsString = string.Concat(internalActionId, Common.INTERNAL_ACTION_ID_DELIMITER, action.ActionId); - if (!string.IsNullOrEmpty(valueAsString)) - sb.Append(string.Concat("ActionID: ", valueAsString, Common.LINE_SEPARATOR)); + if (!string.IsNullOrEmpty(valueAsString)) + sb.Append(string.Concat("ActionID: ", valueAsString, Common.LINE_SEPARATOR)); - Dictionary getters = Helper.GetGetters(action.GetType()); + Dictionary getters = Helper.GetGetters(action.GetType()); - foreach (string name in getters.Keys) - { - string nameLower = name.ToLower(Helper.CultureInfo); - if (nameLower == "class" || nameLower == "action" || nameLower == "actionid") - continue; + foreach (string name in getters.Keys) + { + string nameLower = name.ToLower(Helper.CultureInfo); + if (nameLower == "class" || nameLower == "action" || nameLower == "actionid") + continue; - getter = getters[name]; - Type propType = getter.ReturnType; - if (!(propType == typeof(string) - || propType == typeof(bool) - || propType == typeof(double) - || propType == typeof(DateTime) - || propType == typeof(int) - || propType == typeof(long) - || propType == typeof(Dictionary) - ) - ) - continue; + getter = getters[name]; + Type propType = getter.ReturnType; + if (!(propType == typeof(string) + || propType == typeof(bool) + || propType == typeof(double) + || propType == typeof(DateTime) + || propType == typeof(int) + || propType == typeof(long) + || propType == typeof(Dictionary) + ) + ) + continue; - try - { - value = getter.Invoke(action, new object[] { }); - } - catch (UnauthorizedAccessException ex) - { + try + { + value = getter.Invoke(action, new object[] { }); + } + catch (UnauthorizedAccessException ex) + { #if LOGGER - logger.Error("Unable to retrieve property '" + name + "' of " + action.GetType(), ex); - continue; + logger.Error("Unable to retrieve property '" + name + "' of " + action.GetType(), ex); + continue; #else throw new ManagerException("Unable to retrieve property '" + name + "' of " + action.GetType(), ex); #endif - } - catch (TargetInvocationException ex) - { + } + catch (TargetInvocationException ex) + { #if LOGGER - logger.Error("Unable to retrieve property '" + name + "' of " + action.GetType(), ex); - continue; + logger.Error("Unable to retrieve property '" + name + "' of " + action.GetType(), ex); + continue; #else throw new ManagerException("Unable to retrieve property '" + name + "' of " + action.GetType(), ex); #endif - } + } - if (value == null) - continue; - if (value is string) - { - valueAsString = (string)value; - if (valueAsString.Length == 0) - continue; - } - else if (value is bool) - valueAsString = ((bool)value ? "true" : "false"); - else if (value is DateTime) - valueAsString = value.ToString(); - else if (value is IDictionary) - { - valueAsString = Helper.JoinVariables((IDictionary)value, Common.LINE_SEPARATOR, ": "); - if (valueAsString.Length == 0) - continue; - sb.Append(valueAsString); - sb.Append(Common.LINE_SEPARATOR); - continue; - } - else - valueAsString = value.ToString(); + if (value == null) + continue; + if (value is string) + { + valueAsString = (string)value; + if (valueAsString.Length == 0) + continue; + } + else if (value is bool) + valueAsString = ((bool)value ? "true" : "false"); + else if (value is DateTime) + valueAsString = value.ToString(); + else if (value is IDictionary) + { + valueAsString = Helper.JoinVariables((IDictionary)value, Common.LINE_SEPARATOR, ": "); + if (valueAsString.Length == 0) + continue; + sb.Append(valueAsString); + sb.Append(Common.LINE_SEPARATOR); + continue; + } + else + valueAsString = value.ToString(); - sb.Append(string.Concat(name, ": ", valueAsString, Common.LINE_SEPARATOR)); - } + sb.Append(string.Concat(name, ": ", valueAsString, Common.LINE_SEPARATOR)); + } IActionVariable actionVar = action as IActionVariable; - if ( actionVar != null ) + if (actionVar != null) { var variables = actionVar.GetVariables(); - if ( variables != null && variables.Count > 0 ) + if (variables != null && variables.Count > 0) { - sb.Append( string.Concat( "Variable: ", Helper.JoinVariables( actionVar.GetVariables(), VAR_DELIMITER, "=" ), Common.LINE_SEPARATOR ) ); + sb.Append(string.Concat("Variable: ", Helper.JoinVariables(actionVar.GetVariables(), VAR_DELIMITER, "="), Common.LINE_SEPARATOR)); } } sb.Append(Common.LINE_SEPARATOR); - return sb.ToString(); - } - #endregion + return sb.ToString(); + } + #endregion - #region GetProtocolIdentifier() - public string GetProtocolIdentifier() - { - return this.protocolIdentifier; - } - #endregion + #region GetProtocolIdentifier() + public string GetProtocolIdentifier() + { + return this.protocolIdentifier; + } + #endregion - #region RegisterUserEventClass(class) - /// - /// Register User Event Class - /// - /// - public void RegisterUserEventClass(Type userEventClass) - { - Helper.RegisterEventClass(registeredEventClasses, userEventClass); - } - #endregion + #region RegisterUserEventClass(class) + /// + /// Register User Event Class + /// + /// + public void RegisterUserEventClass(Type userEventClass) + { + Helper.RegisterEventClass(registeredEventClasses, userEventClass); + } + #endregion - #region DispatchResponse(response) - /// - /// This method is called by the reader whenever a ManagerResponse is - /// received. The response is dispatched to the associated ManagerResponseHandler. - /// - /// the response received by the reader - /// - internal void DispatchResponse(Dictionary buffer) - { + #region DispatchResponse(response) + /// + /// This method is called by the reader whenever a ManagerResponse is + /// received. The response is dispatched to the associated ManagerResponseHandler. + /// + /// the response received by the reader + /// + internal void DispatchResponse(Dictionary buffer) + { #if LOGGER - logger.Debug("Dispatch response packet : {0}", Helper.JoinVariables(buffer, ", ", ": ")); + logger.Debug("Dispatch response packet : {0}", Helper.JoinVariables(buffer, ", ", ": ")); #endif - DispatchResponse(buffer, null); - } + DispatchResponse(buffer, null); + } - internal void DispatchResponse(ManagerResponse response) - { + internal void DispatchResponse(ManagerResponse response) + { #if LOGGER - logger.Debug("Dispatch response : {0}", response); + logger.Debug("Dispatch response : {0}", response); #endif - DispatchResponse(null, response); - } + DispatchResponse(null, response); + } - internal void DispatchResponse(Dictionary buffer, ManagerResponse response) - { - string responseActionId = string.Empty; - string actionId = string.Empty; - IResponseHandler responseHandler = null; + internal void DispatchResponse(Dictionary buffer, ManagerResponse response) + { + string responseActionId = string.Empty; + string actionId = string.Empty; + IResponseHandler responseHandler = null; - if (buffer != null) - { - if (buffer["response"].ToLower(Helper.CultureInfo) == "error") - response = new ManagerError(buffer); - else if (buffer.ContainsKey("actionid")) - actionId = buffer["actionid"]; - } + if (buffer != null) + { + if (buffer["response"].ToLower(Helper.CultureInfo) == "error") + response = new ManagerError(buffer); + else if (buffer.ContainsKey("actionid")) + actionId = buffer["actionid"]; + } - if (response != null) - actionId = response.ActionId; + if (response != null) + actionId = response.ActionId; - if (!string.IsNullOrEmpty(actionId)) - { - int hash = Helper.GetInternalActionId(actionId).GetHashCode(); - responseActionId = Helper.StripInternalActionId(actionId); - responseHandler = GetRemoveResponseHandler(hash); + if (!string.IsNullOrEmpty(actionId)) + { + int hash = Helper.GetInternalActionId(actionId).GetHashCode(); + responseActionId = Helper.StripInternalActionId(actionId); + responseHandler = GetRemoveResponseHandler(hash); - if (response != null) - response.ActionId = responseActionId; - if (responseHandler != null) - { - if (response == null) - { - ManagerActionResponse action = responseHandler.Action as ManagerActionResponse; - if (action == null || (response = action.ActionCompleteResponseClass() as ManagerResponse) == null) - response = Helper.BuildResponse(buffer); - else - Helper.SetAttributes(response, buffer); - response.ActionId = responseActionId; - } + if (response != null) + response.ActionId = responseActionId; + if (responseHandler != null) + { + if (response == null) + { + ManagerActionResponse action = responseHandler.Action as ManagerActionResponse; + if (action == null || (response = action.ActionCompleteResponseClass() as ManagerResponse) == null) + response = Helper.BuildResponse(buffer); + else + Helper.SetAttributes(response, buffer); + response.ActionId = responseActionId; + } - try - { - responseHandler.HandleResponse(response); - } - catch (Exception ex) - { + try + { + responseHandler.HandleResponse(response); + } + catch (Exception ex) + { #if LOGGER - logger.Error("Unexpected exception in responseHandler {0}\n{1}", response, ex); + logger.Error("Unexpected exception in responseHandler {0}\n{1}", response, ex); #else throw new ManagerException("Unexpected exception in responseHandler " + responseHandler.GetType().FullName, ex); #endif - } - } - } - - if (response == null && buffer.ContainsKey("ping") && buffer["ping"] == "Pong") - { - response = Helper.BuildResponse(buffer); - foreach (ResponseHandler pingHandler in pingHandlers.Values) - pingHandler.HandleResponse(response); - pingHandlers.Clear(); - } + } + } + } - if (!reconnected) - return; + if (response == null && buffer.ContainsKey("ping") && buffer["ping"] == "Pong") + { + response = Helper.BuildResponse(buffer); + foreach (ResponseHandler pingHandler in pingHandlers.Values) + pingHandler.HandleResponse(response); + pingHandlers.Clear(); + } - if (response == null) - { - response = Helper.BuildResponse(buffer); - response.ActionId = responseActionId; - } + if (!reconnected) + return; + + if (response == null) + { + response = Helper.BuildResponse(buffer); + response.ActionId = responseActionId; + } #if LOGGER - logger.Info("Reconnected - DispatchEvent : " + response); + logger.Info("Reconnected - DispatchEvent : " + response); #endif - #region Support background reconnect - if (response is ChallengeResponse) - { - string key = null; - if (response.IsSuccess()) - { - ChallengeResponse challengeResponse = (ChallengeResponse)response; - string challenge = challengeResponse.Challenge; - try - { - Util.MD5Support md = Util.MD5Support.GetInstance(); - if (challenge != null) - md.Update(UTF8Encoding.UTF8.GetBytes(challenge)); - if (password != null) - md.Update(UTF8Encoding.UTF8.GetBytes(password)); - key = Helper.ToHexString(md.DigestData); - } + #region Support background reconnect + if (response is ChallengeResponse) + { + string key = null; + if (response.IsSuccess()) + { + ChallengeResponse challengeResponse = (ChallengeResponse)response; + string challenge = challengeResponse.Challenge; + try + { + Util.MD5Support md = Util.MD5Support.GetInstance(); + if (challenge != null) + md.Update(UTF8Encoding.UTF8.GetBytes(challenge)); + if (password != null) + md.Update(UTF8Encoding.UTF8.GetBytes(password)); + key = Helper.ToHexString(md.DigestData); + } #if LOGGER - catch (Exception ex) - { - logger.Error("Unable to create login key using MD5 Message Digest", ex); + catch (Exception ex) + { + logger.Error("Unable to create login key using MD5 Message Digest", ex); #else catch { #endif - key = null; - } - } - bool fail = true; - if (!string.IsNullOrEmpty(key)) - try - { - Action.LoginAction loginAction = new Action.LoginAction(username, "MD5", key); - SendAction(loginAction, null); - fail = false; - } - catch { } - if (fail) - if (keepAliveAfterAuthenticationFailure) - reconnect(true); - else - disconnect(true); - } - else if (response is ManagerError) - { - if (keepAliveAfterAuthenticationFailure) - reconnect(true); - else - disconnect(true); - } - else if (response is ManagerResponse) - { - if (response.IsSuccess()) - { - reconnected = false; - enableEvents = true; - reconnectEnable = keepAlive; - ConnectEvent ce = new ConnectEvent(this); - ce.Reconnect = true; - ce.ProtocolIdentifier = protocolIdentifier; - fireEvent(ce); - } - else if (keepAliveAfterAuthenticationFailure) - reconnect(true); - else - disconnect(true); - } - #endregion - } - #endregion + key = null; + } + } + bool fail = true; + if (!string.IsNullOrEmpty(key)) + try + { + Action.LoginAction loginAction = new Action.LoginAction(username, "MD5", key); + SendAction(loginAction, null); + fail = false; + } + catch { } + if (fail) + if (keepAliveAfterAuthenticationFailure) + reconnect(true); + else + disconnect(true); + } + else if (response is ManagerError) + { + if (keepAliveAfterAuthenticationFailure) + reconnect(true); + else + disconnect(true); + } + else if (response is ManagerResponse) + { + if (response.IsSuccess()) + { + reconnected = false; + enableEvents = true; + reconnectEnable = keepAlive; + ConnectEvent ce = new ConnectEvent(this); + ce.Reconnect = true; + ce.ProtocolIdentifier = protocolIdentifier; + fireEvent(ce); + } + else if (keepAliveAfterAuthenticationFailure) + reconnect(true); + else + disconnect(true); + } + #endregion + } + #endregion - #region DispatchEvent(...) - /// - /// This method is called by the reader whenever a ManagerEvent is received. - /// The event is dispatched to all registered ManagerEventHandlers. - /// - /// the event received by the reader - /// - internal void DispatchEvent(Dictionary buffer) - { - ManagerEvent e = Helper.BuildEvent(registeredEventClasses, this, buffer); - DispatchEvent(e); - } + #region DispatchEvent(...) + /// + /// This method is called by the reader whenever a ManagerEvent is received. + /// The event is dispatched to all registered ManagerEventHandlers. + /// + /// the event received by the reader + /// + internal void DispatchEvent(Dictionary buffer) + { + ManagerEvent e = Helper.BuildEvent(registeredEventClasses, this, buffer); + DispatchEvent(e); + } - internal void DispatchEvent(ManagerEvent e) - { + internal void DispatchEvent(ManagerEvent e) + { #if LOGGER - logger.Debug("Dispatching event: {0}", e); + logger.Debug("Dispatching event: {0}", e); #endif - if (e is ResponseEvent) - { - ResponseEvent responseEvent = (ResponseEvent)e; - if (!string.IsNullOrEmpty(responseEvent.ActionId) && !string.IsNullOrEmpty(responseEvent.InternalActionId)) - { - ResponseEventHandler eventHandler = (ResponseEventHandler)GetResponseEventHandler(responseEvent.InternalActionId.GetHashCode()); - if (eventHandler != null) - try - { - eventHandler.HandleEvent(e); - } - catch (SystemException ex) - { + if (e is ResponseEvent) + { + ResponseEvent responseEvent = (ResponseEvent)e; + if (!string.IsNullOrEmpty(responseEvent.ActionId) && !string.IsNullOrEmpty(responseEvent.InternalActionId)) + { + ResponseEventHandler eventHandler = (ResponseEventHandler)GetResponseEventHandler(responseEvent.InternalActionId.GetHashCode()); + if (eventHandler != null) + try + { + eventHandler.HandleEvent(e); + } + catch (SystemException ex) + { #if LOGGER - logger.Error("Unexpected exception", ex); + logger.Error("Unexpected exception", ex); #else throw ex; #endif - } - } - } + } + } + } - #region ConnectEvent - if (e is ConnectEvent) - { - string protocol = ((ConnectEvent)e).ProtocolIdentifier; + #region ConnectEvent + if (e is ConnectEvent) + { + string protocol = ((ConnectEvent)e).ProtocolIdentifier; #if LOGGER - logger.Info("Connected via {0}", protocol); + logger.Info("Connected via {0}", protocol); #endif - if (!string.IsNullOrEmpty(protocol) && protocol.StartsWith("Asterisk Call Manager")) - { - this.protocolIdentifier = protocol; - } - else - { - this.protocolIdentifier = (string.IsNullOrEmpty(protocol) ? "Empty" : protocol); + if (!string.IsNullOrEmpty(protocol) && protocol.StartsWith("Asterisk Call Manager")) + { + this.protocolIdentifier = protocol; + } + else + { + this.protocolIdentifier = (string.IsNullOrEmpty(protocol) ? "Empty" : protocol); #if LOGGER - logger.Warning("Unsupported protocol version '{0}'. Use at your own risk.", protocol); + logger.Warning("Unsupported protocol version '{0}'. Use at your own risk.", protocol); #endif - } - if (reconnected) - { + } + if (reconnected) + { #if LOGGER - logger.Info("Send Challenge action."); + logger.Info("Send Challenge action."); #endif - ChallengeAction challengeAction = new ChallengeAction(); - try - { - SendAction(challengeAction, null); - } + ChallengeAction challengeAction = new ChallengeAction(); + try + { + SendAction(challengeAction, null); + } #if LOGGER - catch(Exception ex) - { - logger.Info("Send Challenge fail : ", ex.Message); + catch (Exception ex) + { + logger.Info("Send Challenge fail : ", ex.Message); #else catch { #endif - disconnect(true); - } - return; - } - } - #endregion + disconnect(true); + } + return; + } + } + #endregion - if (reconnected && e is DisconnectEvent) - { - ((DisconnectEvent)e).Reconnect = true; - fireEvent(e); - reconnect(false); - } - else if (!reconnected && reconnectEnable && (e is DisconnectEvent || e is ReloadEvent || e is ShutdownEvent)) - { - ((ConnectionStateEvent)e).Reconnect = true; - fireEvent(e); - reconnect(true); - } - else - fireEvent(e); - } + if (reconnected && e is DisconnectEvent) + { + ((DisconnectEvent)e).Reconnect = true; + fireEvent(e); + reconnect(false); + } + else if (!reconnected && reconnectEnable && (e is DisconnectEvent || e is ReloadEvent || e is ShutdownEvent)) + { + ((ConnectionStateEvent)e).Reconnect = true; + fireEvent(e); + reconnect(true); + } + else + fireEvent(e); + } - private void eventComplete(IAsyncResult result) - { - } + private void eventComplete(IAsyncResult result) + { + } - private void fireEvent(ManagerEvent e) - { - if (enableEvents && internalEvent != null) - if(UseASyncEvents) - internalEvent.BeginInvoke(this, e, new AsyncCallback(eventComplete), null); + private void fireEvent(ManagerEvent e) + { + if (enableEvents && internalEvent != null) + if (UseASyncEvents) + internalEvent.BeginInvoke(this, e, new AsyncCallback(eventComplete), null); else internalEvent.Invoke(this, e); - } - #endregion - } + } + + /// + /// This method is called when send event to client if subscribed + /// + /// EventHandler argument + /// Event delegate + /// ManagerEvent or inherited class. Argument of eventHandler. + private bool fireEvent(EventHandler asterEvent, ManagerEvent arg) where T : ManagerEvent + { + if (asterEvent != null) + { + asterEvent(this, (T)arg); + return true; + } + + return false; + } + #endregion + } }