Author: verifier Date: Thu May 1 14:27:39 2008 New Revision: 8236 Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/Call.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/CallManager.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/CallStateEvent.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/EventWatcher.csproj freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/Extension.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/Form1.Designer.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/Form1.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/Form1.resx freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/LabelTextBox.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/Program.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/Properties/ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/Properties/AssemblyInfo.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/Properties/Resources.Designer.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/Properties/Resources.resx freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/Properties/Settings.Designer.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/Properties/Settings.settings freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/ReadMePlease.txt freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitch.EventSocket.Test/ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitch.EventSocket.Test/EventSocket.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitch.EventSocket.Test/FreeSwitch.EventSocket.Test.csproj freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitch.EventSocket.Test/ParserTest.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitch.EventSocket.Test/Program.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitch.EventSocket.Test/Properties/ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitch.EventSocket.Test/Properties/AssemblyInfo.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitch.EventSocket.sln freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/ChannelEvent.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelAnswer.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelApplication.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelBridge.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelCreate.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelDestroy.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelExecute.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelExecuteComplete.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelHangup.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelOriginate.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelOutgoing.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelProgress.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelState.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelUnbridge.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelUnpark.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventCodec.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventDtmf.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventDtmfStatus.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelInfo.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/AnyCommand.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/Api.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/AuthCommand.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/CmdBase.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/CommandReply.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/ExecuteJavascript.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/GetVariable.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/HoldCmd.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/Originate.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/ParkCmd.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/Playback.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/RecordCmd.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/SendMsg.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/SetVariable.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/SleepCmd.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/TransferCmd.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/EventManager.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/EventParser.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/EventSocket.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/EventSocket.pfx (contents, props changed) freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Events/ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Events.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Events/EventApiCommand.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Events/EventBase.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Events/EventHeartbeat.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Events/EventMessageQuery.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Events/EventMessageWaiting.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Events/EventReSchedule.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/FreeSwitch.EventSocket.csproj freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/General/ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/General/Address.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/General/ChannelVariable.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/General/SipAddress.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/General/SofiaSipAddress.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Ivr/ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Ivr/IvrInterface.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/PartyInfo.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/PlainEventMsg.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Program.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Properties/ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Properties/AssemblyInfo.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/SipEvents/ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/SipEvents/EventPresence.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/SipEvents/EventPresenceIn.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/SipEvents/EventPresenceOut.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/SipEvents/EventPresenceProbe.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/SipEvents/EventRoster.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/SipEvents/EventSofiaExpire.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/SipEvents/EventSofiaRegister.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/SipEvents/SipEvent.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/StringHelper.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/StringParser.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/IvrSocket/ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/IvrSocket/IvrSocket.csproj freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/IvrSocket/Program.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/IvrSocket/Properties/ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/IvrSocket/Properties/AssemblyInfo.cs freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/IvrSocket/Voicemail.cs Log: Initial version Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/Call.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/Call.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace EventWatcher +{ + public class Call + { + private CallState _currentState = CallState.Disconnected; + private CallState _previousState = CallState.Disconnected; + private string _id; + private string _destination; + + public Call(string id) + { + _id = id; + } + + public string Id + { + get { return _id; } + set { _id = value; } + } + + public string Destination + { + get { return _destination; } + } + + public CallState State + { + get { return _currentState; } + } + + public CallState PreviousState + { + get { return _previousState; } + } + + internal void SetCallState(CallState state) + { + _previousState = _currentState; + _currentState = state; + } + + internal void SetDestination(string dest) + { + _destination = dest; + } + + } +} Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/CallManager.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/CallManager.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,251 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using FreeSwitch.EventSocket; +using FreeSwitch.EventSocket.Commands; + +namespace EventWatcher +{ + internal class CallManager + { + #region Delegates + + public delegate void CallStateHandler(CallManager mgr, CallStateEvent callEvent); + + #endregion + + private EventManager _eventMgr; + private IDictionary<string, CallStateEvent> _events = new Dictionary<string, CallStateEvent>(); + + private IDictionary<string, ExtensionMapper> _extensions = new Dictionary<string, ExtensionMapper>(); + private int _lastCallId = 0; + + public CallManager(EventManager eventSocket) + { + _eventMgr = eventSocket; + } + + public event ExtensionHandler ExtensionAdded; + public event CallHandler ExtensionChanged; + public event ExtensionHandler ExtensionDisconnected; + public event CallStateHandler OnCallState; + + private ExtensionMapper GetMapper(string address) + { + if (_extensions.ContainsKey(address)) + return _extensions[address]; + else + { + ExtensionMapper em = new ExtensionMapper(); + em.setter = new ExtensionSetters(); + em.extension = new Extension(address, em.setter); + _extensions.Add(address, em); + if (ExtensionAdded != null) + ExtensionAdded(em.extension); + + return em; + } + } + + private string ChannelDestination(string channelName) + { + //Check.Require(channelName, "Channel name must be set."); + string[] parts = channelName.Split('/'); + //Check.Require(parts.Length == 3, "Channel must be sofia/<domain>/<user>"); + return parts[2]; + } + + public void OnSwitchEvents(EventBase theEvent) + { + if (theEvent is EventPresenceIn) + { + EventPresenceIn ep = (EventPresenceIn) theEvent; + //Channel-State: CS_RING + //Channel-Name: sofia/default/jonas%40192.168.1.102%3A5070 + //Unique-ID: 2f87ba27-2f71-d64d-8c64-9966ee894eac + //Call-Direction: inbound + //Answer-State: ringing + //Event-Name: PRESENCE_IN + CallState state = CallState.Unknown; + string destination = string.Empty; + if (ep.ChannelState.ChannelInfo.State == ChannelState.Ring) + { + if (IsInbound(ep)) + { + state = CallState.Alerting; + destination = ep.Caller.DestinationNumber; + } + else + { + state = CallState.Offering; + destination = ep.Caller.UserName; + } + } + else if (ep.ChannelState.ChannelInfo.State == ChannelState.Hangup) + { + state = CallState.Disconnected; + if (IsInbound(ep)) + destination = ep.Caller.DestinationNumber; + else + destination = ep.Caller.UserName; + } + if (state != CallState.Unknown) + TriggerCallState(ep.ChannelState.ChannelInfo.Address, ep.ChannelState.UniqueId, state, destination); + } + else if (theEvent is EventChannelAnswer) + { + EventChannelAnswer ea = (EventChannelAnswer) theEvent; + string destination; + if (IsInbound(ea)) + destination = ea.Caller.DestinationNumber; + else + destination = ea.Caller.UserName; + + TriggerCallState(ea.ChannelInfo.Address, ea.UniqueId, CallState.Connected, destination); + } + + else if (theEvent is EventChannelDestroy) + { + EventChannelDestroy e = (EventChannelDestroy) theEvent; + Debug.WriteLine("triggering CallState.Disconnected"); + TriggerCallState(e.ChannelInfo.Address, e.UniqueId, CallState.Disconnected, + e.Originator.DestinationNumber); + } + } + + /// <summary> + /// + /// </summary> + /// <param name="evt"></param> + /// <returns>true if it's inbound to pbx (not to user)</returns> + private bool IsInbound(EventBase evt) + { + return evt.Parameters["Call-Direction"] == "inbound"; + } + + + public void OnSwitchEvents2(EventBase theEvent) + { + ChannelEvent evt = theEvent as ChannelEvent; + EventChannelState channelState = theEvent as EventChannelState; + if (channelState != null) + Debug.WriteLine("ChannelState: " + channelState.ChannelInfo.State + " " + channelState.Caller.UserName + + " " + channelState.Caller.DestinationNumber); + else if (evt != null && evt.ChannelInfo != null) + Debug.WriteLine("ChannelEvent: " + evt.Name + " " + evt.ChannelInfo.Address); + if (evt != null) + { + // CHANNEL_ANSWER, No originator = new outgoing call. + // ChannelName = the one who makes the call + if (evt is EventChannelAnswer) + { + EventChannelAnswer e = (EventChannelAnswer) evt; + if (e.Originator.CallerIdName != string.Empty) + { + Debug.WriteLine("Skipping emoty ChannelAnswer"); + return; // We do only want empty ones. + } + + if (!IsExternalNumber(evt.ChannelInfo.Address)) + { + Debug.WriteLine("triggering CallState.Alerting"); + TriggerCallState(evt.ChannelInfo.Address, e.UniqueId, CallState.Alerting, + e.Caller.DestinationNumber); + } + } + + // CHANNEL_OUTGOING, Event for Alerting/Offering + // Originator = the one calling + // ChannelName = the one getting called. + else if (evt is EventChannelOutgoing) + { + EventChannelOutgoing e = (EventChannelOutgoing) evt; + if (!IsExternalNumber(evt.ChannelInfo.Address)) + { + Debug.WriteLine("triggering CallState.Offering"); + TriggerCallState(evt.ChannelInfo.Address, e.UniqueId, CallState.Offering, e.Originator.UserName); + } + if (!IsExternalNumber(e.Originator.UserName)) + { + Debug.WriteLine("triggering CallState.Alerting"); + TriggerCallState(e.Originator.UserName, e.Originator.UniqueId, CallState.Alerting, + e.ChannelInfo.Address); + } + } + + else if (evt is EventChannelBridge) + { + EventChannelBridge e = (EventChannelBridge) evt; + if (!IsExternalNumber(evt.ChannelInfo.Address)) + { + Debug.WriteLine("triggering CallState.Connected"); + TriggerCallState(evt.ChannelInfo.Address, e.UniqueId, CallState.Connected, + e.Caller.DestinationNumber); + } + + // Trigger destination + if (!IsExternalNumber(e.Caller.DestinationNumber) && e.Originator.ChannelName != string.Empty) + { + Debug.WriteLine("triggering CallState.Connected"); + TriggerCallState(ChannelDestination(e.Originator.ChannelName), e.UniqueId, CallState.Connected, + e.ChannelInfo.Address); + } + } + + else if (evt is EventChannelDestroy) + { + EventChannelDestroy e = (EventChannelDestroy) evt; + Debug.WriteLine("triggering CallState.Disconnected"); + TriggerCallState(evt.ChannelInfo.Address, e.UniqueId, CallState.Disconnected, + e.Originator.DestinationNumber); + } + } + } + + private bool IsExternalNumber(string number) + { + if (number == null || number == string.Empty) + return false; + return number[0] == '+'; + } + + private void TriggerCallState(string extensionOrUserName, string id, CallState state, string destination) + { + ExtensionMapper em = GetMapper(extensionOrUserName); + Debug.WriteLine(String.Format("{0} -> {1}, {2} id: {3}", extensionOrUserName, destination, state, id)); + Call call = em.setter.callState(id, state, destination); + if (ExtensionChanged != null) + ExtensionChanged(em.extension, call); + } + + private void OnBridgeCallId(CmdBase command, CommandReply reply) + { + GetVariableReply gvr = (GetVariableReply) reply; + if (!gvr.Success) + Debug.WriteLine("OnBridgeCallId " + reply.ErrCode); + + string otherChannelId = (string) command.ContextData; + SetVariable sv = new SetVariable(otherChannelId, "gate_callid", gvr.Value); + sv.OnReply += OnCallIdReply; + _eventMgr.Send(sv); + command.OnReply -= OnBridgeCallId; + } + + private void OnCallIdReply(CmdBase command, CommandReply reply) + { + if (!reply.Success) + Debug.WriteLine("OnCallIdReply " + reply.ErrCode); + command.OnReply -= OnCallIdReply; + } + + #region Nested type: ExtensionMapper + + private class ExtensionMapper + { + public Extension extension; + public ExtensionSetters setter; + } + + #endregion + } +} \ No newline at end of file Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/CallStateEvent.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/CallStateEvent.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,158 @@ +using System; + +namespace EventWatcher +{ + public enum CallState + { + Unknown, + + /// <summary> + /// The call has been created, but Connect has not been called yet. + /// A call can never transition into the idle state. + /// This is the initial state for both incoming and outgoing calls. + /// </summary> + Idle, + /// <summary> + /// Connect has been called, and the service provider is working on + /// making a connection. This state is valid only on outgoing calls. + /// This message is optional, because a service provider may have a + /// call transition directly to the connected state. + /// </summary> + InProgress, + /// <summary> + /// Call has been connected to the remote end and communication can take place. + /// </summary> + Connected, + /// <summary> + /// Call has been disconnected. There are several causes for disconnection. + /// See the table of valid call state transitions below. + /// </summary> + Disconnected, + /// <summary> + /// A new call has appeared, and is being offered to an application. + /// If the application has owner privileges on the call, it can either + /// call Answer or Disconnect while the call is in the offering state. + /// </summary> + Offering, + Alerting, + /// <summary> + /// The call is in the hold state. + /// </summary> + Held, + } + + public enum HangupCause + { + Success, + NormalClearing, + NoRouteTransitNet, + NoRouteDestination, + Busy, + Noanswer, + Rejected, + NumberChanged, + Congestion, + } + /// <summary> + /// Subclass for all call events. + /// The events are sent as commands through the + /// Command Dispatcher. + /// </summary> + [Serializable] + public class CallStateEvent + { + private string _callId; + private string _pbxId; + private string _destination; + private string _from; + private CallState _state = CallState.Idle; + private bool _isIncoming = true; + private bool _isInternal; + private HangupCause _hangupCause; + + public CallStateEvent() + { + } + + /// <summary> + /// + /// </summary> + /// <param name="callId">Call identification string</param> + /// <param name="pbxId">Id used internally in the pbx to identify the call.</param> + /// <param name="from">Sip-Address to the one that made the call</param> + /// <param name="destination">Sip-address to where the call was made.</param> + public CallStateEvent(string callId, string pbxId, string from, string destination) + { + _callId = callId; + _from = from; + PbxId = pbxId; + _destination = destination; + } + + /// <summary> + /// Call identification string. + /// </summary> + public string CallId + { + get { return _callId; } + set { _callId = value; } + } + + /// <summary> + /// User that made the call. + /// </summary> + public string From + { + get { return _from; } + set { _from = value; } + } + + /// <summary> + /// To whom the call was made. + /// </summary> + public string Destination + { + get { return _destination; } + set { _destination = value; } + } + + /// <summary> + /// Current CallState. + /// </summary> + public CallState State + { + get { return _state; } + set { _state = value; } + } + + /// <summary> + /// This is an incoming call. + /// </summary> + public bool Incoming + { + get { return _isIncoming; } + set { _isIncoming = value; } + } + + /// <summary> + /// This is an internal call in the pbx. + /// </summary> + public bool Internal + { + get { return _isInternal; } + set { _isInternal = value; } + } + + public HangupCause HangupCause + { + get { return _hangupCause; } + set { _hangupCause = value; } + } + + internal string PbxId + { + get { return _pbxId; } + set { _pbxId = value; } + } + } +} \ No newline at end of file Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/EventWatcher.csproj ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/EventWatcher.csproj Thu May 1 14:27:39 2008 @@ -0,0 +1,96 @@ +<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <ProductVersion>8.0.50727</ProductVersion> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{E65ABA5F-A578-4E3C-989D-0FE4E459C03D}</ProjectGuid> + <OutputType>WinExe</OutputType> + <AppDesignerFolder>Properties</AppDesignerFolder> + <RootNamespace>EventWatcher</RootNamespace> + <AssemblyName>EventWatcher</AssemblyName> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> + <DebugSymbols>true</DebugSymbols> + <DebugType>full</DebugType> + <Optimize>false</Optimize> + <OutputPath>bin\Debug\</OutputPath> + <DefineConstants>DEBUG;TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> + <DebugType>pdbonly</DebugType> + <Optimize>true</Optimize> + <OutputPath>bin\Release\</OutputPath> + <DefineConstants>TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <ItemGroup> + <Reference Include="System" /> + <Reference Include="System.Data" /> + <Reference Include="System.Deployment" /> + <Reference Include="System.Design" /> + <Reference Include="System.Drawing" /> + <Reference Include="System.Windows.Forms" /> + <Reference Include="System.Xml" /> + </ItemGroup> + <ItemGroup> + <Compile Include="Call.cs" /> + <Compile Include="CallManager.cs" /> + <Compile Include="CallStateEvent.cs" /> + <Compile Include="Extension.cs" /> + <Compile Include="Form1.cs"> + <SubType>Form</SubType> + </Compile> + <Compile Include="Form1.Designer.cs"> + <DependentUpon>Form1.cs</DependentUpon> + </Compile> + <Compile Include="LabelTextBox.cs"> + <SubType>Component</SubType> + </Compile> + <Compile Include="Program.cs" /> + <Compile Include="Properties\AssemblyInfo.cs" /> + <EmbeddedResource Include="Form1.resx"> + <SubType>Designer</SubType> + <DependentUpon>Form1.cs</DependentUpon> + </EmbeddedResource> + <EmbeddedResource Include="Properties\Resources.resx"> + <Generator>ResXFileCodeGenerator</Generator> + <LastGenOutput>Resources.Designer.cs</LastGenOutput> + <SubType>Designer</SubType> + </EmbeddedResource> + <Compile Include="Properties\Resources.Designer.cs"> + <AutoGen>True</AutoGen> + <DependentUpon>Resources.resx</DependentUpon> + <DesignTime>True</DesignTime> + </Compile> + <None Include="Properties\Settings.settings"> + <Generator>SettingsSingleFileGenerator</Generator> + <LastGenOutput>Settings.Designer.cs</LastGenOutput> + </None> + <Compile Include="Properties\Settings.Designer.cs"> + <AutoGen>True</AutoGen> + <DependentUpon>Settings.settings</DependentUpon> + <DesignTimeSharedInput>True</DesignTimeSharedInput> + </Compile> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\FreeSwitchEventSocket\FreeSwitch.EventSocket.csproj"> + <Project>{3F8895F6-F710-4323-B96A-4EFB6BC97E08}</Project> + <Name>FreeSwitch.EventSocket</Name> + </ProjectReference> + </ItemGroup> + <ItemGroup> + <Content Include="ReadMePlease.txt" /> + </ItemGroup> + <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> + <!-- To modify your build process, add your task inside one of the targets below and uncomment it. + Other similar extension points exist, see Microsoft.Common.targets. + <Target Name="BeforeBuild"> + </Target> + <Target Name="AfterBuild"> + </Target> + --> +</Project> \ No newline at end of file Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/Extension.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/Extension.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,162 @@ +using System; +using System.Collections.Generic; + +namespace EventWatcher +{ + public delegate void ExtensionHandler(Extension extension); + public delegate void CallHandler(Extension extension, Call call); + public delegate Call CallStateSetter(string id, CallState state, string destination); + + /// <summary> + /// Used to set states for the extension. + /// We are using this method since we do not want anything else + /// but the CallMgr to be able to set stuff. + /// </summary> + /// <param name="forwardAll">null if it has changed, else the new forward destination</param> + /// <param name="forwardBusy">null if it has changed, else the new forward destination</param> + /// <param name="forwardNoAnswer">null if it has changed, else the new forward destination</param> + public delegate void ForwardSetter(string forwardAll, string forwardBusy, string forwardNoAnswer); + + public class ExtensionSetters + { + public CallStateSetter callState; + public ForwardSetter forwardSetter; + } + + /// <summary> + /// Class representing an extension. + /// </summary> + [Serializable] + public class Extension + { + private readonly string _address = string.Empty; + private readonly IDictionary<string, Call> _calls = new Dictionary<string, Call>(); + private readonly string _destination = string.Empty; + private string _forwardAll = string.Empty; + private string _forwardBusy = string.Empty; + private string _forwardNoAnswer = string.Empty; + private ExtensionSetters _handler; + + public Extension(string address) + { + _address = address; + } + + public Extension(string address, ExtensionSetters setters) + { + _address = address; + Handler = setters; + } + + public bool IsBusy + { + get + { + foreach (KeyValuePair<string, Call> pair in _calls) + { + if (pair.Value.State != CallState.Disconnected + && pair.Value.State != CallState.Held) + return false; + } + return true; + } + } + + /// <summary> + /// Determines if this extension is forwarded in any way + /// </summary> + public bool IsForwarded + { + get + { + return _forwardNoAnswer != string.Empty + || _forwardBusy != string.Empty + || _forwardAll != string.Empty; + } + } + + public string ForwardAll + { + get { return _forwardAll; } + } + + public string ForwardBusy + { + get { return _forwardBusy; } + } + + public string ForwardNoAnswer + { + get { return _forwardNoAnswer; } + } + + public string Destination + { + get { return _destination; } + } + + public string Address + { + get { return _address; } + } + + public ExtensionSetters Handler + { + get { return _handler; } + set + { + if (value != null) + //Check.Require(_handler == null, "Handler can only be assigned one time."); + + _handler = value; + if (value != null) + { + value.callState = SetCallState; + value.forwardSetter = SetForward; + } + } + } + + private Call SetCallState(string id, CallState state, string destination) + { + bool wasBusy = IsBusy; + + Call call; + if (!_calls.ContainsKey(id)) + call = new Call(id); + else + call = _calls[id]; + + call.SetCallState(state); + call.SetDestination(destination); + + if (CallChanged != null) + CallChanged(this, call); + + if (state == CallState.Disconnected) + _calls.Remove(id); + + + if (wasBusy != IsBusy && BusyStateChanged != null) + BusyStateChanged(this); + + return call; + } + + private void SetForward(string forwardAll, string forwardBusy, string forwardNoAnswer) + { + if (forwardAll != null) + _forwardAll = forwardAll; + if (forwardBusy != null) + _forwardBusy = forwardBusy; + if (forwardNoAnswer != null) + _forwardNoAnswer = forwardNoAnswer; + if (ForwardChanged != null) + ForwardChanged(this); + } + + public event ExtensionHandler BusyStateChanged; + public event CallHandler CallChanged; + public event ExtensionHandler ForwardChanged; + } +} \ No newline at end of file Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/Form1.Designer.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/Form1.Designer.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,212 @@ +namespace EventWatcher +{ + partial class Form1 + { + /// <summary> + /// Required designer variable. + /// </summary> + private System.ComponentModel.IContainer components = null; + + /// <summary> + /// Clean up any resources being used. + /// </summary> + /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// <summary> + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// </summary> + private void InitializeComponent() + { + this.panel1 = new System.Windows.Forms.Panel(); + this.log = new System.Windows.Forms.TextBox(); + this.info = new System.Windows.Forms.RichTextBox(); + this.lv = new System.Windows.Forms.ListView(); + this.colAddress = new System.Windows.Forms.ColumnHeader(); + this.colId = new System.Windows.Forms.ColumnHeader(); + this.colPbxId = new System.Windows.Forms.ColumnHeader(); + this.colState = new System.Windows.Forms.ColumnHeader(); + this.colCaller = new System.Windows.Forms.ColumnHeader(); + this.colOriginator = new System.Windows.Forms.ColumnHeader(); + this.colOrginatee = new System.Windows.Forms.ColumnHeader(); + this.lvAll = new System.Windows.Forms.ListView(); + this.from = new System.Windows.Forms.ColumnHeader(); + this.To = new System.Windows.Forms.ColumnHeader(); + this.ChannelId = new System.Windows.Forms.ColumnHeader(); + this.SessionId = new System.Windows.Forms.ColumnHeader(); + this.State = new System.Windows.Forms.ColumnHeader(); + this.panel1.SuspendLayout(); + this.SuspendLayout(); + // + // panel1 + // + this.panel1.Controls.Add(this.log); + this.panel1.Controls.Add(this.info); + this.panel1.Dock = System.Windows.Forms.DockStyle.Right; + this.panel1.Location = new System.Drawing.Point(627, 0); + this.panel1.Name = "panel1"; + this.panel1.Size = new System.Drawing.Size(293, 546); + this.panel1.TabIndex = 11; + // + // log + // + this.log.Dock = System.Windows.Forms.DockStyle.Bottom; + this.log.Location = new System.Drawing.Point(0, 526); + this.log.Name = "log"; + this.log.Size = new System.Drawing.Size(293, 20); + this.log.TabIndex = 11; + // + // info + // + this.info.Dock = System.Windows.Forms.DockStyle.Fill; + this.info.Location = new System.Drawing.Point(0, 0); + this.info.Name = "info"; + this.info.Size = new System.Drawing.Size(293, 546); + this.info.TabIndex = 10; + this.info.Text = ""; + // + // lv + // + this.lv.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { + this.colAddress, + this.colId, + this.colPbxId, + this.colState, + this.colCaller, + this.colOriginator, + this.colOrginatee}); + this.lv.Dock = System.Windows.Forms.DockStyle.Top; + this.lv.Location = new System.Drawing.Point(0, 0); + this.lv.Name = "lv"; + this.lv.Size = new System.Drawing.Size(627, 152); + this.lv.TabIndex = 12; + this.lv.UseCompatibleStateImageBehavior = false; + this.lv.View = System.Windows.Forms.View.Details; + // + // colAddress + // + this.colAddress.Text = "Anknytning"; + this.colAddress.Width = 65; + // + // colId + // + this.colId.Text = "Id"; + this.colId.Width = 26; + // + // colPbxId + // + this.colPbxId.Text = "PbxId"; + this.colPbxId.Width = 230; + // + // colState + // + this.colState.Text = "Status"; + this.colState.Width = 50; + // + // colCaller + // + this.colCaller.Text = "Caller"; + this.colCaller.Width = 62; + // + // colOriginator + // + this.colOriginator.Text = "Originator"; + this.colOriginator.Width = 72; + // + // colOrginatee + // + this.colOrginatee.Text = "Orginatee"; + this.colOrginatee.Width = 116; + // + // lvAll + // + this.lvAll.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { + this.from, + this.To, + this.ChannelId, + this.SessionId, + this.State}); + this.lvAll.Dock = System.Windows.Forms.DockStyle.Fill; + this.lvAll.Location = new System.Drawing.Point(0, 152); + this.lvAll.Name = "lvAll"; + this.lvAll.Size = new System.Drawing.Size(627, 394); + this.lvAll.TabIndex = 13; + this.lvAll.UseCompatibleStateImageBehavior = false; + this.lvAll.View = System.Windows.Forms.View.Details; + this.lvAll.SelectedIndexChanged += new System.EventHandler(this.lvAll_SelectedIndexChanged); + this.lvAll.ItemSelectionChanged += new System.Windows.Forms.ListViewItemSelectionChangedEventHandler(this.lvAll_ItemSelectionChanged); + // + // from + // + this.from.Text = "Fr�n"; + // + // To + // + this.To.Text = "Till"; + this.To.Width = 84; + // + // ChannelId + // + this.ChannelId.Text = "ChannelId"; + this.ChannelId.Width = 282; + // + // SessionId + // + this.SessionId.Text = "SessionId"; + this.SessionId.Width = 318; + // + // State + // + this.State.Text = "State"; + this.State.Width = 99; + // + // Form1 + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(920, 546); + this.Controls.Add(this.lvAll); + this.Controls.Add(this.lv); + this.Controls.Add(this.panel1); + this.Name = "Form1"; + this.Text = "Form1"; + this.Load += new System.EventHandler(this.Form1_Load); + this.panel1.ResumeLayout(false); + this.panel1.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.Panel panel1; + private System.Windows.Forms.TextBox log; + private System.Windows.Forms.RichTextBox info; + private System.Windows.Forms.ListView lv; + private System.Windows.Forms.ColumnHeader colAddress; + private System.Windows.Forms.ColumnHeader colId; + private System.Windows.Forms.ColumnHeader colPbxId; + private System.Windows.Forms.ColumnHeader colState; + private System.Windows.Forms.ColumnHeader colCaller; + private System.Windows.Forms.ColumnHeader colOriginator; + private System.Windows.Forms.ColumnHeader colOrginatee; + private System.Windows.Forms.ListView lvAll; + private System.Windows.Forms.ColumnHeader from; + private System.Windows.Forms.ColumnHeader To; + private System.Windows.Forms.ColumnHeader ChannelId; + private System.Windows.Forms.ColumnHeader SessionId; + private System.Windows.Forms.ColumnHeader State; + + } +} + Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/Form1.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/Form1.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,235 @@ +using System; +using System.Diagnostics; +using System.Drawing; +using System.Reflection; +using System.Windows.Forms; +using FreeSwitch.EventSocket; +using FreeSwitch.EventSocket.Commands; +using FreeSwitch.EventSocket.General; + +namespace EventWatcher +{ + public partial class Form1 : Form + { + private EventManager _eventMgr; + private CallManager _callMgr; + + public Form1() + { + InitializeComponent(); + _eventMgr = new EventManager(); + _callMgr = new CallManager(_eventMgr); + _callMgr.OnCallState += OnCallState; + _callMgr.ExtensionAdded += OnExtensionAdded; + _callMgr.ExtensionChanged += OnExtensionChanged; + + + } + + private void OnExtensionAdded(Extension extension) + { + //throw new NotImplementedException(); + } + + private void OnExtensionChanged(Extension extension, Call call) + { + if (lv.InvokeRequired) + BeginInvoke((MethodInvoker)delegate { OnExtensionChangedX(extension, call); }); + else + OnExtensionChangedX(extension, call); + } + + private void OnExtensionChangedX(Extension extension, Call call) + { + ListViewItem item = null; + foreach (ListViewItem item2 in lv.Items) + { + if (String.Compare(item2.Name, extension.Address, true) == 0) + { + item = item2; + break; + } + } + if (item == null)//(!lv.Items.ContainsKey(extension.Address)) + { + item = lv.Items.Add(extension.Address, extension.Address, 0); + item.Tag = extension; + item.SubItems.Add(call.Id); + item.SubItems.Add(call.State.ToString()); + item.SubItems.Add(call.PreviousState.ToString()); + item.SubItems.Add(""); + item.SubItems.Add(extension.Destination); + } + else + { + item.SubItems[2].Text = call.State.ToString(); + item.SubItems[3].Text = call.PreviousState.ToString(); + } + } + + private void OnExtensionCallState(Extension e) + { + + } + private void OnCallState(CallManager mgr, CallStateEvent cs) + { + if (lv.InvokeRequired) + BeginInvoke((MethodInvoker)delegate { OnCallStateX(mgr, cs); }); + else + OnCallStateX(mgr, cs); + } + + private void OnCallStateX(CallManager mgr, CallStateEvent cs) + { + ListViewItem item; + if (!lv.Items.ContainsKey(cs.PbxId)) + { + item = lv.Items.Add(cs.PbxId, cs.From, 0); + item.Tag = cs; + item.SubItems.Add(cs.CallId); + item.SubItems.Add(cs.PbxId); + item.SubItems.Add(cs.State.ToString()); + item.SubItems.Add(cs.From); + item.SubItems.Add(cs.Destination); + } + else + item = lv.Items[cs.PbxId]; + + item.SubItems[1].Text = cs.CallId; + item.SubItems[3].Text = cs.State.ToString(); + item.SubItems[4].Text = cs.Destination; + + if (cs.State == CallState.Disconnected) + lv.Items.RemoveByKey(cs.PbxId); + } + + private void Form1_Load(object sender, EventArgs e) + { + _eventMgr.Password = "ClueCon"; + _eventMgr.Start("localhost"); + _eventMgr.Subscribe(new Events(Event.All)); + _eventMgr.EventReceived += OnPreSwitchEvent; + } + + private void OnPreSwitchEvent(EventBase theEvent) + { + _callMgr.OnSwitchEvents(theEvent); + if (lvAll.InvokeRequired) + BeginInvoke((MethodInvoker)delegate { OnSwitchEvent(theEvent); }); + else + OnSwitchEvent(theEvent); + } + + + private string DisplayProperties(object o) + { + return DisplayProperties(o, 0); + } + + private string DisplayProperties(object o, int spaces) + { + PropertyInfo[] pis = o.GetType().GetProperties(); + string info = string.Empty; + foreach (PropertyInfo pi in pis) + { + if (pi.PropertyType == typeof (ChannelInfo) || pi.PropertyType == typeof (PartyInfo)) + { + info += pi.Name.PadLeft(spaces + pi.Name.Length) + "\r\n"; + info += DisplayProperties(pi.GetValue(o, null), spaces + 2); + } + else + info += pi.Name.PadLeft(spaces + pi.Name.Length) + ": " + pi.GetValue(o, null) + "\r\n"; + } + return info; + } + + private void OnSwitchEvent(EventBase theEvent) + { + EventChannelState e = theEvent as EventChannelState; + if (e != null) + { + + EventChannelState channelEvent = theEvent as EventChannelState; + if (channelEvent == null) + return; + + //OnSwitchEvents(theEvent); + + ListViewItem item; + item = lvAll.Items.Add(channelEvent.ChannelInfo.Address); + item.Tag = channelEvent; + item.SubItems.Add(channelEvent.Originator.UserName); + item.SubItems.Add(channelEvent.UniqueId); + item.SubItems.Add(channelEvent.Caller.UniqueId); + if (channelEvent.Name == "CHANNEL_STATE") + item.SubItems.Add(e.ChannelInfo.State.ToString()); + else + item.SubItems.Add(e.Name); + + if (e.GetType() == typeof(EventCodec) || theEvent.GetType() == typeof(EventChannelExecute) + || e.Originator.DestinationNumber == string.Empty) + { + item.ForeColor = Color.Gray; + } + + } + log.Text = theEvent.Name; + } + + private void AddEvent(ListBox box, ChannelEvent e) + { + box.Items.Insert(0, new Wrapper(e)); + } + + private void lvAll_SelectedIndexChanged(object sender, EventArgs e) + { + /* + if (lvAll.SelectedItems.Count == 0) + return; + ListViewItem itm = lvAll.SelectedItems[0]; + MessageBox.Show(DisplayProperties(itm.Tag)); + * */ + } + + private void lvAll_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e) + { + if (lvAll.SelectedItems.Count == 0) + return; + ListViewItem itm = lvAll.SelectedItems[0]; + info.Text = DisplayProperties(itm.Tag); + } + + #region Nested type: SwitchEventHandler + + private delegate void SwitchEventHandler(EventBase theEvent); + + #endregion + + #region Nested type: Wrapper + + private class Wrapper + { + public ChannelEvent e; + + public Wrapper(ChannelEvent e) + { + this.e = e; + } + + public override string ToString() + { + return "[" + e.Name + "] " + e.ChannelInfo.State; + } + } + + #endregion + + private void btnOriginate_Click(object sender, EventArgs e) + { + //Originate org = new Originate(); + //org.Caller = new SofiaSipAddress("gauffin.com"); + //from_id.Text + } + + } +} \ No newline at end of file Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/Form1.resx ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/Form1.resx Thu May 1 14:27:39 2008 @@ -0,0 +1,120 @@ +<?xml version="1.0" encoding="utf-8"?> +<root> + <!-- + Microsoft ResX Schema + + Version 2.0 + + The primary goals of this format is to allow a simple XML format + that is mostly human readable. The generation and parsing of the + various data types are done through the TypeConverter classes + associated with the data types. + + Example: + + ... ado.net/XML headers & schema ... + <resheader name="resmimetype">text/microsoft-resx</resheader> + <resheader name="version">2.0</resheader> + <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> + <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> + <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> + <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> + <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> + <value>[base64 mime encoded serialized .NET Framework object]</value> + </data> + <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> + <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> + <comment>This is a comment</comment> + </data> + + There are any number of "resheader" rows that contain simple + name/value pairs. + + Each data row contains a name, and value. The row also contains a + type or mimetype. Type corresponds to a .NET class that support + text/value conversion through the TypeConverter architecture. + Classes that don't support this are serialized and stored with the + mimetype set. + + The mimetype is used for serialized objects, and tells the + ResXResourceReader how to depersist the object. This is currently not + extensible. For a given mimetype the value must be set accordingly: + + Note - application/x-microsoft.net.object.binary.base64 is the format + that the ResXResourceWriter will generate, however the reader can + read any of the formats listed below. + + mimetype: application/x-microsoft.net.object.binary.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.soap.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Soap.SoapFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.bytearray.base64 + value : The object must be serialized into a byte array + : using a System.ComponentModel.TypeConverter + : and then encoded with base64 encoding. + --> + <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> + <xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> + <xsd:element name="root" msdata:IsDataSet="true"> + <xsd:complexType> + <xsd:choice maxOccurs="unbounded"> + <xsd:element name="metadata"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" /> + </xsd:sequence> + <xsd:attribute name="name" use="required" type="xsd:string" /> + <xsd:attribute name="type" type="xsd:string" /> + <xsd:attribute name="mimetype" type="xsd:string" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="assembly"> + <xsd:complexType> + <xsd:attribute name="alias" type="xsd:string" /> + <xsd:attribute name="name" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="data"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> + <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> + <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="resheader"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" /> + </xsd:complexType> + </xsd:element> + </xsd:choice> + </xsd:complexType> + </xsd:element> + </xsd:schema> + <resheader name="resmimetype"> + <value>text/microsoft-resx</value> + </resheader> + <resheader name="version"> + <value>2.0</value> + </resheader> + <resheader name="reader"> + <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <resheader name="writer"> + <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> +</root> \ No newline at end of file Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/LabelTextBox.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/LabelTextBox.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Text; +using System.Windows.Forms; + +namespace EventWatcher +{ + class LabelTextBox : TextBox + { + private string _label; + + public string Label + { + get { return _label; } + set + { + _label = value; + if (Text == string.Empty) + SetLabel(); + } + } + + public void test() + { + TextBox x = new TextBox(); + x.KeyDown += tb_KeyDown; + x.TextChanged += tb_TextChanged; + } + + private void tb_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e) + { + if (ForeColor == Color.FromKnownColor(KnownColor.InactiveCaptionText)) + RemoveLabel(); + } + + private void tb_TextChanged(object sender, EventArgs e) + { + if (Text == string.Empty) + SetLabel(); + else if (Text != _label && Text != string.Empty) + RemoveLabel(); + } + + private void RemoveLabel() + { + ForeColor = Color.FromKnownColor(KnownColor.WindowText); + Text = string.Empty; + + } + private void SetLabel() + { + ForeColor = Color.FromKnownColor(KnownColor.InactiveCaptionText); + Text = _label; + + } + + } +} Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/Program.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/Program.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Windows.Forms; + +namespace EventWatcher +{ + static class Program + { + /// <summary> + /// The main entry point for the application. + /// </summary> + [STAThread] + static void Main() + { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + Application.Run(new Form1()); + } + } +} \ No newline at end of file Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/Properties/AssemblyInfo.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/Properties/AssemblyInfo.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,33 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("EventWatcher")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("EventWatcher")] +[assembly: AssemblyCopyright("Copyright © 2007")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("e6a71f21-6833-455f-a398-a0d6a54c1359")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/Properties/Resources.Designer.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/Properties/Resources.Designer.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// <auto-generated> +// This code was generated by a tool. +// Runtime Version:2.0.50727.312 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// </auto-generated> +//------------------------------------------------------------------------------ + +namespace EventWatcher.Properties { + using System; + + + /// <summary> + /// A strongly-typed resource class, for looking up localized strings, etc. + /// </summary> + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// <summary> + /// Returns the cached ResourceManager instance used by this class. + /// </summary> + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("EventWatcher.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// <summary> + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// </summary> + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/Properties/Resources.resx ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/Properties/Resources.resx Thu May 1 14:27:39 2008 @@ -0,0 +1,117 @@ +<?xml version="1.0" encoding="utf-8"?> +<root> + <!-- + Microsoft ResX Schema + + Version 2.0 + + The primary goals of this format is to allow a simple XML format + that is mostly human readable. The generation and parsing of the + various data types are done through the TypeConverter classes + associated with the data types. + + Example: + + ... ado.net/XML headers & schema ... + <resheader name="resmimetype">text/microsoft-resx</resheader> + <resheader name="version">2.0</resheader> + <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> + <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> + <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> + <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> + <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> + <value>[base64 mime encoded serialized .NET Framework object]</value> + </data> + <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> + <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> + <comment>This is a comment</comment> + </data> + + There are any number of "resheader" rows that contain simple + name/value pairs. + + Each data row contains a name, and value. The row also contains a + type or mimetype. Type corresponds to a .NET class that support + text/value conversion through the TypeConverter architecture. + Classes that don't support this are serialized and stored with the + mimetype set. + + The mimetype is used for serialized objects, and tells the + ResXResourceReader how to depersist the object. This is currently not + extensible. For a given mimetype the value must be set accordingly: + + Note - application/x-microsoft.net.object.binary.base64 is the format + that the ResXResourceWriter will generate, however the reader can + read any of the formats listed below. + + mimetype: application/x-microsoft.net.object.binary.base64 + value : The object must be serialized with + : System.Serialization.Formatters.Binary.BinaryFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.soap.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Soap.SoapFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.bytearray.base64 + value : The object must be serialized into a byte array + : using a System.ComponentModel.TypeConverter + : and then encoded with base64 encoding. + --> + <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> + <xsd:element name="root" msdata:IsDataSet="true"> + <xsd:complexType> + <xsd:choice maxOccurs="unbounded"> + <xsd:element name="metadata"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" /> + <xsd:attribute name="type" type="xsd:string" /> + <xsd:attribute name="mimetype" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="assembly"> + <xsd:complexType> + <xsd:attribute name="alias" type="xsd:string" /> + <xsd:attribute name="name" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="data"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" /> + <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> + <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="resheader"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" /> + </xsd:complexType> + </xsd:element> + </xsd:choice> + </xsd:complexType> + </xsd:element> + </xsd:schema> + <resheader name="resmimetype"> + <value>text/microsoft-resx</value> + </resheader> + <resheader name="version"> + <value>2.0</value> + </resheader> + <resheader name="reader"> + <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <resheader name="writer"> + <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> +</root> \ No newline at end of file Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/Properties/Settings.Designer.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/Properties/Settings.Designer.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,30 @@ +//------------------------------------------------------------------------------ +// <auto-generated> +// This code was generated by a tool. +// Runtime Version:2.0.50727.312 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// </auto-generated> +//------------------------------------------------------------------------------ + +namespace EventWatcher.Properties +{ + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "8.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase + { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default + { + get + { + return defaultInstance; + } + } + } +} Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/Properties/Settings.settings ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/Properties/Settings.settings Thu May 1 14:27:39 2008 @@ -0,0 +1,7 @@ +<?xml version='1.0' encoding='utf-8'?> +<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)"> + <Profiles> + <Profile Name="(Default)" /> + </Profiles> + <Settings /> +</SettingsFile> Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/ReadMePlease.txt ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/ReadMePlease.txt Thu May 1 14:27:39 2008 @@ -0,0 +1,3 @@ +This is just a test project that I used to develop the event socket lib. + +It could in the future be an application that keep track on all channels and their current state. \ No newline at end of file Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitch.EventSocket.Test/EventSocket.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitch.EventSocket.Test/EventSocket.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Text; +using FreeSwitch.EventSocket; +using FreeSwitch.EventSocket.Commands; +using FreeSwitch.EventSocket.General; + +namespace FreeSwitch.EventSocket.Test +{ + class EventSocket + { + private FreeSwitch.EventSocket.EventSocket m_es = new FreeSwitch.EventSocket.EventSocket(); + + public void Setup() + { + m_es.Connect("192.168.1.102"); + m_es.Subscribe(new Events(Event.All)); + //m_es.SendApi(new Originate(new SofiaSipAddress("gauffin.com", "arne"), new Address("8888"))); + System.Threading.Thread.Sleep(500000); + } + } +} Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitch.EventSocket.Test/FreeSwitch.EventSocket.Test.csproj ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitch.EventSocket.Test/FreeSwitch.EventSocket.Test.csproj Thu May 1 14:27:39 2008 @@ -0,0 +1,55 @@ +<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <ProductVersion>8.0.50727</ProductVersion> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{3679225D-79A3-4B6C-BCA1-E2DC265E423A}</ProjectGuid> + <OutputType>Exe</OutputType> + <AppDesignerFolder>Properties</AppDesignerFolder> + <RootNamespace>FreeSwitch.EventSocket.Test</RootNamespace> + <AssemblyName>FreeSwitch.EventSocket.Test</AssemblyName> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> + <DebugSymbols>true</DebugSymbols> + <DebugType>full</DebugType> + <Optimize>false</Optimize> + <OutputPath>bin\Debug\</OutputPath> + <DefineConstants>DEBUG;TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> + <DebugType>pdbonly</DebugType> + <Optimize>true</Optimize> + <OutputPath>bin\Release\</OutputPath> + <DefineConstants>TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <ItemGroup> + <Reference Include="System" /> + <Reference Include="System.Data" /> + <Reference Include="System.Xml" /> + </ItemGroup> + <ItemGroup> + <Compile Include="EventSocket.cs" /> + <Compile Include="ParserTest.cs" /> + <Compile Include="Program.cs" /> + <Compile Include="Properties\AssemblyInfo.cs" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\FreeSwitchEventSocket\FreeSwitch.EventSocket.csproj"> + <Project>{3F8895F6-F710-4323-B96A-4EFB6BC97E08}</Project> + <Name>FreeSwitch.EventSocket</Name> + </ProjectReference> + </ItemGroup> + <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> + <!-- To modify your build process, add your task inside one of the targets below and uncomment it. + Other similar extension points exist, see Microsoft.Common.targets. + <Target Name="BeforeBuild"> + </Target> + <Target Name="AfterBuild"> + </Target> + --> +</Project> \ No newline at end of file Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitch.EventSocket.Test/ParserTest.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitch.EventSocket.Test/ParserTest.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,10 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace FreeSwitch.EventSocket.Test +{ + class ParserTest + { + } +} Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitch.EventSocket.Test/Program.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitch.EventSocket.Test/Program.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Reflection; +using System.Text; + +namespace FreeSwitch.EventSocket.Test +{ + class Program + { + static void Main(string[] args) + { + EventManager mgr = new EventManager(); + mgr.Subscribe(Events.GetChannelEvents()); + mgr.Start("localhost"); + Console.ReadLine(); + + string buffer = File.ReadAllText("..\\..\\..\\watcherRaw.log"); + int bufLen = buffer.Length; + + EventParser ep = new EventParser(buffer); + //int cnt = 0; + EventSocket es = new EventSocket(); + es.Setup(); + } + } +} Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitch.EventSocket.Test/Properties/AssemblyInfo.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitch.EventSocket.Test/Properties/AssemblyInfo.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,33 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("FreeSwitch.EventSocket.Test")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("FreeSwitch.EventSocket.Test")] +[assembly: AssemblyCopyright("Copyright © 2007")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("b496f9be-f1be-457d-b8c8-fae97c43df8e")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitch.EventSocket.sln ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitch.EventSocket.sln Thu May 1 14:27:39 2008 @@ -0,0 +1,38 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FreeSwitch.EventSocket", "FreeSwitchEventSocket\FreeSwitch.EventSocket.csproj", "{3F8895F6-F710-4323-B96A-4EFB6BC97E08}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FreeSwitch.EventSocket.Test", "FreeSwitch.EventSocket.Test\FreeSwitch.EventSocket.Test.csproj", "{3679225D-79A3-4B6C-BCA1-E2DC265E423A}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EventWatcher", "EventWatcher\EventWatcher.csproj", "{E65ABA5F-A578-4E3C-989D-0FE4E459C03D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IvrSocket", "IvrSocket\IvrSocket.csproj", "{22F26D13-0A0E-4345-9FEC-CE13FC8F37FD}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {3F8895F6-F710-4323-B96A-4EFB6BC97E08}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3F8895F6-F710-4323-B96A-4EFB6BC97E08}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3F8895F6-F710-4323-B96A-4EFB6BC97E08}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3F8895F6-F710-4323-B96A-4EFB6BC97E08}.Release|Any CPU.Build.0 = Release|Any CPU + {3679225D-79A3-4B6C-BCA1-E2DC265E423A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3679225D-79A3-4B6C-BCA1-E2DC265E423A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3679225D-79A3-4B6C-BCA1-E2DC265E423A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3679225D-79A3-4B6C-BCA1-E2DC265E423A}.Release|Any CPU.Build.0 = Release|Any CPU + {E65ABA5F-A578-4E3C-989D-0FE4E459C03D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E65ABA5F-A578-4E3C-989D-0FE4E459C03D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E65ABA5F-A578-4E3C-989D-0FE4E459C03D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E65ABA5F-A578-4E3C-989D-0FE4E459C03D}.Release|Any CPU.Build.0 = Release|Any CPU + {22F26D13-0A0E-4345-9FEC-CE13FC8F37FD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {22F26D13-0A0E-4345-9FEC-CE13FC8F37FD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {22F26D13-0A0E-4345-9FEC-CE13FC8F37FD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {22F26D13-0A0E-4345-9FEC-CE13FC8F37FD}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/ChannelEvent.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/ChannelEvent.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,66 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace FreeSwitch.EventSocket +{ + public class ChannelEvent : EventBase + { + private ChannelInfo _channelInfo; + private string _uniqueId = string.Empty; + private string _answerState; + private string _callDirection; + + public override bool IsChannelEvent + { + get { return true; } + } + + /// <summary> + /// Information about the used channel and it's state. + /// </summary> + public ChannelInfo ChannelInfo + { + get { return _channelInfo; } + set { _channelInfo = value; } + } + + public string UniqueId + { + get { return _uniqueId; } + set { _uniqueId = value; } + } + + public string AnswerState + { + get { return _answerState; } + set { _answerState = value; } + } + + public string CallDirection + { + get { return _callDirection; } + set { _callDirection = value; } + } + + public override bool ParseCommand(string name, string value) + { + if (name == "unique-id") + _uniqueId = value; + else if (name == "answer-state") + _answerState = value; + else if (name == "call-direction") + _callDirection = value; + else if (name.Length > 8 && name.Substring(0, 8) == "channel-") + { + if (_channelInfo == null) + _channelInfo = new ChannelInfo(); + return _channelInfo.Parse(name, value); + } + else + return base.ParseCommand(name, value); + + return true; + } + } +} Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelAnswer.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelAnswer.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,6 @@ +namespace FreeSwitch.EventSocket +{ + public class EventChannelAnswer : EventChannelState + { + } +} Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelApplication.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelApplication.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,10 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace FreeSwitch.EventSocket +{ + public class EventChannelApplication : EventChannelState + { + } +} Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelBridge.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelBridge.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,10 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace FreeSwitch.EventSocket +{ + public class EventChannelBridge : EventChannelState + { + } +} Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelCreate.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelCreate.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,6 @@ +namespace FreeSwitch.EventSocket +{ + public class EventChannelCreate : ChannelEvent + { + } +} Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelDestroy.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelDestroy.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,10 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace FreeSwitch.EventSocket +{ + public class EventChannelDestroy : EventChannelState + { + } +} Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelExecute.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelExecute.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,10 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace FreeSwitch.EventSocket +{ + public class EventChannelExecute : EventChannelState + { + } +} Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelExecuteComplete.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelExecuteComplete.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,7 @@ +namespace FreeSwitch.EventSocket +{ + public class EventChannelExecuteComplete : EventChannelState + { + } +} + Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelHangup.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelHangup.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,91 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace FreeSwitch.EventSocket +{ + public class EventChannelHangup : EventChannelState + { + private Causes m_hangupCause; + + public enum Causes + { + Success, + NoRouteTransitNet, + NoRouteDestination, + ChannelUnacceptable, + CallAwardedDelivered, + NormalClearing, + UserBusy, + NoUserResponse, + NoAnswer, + SubscriberAbsent, + CallRejected, + NumberChanged, + RedirectionToNewDestination, + ExchangeRoutingError, + DestinationOutOfOrder, + InvalidNumberFormat, + FacilityRejected, + ResponseToStatusEnquiry, + NormalUnspecified, + NormalCircuitCongestion, + NetworkOutOfOrder, + NormalTemporaryFailure, + SwitchCongestion, + AccessInfoDiscarded, + RequestedChanUnavail, + PreEmpted, + FacilityNotSubscribed, + OutgoingCallBarred, + IncomingCallBarred, + BearercapabilityNotauth, + BearercapabilityNotavail, + ServiceUnavailable, + ChanNotImplemented, + FacilityNotImplemented, + ServiceNotImplemented, + InvalidCallReference, + IncompatibleDestination, + InvalidMsgUnspecified, + MandatoryIeMissing, + MessageTypeNonexist, + WrongMessage, + IeNonexist, + InvalidIeContents, + WrongCallState, + RecoveryOnTimerExpire, + MandatoryIeLengthError, + ProtocolError, + Interworking, + OriginatorCancel, + Crash, + SystemShutdown, + LoseRace, + ManagerRequest, + BlindTransfer, + AttendedTransfer, + AllottedTimeout + } + + public Causes Cause + { + get { return m_hangupCause; } + set { m_hangupCause = value; } + } + + public override bool ParseCommand(string name, string value) + { + if (name == "hangupcause" || name == "hangup-cause") + { + string cause = StringHelper.UpperCaseToCamelCase(value); + m_hangupCause = (Causes)Enum.Parse(typeof(Causes), cause); + } + else + return base.ParseCommand(name, value); + + return true; + } + + } +} Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelOriginate.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelOriginate.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace FreeSwitch.EventSocket +{ + public class EventChannelOriginate : ChannelEvent + { + + } +} Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelOutgoing.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelOutgoing.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace FreeSwitch.EventSocket +{ + public class EventChannelOutgoing : EventChannelState + { + + } +} Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelProgress.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelProgress.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,10 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace FreeSwitch.EventSocket +{ + public class EventChannelProgress : EventChannelState + { + } +} Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelState.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelState.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,63 @@ +namespace FreeSwitch.EventSocket +{ + public class EventChannelState : ChannelEvent + { + private PartyInfo _caller = new PartyInfo(); + private PartyInfo _originator = new PartyInfo(); + private bool _screenBit = false; + + /// <summary> + /// Information about the called party. + /// This property is null for certain channel states, + /// depending on if freeswitch sends it or not. + /// </summary> + public PartyInfo Caller + { + get { return _caller; } + set { _caller = value; } + } + + /// <summary> + /// Information about the destination (place that the caller want to reach). + /// This property is null for certain channel states, + /// depending on if freeswitch sends it or not. + /// </summary> + public PartyInfo Originator + { + get { return _originator; } + set { _originator = value; } + } + + public bool ScreenBit + { + get { return _screenBit; } + set { _screenBit = value; } + } + + public override bool ParseCommand(string name, string value) + { + if (name == "screen-bit") + { + ScreenBit = value == "yes"; + return true; + } + else if (name.Length > 11 && name.Substring(0, 11) == "originator-" + || name.Length > 11 && name.Substring(0, 11) == "originatee-") + { + if (_originator == null) + _originator = new PartyInfo(); + + return _originator.Parse(name.Substring(11), value); + } + else if (name.Length > 7 && name.Substring(0, 7) == "caller-") + { + if (_caller == null) + _caller = new PartyInfo(); + + return _caller.Parse(name.Substring(7), value); + } + else + return base.ParseCommand(name, value); + } + } +} \ No newline at end of file Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelUnbridge.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelUnbridge.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,10 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace FreeSwitch.EventSocket +{ + public class EventChannelUnbridge : EventChannelState + { + } +} Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelUnpark.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelUnpark.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,10 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace FreeSwitch.EventSocket +{ + public class EventChannelUnpark : EventChannelState + { + } +} Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventCodec.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventCodec.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,6 @@ +namespace FreeSwitch.EventSocket +{ + public class EventCodec : EventChannelState + { + } +} Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventDtmf.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventDtmf.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,35 @@ +namespace FreeSwitch.EventSocket +{ + public class EventDtmf : ChannelEvent + { + private char _digit; + private int _duration; + + public char Digit + { + get { return _digit; } + set { _digit = value; } + } + + public int Duration + { + get { return _duration; } + set { _duration = value; } + } + + public override bool ParseCommand(string name, string value) + { + switch(name) + { + case "dtmf-digit": + _digit = value[0]; + break; + case "dtmf-duration": + int.TryParse(value, out _duration); + break; + } + + return base.ParseCommand(name, value); + } + } +} Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventDtmfStatus.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventDtmfStatus.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,31 @@ +namespace FreeSwitch.EventSocket +{ + /// <summary> + /// Reports when DTMF digits have been pressed + /// </summary> + public class EventDtmfStatus : ChannelEvent + { + private int _count; + + /// <summary> + /// Number of digits in the buffer. + /// </summary> + public int Count + { + get { return _count; } + } + + + public override bool ParseCommand(string name, string value) + { + switch (name) + { + case "dtmf-count": + int.TryParse(value, out _count); + break; + } + + return base.ParseCommand(name, value); + } + } +} Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelInfo.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelInfo.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,225 @@ +namespace FreeSwitch.EventSocket +{ + #region enum ChannelState + public enum ChannelState + { + New, // Channel is newly created + Init, // Channel has been initilized + Ring, // Channel is looking for a dialplan + Transmit, // Channel is in a passive transmit state + Execute, // Channel is executing it's dialplan + Loopback, // Channel is in loopback + Hold, // Channel is on hold + Hibernate, // Channel is in a sleep state + Hangup, // Channel is flagged for hangup and ready to end + Done, // Channel is ready to be destroyed and out of the state machine + Unknown + } + #endregion + + public class ChannelInfo + { + private ChannelState m_state; + private int m_stateNumber; + private string _profile; + private string m_address; + private string _hostName; + private string m_protocol = string.Empty; + private string m_readCodecName; + private int m_readCodecRate; + private string m_writeCodecName; + private int m_writeCodecRate; + + /// <summary> + /// Coded used to read information from the channel. + /// Example: L16 + /// </summary> + public string ReadCodecName + { + get { return m_readCodecName; } + set { m_readCodecName = value; } + } + + /// <summary> + /// Bitrate of the read coded that is used. + /// Example: 8000 + /// </summary> + public int ReadCodecRate + { + get { return m_readCodecRate; } + set { m_readCodecRate = value; } + } + + /// <summary> + /// Codec used for writing to the channel. + /// Example: L16 + /// </summary> + public string WriteCodecName + { + get { return m_writeCodecName; } + set { m_writeCodecName = value; } + } + + /// <summary> + /// Bitrate of the codec. + /// Example: 8000 + /// </summary> + public int WriteCodecRate + { + get { return m_writeCodecRate; } + set { m_writeCodecRate = value; } + } + + /// <summary> + /// State that the channel is in. Check ChannelState enum for more information. + /// </summary> + public ChannelState State + { + get { return m_state; } + set { m_state = value; } + } + + /// <summary> + /// Number of the state (from the enum in FreeSwitch) + /// </summary> + public int StateNumber + { + get { return m_stateNumber; } + set { m_stateNumber = value; } + } + + /// <summary> + /// Name of the channel. + /// </summary> + /// <example>sofia/mydomain.com/1234@conference.freeswitch.org</example> + /// <seealso cref="ChannelInfo.Protocol"/> + /// <seealso cref="ProfileName"/> + /// <seealso cref="Address"/> + /// <seealso cref="HostName"/> + public string Name + { + get { return m_protocol + "/" + _profile + "/" + m_address + "@" + _hostName; } + set + { + string[] bits = value.Split('/'); + if (bits.Length == 3) + { + m_protocol = bits[0]; + _profile = bits[1]; + string[] userParts = bits[2].Split('@'); + if (userParts.Length == 2) + { + m_address = userParts[0]; + HostName = userParts[1]; + } + else + m_address = bits[2]; + } + + } + } + + /// <summary> + /// ProfileName for the diaplan/sip. + /// </summary> + public string ProfileName + { + get { return _profile; } + set { _profile = value; } + } + + /// <summary> + /// Extension/Username for the channel + /// </summary> + public string Address + { + get { return m_address; } + set { m_address = value; } + } + + /// <summary> + /// Where the extension/user is calling from. + /// </summary> + public string HostName + { + get { return _hostName; } + set + { + if (value == null) + { + _hostName = string.Empty; + return; + } + + int pos = value.IndexOf(':'); + if (pos == -1) + _hostName = value; + else + _hostName = value.Substring(0, pos); + } + } + + /// <summary> + /// Protocol used for communication. + /// "sofia" = sip. + /// </summary> + public string Protocol + { + get { return m_protocol; } + } + + public bool Parse(string name, string value) + { + switch (name) + { + case "channel-state": + m_state = StateFromString(value); + break; + case "channel-state-number": + int.TryParse(value, out m_stateNumber); + break; + case "channel-name": + Name = value; + break; + case "channel-read-codec-name": + m_readCodecName = value; + break; + case "channel-read-codec-rate": + int.TryParse(value, out m_readCodecRate); + break; + case "channel-write-codec-name": + m_writeCodecName = value; + break; + case "channel-write-codec-rate": + int.TryParse(value, out m_writeCodecRate); + break; + default: + return false; + } + return true; + } + + public ChannelState StateFromString(string state) + { + switch (state) + { + case "CS_NEW": return ChannelState.New; + case "CS_INIT": return ChannelState.Init; + case "CS_RING": return ChannelState.Ring; + case "CS_TRANSMIT": return ChannelState.Transmit; + case "CS_EXECUTE": return ChannelState.Execute; + case "CS_LOOPBACK": return ChannelState.Loopback; + case "CS_HOLD": return ChannelState.Hold; + case "CS_HIBERNATE": return ChannelState.Hibernate; + case "CS_HANGUP": return ChannelState.Hangup; + case "CS_DONE": return ChannelState.Done; + default: return ChannelState.Unknown; + } + } + + public string StateToString(ChannelState state) + { + return "Unknown"; + } + } +} Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/AnyCommand.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/AnyCommand.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,36 @@ +namespace FreeSwitch.EventSocket.Commands +{ + public class AnyCommand : Api + { + private readonly string _name; + private readonly string _value; + + public AnyCommand(string name, string arguments) + { + _name = name; + _value = arguments; + } + + public override string Command + { + get { return _name; } + } + + public override string Arguments + { + get { return _value; } + } + + public override CommandReply CreateReply(string dataToParse) + { + if (dataToParse.Length > 0 && (dataToParse[0] == '+') || dataToParse == "OK") + return new CommandReply(true); + else + { + CommandReply reply = new CommandReply(false); + reply.ErrCode = dataToParse; + return reply; + } + } + } +} Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/Api.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/Api.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,10 @@ +namespace FreeSwitch.EventSocket.Commands +{ + public abstract class Api : CmdBase + { + public override string ToString() + { + return string.Format("api {0} {1}", Command, Arguments); + } + } +} Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/AuthCommand.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/AuthCommand.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,34 @@ +namespace FreeSwitch.EventSocket.Commands +{ + public class AuthCommand : CmdBase + { + private readonly string _password; + + public AuthCommand(string password) + { + _password = password; + } + + public override string Command + { + get { return "auth"; } + } + + public override string Arguments + { + get { return _password; } + } + + public override CommandReply CreateReply(string dataToParse) + { + if (dataToParse.Contains("+OK")) + return new CommandReply(true); + else + { + CommandReply reply = new CommandReply(false); + reply.ErrCode = dataToParse; + return reply; + } + } + } +} \ No newline at end of file Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/CmdBase.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/CmdBase.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,55 @@ +namespace FreeSwitch.EventSocket.Commands +{ + #region Delegates + + public delegate void ReplyHandler(CmdBase command, CommandReply reply); + + #endregion + + public abstract class CmdBase + { + public event ReplyHandler OnReply; + + private object _contextData; + + public abstract string Command + { + get; + } + + public abstract string Arguments + { + get; + } + + /// <summary> + /// You can attach something that you need to + /// identify the command. + /// </summary> + public object ContextData + { + get { return _contextData; } + set { _contextData = value; } + } + + public virtual void HandleReply(CommandReply reply) + { + // a command is only invoked once. + if (OnReply != null) + { + OnReply(this, reply); + OnReply = null; + } + } + + public virtual CommandReply CreateReply(string dataToParse) + { + return null; + } + + public override string ToString() + { + return string.Format("{0} {1}", Command, Arguments); + } + } +} Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/CommandReply.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/CommandReply.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,35 @@ +namespace FreeSwitch.EventSocket.Commands +{ + /// <summary> + /// Baseclass for replies that commands get. + /// </summary> + public class CommandReply + { + private bool _success; + private string _errCode; + + public CommandReply(bool success) + { + _success = success; + } + + public bool Success + { + get { return _success; } + } + + public string ErrCode + { + get { return _errCode; } + set { _errCode = value; } + } + + public override string ToString() + { + if (_success) + return "Success"; + else + return "Failed: " + _errCode; + } + } +} Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/ExecuteJavascript.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/ExecuteJavascript.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,63 @@ +using System.Collections.Generic; + +namespace FreeSwitch.EventSocket.Commands +{ + public class ExecuteJavascript : Api + { + private readonly string _scriptName; + private readonly IList<string> _arguments = new List<string>(); + + public ExecuteJavascript() + { + + } + + public ExecuteJavascript(string scriptName) + { + _scriptName = scriptName; + } + + /// <summary> + /// Arguments to javascript + /// </summary> + /// <seealso cref="Arguments"/> + public IList<string> Args + { + get { return _arguments; } + } + + public override string Command + { + get { return "jsrun"; } + } + + /// <summary> + /// Args to the CmdBase api + /// </summary> + /// <seealso cref="Args"/> + public override string Arguments + { + get { return _scriptName + " " + JoinArguments(); } + } + + public override CommandReply CreateReply(string dataToParse) + { + if (dataToParse == "OK") + return new CommandReply(true); + else + { + CommandReply reply = new CommandReply(false); + reply.ErrCode = dataToParse; + return reply; + } + } + + private string JoinArguments() + { + string args = string.Empty; + foreach (string arg in Args) + args += arg + " "; + return args; + } + } +} Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/GetVariable.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/GetVariable.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,69 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace FreeSwitch.EventSocket.Commands +{ + public class GetVariable : Api + { + private readonly string _channelId; + private readonly string _name; + + public GetVariable() + { + + } + + public GetVariable(string uuid, string name) + { + _channelId = uuid; + _name = name; + } + + public override string Command + { + get { return "uuid_getvar"; } + } + + public override string Arguments + { + get { return _channelId + " " + _name; } + } + + public override CommandReply CreateReply(string dataToParse) + { + if (dataToParse.Substring(0, 2) == "OK") + { + return new GetVariableReply(true, dataToParse.Substring(3)); + } + else + { + GetVariableReply reply = new GetVariableReply(false, string.Empty); + reply.ErrCode = dataToParse; + return reply; + } + } + } + + + public class GetVariableReply : CommandReply + { + private string _value; + + public GetVariableReply(bool success, string value) + : base(success) + { + _value = value; + } + + public string SessionId + { + get { return _value; } + } + + public string Value + { + get { return _value; } + } + } +} Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/HoldCmd.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/HoldCmd.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,29 @@ +namespace FreeSwitch.EventSocket.Commands +{ + public class HoldCmd : Api + { + private readonly string _sessionId; + private readonly bool _activate; + + public HoldCmd(string sessionId, bool activate) + { + _sessionId = sessionId; + _activate = activate; + } + + public override string Command + { + get { return "hold"; } + } + + public override string Arguments + { + get { return (_activate ? string.Empty : "off ") + _sessionId; } + } + + public override CommandReply CreateReply(string dataToParse) + { + return base.CreateReply(dataToParse); + } + } +} Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/Originate.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/Originate.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,108 @@ +using System.Collections.Generic; +using FreeSwitch.EventSocket.General; + +namespace FreeSwitch.EventSocket.Commands +{ + public class OriginateReply : CommandReply + { + private readonly string _sessionId; + + public OriginateReply(bool success, string sessionId) : base(success) + { + _sessionId = sessionId; + } + + public string SessionId + { + get { return _sessionId; } + } + } + + public class Originate : Api + { + private SofiaSipAddress _caller; + private Address _destination; + private readonly IList<ChannelVariable> _variables = new List<ChannelVariable>(); + private string _callerIdName = null; + private string _callerIdNumber = null; + + public Originate() + {} + + public Originate(SofiaSipAddress caller, Address destination) + { + _caller = caller; + _destination = destination; + } + + public SofiaSipAddress Caller + { + get { return _caller; } + set { _caller = value; } + } + + public Address Destination + { + get { return _destination; } + set { _destination = value; } + } + + public IList<ChannelVariable> Variables + { + get { return _variables; } + } + + public string CallerIdNumber + { + get { return _callerIdNumber; } + set { _callerIdNumber = value; } + } + + public string CallerIdName + { + get { return _callerIdName; } + set { _callerIdName = value; } + } + + public override string Command + { + get { return "originate"; } + } + + public override string Arguments + { + get + { + _variables.Add(new ChannelVariable("origination_caller_id_name", CallerIdName ?? _caller.Extension)); + if (!string.IsNullOrEmpty(_callerIdNumber)) + _variables.Add(new ChannelVariable("origination_caller_id_number", _callerIdNumber)); + + string variables = string.Empty; + foreach (ChannelVariable var in _variables) + variables += var + ","; + if (variables.Length > 0) + variables = "{" + variables.Remove(variables.Length - 1, 1) + "}"; + + return variables + Caller + " " + Destination; + } + } + + public override CommandReply CreateReply(string dataToParse) + { + dataToParse = dataToParse.Replace(" ", string.Empty); + string[] nameValue = dataToParse.Split(':'); + if (nameValue[0].ToLower() == "success") + return new OriginateReply(true, nameValue[1]); + else + { + OriginateReply reply = new OriginateReply(false, string.Empty); + if (nameValue.Length > 1) + reply.ErrCode = nameValue[1]; + else + reply.ErrCode = dataToParse; + return reply; + } + } + + } +} Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/ParkCmd.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/ParkCmd.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,22 @@ +namespace FreeSwitch.EventSocket.Commands +{ + public class ParkCmd : Api + { + private readonly string _uuid; + + public ParkCmd(string uuid) + { + _uuid = uuid; + } + + public override string Command + { + get { return "uuid_park"; } + } + + public override string Arguments + { + get { return _uuid; } + } + } +} Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/Playback.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/Playback.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,34 @@ +namespace FreeSwitch.EventSocket.Commands +{ + /// <summary> + /// Play a file + /// </summary> + public class PlaybackCmd : SendMsg + { + private readonly string _fileName; + + /// <summary> + /// + /// </summary> + /// <param name="uuid">channel identifier</param> + /// <param name="fileName">Path and filename to sound file</param> + /// <remarks>Path should be relative to FS path.</remarks> + /// <example> + /// mgr.SendApi(new PlaybackCmd(evt.UniqueId, "sounds\\sv\\welcome.wav", PlaybackCmd.All)); + /// </example> + public PlaybackCmd(string uuid, string fileName) : base(uuid) + { + _fileName = fileName; + } + + public override string Command + { + get { return "playback"; } + } + + public override string Arguments + { + get { return _fileName; } + } + } +} Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/RecordCmd.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/RecordCmd.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,72 @@ +using System; + +namespace FreeSwitch.EventSocket.Commands +{ + public class RecordCmd : Api + { + //<uuid> [start|stop] <path> [<limit>] + private readonly string _uuid; + private readonly bool _start; + private readonly string _path; + private readonly int _limit; + + /// <param name="uuid">channel id</param> + /// <param name="path">FS relative path to sound file</param> + public RecordCmd(string uuid, string path) + { + if (string.IsNullOrEmpty(uuid)) + throw new ArgumentException("uuid"); + if (string.IsNullOrEmpty(path)) + throw new ArgumentException("path"); + + _uuid = uuid; + _path = path; + } + + /// <param name="uuid">channel id</param> + /// <param name="path">FS relative path to sound file</param> + /// <param name="limit">number of seconds that maximum can be recorded.</param> + public RecordCmd(string uuid, string path, int limit) + { + if (string.IsNullOrEmpty(uuid)) + throw new ArgumentException("uuid"); + if (string.IsNullOrEmpty(path)) + throw new ArgumentException("path"); + + _uuid = uuid; + _path = path; + _limit = limit; + } + + /// <param name="uuid">channel id</param> + /// <param name="path">FS relative path to sound file</param> + /// <param name="stop">stop the recording if true</param> + public RecordCmd(string uuid, string path, bool stop) : this(uuid, path) + { + _start = !stop; + } + + /// <summary> + /// + /// </summary> + /// <param name="uuid">channel id</param> + /// <param name="path">FS relative path to sound file</param> + /// <param name="stop">stop the recording if true</param> + /// <param name="limit">number of seconds that maximum can be recorded.</param> + public RecordCmd(string uuid, string path, bool stop, int limit) + : this(uuid, path, limit) + { + _start = !stop; + } + + public override string Command + { + get { return "uuid_record"; } + } + + public override string Arguments + { + get { return _uuid + (_start ? "start" : "stop") + " " + _path + " " + _limit; } + } + } +} Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/SendMsg.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/SendMsg.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,26 @@ +namespace FreeSwitch.EventSocket.Commands +{ + public abstract class SendMsg : CmdBase + { + private readonly string _uuid; + private readonly string _callCommand = "execute"; + + public SendMsg(string uuid) + { + _uuid = uuid; + } + + public SendMsg(string uuid, string callCommand) + { + _callCommand = callCommand; + _uuid = uuid; + } + + public override string ToString() + { + return + string.Format("SendMsg {0}\ncall-command: {1}\nexecute-app-name: {2}\nexecute-app-arg: {3}\n", _uuid, + _callCommand, Command, Arguments); + } + } +} Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/SetVariable.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/SetVariable.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,44 @@ +namespace FreeSwitch.EventSocket.Commands +{ + public class SetVariable : Api + { + private readonly string _channelId; + private readonly string _name; + private readonly string _value; + + public SetVariable() + { + + } + + public SetVariable(string uuid, string name, string value) + { + _channelId = uuid; + _name = name; + _value = value; + } + + public override string Command + { + get { return "uuid_setvar"; } + } + + public override string Arguments + { + get { return _channelId + " " + _name + " " + _value; } + } + + public override CommandReply CreateReply(string dataToParse) + { + if (dataToParse == "OK") + return new CommandReply(true); + else + { + CommandReply reply = new CommandReply(false); + reply.ErrCode = dataToParse; + return reply; + } + } + + } +} Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/SleepCmd.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/SleepCmd.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,22 @@ +namespace FreeSwitch.EventSocket.Commands +{ + public class SleepCmd : SendMsg + { + private readonly int _ms; + + public SleepCmd(string uuid, int ms) : base(uuid) + { + _ms = ms; + } + + public override string Command + { + get { return "sleep"; } + } + + public override string Arguments + { + get { return _ms.ToString(); } + } + } +} Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/TransferCmd.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/TransferCmd.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,36 @@ +namespace FreeSwitch.EventSocket.Commands +{ + public class TransferCmd : PbxCommand + { + private readonly string _sessionId; + private readonly string _destination; + + /// <summary> + /// Transfer a call to somewhere. + /// </summary> + /// <param name="sessionId"></param> + /// <param name="destination"></param> + public TransferCmd(string sessionId, string destination) + { + _sessionId = sessionId; + _destination = destination; + } + + public override PbxCommandReply CreateReply(string dataToParse) + { + if (dataToParse == "OK") + return new PbxCommandReply(true); + else + { + PbxCommandReply reply = new PbxCommandReply(false); + reply.ErrCode = dataToParse; + return reply; + } + } + + public override string ToString() + { + return "transfer " + _sessionId + " " + _destination; + } + } +} Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/EventManager.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/EventManager.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,143 @@ +using System; +using System.Collections.Specialized; +using System.IO; +using FreeSwitch.EventSocket.Commands; + +namespace FreeSwitch.EventSocket +{ + public delegate void EventHandler(EventBase receivedEvent); + + public delegate void EventsWriter(string text); + + public class EventManager + { + private readonly EventSocket _socket = new EventSocket(); + public event EventHandler EventReceived; + private EventsWriter _writer; + private TextWriter _myWriter; + public string Password + { + set { _socket.Password = value; } + } + + public EventManager() + { + _writer = MyWriter; + _myWriter = new StreamWriter(new FileStream("C:\\temp\\WatcherRow.log", FileMode.Create, FileAccess.Write, FileShare.ReadWrite)); + } + + private void MyWriter(string text) + { + _myWriter.Write(text); + } + + + public EventManager(EventsWriter writer) + { + _writer = writer; + } + + public void Start(string hostname) + { + _socket.MessageReceived += OnMessage; + _socket.Connect(hostname); + _socket.DataReceived += OnData; + } + + private void OnData(string data) + { + _writer(data); + } + + /// <summary> + /// Send a command to the server. + /// </summary> + /// <param name="cmd"></param> + /// <exception cref="IOException">If socket is not connected</exception> + /// <exception cref="InvalidOperationException"></exception> + /// <exception cref="ObjectDisposedException"></exception> + public void Send(CmdBase cmd) + { + _socket.Send(cmd); + } + + public void Send(SendMsg cmd) + { + _socket.Send(cmd); + } + + protected void OnMessage(PlainEventMsg msg) + { + NameValueCollection parameters = msg.BodyToNameValue(true); + string eventName = parameters["event-name"]; + if (eventName == null) + return; + + if (string.Compare(parameters["event-name"], "custom", true) == 0) + eventName = parameters["event-subclass"]; + else + eventName = parameters["event-name"]; + + //Quickhack for Sofia::Register (convert to sofia_register) + eventName = eventName.Replace("::", "_"); + eventName = StringHelper.UpperCaseToCamelCase(eventName); + + // Try to load the event (check if we've created an event class for the registered event) + EventBase eb = EventBase.CreateEvent(eventName); + + // Yep, we got an event class. Let it parse the event information + if (eb != null) + { + eb.SetParameters(parameters); + eb.Parse(parameters); + if (EventReceived != null) + EventReceived(eb); + + /* + EventChannelState channel = eb as EventChannelState; + if (channel != null) + { + Console.WriteLine("[" + eb.Name + "/" + channel.ChannelInfo.State + "] (uid: " + + channel.UniqueId + ")"); + Console.WriteLine(" ChannelInfo:"); + Console.WriteLine(" Name: " + channel.ChannelInfo.Name); + Console.WriteLine(" State: " + channel.ChannelInfo.State); + if (channel.Caller != null) + { + Console.WriteLine(" CallerInfo:"); + Console.WriteLine(" Id: " + channel.Caller.UniqueId); + Console.WriteLine(" UserName: " + channel.Caller.UserName); + Console.WriteLine(" CallerId: " + channel.Caller.CallerIdName + "/" + + channel.Caller.CallerIdNumber); + Console.WriteLine(" ChannelName: " + channel.Caller.ChannelName); + Console.WriteLine(" DestinationNumber: " + channel.Caller.DestinationNumber); + } + + if (channel.Originator != null) + { + Console.WriteLine(" Originator:"); + Console.WriteLine(" Id: " + channel.Originator.UniqueId); + Console.WriteLine(" UserName: " + channel.Originator.UserName); + Console.WriteLine(" CallerId: " + channel.Originator.CallerIdName + "/" + + channel.Originator.CallerIdNumber); + Console.WriteLine(" ChannelName: " + channel.Originator.ChannelName); + Console.WriteLine(" DestinationNumber: " + channel.Originator.DestinationNumber); + } + } + //}*/ + } + else + Console.WriteLine("* Failed to load '" + eventName + "'."); + } + + public void Subscribe(Events events) + { + _socket.Subscribe(events); + } + + public void Subscribe(params Event[] events) + { + _socket.Subscribe(new Events(events)); + } + } +} \ No newline at end of file Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/EventParser.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/EventParser.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,99 @@ +using EventSocketParser; + +namespace FreeSwitch.EventSocket +{ + public class EventParser + { + private PlainEventMsg _msg; + private readonly StringParser _parser; + + public EventParser(string text) + { + _parser = new StringParser(text); + } + + public PlainEventMsg ParseMessage() + { + _parser.ClearSavedPositions(); + _msg = new PlainEventMsg(); + + // Save pos if we cant parse the whole message + _parser.SavePos(); + + ReadHeader(); + if (!_msg.ValidateHeader()) + { + _parser.RestorePos(); + return null; + } + + // skip empty line between body and header + _parser.ReadLine(true); + + // we got no body. + if (_msg.ContentLength == -1) + return _msg; + + // Unfortunately, \n\n doesnt appear after all content. + if (_msg.ContentLength != 0) + _msg.Body = _parser.Read(_msg.ContentLength); + else + _msg.Body = _parser.ReadToEmptyLine(); + + // assume that we have not got a complete packet yet. + if (!_msg.Validate()) + { + _parser.RestorePos(); + return null; + } + + return _msg; + } + + public bool ReadHeader() + { + // skip empty lines + while (!_parser.EOF && _parser.PeekWord(true, true) == string.Empty) + _parser.ReadLine(false); + + if (_parser.EOF) + return false; + + string name = _parser.Read(':', true); + while (name != string.Empty) + { + switch (name) + { + case "Content-Length": + _msg.ContentLength = int.Parse(_parser.ReadLine(true)); + break; + case "Content-Type": + _msg.ContentType = _parser.ReadLine(true); + break; + case "Reply-Text": + _msg.Body = _parser.ReadLine(); + break; + } + + // empty line == end of header + if (_parser.EOL) + break; + + name = _parser.Read(':', true); + } + + return _msg.ContentType != string.Empty; + } + + public void Append(string value) + { + _parser.RemoveUsedContent(); + _parser.Append(value); + } + + public void Clear() + { + _parser.Clear(); + } + } +} \ No newline at end of file Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/EventSocket.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/EventSocket.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,298 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Net.Sockets; +using System.Text; +using System.Threading; +using FreeSwitch.EventSocket.Commands; + +namespace FreeSwitch.EventSocket +{ + public delegate void MessageHandler(PlainEventMsg msg); + + public class EventSocket + { + #region Delegates + + public delegate void EventSocketHandler(EventSocket client); + + public delegate void DataHandler(string data); + + #endregion + + private readonly Queue<CmdBase> _commands = new Queue<CmdBase>(); + private bool _autoConnect = true; + private Events _events; + private string _hostName; + private readonly EventParser _parser = new EventParser(string.Empty); + public event DataHandler DataReceived; + private string _password = "ClueCon"; + private int _port = 8021; + private object _lockobj = new object(); + private readonly byte[] _readBuffer = new byte[8192]; + private string _temp = string.Empty; + private Socket _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + private NetworkStream _stream; + private Timer _timer; + private bool _authed = false; + const int RetryTimeout = 5000; + + public string Password + { + get { return _password; } + set { _password = value; } + } + + public bool AutoConnect + { + get { return _autoConnect; } + set { _autoConnect = value; } + } + + public event MessageHandler MessageReceived; + + public event EventSocketHandler Disconnected; + public event EventSocketHandler Connected; + + public void Connect(string server) + { + int pos = server.IndexOf(':'); + if (pos == -1) + _hostName = server; + else + { + _port = int.Parse(server.Substring(pos + 1)); + _hostName = server.Substring(0, pos); + } + + Connect(); + } + + public void Connect() + { + if (_hostName == null) + throw new InvalidOperationException("Must call the other Connect method first to set hostname/port."); + + try + { + TryConnect(); + } + catch (SocketException) + { + Console.WriteLine("EventSocket: Connect failed"); + HandleDisconnect(); + } + } + + private void TryConnect() + { + lock (_lockobj) + { + Console.WriteLine("EventSocket.TryConnect: Connecting to " + _hostName + ":" + _port); + + _socket.Connect(_hostName, _port); + if (_stream == null) + _stream = new NetworkStream(_socket, false); + + if (Connected != null) + Connected(this); + BeginRead(); + + if (_timer != null) + { + Timer tmr = _timer; + _timer = null; + tmr.Change(Timeout.Infinite, Timeout.Infinite); + tmr.Dispose(); + } + } + } + + private void BeginRead() + { + _stream.BeginRead(_readBuffer, 0, _readBuffer.Length, OnReadCompleted, null); + } + + private void OnReadCompleted(IAsyncResult ar) + { + int bytesRead; + try + { + bytesRead = _stream.EndRead(ar); + if (bytesRead == 0) + { + HandleDisconnect(); + return; + } + } + catch (IOException) + { + // Remote end disconnected. + HandleDisconnect(); + return; + } + + string text = Encoding.ASCII.GetString(_readBuffer, 0, bytesRead); + if (DataReceived != null) + DataReceived(text); + _temp += text; + _parser.Append(text); + ParseMessages(); + + _stream.BeginRead(_readBuffer, 0, _readBuffer.Length, OnReadCompleted, null); + } + + /// <summary> + /// Subscribe on the specified events. + /// </summary> + /// <param name="events">The events.</param> + public void Subscribe(Events events) + { + _events = events; + if (_socket.Connected && _authed) + RequestEvents(); + } + + /// <summary> + /// + /// </summary> + /// <param name="s"></param> + /// <exception cref="InvalidOperationException"></exception> + /// <exception cref="ObjectDisposedException"></exception> + private void Write(string s) + { + if (_socket == null) + return; + if (!_socket.Connected) + { + try + { + Console.WriteLine("EventSocket.Write: Trying to connect eventsocket."); + TryConnect(); + Console.WriteLine("EventSocket.Write: Connected."); + } + catch (SocketException) + { + return; + } + } + + byte[] bytes = Encoding.ASCII.GetBytes(s); + _stream.Write(bytes, 0, bytes.Length); + } + + private void ParseMessages() + { + PlainEventMsg msg = _parser.ParseMessage(); + while (msg != null) + { + if (msg.ContentType == "auth/request") + { + AuthCommand cmd = new AuthCommand(_password); + cmd.OnReply += OnAuthed; + _commands.Enqueue(cmd); + Write(cmd + "\n\n"); + } + else if (msg.ContentType == "command/reply" + || msg.ContentType == "api/response") + { + if (_commands.Count > 0) + { + CmdBase cmd = _commands.Dequeue(); + Console.WriteLine("Reply to " + cmd.GetType().Name + ": " + msg.Body); + cmd.HandleReply(cmd.CreateReply(msg.Body)); + } + else + { + Console.ForegroundColor = ConsoleColor.Red; + Console.WriteLine("Got command reply or api response, but no actual command/api: " + msg.Body); + Console.ForegroundColor = ConsoleColor.Gray; + } + } + else + { + if (MessageReceived != null) + MessageReceived(msg); + } + msg = _parser.ParseMessage(); + } + } + + private void OnAuthed(CmdBase command, CommandReply reply) + { + _authed = true; + RequestEvents(); + } + + private void HandleDisconnect() + { + _parser.Clear(); + _authed = false; + _socket.Close(); + _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + if (_stream != null) + { + _stream.Dispose(); + _stream = null; + } + + if (Disconnected != null) + Disconnected.Invoke(this); + if (AutoConnect && _timer == null) + { + Console.WriteLine("EventSocket: Launching timer."); + _timer = new Timer(TryConnect, this, RetryTimeout, RetryTimeout); + } + } + + private void RequestEvents() + { + if (_events.Count <= 0 && _authed) + return; + + Write("event plain " + GetEventString() + "\n\n"); + } + + private string GetEventString() + { + string events = string.Empty; + for (int i = 0; i < _events.Count; ++i) + events += StringHelper.CamelCaseToUpperCase(_events[i].ToString()) + " "; + return events; + } + + /// <summary> + /// Send a command to FreeSwitch. + /// Do you want a response? Then use the delegate in the Command class. + /// </summary> + /// <param name="command">Command to send.</param> + /// <exception cref="IOException">If socket is not connected.</exception> + /// <exception cref="InvalidOperationException"></exception> + /// <exception cref="ObjectDisposedException"></exception> + public void Send(CmdBase command) + { + if (!_socket.Connected) + throw new IOException("Socket is not connected."); + + _commands.Enqueue(command); + + // All commands need replies. + Write(command + "\n\n"); + } + + private static void TryConnect(object state) + { + EventSocket client = (EventSocket) state; + try + { + Console.WriteLine("EventSocket.Timer: Trying to connect eventsocket."); + client.TryConnect(); + Console.WriteLine("EventSocket.Timer: Connected."); + } + catch (SocketException err) + { + Console.WriteLine("Eventsocket.TryConnect: " + err.Message); + } + } + } +} \ No newline at end of file Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/EventSocket.pfx ============================================================================== Binary file. No diff available. Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Events.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Events.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,107 @@ +using System.Collections.Generic; + +namespace FreeSwitch.EventSocket +{ + #region Event enum + public enum Event + { + Custom, + ChannelCreate, + ChannelDestroy, + ChannelState, + ChannelAnswer, + ChannelApplication, + ChannelHangup, + ChannelExecute, + ChannelExecuteComplete, + ChannelBridge, + ChannelUnbridge, + ChannelProgress, + ChannelOriginate, + ChannelOutgoing, + ChannelPark, + ChannelUnpark, + Api, + Log, + InboundChan, + OutboundChan, + Startup, + Shutdown, + Publish, + Unpublish, + Talk, + Notalk, + SessionCrash, + ModuleLoad, + Dtmf, + Message, + PresenceIn, + PresenceOut, + PresenceProbe, + SofiaRegister, + SofiaExpires, + Roster, + Codec, + BackgroundJob, + DetectedSpeech, + PrivateCommand, + Heartbeat, + All + } + #endregion + + #region Events class + public class Events + { + private IList<Event> m_events = new List<Event>(); + + public Events() { } + public Events(params Event[] parameters) + { + foreach (Event e in parameters) + { + Add(e); + } + } + + public void Add(Event e) + { + m_events.Add(e); + } + + public Event this[int index] + { + get { return m_events[index]; } + } + + public void Clear() + { + m_events.Clear(); + } + + public int Count + { + get { return m_events.Count; } + } + + public static Events GetChannelEvents() + { + Events e = new Events(); + e.Add(Event.ChannelAnswer); + e.Add(Event.ChannelBridge); + e.Add(Event.ChannelCreate); + e.Add(Event.ChannelDestroy); + e.Add(Event.ChannelExecute); + e.Add(Event.ChannelHangup); + e.Add(Event.ChannelOutgoing); + e.Add(Event.ChannelPark); + e.Add(Event.ChannelProgress); + e.Add(Event.ChannelState); + e.Add(Event.ChannelUnbridge); + e.Add(Event.ChannelUnpark); + return e; + } + } + #endregion + +} \ No newline at end of file Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Events/EventApiCommand.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Events/EventApiCommand.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace FreeSwitch.EventSocket +{ + class EventApiCommand : EventBase + { + private string m_command; + + public override bool ParseCommand(string name, string value) + { + switch (name) + { + case "api-command": + m_command = value; + break; + default: + return base.ParseCommand(name, value); + } + + return true; + } + } +} Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Events/EventBase.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Events/EventBase.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,139 @@ +using System; +using System.Collections.Specialized; + +namespace FreeSwitch.EventSocket +{ + public class EventBase + { + private string m_callingFile; + private string m_callingFunction; + private int m_callingLineNumber; + private string m_coreId; + private DateTime m_dateGMT; + private DateTime m_dateLocal; + private string m_name; + private readonly NameValueCollection _parameters = new NameValueCollection(); + private NameValueCollection _allParameters; + + #region Properties + + public string Name + { + get { return m_name; } + set { m_name = value; } + } + + public string CoreId + { + get { return m_coreId; } + set { m_coreId = value; } + } + + public DateTime DateLocal + { + get { return m_dateLocal; } + set { m_dateLocal = value; } + } + + public DateTime DateGMT + { + get { return m_dateGMT; } + set { m_dateGMT = value; } + } + + public string CallingFile + { + get { return m_callingFile; } + set { m_callingFile = value; } + } + + public string CallingFunction + { + get { return m_callingFunction; } + set { m_callingFunction = value; } + } + + public int CallingLineNumber + { + get { return m_callingLineNumber; } + set { m_callingLineNumber = value; } + } + + #endregion + + public virtual bool IsChannelEvent + { + get { return false; } + } + + public NameValueCollection Parameters + { + get { return _parameters; } + } + + public NameValueCollection AllParameters + { + get { return _allParameters; } + } + + internal void SetParameters(NameValueCollection allparams) + { + _allParameters = allparams; + } + + public void Parse(NameValueCollection variables) + { + for (int i = 0; i < variables.Count; ++i) + ParseCommand(variables.GetKey(i), variables.Get(i)); + } + + public static EventBase CreateEvent(string eventName) + { + try + { + string eventNamea = "Event" + eventName; + Type t = Type.GetType("FreeSwitch.EventSocket.Event" + eventName); + if (t == null) + return null; + return (EventBase) Activator.CreateInstance(t); + } + catch (TypeLoadException) + { + return null; + } + } + + public virtual bool ParseCommand(string name, string value) + { + switch (name) + { + case "event-name": + m_name = value; + break; + case "core-uuid": + m_coreId = value; + break; + case "event-date-local": + m_dateLocal = DateTime.Parse(value); + break; + case "event-date-gmt": + m_dateGMT = DateTime.Parse(value); + break; + case "event-calling-file": + m_callingFile = value; + break; + case "event-calling-function": + m_callingFunction = value; + break; + case "event-calling-line-number": + int.TryParse(value, out m_callingLineNumber); + break; + default: + Parameters.Add(name, value); + //Console.WriteLine(m_name + ", Unhandled parameter: [" + name + "] " + value); + return false; + } + return true; + } + } +} \ No newline at end of file Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Events/EventHeartbeat.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Events/EventHeartbeat.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,57 @@ +namespace FreeSwitch.EventSocket +{ + class EventHeartbeat : EventBase + { + private string _info; + private string _upTime; + private int _sessionCount; + + public string Info + { + get { return _info; } + set { _info = value; } + } + + public string UpTime + { + get { return _upTime; } + set { _upTime = value; } + } + + public int SessionCount + { + get { return _sessionCount; } + set { _sessionCount = value; } + } + + public override bool ParseCommand(string name, string value) + { + switch (name) + { + case "event-info": + Info = value; + break; + case "up-time": + UpTime = value; + break; + case "session-count": + int.TryParse(value, out _sessionCount); + break; + + default: + return base.ParseCommand(name, value); + } + + return true; + + } + } + +/* + Event-Info: System%20Ready +Up-Time: 0%20years,%200%20days,%201%20hour,%2048%20minutes,%207%20seconds,%20265 +%20milliseconds,%20625%20microseconds%0A +Session-Count: 0 +Event-Name: HEARTBEAT + */ +} Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Events/EventMessageQuery.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Events/EventMessageQuery.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace FreeSwitch.EventSocket +{ + public class EventMessageQuery : EventBase + { + private string _account; + + public string Account + { + get { return _account; } + set { _account = value; } + } + + public override bool ParseCommand(string name, string value) + { + if (name == "message-account") + Account = value; + else + return base.ParseCommand(name, value); + + return true; + } + } +} Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Events/EventMessageWaiting.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Events/EventMessageWaiting.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,133 @@ +namespace FreeSwitch.EventSocket +{ + public class EventMessageWaiting : EventBase + { + private string _account; + private int _newMessages; + private int _newUrgentMessages; + private int _totalMessages; + private int _totalUrgentMessages; + + /// <summary> + /// Messages are for this account + /// </summary> + public string Account + { + get { return _account; } + set { _account = value; } + } + + /// <summary> + /// Total count of messages + /// </summary> + public bool MessagesWaiting + { + get { return _newMessages != 0 || _newUrgentMessages != 0; } + } + + /// <summary> + /// Number of new messages + /// </summary> + public int NewMessages + { + get { return _newMessages; } + set { _newMessages = value; } + } + + /// <summary> + /// Number of new urgent messages + /// </summary> + public int NewUrgentMessages + { + get { return _newUrgentMessages; } + set { _newUrgentMessages = value; } + } + + /// <summary> + /// Total number of new/saved/old messages + /// </summary> + public int TotalMessages + { + get { return _totalMessages; } + set { _totalMessages = value; } + } + + /// <summary> + /// Total number of new urgent messages + /// </summary> + public int TotalUrgentMessages + { + get { return _totalUrgentMessages; } + set { _totalUrgentMessages = value; } + } + + public override bool ParseCommand(string name, string value) + { + switch (name) + { + case "mwi-messages-waiting": + // are calculated by using voice messages + break; + case "mwi-message-account": + _account = value; + break; + case "mwi-voice-message": + return ParseVoiceMessages(value); + default: + return base.ParseCommand(name, value); + } + + return true; + } + + private bool ParseVoiceMessages(string value) + { + /* + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "MWI-Voice-Message", "%d/%d (%d/%d)", + total_new_messages, total_saved_messages, total_new_urgent_messages, total_saved_urgent_messages); + * */ + int pos = value.IndexOf('/'); + if (pos == -1) + return false; + if (!int.TryParse(value.Substring(0, pos), out _newMessages)) + return false; + + int oldPos = pos + 1; + pos = value.IndexOf(' ', pos); + if (pos == -1) + return false; + if (!int.TryParse(value.Substring(oldPos, pos - oldPos), out _totalMessages)) + return false; + + oldPos = pos + 2; + pos = value.IndexOf('/', pos); + if (pos == -1) + return false; + if (!int.TryParse(value.Substring(oldPos, pos - oldPos), out _newUrgentMessages)) + return false; + + oldPos = pos + 1; + pos = value.IndexOf(')', pos); + if (pos == -1) + return false; + if (!int.TryParse(value.Substring(oldPos, pos - oldPos), out _totalUrgentMessages)) + return false; + + return true; + } + + public override string ToString() + { + string str = base.ToString(); + str += "WMI-Messages-Waiting: " + (MessagesWaiting ? "yes" : "no") + "\n"; + str += "WMI-Message-Account: " + _account + "\n"; + if (_newUrgentMessages != 0 || _newMessages != 0) + str += string.Format("WMI-Voice-Message: {0}/{1} ({2}/{3})\n", + _newMessages, + _totalMessages, + _newMessages, + _totalUrgentMessages); + return str; + } + } +} \ No newline at end of file Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Events/EventReSchedule.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Events/EventReSchedule.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,62 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace FreeSwitch.EventSocket +{ + class EventReSchedule : EventBase + { + private int m_taskId; + private string m_description; + private string m_group; + private string m_runtime; + + public int TaskId + { + get { return m_taskId; } + set { m_taskId = value; } + } + + public string Description + { + get { return m_description; } + set { m_description = value; } + } + + public string Group + { + get { return m_group; } + set { m_group = value; } + } + + public string Runtime + { + get { return m_runtime; } + set { m_runtime = value; } + } + + public override bool ParseCommand(string name, string value) + { + switch (name) + { + case "task-id": + int.TryParse(value, out m_taskId); + break; + case "task-desc": + m_description = value; + break; + case "task-group": + m_group = value; + break; + case "task-runtime": + m_runtime = value; + break; + default: + return base.ParseCommand(name, value); + } + + return true; + + } + } +} Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/FreeSwitch.EventSocket.csproj ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/FreeSwitch.EventSocket.csproj Thu May 1 14:27:39 2008 @@ -0,0 +1,123 @@ +<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <ProductVersion>8.0.50727</ProductVersion> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{3F8895F6-F710-4323-B96A-4EFB6BC97E08}</ProjectGuid> + <OutputType>Library</OutputType> + <AppDesignerFolder>Properties</AppDesignerFolder> + <RootNamespace>FreeSwitch.EventSocket</RootNamespace> + <AssemblyName>FreeSwitch.EventSocket</AssemblyName> + <StartupObject> + </StartupObject> + <SignAssembly>true</SignAssembly> + <AssemblyOriginatorKeyFile>EventSocket.pfx</AssemblyOriginatorKeyFile> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> + <DebugSymbols>true</DebugSymbols> + <DebugType>full</DebugType> + <Optimize>false</Optimize> + <OutputPath>bin\Debug\</OutputPath> + <DefineConstants>DEBUG;TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> + <DebugType>pdbonly</DebugType> + <Optimize>true</Optimize> + <OutputPath>bin\Release\</OutputPath> + <DefineConstants>TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <ItemGroup> + <Reference Include="System" /> + <Reference Include="System.Data" /> + <Reference Include="System.Xml" /> + <Reference Include="Tiny.Net, Version=1.0.0.1, Culture=neutral, PublicKeyToken=15480ee9e0247fcb, processorArchitecture=MSIL"> + <SpecificVersion>False</SpecificVersion> + <HintPath>..\..\..\dlls\Debug\Tiny.Net.dll</HintPath> + </Reference> + </ItemGroup> + <ItemGroup> + <Compile Include="ChannelEvents\EventChannelApplication.cs" /> + <Compile Include="ChannelEvents\EventChannelExecuteComplete.cs" /> + <Compile Include="ChannelEvents\EventChannelOriginate.cs" /> + <Compile Include="ChannelEvents\EventChannelBridge.cs" /> + <Compile Include="ChannelEvents\ChannelEvent.cs" /> + <Compile Include="ChannelEvents\EventChannelAnswer.cs" /> + <Compile Include="ChannelEvents\EventChannelProgress.cs" /> + <Compile Include="ChannelEvents\EventChannelUnbridge.cs" /> + <Compile Include="ChannelEvents\EventChannelUnpark.cs" /> + <Compile Include="ChannelEvents\EventCodec.cs" /> + <Compile Include="ChannelInfo.cs" /> + <Compile Include="Commands\AnyCommand.cs"> + </Compile> + <Compile Include="Commands\Api.cs" /> + <Compile Include="Commands\AuthCommand.cs" /> + <Compile Include="Commands\CmdBase.cs" /> + <Compile Include="Commands\CommandReply.cs" /> + <Compile Include="Commands\ExecuteJavascript.cs" /> + <Compile Include="Commands\GetVariable.cs" /> + <Compile Include="Commands\HoldCmd.cs" /> + <Compile Include="Commands\Originate.cs" /> + <Compile Include="Commands\ParkCmd.cs" /> + <Compile Include="Commands\Playback.cs" /> + <Compile Include="Commands\RecordCmd.cs" /> + <Compile Include="Commands\SendMsg.cs" /> + <Compile Include="Commands\SetVariable.cs" /> + <Compile Include="Commands\SleepCmd.cs" /> + <Compile Include="EventManager.cs" /> + <Compile Include="ChannelEvents\EventDtmfStatus.cs" /> + <Compile Include="Ivr\IvrInterface.cs" /> + <Compile Include="PlainEventMsg.cs" /> + <Compile Include="EventParser.cs" /> + <Compile Include="Events.cs" /> + <Compile Include="Events\EventApiCommand.cs" /> + <Compile Include="Events\EventBase.cs" /> + <Compile Include="ChannelEvents\EventChannelCreate.cs" /> + <Compile Include="ChannelEvents\EventChannelDestroy.cs" /> + <Compile Include="ChannelEvents\EventChannelExecute.cs" /> + <Compile Include="ChannelEvents\EventChannelHangup.cs" /> + <Compile Include="ChannelEvents\EventChannelOutgoing.cs" /> + <Compile Include="ChannelEvents\EventChannelState.cs" /> + <Compile Include="EventSocket.cs" /> + <Compile Include="Events\EventHeartbeat.cs" /> + <Compile Include="Events\EventReSchedule.cs" /> + <Compile Include="General\Address.cs" /> + <Compile Include="General\ChannelVariable.cs" /> + <Compile Include="General\SipAddress.cs" /> + <Compile Include="General\SofiaSipAddress.cs" /> + <Compile Include="PartyInfo.cs" /> + <Compile Include="Program.cs" /> + <Compile Include="Properties\AssemblyInfo.cs" /> + <Compile Include="Events\EventMessageQuery.cs" /> + <Compile Include="ChannelEvents\EventDtmf.cs" /> + <Compile Include="SipEvents\EventPresenceIn.cs" /> + <Compile Include="SipEvents\EventPresenceOut.cs" /> + <Compile Include="SipEvents\EventPresenceProbe.cs" /> + <Compile Include="SipEvents\EventRoster.cs" /> + <Compile Include="Events\EventMessageWaiting.cs" /> + <Compile Include="SipEvents\SipEvent.cs" /> + <Compile Include="SipEvents\EventPresence.cs" /> + <Compile Include="SipEvents\EventSofiaExpire.cs" /> + <Compile Include="SipEvents\EventSofiaRegister.cs" /> + <Compile Include="StringHelper.cs" /> + <Compile Include="StringParser.cs" /> + </ItemGroup> + <ItemGroup> + <None Include="EventSocket.pfx" /> + </ItemGroup> + <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> + <!-- To modify your build process, add your task inside one of the targets below and uncomment it. + Other similar extension points exist, see Microsoft.Common.targets. + <Target Name="BeforeBuild"> + </Target> + <Target Name="AfterBuild"> + </Target> + --> + <PropertyGroup> + <PostBuildEvent>copy $(TargetPath) $(SolutionDir)..\..\dlls\$(ConfigurationName)</PostBuildEvent> + </PropertyGroup> +</Project> \ No newline at end of file Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/General/Address.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/General/Address.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace FreeSwitch.EventSocket.General +{ + public class Address + { + private string _extension; + + public Address() + { + + } + + public Address(string extension) + { + _extension = extension; + } + + public string Extension + { + get { return _extension; } + set { _extension = value; } + } + + public override string ToString() + { + return Extension; + } + } + +} Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/General/ChannelVariable.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/General/ChannelVariable.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,33 @@ +namespace FreeSwitch.EventSocket.General +{ + /// <summary> + /// Channel variables are used in freeswitch to store information + /// that can be used by javascript programs. + /// </summary> + public class ChannelVariable + { + private readonly string _name; + private readonly string _value; + + public ChannelVariable(string name, string value) + { + _name = name; + _value = value; + } + + public string Name + { + get { return _name; } + } + + public string Value + { + get { return _value; } + } + + public override string ToString() + { + return _name + "=" + _value; + } + } +} Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/General/SipAddress.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/General/SipAddress.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,38 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace FreeSwitch.EventSocket.General +{ + public class SipAddress : Address + { + private string _domain; + + public SipAddress(string domain, string extension) + : base(extension) + { + _domain = domain; + } + + public string Domain + { + get { return _domain; } + set { _domain = value; } + } + + public override string ToString() + { + return Extension + "@" + Domain; + } + + public static SipAddress Parse(string fullAddress) + { + string[] parts = fullAddress.Split('@'); + if (parts.Length == 2) + { + return new SipAddress(parts[1], parts[0]); + } + return null; + } + } +} Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/General/SofiaSipAddress.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/General/SofiaSipAddress.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,44 @@ +namespace FreeSwitch.EventSocket.General +{ + public class SofiaSipAddress : Address + { + private readonly string _domain; + + public SofiaSipAddress(string domain, string userName) + { + Extension = userName; + _domain = domain; + } + + public SofiaSipAddress(SipAddress address) + { + _domain = address.Domain; + Extension = address.Extension; + } + + public override string ToString() + { + return "sofia/mydomain.com/" + Extension + "%" + _domain; + } + + public static SofiaSipAddress Parse(string fullAddress) + { + string[] parts = fullAddress.Split('@'); + if (parts.Length == 2) + { + return new SofiaSipAddress(parts[1], parts[0]); + } + else + { + parts = fullAddress.Split('/'); + if (parts.Length == 3) + { + return new SofiaSipAddress(parts[1], parts[2]); + } + } + + return null; + + } + } +} Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Ivr/IvrInterface.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Ivr/IvrInterface.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,212 @@ +using System; +using System.Threading; +using FreeSwitch.EventSocket.Commands; + +namespace FreeSwitch.EventSocket.Ivr +{ + public class IvrInterface + { + public const string AllDigits = "*#0123456789"; + private readonly string _uuid; + private readonly string _baseSoundPath = "sounds\\"; + private string _dtmf = string.Empty; + private EventManager _mgr; + public event DtmfHandler DtmfReceived; + private readonly int _dtmfWaitCount = 0; + private ManualResetEvent _dtmfWaitEvent; + private bool _abortSpeechOnDtmf; + private bool _answered; + private IvrInterfaceHandler _handler = null; + private string _lastAbortDigits = "*"; + + public IvrInterface(EventManager mgr, string uuid) + { + if (mgr == null) + throw new ArgumentNullException("mgr"); + if (string.IsNullOrEmpty(uuid)) + throw new ArgumentNullException("uuid"); + + _mgr = mgr; + mgr.EventReceived += OnEvent; + _uuid = uuid; + + mgr.Send(new ParkCmd(uuid)); + } + + public IAsyncResult BeginInvoke(IvrInterfaceHandler handler, AsyncCallback callback, object state) + { + _handler = handler; + return handler.BeginInvoke(this, callback, state); + } + + public void EndInvoke(IAsyncResult result) + { + if (_handler != null) + _handler.EndInvoke(result); + } + + /// <summary> + /// dont play phrases as long as we have DTMF in the buffer. + /// </summary> + public bool AbortSpeechOnDtmf + { + get { return _abortSpeechOnDtmf; } + set { _abortSpeechOnDtmf = value; } + } + + public bool Answered + { + get { return _answered; } + } + + private void OnEvent(EventBase receivedEvent) + { + if (receivedEvent is EventChannelAnswer) + { + _answered = true; + } +/* else if (receivedEvent is EventDtmfStatus) + { + // Let's always dequeue dtmf. + EventDtmfStatus evt = (EventDtmfStatus) receivedEvent; + if (evt.UniqueId == _uuid) + _mgr.Send(new GetDtmfCmd(_uuid, evt.Count)); + }*/ + else if (receivedEvent is EventDtmf) + { + EventDtmf evt = (EventDtmf) receivedEvent; + lock (_dtmf) + _dtmf += evt.Digit; + if (_dtmfWaitCount >= _dtmf.Length) + _dtmfWaitEvent.Set(); + + if (DtmfReceived != null) + DtmfReceived(this, new DtmfEventArgs(_dtmf)); + } + else if (receivedEvent is EventChannelDestroy || receivedEvent is EventChannelHangup) + { + if (_mgr != null) + { + _mgr.EventReceived -= OnEvent; + _mgr = null; + } + } + } + + /// <summary> + /// Wait on dtmf. + /// </summary> + /// <param name="count">Number of digits to get</param> + /// <param name="timeout">number of seconds to wait on all digits.</param> + /// <remarks>You can also used the Dtmf event if you want to use asynchrounous programming.</remarks> + /// <seealso cref="DtmfReceived"/> + public string GetDtmf(int count, int timeout) + { + if (_mgr == null) + return string.Empty; + if (_dtmfWaitEvent != null) + throw new InvalidOperationException("Already waiting on an event."); + + if (_dtmf.Length < count) + { + _dtmfWaitEvent = new ManualResetEvent(false); + if (!_dtmfWaitEvent.WaitOne(timeout * 1000, true)) + { + _dtmf = string.Empty; + return string.Empty; + } + } + + lock (_dtmf) + { + if (_dtmf.Length >= count) + { + string dtmf = _dtmf.Substring(0, count); + _dtmf = _dtmf.Remove(count); + return dtmf; + } + } + + return string.Empty; + } + + public void Play(string path, string digitsToAbortOn) + { + if (_mgr == null) + return; + + if (_abortSpeechOnDtmf && _dtmf != string.Empty) + return; + + if (digitsToAbortOn != _lastAbortDigits) + { + _mgr.Send(new SetVariable(_uuid, "playback_terminators", digitsToAbortOn)); + _lastAbortDigits = digitsToAbortOn; + } + + _mgr.Send(new PlaybackCmd(_uuid, _baseSoundPath + path)); + } + + public void Record(string path, bool stop, int limit) + { + if (_mgr == null) + return; + _mgr.Send(new RecordCmd(_uuid, _baseSoundPath + path, stop, limit)); + } + + public void Record(string path, int limit) + { + if (_mgr == null) + return; + _mgr.Send(new RecordCmd(_uuid, _baseSoundPath + path, limit)); + } + + public void Sleep(int ms) + { + if (_mgr == null) + return; + _mgr.Send(new SleepCmd(_uuid, ms)); + } + } + + public class DtmfEventArgs : EventArgs + { + private string _dtmf; + private string _dtmfCopy; + + public DtmfEventArgs(string dtmf) + { + _dtmf = dtmf; + _dtmfCopy = (string) _dtmf.Clone(); + } + + /// <summary> + /// You cannot remove digits from the buffer (since it's a copy of the real buffer). + /// </summary> + /// <seealso cref="RemoveDigits"/> + public string Dtmf + { + get { return _dtmfCopy; } + } + + /// <summary> + /// Remove digits from the real buffer. + /// </summary> + /// <param name="count">number of digits to remove.</param> + public void RemoveDigits(int count) + { + lock (_dtmf) + { + if (count > _dtmf.Length) + _dtmf = string.Empty; + else + _dtmf = _dtmf.Remove(0, count); + _dtmfCopy = (string)_dtmf.Clone(); + } + } + } + + public delegate void DtmfHandler(object source, DtmfEventArgs args); + + public delegate void IvrInterfaceHandler(IvrInterface app); +} Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/PartyInfo.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/PartyInfo.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,150 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace FreeSwitch.EventSocket +{ + public class PartyInfo + { + private string m_userName = string.Empty; + private string m_dialplan = string.Empty; + private string m_callerIdName = string.Empty; + private string m_callerIdNumber = string.Empty; + private string m_destinationNumber = string.Empty; + private string m_uniqueId = string.Empty; + private string m_source = string.Empty; + private string m_context = string.Empty; + private string m_channelName = string.Empty; + private bool m_screenBit; + private bool m_privacyHideName; + private bool m_privacyHideNumber; + + public PartyInfo() + { + m_userName = string.Empty; + m_dialplan = string.Empty; + m_callerIdName = string.Empty; + } + + public string Dialplan + { + get { return m_dialplan; } + set { m_dialplan = value; } + } + + public string CallerIdName + { + get { return m_callerIdName; } + set { m_callerIdName = value; } + } + + public string CallerIdNumber + { + get { return m_callerIdNumber; } + set { m_callerIdNumber = value; } + } + + public string DestinationNumber + { + get { return m_destinationNumber; } + set { m_destinationNumber = value; } + } + + public string UniqueId + { + get { return m_uniqueId; } + set { m_uniqueId = value; } + } + + public string Source + { + get { return m_source; } + set { m_source = value; } + } + + public string Context + { + get { return m_context; } + set { m_context = value; } + } + + public string ChannelName + { + get { return m_channelName; } + set { m_channelName = value; } + } + + public bool ScreenBit + { + get { return m_screenBit; } + set { m_screenBit = value; } + } + + public bool PrivacyHideName + { + get { return m_privacyHideName; } + set { m_privacyHideName = value; } + } + + public bool PrivacyHideNumber + { + get { return m_privacyHideNumber; } + set { m_privacyHideNumber = value; } + } + + public string UserName + { + get { return m_userName; } + set { m_userName = value; } + } + + public bool Parse(string name, string value) + { + switch (name) + { + case "username": + m_userName = value; + break; + case "dialplan": + Dialplan = value; + break; + case "caller-id-name": + CallerIdName = value; + break; + case "caller-id-number": + CallerIdNumber = value; + break; + case "destination-number": + DestinationNumber = value; + break; + case "unique-id": + UniqueId = value; + break; + case "source": + Source = value; + break; + case "context": + Context = value; + break; + case "channel-name": + ChannelName = value; + break; + case "screen-bit": + ScreenBit = value == "yes"; + break; + case "privacy-hide-name": + PrivacyHideName = value == "yes"; + break; + case "privacy-hide-number": + PrivacyHideNumber = value == "yes"; + break; + default: + return false; + } + + return true; + + } + + } +} Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/PlainEventMsg.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/PlainEventMsg.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,80 @@ +using System; +using System.Collections.Specialized; +using EventSocketParser; + +namespace FreeSwitch.EventSocket +{ + public class PlainEventMsg + { + private string _contentType = string.Empty; + private int _contentLength = -1; + private string _body = string.Empty; + + public string ContentType + { + get { return _contentType; } + set { _contentType = value; } + } + + public int ContentLength + { + get { return _contentLength; } + set { _contentLength = value; } + } + + public string Body + { + get { return _body; } + set { _body = value; } + } + + public bool ValidateHeader() + { + if (_contentType == string.Empty) + return false; + if (_contentType == "command/reply") + return _body != string.Empty; + + return true; + } + + public bool Validate() + { + if (!ValidateHeader()) + return false; + + if (_contentLength > 0) + return _contentLength == _body.Length || _contentLength == _body.Length + 2; // include first and last line breaks that we skip in parsing + + return true; + } + + + public NameValueCollection BodyToNameValue(bool urlDecodeValues) + { + NameValueCollection items = new NameValueCollection(); + StringParser parser = new StringParser(_body); + string name = parser.Read(':', true); + while (!parser.EOF && name != string.Empty) + { + string value = parser.ReadLine(true); + if (items[name] == null) + { + try + { + items.Add(name.ToLower(), Uri.UnescapeDataString(value)); + } + catch (UriFormatException) + { + // add the value unformatted + items.Add(name.ToLower(), value); + } + } + + name = parser.Read(':', true); + } + + return items; + } + } +} Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Program.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Program.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using System.Text; +using FreeSwitch.EventSocket; + +namespace FreeSwitch.EventSocket +{ + class Program + { + /// <summary> + /// This method is called by the event delegate. + /// </summary> + /// <param name="eb">Reference to an event, each event has their own class.</param> + void HandleEvent(EventBase eb) + { + //Console.WriteLine(eb.DateLocal + " Got Event: " + eb.Name); + + + if (eb is EventChannelHangup) + Console.WriteLine(eb.DateLocal + " Hangup reason: " + ((EventChannelHangup)eb).Cause.ToString()); + } + + static void Main(string[] args) + { + Program p = new Program(); + + /// Create a new FreeSwitch event socket. + EventManager eventManager = new EventManager(); + + // Hook all events to the same delegate. Can also provide one delegate per event. + eventManager.EventReceived += p.HandleEvent; + eventManager.Subscribe(new Events(Event.All)); + + // Connect to localhost + eventManager.Start("localhost"); + + + System.Threading.Thread.Sleep(1000000); + + //a. + } + } +} Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Properties/AssemblyInfo.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Properties/AssemblyInfo.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,33 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("FreeSwitch.EventSocket")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("FreeSwitch.EventSocket")] +[assembly: AssemblyCopyright("Copyright © 2007")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("db16a54e-3305-4b56-92a1-70cc95179bc6")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/SipEvents/EventPresence.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/SipEvents/EventPresence.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,112 @@ +namespace FreeSwitch.EventSocket +{ + public class EventPresence : SipEvent + { + private PartyInfo _caller; + private string _rpid = string.Empty; + private string _status = string.Empty; + //private string _callId; // not "presencein/register", "presenceout/register" + //private string _contact; // not "presencein/register", "presenceout/register" + //private string _expires; //not "presencein/register", "presenceout/register" + private string _eventType = string.Empty; + private string _login = string.Empty; + private EventChannelState _channelState; + + public string Login + { + get { return _login; } + set { _login = value; } + } + + /// <summary> + /// "Click to call", "Registered", "unavailable", "Active (%d waiting)", "Idle" + /// </summary> + public string Status + { + get { return _status; } + set { _status = value; } + } + + public string Rpid + { + get { return _rpid; } + set { _rpid = value; } + } + + /// <summary> + /// Caller is only specified on state CS_RING + /// and not on CS_HANGUP + /// </summary> + public PartyInfo Caller + { + get { return _caller; } + set { _caller = value; } + } + + /// <summary> + /// presence, + /// </summary> + public string PresenceEventType + { + get { return _eventType; } + set { _eventType = value; } + } + + /// <summary> + /// We *may* have channel state info + /// </summary> + public EventChannelState ChannelState + { + get { return _channelState; } + set { _channelState = value; } + } + + + /* + proto: sip + login: sip%3Amod_sofia%40192.168.0.58%3A5070 + rpid: unknown + from: gauffin%40gauffin.com + status: Registered + * */ + public override bool ParseCommand(string name, string value) + { + switch (name) + { + case "status": + _status = value; + break; + case "rpid": + _rpid = value; + break; + case "login": + _login = value; + break; + case "event_type": + _eventType = value; + break; + + default: + if (name.Length > 7 && name.Substring(0, 7) == "caller-") + { + if (Caller == null) + Caller = new PartyInfo(); + return Caller.Parse(name.Substring(7), value); + } + else + { + if (base.ParseCommand(name, value)) + return true; + else + { + if (_channelState == null) + _channelState = new EventChannelState(); + return _channelState.ParseCommand(name, value); + } + } + + } + return true; + } + } +} \ No newline at end of file Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/SipEvents/EventPresenceIn.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/SipEvents/EventPresenceIn.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,6 @@ +namespace FreeSwitch.EventSocket +{ + public class EventPresenceIn : EventPresence + { + } +} Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/SipEvents/EventPresenceOut.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/SipEvents/EventPresenceOut.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,8 @@ +namespace FreeSwitch.EventSocket +{ + public class EventPresenceOut : EventPresence + { + + + } +} Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/SipEvents/EventPresenceProbe.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/SipEvents/EventPresenceProbe.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,10 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace FreeSwitch.EventSocket.SipEvents +{ + class EventPresenceProbe : EventPresence + { + } +} Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/SipEvents/EventRoster.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/SipEvents/EventRoster.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,10 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace FreeSwitch.EventSocket +{ + class EventRoster : SipEvent + { + } +} Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/SipEvents/EventSofiaExpire.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/SipEvents/EventSofiaExpire.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,63 @@ +namespace FreeSwitch.EventSocket +{ + public class EventSofiaExpire : EventPresence + { + private string _profileName; + private string _userName; + private string _domain; + private string _userAgent; + + public string ProfileName + { + get { return _profileName; } + set { _profileName = value; } + } + + public string UserName + { + get { return _userName; } + set { _userName = value; } + } + + public string Domain + { + get { return _domain; } + set { _domain = value; } + } + + public string UserAgent + { + get { return _userAgent; } + set { _userAgent = value; } + } + + /* + switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "profile-name", "%s", argv[6]); + switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "user", "%s", argv[1]); + switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "host", "%s", argv[2]); + switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "user-agent", "%s", argv[5]); + * */ + public override bool ParseCommand(string name, string value) + { + switch (name) + { + case "profile-name": + _profileName = value; + break; + case "user": + _userName = value; + break; + case "host": + _domain = value; + break; + case "user-agent": + _userAgent = value; + break; + default: + return base.ParseCommand(name, value); + } + return true; + + } + } +} Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/SipEvents/EventSofiaRegister.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/SipEvents/EventSofiaRegister.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,92 @@ +namespace FreeSwitch.EventSocket +{ + /* + * profile-name: gauffin.com +from-user: jonas +from-host: gauffin.com +contact: %22Jonas%20Gauffin%22%20%3Csip%3Ajonas%40192.168.1.101%3A5060%3E +*/ + + /// <summary> + /// Sofia_reg.c way down in sofia_reg_handle_register + /// </summary> + public class EventSofiaRegister : EventBase + { + private string _domain; + private string _profileName; + private string _user; + private string _contact; + private string _callId; + private int _expires; + + public string ProfileName + { + get { return _profileName; } + set { _profileName = value; } + } + + public string UserName + { + get { return _user; } + set { _user = value; } + } + + public string Domain + { + get { return _domain; } + set { _domain = value; } + } + + public string Contact + { + get { return _contact; } + set { _contact = value; } + } + + public string CallId + { + get { return _callId; } + set { _callId = value; } + } + + public int Expires + { + get { return _expires; } + set { _expires = value; } + } + + /* + switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "profile-name", "%s", profile->name); + switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "from-user", "%s", to_user); + switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "from-host", "%s", to_host); + switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "rpid", "%s", rpid); + */ + public override bool ParseCommand(string name, string value) + { + switch (name) + { + case "profile-name": + _profileName = value; + break; + case "from-user": + _user = value; + break; + case "from-host": + _domain = value; + break; + case "contact": + _contact = value; + break; + case "call-id": + _callId = value; + break; + case "expires": + int.TryParse(value, out _expires); + break; + default: + return base.ParseCommand(name, value); + } + return true; + } + } +} \ No newline at end of file Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/SipEvents/SipEvent.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/SipEvents/SipEvent.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,39 @@ +namespace FreeSwitch.EventSocket +{ + public class SipEvent : EventBase + { + private string _from; + private string _protocol; + + public string Protocol + { + get { return _protocol; } + set { _protocol = value; } + } + + /// <summary> + /// username@domain + /// </summary> + public string From + { + get { return _from; } + set { _from = value; } + } + + public override bool ParseCommand(string name, string value) + { + switch (name) + { + case "from": + _from = value; + break; + case "proto": + _protocol = value; + break; + default: + return base.ParseCommand(name, value); + } + return true; + } + } +} \ No newline at end of file Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/StringHelper.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/StringHelper.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,55 @@ +namespace FreeSwitch.EventSocket +{ + public static class StringHelper + { + /// <summary> + /// This method converts a enum value to the correct format + /// that FreeSwitch uses (WORD1_WORD2) instead of the CamelCase that + /// we use in .net. + /// </summary> + /// <param name="name"></param> + /// <returns></returns> + public static string UpperCaseToCamelCase(string name) + { + bool isFirst = true; + string result = string.Empty; + foreach (char ch in name) + { + if (isFirst) + { + result += char.ToUpper(ch); + isFirst = false; + } + else + { + if (ch == '_') + isFirst = true; + else + result += char.ToLower(ch); + } + } + return result; + } + + public static string CamelCaseToUpperCase(string name) + { + string result = string.Empty; + bool isFirst = true; + foreach (char ch in name) + { + if (char.IsUpper(ch)) + { + if (!isFirst) + result += '_'; + else + isFirst = false; + result += char.ToUpper(ch); + } + else + result += char.ToUpper(ch); + } + + return result; + } + } +} \ No newline at end of file Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/StringParser.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/StringParser.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,269 @@ +using System.Collections.Generic; + +namespace EventSocketParser +{ + internal class StringParser + { + private readonly Stack<int> _savedPositions = new Stack<int>(); + private int _pos; + private string _text; + + public StringParser(string text) + { + _pos = 0; + _text = text; + } + + public bool EOF + { + get { return IsEOF(_pos); } + } + + /// <summary> + /// true if we are currently on a emty line + /// </summary> + public bool EOL + { + get + { + if (EOF) + return false; + else if (_text[_pos] == '\n') + return true; + else if (_pos < _text.Length - 2) + return _text[_pos] == '\r' && _text[_pos + 1] == '\n'; + else + return false; + } + } + + public void SavePos() + { + _savedPositions.Push(_pos); + } + + public void RestorePos() + { + _pos = _savedPositions.Pop(); + } + + public void RemoveSavedPos() + { + _savedPositions.Pop(); + } + + public void ClearSavedPositions() + { + _savedPositions.Clear(); + } + + private bool IsEOF(int pos) + { + return pos >= _text.Length - 1; + } + + public bool IsEmptyLine(bool skipWhitespaces) + { + if (EOF) + return false; + else if (_pos == _text.Length - 1) + return _text[_pos] == '\n'; + else + return _text[_pos] == '\r' && _text[_pos + 1] == '\n'; + } + + public string PeekWord(bool skipWS, bool stopAtEOL) + { + int startpos = _pos; + if (skipWS) + SkipWS(); + int pos = FindWS(stopAtEOL); + _pos = startpos; + + if (pos != -1) + return _text.Substring(_pos, pos - _pos); + else + return string.Empty; + } + + public string GetWord(bool skipWS, bool stopAtEOL) + { + int startpos = _pos; + if (skipWS) + SkipWS(); + int pos = FindWS(stopAtEOL); + + _pos = pos; + + if (pos != -1) + return _text.Substring(startpos, pos - startpos); + else + return string.Empty; + } + + public string ReadLine() + { + return ReadLine(false); + } + + public string ReadLine(bool trimWhiteSpaces) + { + if (EOF) + return string.Empty; + + if (trimWhiteSpaces) + SkipWS(); + + // loop until we get new line chars + int startpos = _pos; + while (!EOF && !IsEOL()) + ++_pos; + + // Save _pos, trim whitespaces, restore _pos + int pos = _pos; + if (trimWhiteSpaces) + TrimEnd(); + int endpos = _pos; + _pos = pos; + + // Move to after new line chars + if (_text[_pos] == '\r') + _pos += 2; + else + ++_pos; + + // .. and the result is line without whitespaces at the end and without new line chars. + return _text.Substring(startpos, endpos - startpos); + } + + public string ReadToEmptyLine() + { + int chars = 4; + int pos = _text.IndexOf("\n\n", _pos); + if (pos == -1) + { + chars = 2; + pos = _text.IndexOf("\n\n", _pos); + } + if (pos == -1) + return string.Empty; + + int startpos = _pos; + _pos = pos + chars; + return _text.Substring(startpos, pos - startpos); + } + + public string Read(int chars) + { + if (_text.Length - _pos < chars) + return string.Empty; + + string result = _text.Substring(_pos, chars); + _pos += chars; + return result; + } + + public string ReadToEnd() + { + string result = _text.Substring(_pos, _text.Length - _pos); + _pos = _text.Length; + return result; + } + + public string Read(char delimiter, bool skipWS) + { + if (skipWS) + SkipWS(); + + // find delimiter + int startpos = _pos; + while (!EOF && _text[_pos] != delimiter) + ++_pos; + + // did not find it, reset pos + if (EOF) + { + _pos = startpos; + return string.Empty; + } + else + { + ++_pos; // skip delimiter + int endpos = TrimEnd(); // skip + return _text.Substring(startpos, endpos - startpos); + } + } + + private int TrimEnd() + { + int pos = _pos; + while (IsWS(_text[pos])) + --pos; + return pos; + } + + private int FindWS(bool stopAtEOL) + { + if (!stopAtEOL) + return FindWS(); + + int pos = _pos; + while (!IsEOF(pos) && !IsEOL(_text[pos]) && !IsWS(_text[pos])) + ++pos; + + return IsEOF(pos) ? -1 : pos; + } + + private bool IsEOL() + { + if (_text[_pos] == '\r' && _text[_pos + 1] == '\n') + return true; + else if (_text[_pos] == '\n') + return true; + else + return false; + } + + private bool IsEOL(char ch) + { + return ch == '\r' || ch == '\n'; + } + + private bool IsWS(char ch) + { + return ch == '\t' || ch == ' '; + } + + private int FindWS() + { + int pos = _pos; + while (!IsEOF(pos) && !IsWS(_text[pos])) + ++pos; + + return IsEOF(pos) ? -1 : pos; + } + + public void SkipWS() + { + while (!EOF && IsWS(_text[_pos])) + ++_pos; + } + + public void RemoveUsedContent() + { + _text = _text.Remove(0, _pos); + _pos = 0; + } + + public void Append(string value) + { + _text += value; + } + + public void Clear() + { + _text = string.Empty; + _pos = 0; + } + } +} \ No newline at end of file Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/IvrSocket/IvrSocket.csproj ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/IvrSocket/IvrSocket.csproj Thu May 1 14:27:39 2008 @@ -0,0 +1,54 @@ +<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <ProductVersion>8.0.50727</ProductVersion> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{22F26D13-0A0E-4345-9FEC-CE13FC8F37FD}</ProjectGuid> + <OutputType>Exe</OutputType> + <AppDesignerFolder>Properties</AppDesignerFolder> + <RootNamespace>IvrSocket</RootNamespace> + <AssemblyName>IvrSocket</AssemblyName> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> + <DebugSymbols>true</DebugSymbols> + <DebugType>full</DebugType> + <Optimize>false</Optimize> + <OutputPath>bin\Debug\</OutputPath> + <DefineConstants>DEBUG;TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> + <DebugType>pdbonly</DebugType> + <Optimize>true</Optimize> + <OutputPath>bin\Release\</OutputPath> + <DefineConstants>TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <ItemGroup> + <Reference Include="System" /> + <Reference Include="System.Data" /> + <Reference Include="System.Xml" /> + </ItemGroup> + <ItemGroup> + <Compile Include="Program.cs" /> + <Compile Include="Properties\AssemblyInfo.cs" /> + <Compile Include="Voicemail.cs" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\FreeSwitchEventSocket\FreeSwitch.EventSocket.csproj"> + <Project>{3F8895F6-F710-4323-B96A-4EFB6BC97E08}</Project> + <Name>FreeSwitch.EventSocket</Name> + </ProjectReference> + </ItemGroup> + <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> + <!-- To modify your build process, add your task inside one of the targets below and uncomment it. + Other similar extension points exist, see Microsoft.Common.targets. + <Target Name="BeforeBuild"> + </Target> + <Target Name="AfterBuild"> + </Target> + --> +</Project> \ No newline at end of file Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/IvrSocket/Program.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/IvrSocket/Program.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,38 @@ +using System; +using FreeSwitch.EventSocket; + +namespace IvrSocket +{ + class Program + { + private static EventManager mgr; + static void Main(string[] args) + { + mgr = new EventManager(); + mgr.EventReceived += IvrManager; + mgr.Subscribe(Event.All); + mgr.Start("localhost"); + Console.ReadLine(); + } + + private static void IvrManager(EventBase receivedEvent) + { + Console.WriteLine(receivedEvent.Name); + if (receivedEvent is ChannelEvent) + { + ChannelEvent evt = (ChannelEvent) receivedEvent; + Console.WriteLine(evt.Name + ": " + evt.UniqueId); + } + if (receivedEvent is EventChannelAnswer) + { + EventChannelAnswer answer = (EventChannelAnswer)receivedEvent; + if (answer.Parameters["variable_ivr_name"] == "voicemail") + new Voicemail(mgr, answer.UniqueId); + } + else if (receivedEvent is EventChannelHangup) + { + Console.WriteLine("Bye bye baby!"); + } + } + } +} Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/IvrSocket/Properties/AssemblyInfo.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/IvrSocket/Properties/AssemblyInfo.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,33 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("IvrSocket")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("IvrSocket")] +[assembly: AssemblyCopyright("Copyright © 2008")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("3e447189-bfd8-4412-93bb-da3543dd2ca6")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/IvrSocket/Voicemail.cs ============================================================================== --- (empty file) +++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/IvrSocket/Voicemail.cs Thu May 1 14:27:39 2008 @@ -0,0 +1,28 @@ +using System; +using System.Threading; +using FreeSwitch.EventSocket; +using FreeSwitch.EventSocket.Ivr; + +namespace IvrSocket +{ + /// <summary> + /// Very simple voicemail app =) + /// </summary> + class Voicemail + { + private readonly IvrInterface _ivr; + + public Voicemail(EventManager mgr, string uuid) + { + _ivr = new IvrInterface(mgr, uuid); + _ivr.BeginInvoke(OnIvr, null, null); + } + + private void OnIvr(IvrInterface app) + { + _ivr.Play("sv\\system\\record_after_beep.wav", IvrInterface.AllDigits); + //_ivr.Sleep(5000); + //_ivr.Record("voicemails\\" + Guid.NewGuid() + ".wav", 60); + } + } +}