public SIPNonInviteServerUserAgent( SIPTransport sipTransport, SIPEndPoint outboundProxy, string sipUsername, string sipDomain, SIPCallDirection callDirection, SIPAssetGetDelegate <SIPAccount> getSIPAccount, SIPAuthenticateRequestDelegate sipAuthenticateRequest, SIPMonitorLogDelegate logDelegate, SIPNonInviteTransaction transaction) { m_sipTransport = sipTransport; m_outboundProxy = outboundProxy; m_sipUsername = sipUsername; m_sipDomain = sipDomain; m_sipCallDirection = callDirection; GetSIPAccount_External = getSIPAccount; SIPAuthenticateRequest_External = sipAuthenticateRequest; Log_External = logDelegate ?? Log_External; m_transaction = transaction; m_transaction.TransactionTraceMessage += TransactionTraceMessage; //m_uasTransaction.UASInviteTransactionTimedOut += ClientTimedOut; //m_uasTransaction.UASInviteTransactionCancelled += UASTransactionCancelled; //m_uasTransaction.TransactionRemoved += new SIPTransactionRemovedDelegate(UASTransaction_TransactionRemoved); //m_uasTransaction.TransactionStateChanged += (t) => { logger.Debug("Transaction state change to " + t.TransactionState + ", uri=" + t.TransactionRequestURI.ToString() + "."); }; }
public SIPCallDescriptor( string username, string password, string uri, string from, string to, string routeSet, List <string> customHeaders, string authUsername, SIPCallDirection callDirection, string contentType, string content, IPAddress mangleIPAddress) { Username = username; Password = password; Uri = uri; From = from ?? m_defaultFromURI; To = to ?? uri; RouteSet = routeSet; CustomHeaders = customHeaders ?? new List <string>(); AuthUsername = authUsername; CallDirection = callDirection; ContentType = contentType; Content = content; MangleIPAddress = mangleIPAddress; }
public SIPServerUserAgent( SIPTransport sipTransport, SIPEndPoint outboundProxy, string sipUsername, string sipDomain, SIPCallDirection callDirection, GetSIPAccountDelegate getSIPAccount, SIPAuthenticateRequestDelegate sipAuthenticateRequest, SIPMonitorLogDelegate logDelegate, UASInviteTransaction uasTransaction) { m_sipTransport = sipTransport; m_outboundProxy = outboundProxy; m_sipUsername = sipUsername; m_sipDomain = sipDomain; CallDirection = callDirection; GetSIPAccount_External = getSIPAccount; SIPAuthenticateRequest_External = sipAuthenticateRequest; Log_External = logDelegate ?? Log_External; m_uasTransaction = uasTransaction; m_uasTransaction.TransactionTraceMessage += TransactionTraceMessage; m_uasTransaction.UASInviteTransactionTimedOut += ClientTimedOut; m_uasTransaction.UASInviteTransactionCancelled += UASTransactionCancelled; m_uasTransaction.TransactionRemoved += new SIPTransactionRemovedDelegate(UASTransaction_TransactionRemoved); }
public SIPNonInviteServerUserAgent( SIPTransport sipTransport, SIPEndPoint outboundProxy, string sipUsername, string sipDomain, SIPCallDirection callDirection, SIPAssetGetDelegate<SIPAccount> getSIPAccount, SIPAuthenticateRequestDelegate sipAuthenticateRequest, SIPMonitorLogDelegate logDelegate, SIPNonInviteTransaction transaction) { m_sipTransport = sipTransport; m_outboundProxy = outboundProxy; m_sipUsername = sipUsername; m_sipDomain = sipDomain; m_sipCallDirection = callDirection; GetSIPAccount_External = getSIPAccount; SIPAuthenticateRequest_External = sipAuthenticateRequest; Log_External = logDelegate ?? Log_External; m_transaction = transaction; m_transaction.TransactionTraceMessage += TransactionTraceMessage; //m_uasTransaction.UASInviteTransactionTimedOut += ClientTimedOut; //m_uasTransaction.UASInviteTransactionCancelled += UASTransactionCancelled; //m_uasTransaction.TransactionRemoved += new SIPTransactionRemovedDelegate(UASTransaction_TransactionRemoved); //m_uasTransaction.TransactionStateChanged += (t) => { logger.Debug("Transaction state change to " + t.TransactionState + ", uri=" + t.TransactionRequestURI.ToString() + "."); }; }
public void Execute( DialPlanContext dialPlanContext, ISIPServerUserAgent uas, SIPCallDirection callDirection, DialogueBridgeCreatedDelegate createBridgeDelegate, ISIPCallManager callManager) { if (dialPlanContext == null) { throw new ArgumentNullException("The DialPlanContext parameter cannot be null when attempting to execute a dialplan."); } if (uas.IsUASAnswered) { // This can occur if the call is cancelled by the caller between when the INVITE was received and when the dialplan execution was ready. logger.Warn("Dialplan execution for " + dialPlanContext.SIPDialPlan.DialPlanName + " for " + uas.CallDirection + " call to " + uas.CallDestination + " did not proceed as call already answered."); dialPlanContext.DialPlanExecutionFinished(); } else { if (dialPlanContext.ContextType == DialPlanContextsEnum.Line) { ThreadPool.QueueUserWorkItem(delegate { ExecuteDialPlanLine((DialPlanLineContext)dialPlanContext, uas, callDirection, createBridgeDelegate, callManager); }); } else { ExecuteDialPlanScript((DialPlanScriptContext)dialPlanContext, uas, callDirection, createBridgeDelegate, callManager); } } }
public SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum serverType, SIPMonitorEventTypesEnum eventType, string message, SIPRequest sipRequest, SIPResponse sipResponse, SIPEndPoint localEndPoint, SIPEndPoint remoteEndPoint, SIPCallDirection callDirection) { m_serialisationPrefix = SERIALISATION_PREFIX; ClientType = SIPMonitorClientTypesEnum.Console; ServerType = serverType; EventType = eventType; Message = message; RemoteEndPoint = remoteEndPoint; ServerEndPoint = localEndPoint; Created = DateTimeOffset.UtcNow; #if !SILVERLIGHT ProcessID = Process.GetCurrentProcess().Id; #endif string dirn = (callDirection == SIPCallDirection.In) ? CALLDIRECTION_IN_STRING : CALLDIRECTION_OUT_STRING; if (sipRequest != null) { Message = $"REQUEST ({Created:HH:mm:ss:fff}): {localEndPoint}{dirn}{remoteEndPoint}\r\n{sipRequest}"; } else if (sipResponse != null) { Message = $"RESPONSE ({Created:HH:mm:ss:fff}): {localEndPoint}{dirn}{remoteEndPoint}\r\n{sipResponse}"; } }
public SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum serverType, SIPMonitorEventTypesEnum eventType, string message, SIPRequest sipRequest, SIPResponse sipResponse, SIPEndPoint localEndPoint, SIPEndPoint remoteEndPoint, SIPCallDirection callDirection) { m_serialisationPrefix = SERIALISATION_PREFIX; ClientType = SIPMonitorClientTypesEnum.Console; ServerType = serverType; EventType = eventType; Message = message; RemoteEndPoint = remoteEndPoint; ServerEndPoint = localEndPoint; Created = DateTimeOffset.UtcNow; ProcessID = Process.GetCurrentProcess().Id; string dirn = (callDirection == SIPCallDirection.In) ? CALLDIRECTION_IN_STRING : CALLDIRECTION_OUT_STRING; if (sipRequest != null) { Message = "REQUEST (" + Created.ToString("HH:mm:ss:fff") + "): " + localEndPoint + dirn + remoteEndPoint + "\r\n" + sipRequest.ToString(); } else if (sipResponse != null) { Message = "RESPONSE (" + Created.ToString("HH:mm:ss:fff") + "): " + localEndPoint + dirn + remoteEndPoint + "\r\n" + sipResponse.ToString(); } }
private void GetRules(int offset, int count, AssetViewPanel panel, SIPCallDirection ruleDirection) { if (!m_routesPanelRefreshInProgress) { m_routesPanelRefreshInProgress = true; m_riaContext.SimpleWizardRules.Clear(); var routesQuery = m_riaContext.GetSimpleWizardRulesQuery().Where(x => x.DialPlanID == m_dialPlan.ID && x.Direction == ruleDirection.ToString()).OrderBy(x => x.Priority).Skip(offset).Take(count); routesQuery.IncludeTotalCount = true; m_riaContext.Load <SimpleWizardRule>(routesQuery, LoadBehavior.RefreshCurrent, RulesLoaded, panel); } }
public List <SimpleWizardRule> GetSimpleWizardRules(string dialplanName, string callDirection) { try { SIPCallDirection callDirn = SIPCallDirection.None; Enum.TryParse <SIPCallDirection>(callDirection, out callDirn); if (callDirn == SIPCallDirection.None) { throw new ApplicationException("The call direction string of " + callDirection + " passed to GetSimpleWizardRules was not recognised."); } using (var ssEntities = new SIPSorceryEntities()) { if (!dialplanName.IsNullOrBlank()) { string callDirnStr = callDirn.ToString(); var rules = (from rule in ssEntities.SimpleWizardRules join dialplan in ssEntities.SIPDialPlans on rule.DialPlanID equals dialplan.ID where rule.Owner == m_owner && dialplan.DialPlanName == dialplanName && rule.Direction == callDirnStr && !rule.IsDisabled orderby rule.Priority select rule).ToList(); logger.Debug("Rules count " + rules.Count + "."); return(rules); } else { throw new ApplicationException("The dialplan name must be specified for GetSimpleWizardRules."); } } } catch (Exception excp) { logger.Error("Exception GetSimpleWizardRules. " + excp.Message); return(null); } }
public SIPCDR( SIPCallDirection callDirection, SIPURI destination, SIPFromHeader from, string callId, SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint) { CDRId = Guid.NewGuid(); Created = DateTimeOffset.UtcNow; CallDirection = callDirection; Destination = destination; From = from; CallId = callId; LocalSIPEndPoint = localSIPEndPoint; RemoteEndPoint = remoteEndPoint; InProgress = false; IsAnswered = false; IsHungup = false; CDRCreated(this); }
public SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum serverType, SIPMonitorEventTypesEnum eventType, string message, SIPRequest sipRequest, SIPResponse sipResponse, SIPEndPoint localEndPoint, SIPEndPoint remoteEndPoint, SIPCallDirection callDirection) { m_serialisationPrefix = SERIALISATION_PREFIX; ClientType = SIPMonitorClientTypesEnum.Console; ServerType = serverType; EventType = eventType; Message = message; RemoteEndPoint = remoteEndPoint; ServerEndPoint = localEndPoint; Created = DateTimeOffset.UtcNow; #if !SILVERLIGHT ProcessID = Process.GetCurrentProcess().Id; #endif string dirn = (callDirection == SIPCallDirection.In) ? CALLDIRECTION_IN_STRING : CALLDIRECTION_OUT_STRING; if (sipRequest != null) { Message = "REQUEST (" + Created.ToString("HH:mm:ss:fff") + "): " + localEndPoint + dirn + remoteEndPoint + "\r\n" + sipRequest.ToString(); } else if (sipResponse != null) { Message = "RESPONSE (" + Created.ToString("HH:mm:ss:fff") + "): " + localEndPoint + dirn + remoteEndPoint + "\r\n" + sipResponse.ToString(); } }
public void Execute( DialPlanContext dialPlanContext, ISIPServerUserAgent uas, SIPCallDirection callDirection, DialogueBridgeCreatedDelegate createBridgeDelegate, ISIPCallManager callManager) { if (dialPlanContext == null) { throw new ArgumentNullException("The DialPlanContext parameter cannot be null when attempting to execute a dialplan."); } if (uas.IsUASAnswered) { // This can occur if the call is cancelled by the caller between when the INVITE was received and when the dialplan execution was ready. logger.Warn("Dialplan execution for " + dialPlanContext.SIPDialPlan.DialPlanName + " for " + uas.CallDirection + " call to " + uas.CallDestination + " did not proceed as call already answered."); dialPlanContext.DialPlanExecutionFinished(); } else { if (dialPlanContext.ContextType == DialPlanContextsEnum.Line) { ThreadPool.QueueUserWorkItem(delegate { ExecuteDialPlanLine((DialPlanLineContext)dialPlanContext, uas, callDirection, createBridgeDelegate, callManager); }); } else { ExecuteDialPlanScript((DialPlanScriptContext)dialPlanContext, uas, callDirection, createBridgeDelegate, callManager); } } }
public SIPCallDescriptor( string username, string password, string uri, string from, string to, string routeSet, List<string> customHeaders, string authUsername, SIPCallDirection callDirection, string contentType, string content, IPAddress mangleIPAddress) { Username = username; Password = password; Uri = uri; From = from ?? m_defaultFromURI; To = to ?? uri; RouteSet = routeSet; CustomHeaders = customHeaders ?? new List<string>(); AuthUsername = authUsername; CallDirection = callDirection; ContentType = contentType; Content = content; MangleIPAddress = mangleIPAddress; }
/// <summary> /// Processes a dialplan script (currently Ruby scripts only) for a received SIP INVITE request. /// </summary> /// <param name="coreLogDelegate">A function delegate that passes log/diagnostics events back to the SIP Proxy Core.</param> /// <param name="createBridgeDelegate">A function delegate that is called in the event that the dial plan command results in a call being answered and a bridge needing to be created.</param> /// <param name="localEndPoint">The SIP Proxy socket the request was received on.</param> /// <param name="remoteEndPoint">The socket the request was recevied from.</param> /// <param name="clientTransaction">The SIP Invite transaction that initiated the dial plan processing.</param> /// <param name="canonicalFromDomain">If (and only if) the call is an outgoing call this will be set to the canonical domain of the host in the SIP From /// header. An outgoing call is one from an authenticated user destined for an external SIP URI. If the call is an incoming this will be null.</param> /// <param name="canonicalToDomain">If (and only if) the call is an incoming call this will be set to the canonical domain of the host in the SIP URI /// request. An incoming call is one from an external caller to a URI corresponding to a hosted domain on this SIP Proxy.</param> private void ExecuteDialPlanScript( DialPlanScriptContext dialPlanContext, ISIPServerUserAgent uas, SIPCallDirection callDirection, DialogueBridgeCreatedDelegate createBridgeDelegate, ISIPCallManager callManager) { try { if (uas == null) { throw new ArgumentNullException("The ISIPServerUserAgent parameter cannot be null when attempting to execute a dialplan script."); } FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.NewCall, "Executing script dial plan for call to " + uas.CallDestination + ".", dialPlanContext.Owner)); if (!dialPlanContext.DialPlanScript.IsNullOrBlank()) { DialPlanExecutingScript dialPlanExecutionScript = null; int runningScriptCount = (from script in m_runningScripts where !script.Complete select script).Count(); if (runningScriptCount < MAX_ALLOWED_SCRIPTSCOPES) { m_dialPlanScriptContextsCreated++; //FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Creating DialPlanExecutingScript number " + m_dialPlanScriptContextsCreated + " for dialplan execution for script owned by " + dialPlanContext.Owner + ".", null)); dialPlanExecutionScript = new DialPlanExecutingScript(FireProxyLogEvent); } else { FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Running script limit of " + MAX_ALLOWED_SCRIPTSCOPES + " reached.", null)); lock (m_runningScripts) { foreach (DialPlanExecutingScript runningScript in m_runningScripts) { FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, " running script owner=" + runningScript.Owner + ", dialplan name=" + runningScript.ExecutingDialPlanContext.SIPDialPlan.DialPlanName + ", start time=" + runningScript.StartTime.ToString("dd MMM yyyy HH:mm:ss") + ", is complete=" + runningScript.Complete + ".", null)); } } } if (dialPlanExecutionScript != null) { dialPlanExecutionScript.Initialise(dialPlanContext); DialPlanScriptFacade planFacade = new DialPlanScriptFacade( m_sipTransport, dialPlanExecutionScript, FireProxyLogEvent, createBridgeDelegate, (uas.CallRequest != null) ? uas.CallRequest.Copy() : null, // A different copy to the req object. Stops inadvertent changes in the dialplan. callDirection, dialPlanContext, GetCanonicalDomainDelegate_External, callManager, m_sipSorceryPersistor, m_outboundProxySocket, this); DialPlanCRMFacade crmFacade = new DialPlanCRMFacade(FireProxyLogEvent, dialPlanContext); DialPlanLookupFacade lookupFacade = new DialPlanLookupFacade(FireProxyLogEvent, dialPlanContext.Owner); ScriptScope rubyScope = dialPlanExecutionScript.DialPlanScriptScope; rubyScope.SetVariable(SCRIPT_HELPEROBJECT_NAME, planFacade); rubyScope.SetVariable(SCRIPT_CRMOBJECT_NAME, crmFacade); rubyScope.SetVariable(SCRIPT_LOOKUPOBJECT_NAME, lookupFacade); if (uas.CallRequest != null) { rubyScope.SetVariable(SCRIPT_REQUESTOBJECT_NAME, uas.CallRequest.Copy()); } dialPlanExecutionScript.DialPlanScriptThread = new Thread(new ParameterizedThreadStart(delegate { ExecuteScript(dialPlanExecutionScript, dialPlanContext, planFacade, m_rubyScriptCommon + dialPlanContext.DialPlanScript); })); lock (m_runningScripts) { m_runningScripts.Add(dialPlanExecutionScript); } dialPlanExecutionScript.DialPlanScriptThread.Start(); } else { FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.Error, "Error processing call " + uas.CallDestination + " there were no script slots available, script could not be executed.", dialPlanContext.Owner)); dialPlanContext.CallFailed(SIPResponseStatusCodesEnum.InternalServerError, "Dial plan script engine was overloaded", null); } } else { FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "A script dial plan was empty, execution cannot continue.", dialPlanContext.Owner)); dialPlanContext.CallFailed(SIPResponseStatusCodesEnum.InternalServerError, "Dial plan script was empty", null); } } catch (Exception excp) { FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.Error, "Error executing script dialplan for " + uas.CallDestination + ". " + excp.Message, dialPlanContext.Owner)); dialPlanContext.CallFailed(SIPResponseStatusCodesEnum.InternalServerError, "Dial plan exception starting script", null); } }
/// <summary> /// Processes the matched dial plan command for an outgoing call request. This method is used for "exten =>" formatted dial plans. In addition if the dial /// plan owner has requested that their dialplan be used for incoming calls it will process those as well. /// </summary> /// <param name="localEndPoint">The SIP Proxy socket the request was received on.</param> /// <param name="remoteEndPoint">The socket the request was recevied from.</param> /// <param name="transaction">The SIP Invite transaction that initiated the dial plan processing.</param> /// <param name="manglePrivateAddresses">If true private IP addresses will be subtituted for the remote socket.</param> /// <param name="canonicalFromDomain">If (and only if) the call is an outgoing call this will be set to the canonical domain of the host in the SIP From /// header. An outgoing call is one from an authenticated user destined for an external SIP URI. If the call is an incoming this will be null.</param> /// <param name="canonicalToDomain">If (and only if) the call is an incoming call this will be set to the canonical domain of the host in the SIP URI /// request. An incoming call is one from an external caller to a URI corresponding to a hosted domain on this SIP Proxy.</param> private void ExecuteDialPlanLine( DialPlanLineContext dialPlanContext, ISIPServerUserAgent uas, SIPCallDirection callDirection, DialogueBridgeCreatedDelegate createBridgeDelegate, ISIPCallManager callManager) { try { //SIPRequest sipRequest = uas.CallRequest; FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Executing line dial plan for call to " + uas.CallDestination + ".", dialPlanContext.Owner)); DialPlanCommand matchedCommand = dialPlanContext.GetDialPlanMatch(uas.CallDestination); if (matchedCommand == null) { FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Destination " + uas.CallDestination + " not found in line dial plan " + dialPlanContext.SIPDialPlan.DialPlanName + ".", dialPlanContext.Owner)); dialPlanContext.CallFailed(SIPResponseStatusCodesEnum.NotFound, null, null); } else if (Regex.Match(matchedCommand.Command, "Switch|Dial", RegexOptions.IgnoreCase).Success) { if (matchedCommand.Data != null && matchedCommand.Data.Trim().Length > 0) { DialStringParser dialStringParser = new DialStringParser(m_sipTransport, dialPlanContext.Owner, dialPlanContext.SIPAccount, dialPlanContext.SIPProviders, m_sipSorceryPersistor.SIPAccountsPersistor.Get, m_sipSorceryPersistor.SIPRegistrarBindingPersistor.Get, GetCanonicalDomainDelegate_External, LogDelegate_External, dialPlanContext.SIPDialPlan.DialPlanName); ForkCall ForkCall = new ForkCall(m_sipTransport, FireProxyLogEvent, callManager.QueueNewCall, dialStringParser, dialPlanContext.Owner, dialPlanContext.AdminMemberId, m_outboundProxySocket, null, null); ForkCall.CallProgress += dialPlanContext.CallProgress; ForkCall.CallFailed += dialPlanContext.CallFailed; ForkCall.CallAnswered += dialPlanContext.CallAnswered; Queue <List <SIPCallDescriptor> > calls = dialStringParser.ParseDialString(DialPlanContextsEnum.Line, uas.CallRequest.Copy(), matchedCommand.Data, null, null, null, dialPlanContext.CallersNetworkId, null, null, null, null, CustomerServiceLevels.None); ForkCall.Start(calls); } else { FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Error processing dialplan Dial command the dial string was empty.", dialPlanContext.Owner)); } } //else if (Regex.Match(matchedCommand.Command, "RTSP", RegexOptions.IgnoreCase).Success) //{ // RTSPApp rtspCall = new RTSPApp(FireProxyLogEvent, (UASInviteTransaction)transaction, dialPlanContext.Owner); // rtspCall.Start(matchedCommand.Data); //} else if (Regex.Match(matchedCommand.Command, "SIPReply", RegexOptions.IgnoreCase).Success) { string[] replyFields = matchedCommand.Data.Split(','); string statusMessage = (replyFields.Length > 1 && replyFields[1] != null) ? replyFields[1].Trim() : null; SIPResponseStatusCodesEnum status = SIPResponseStatusCodes.GetStatusTypeForCode(Convert.ToInt32(replyFields[0])); if ((int)status >= 300) { dialPlanContext.CallFailed(status, statusMessage, null); } else if ((int)status < 200) { dialPlanContext.CallProgress(status, statusMessage, null, null, null, null); } } else { FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.Error, "Command " + matchedCommand.Command + " is not a valid dial plan command.", dialPlanContext.Owner)); dialPlanContext.CallFailed(SIPResponseStatusCodesEnum.InternalServerError, "Invalid dialplan command " + matchedCommand.Command, null); } } catch (Exception excp) { FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.Error, "Error executing line dialplan for " + uas.CallRequest.URI.ToString() + ". " + excp.Message, dialPlanContext.Owner)); dialPlanContext.DialPlanExecutionFinished(); } }
public SIPCDR( SIPCallDirection callDirection, SIPURI destination, SIPFromHeader from, string callId, SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint) { CDRId = Guid.NewGuid(); Created = DateTimeOffset.UtcNow; CallDirection = callDirection; Destination = destination; From = from; CallId = callId; LocalSIPEndPoint = localSIPEndPoint; RemoteEndPoint = remoteEndPoint; InProgress = false; IsAnswered = false; IsHungup = false; CDRCreated(this); }
/// <summary> /// Processes the matched dial plan command for an outgoing call request. This method is used for "exten =>" formatted dial plans. In addition if the dial /// plan owner has requested that their dialplan be used for incoming calls it will process those as well. /// </summary> /// <param name="localEndPoint">The SIP Proxy socket the request was received on.</param> /// <param name="remoteEndPoint">The socket the request was recevied from.</param> /// <param name="transaction">The SIP Invite transaction that initiated the dial plan processing.</param> /// <param name="manglePrivateAddresses">If true private IP addresses will be subtituted for the remote socket.</param> /// <param name="canonicalFromDomain">If (and only if) the call is an outgoing call this will be set to the canonical domain of the host in the SIP From /// header. An outgoing call is one from an authenticated user destined for an external SIP URI. If the call is an incoming this will be null.</param> /// <param name="canonicalToDomain">If (and only if) the call is an incoming call this will be set to the canonical domain of the host in the SIP URI /// request. An incoming call is one from an external caller to a URI corresponding to a hosted domain on this SIP Proxy.</param> private void ExecuteDialPlanLine( DialPlanLineContext dialPlanContext, ISIPServerUserAgent uas, SIPCallDirection callDirection, DialogueBridgeCreatedDelegate createBridgeDelegate, ISIPCallManager callManager) { try { //SIPRequest sipRequest = uas.CallRequest; FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Executing line dial plan for call to " + uas.CallDestination + ".", dialPlanContext.Owner)); DialPlanCommand matchedCommand = dialPlanContext.GetDialPlanMatch(uas.CallDestination); if (matchedCommand == null) { FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Destination " + uas.CallDestination + " not found in line dial plan " + dialPlanContext.SIPDialPlan.DialPlanName + ".", dialPlanContext.Owner)); dialPlanContext.CallFailed(SIPResponseStatusCodesEnum.NotFound, null, null); } else if (Regex.Match(matchedCommand.Command, "Switch|Dial", RegexOptions.IgnoreCase).Success) { if (matchedCommand.Data != null && matchedCommand.Data.Trim().Length > 0) { DialStringParser dialStringParser = new DialStringParser(m_sipTransport, dialPlanContext.Owner, dialPlanContext.SIPAccount, dialPlanContext.SIPProviders, m_sipSorceryPersistor.SIPAccountsPersistor.Get, m_sipSorceryPersistor.SIPRegistrarBindingPersistor.Get, GetCanonicalDomainDelegate_External, LogDelegate_External, dialPlanContext.SIPDialPlan.DialPlanName); ForkCall ForkCall = new ForkCall(m_sipTransport, FireProxyLogEvent, callManager.QueueNewCall, dialStringParser, dialPlanContext.Owner, dialPlanContext.AdminMemberId, m_outboundProxySocket, null, null); ForkCall.CallProgress += dialPlanContext.CallProgress; ForkCall.CallFailed += dialPlanContext.CallFailed; ForkCall.CallAnswered += dialPlanContext.CallAnswered; Queue<List<SIPCallDescriptor>> calls = dialStringParser.ParseDialString(DialPlanContextsEnum.Line, uas.CallRequest.Copy(), matchedCommand.Data, null, null, null, dialPlanContext.CallersNetworkId, null, null, null, null, CustomerServiceLevels.None); ForkCall.Start(calls); } else { FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Error processing dialplan Dial command the dial string was empty.", dialPlanContext.Owner)); } } //else if (Regex.Match(matchedCommand.Command, "RTSP", RegexOptions.IgnoreCase).Success) //{ // RTSPApp rtspCall = new RTSPApp(FireProxyLogEvent, (UASInviteTransaction)transaction, dialPlanContext.Owner); // rtspCall.Start(matchedCommand.Data); //} else if (Regex.Match(matchedCommand.Command, "SIPReply", RegexOptions.IgnoreCase).Success) { string[] replyFields = matchedCommand.Data.Split(','); string statusMessage = (replyFields.Length > 1 && replyFields[1] != null) ? replyFields[1].Trim() : null; SIPResponseStatusCodesEnum status = SIPResponseStatusCodes.GetStatusTypeForCode(Convert.ToInt32(replyFields[0])); if ((int)status >= 300) { dialPlanContext.CallFailed(status, statusMessage, null); } else if ((int)status < 200) { dialPlanContext.CallProgress(status, statusMessage, null, null, null, null); } } else { FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.Error, "Command " + matchedCommand.Command + " is not a valid dial plan command.", dialPlanContext.Owner)); dialPlanContext.CallFailed(SIPResponseStatusCodesEnum.InternalServerError, "Invalid dialplan command " + matchedCommand.Command, null); } } catch (Exception excp) { FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.Error, "Error executing line dialplan for " + uas.CallRequest.URI.ToString() + ". " + excp.Message, dialPlanContext.Owner)); dialPlanContext.DialPlanExecutionFinished(); } }
/// <summary> /// Processes a dialplan script (currently Ruby scripts only) for a received SIP INVITE request. /// </summary> /// <param name="coreLogDelegate">A function delegate that passes log/diagnostics events back to the SIP Proxy Core.</param> /// <param name="createBridgeDelegate">A function delegate that is called in the event that the dial plan command results in a call being answered and a bridge needing to be created.</param> /// <param name="localEndPoint">The SIP Proxy socket the request was received on.</param> /// <param name="remoteEndPoint">The socket the request was recevied from.</param> /// <param name="clientTransaction">The SIP Invite transaction that initiated the dial plan processing.</param> /// <param name="canonicalFromDomain">If (and only if) the call is an outgoing call this will be set to the canonical domain of the host in the SIP From /// header. An outgoing call is one from an authenticated user destined for an external SIP URI. If the call is an incoming this will be null.</param> /// <param name="canonicalToDomain">If (and only if) the call is an incoming call this will be set to the canonical domain of the host in the SIP URI /// request. An incoming call is one from an external caller to a URI corresponding to a hosted domain on this SIP Proxy.</param> private void ExecuteDialPlanScript( DialPlanScriptContext dialPlanContext, ISIPServerUserAgent uas, SIPCallDirection callDirection, DialogueBridgeCreatedDelegate createBridgeDelegate, ISIPCallManager callManager) { try { if (uas == null) { throw new ArgumentNullException("The ISIPServerUserAgent parameter cannot be null when attempting to execute a dialplan script."); } FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.NewCall, "Executing script dial plan for call to " + uas.CallDestination + ".", dialPlanContext.Owner)); if (!dialPlanContext.DialPlanScript.IsNullOrBlank()) { DialPlanExecutingScript dialPlanExecutionScript = null; int runningScriptCount = (from script in m_runningScripts where !script.Complete select script).Count(); if (runningScriptCount < MAX_ALLOWED_SCRIPTSCOPES) { m_dialPlanScriptContextsCreated++; //FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Creating DialPlanExecutingScript number " + m_dialPlanScriptContextsCreated + " for dialplan execution for script owned by " + dialPlanContext.Owner + ".", null)); dialPlanExecutionScript = new DialPlanExecutingScript(FireProxyLogEvent); } else { FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Running script limit of " + MAX_ALLOWED_SCRIPTSCOPES + " reached.", null)); lock (m_runningScripts) { foreach (DialPlanExecutingScript runningScript in m_runningScripts) { FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, " running script owner=" + runningScript.Owner + ", dialplan name=" + runningScript.ExecutingDialPlanContext.SIPDialPlan.DialPlanName + ", start time=" + runningScript.StartTime.ToString("dd MMM yyyy HH:mm:ss") + ", is complete=" + runningScript.Complete + ".", null)); } } } if (dialPlanExecutionScript != null) { dialPlanExecutionScript.Initialise(dialPlanContext); DialPlanScriptFacade planFacade = new DialPlanScriptFacade( m_sipTransport, dialPlanExecutionScript, FireProxyLogEvent, createBridgeDelegate, (uas.CallRequest != null) ? uas.CallRequest.Copy() : null, // A different copy to the req object. Stops inadvertent changes in the dialplan. callDirection, dialPlanContext, GetCanonicalDomainDelegate_External, callManager, m_sipSorceryPersistor, m_outboundProxySocket, this); DialPlanCRMFacade crmFacade = new DialPlanCRMFacade(FireProxyLogEvent, dialPlanContext); DialPlanLookupFacade lookupFacade = new DialPlanLookupFacade(FireProxyLogEvent, dialPlanContext.Owner); ScriptScope rubyScope = dialPlanExecutionScript.DialPlanScriptScope; rubyScope.SetVariable(SCRIPT_HELPEROBJECT_NAME, planFacade); rubyScope.SetVariable(SCRIPT_CRMOBJECT_NAME, crmFacade); rubyScope.SetVariable(SCRIPT_LOOKUPOBJECT_NAME, lookupFacade); if (uas.CallRequest != null) { rubyScope.SetVariable(SCRIPT_REQUESTOBJECT_NAME, uas.CallRequest.Copy()); } dialPlanExecutionScript.DialPlanScriptThread = new Thread(new ParameterizedThreadStart(delegate { ExecuteScript(dialPlanExecutionScript, dialPlanContext, planFacade, m_rubyScriptCommon + dialPlanContext.DialPlanScript); })); lock (m_runningScripts) { m_runningScripts.Add(dialPlanExecutionScript); } dialPlanExecutionScript.DialPlanScriptThread.Start(); } else { FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.Error, "Error processing call " + uas.CallDestination + " there were no script slots available, script could not be executed.", dialPlanContext.Owner)); dialPlanContext.CallFailed(SIPResponseStatusCodesEnum.InternalServerError, "Dial plan script engine was overloaded", null); } } else { FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "A script dial plan was empty, execution cannot continue.", dialPlanContext.Owner)); dialPlanContext.CallFailed(SIPResponseStatusCodesEnum.InternalServerError, "Dial plan script was empty", null); } } catch (Exception excp) { FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.Error, "Error executing script dialplan for " + uas.CallDestination + ". " + excp.Message, dialPlanContext.Owner)); dialPlanContext.CallFailed(SIPResponseStatusCodesEnum.InternalServerError, "Dial plan exception starting script", null); } }
public DialPlanScriptFacade( SIPTransport sipTransport, DialPlanExecutingScript executingScript, SIPMonitorLogDelegate logDelegate, DialogueBridgeCreatedDelegate createBridge, SIPRequest sipRequest, SIPCallDirection callDirection, DialPlanContext dialPlanContext, GetCanonicalDomainDelegate getCanonicalDomain, ISIPCallManager callManager, //SIPAssetPersistor<SIPAccount> sipAccountPersistor, //SIPAssetPersistor<SIPDialPlan> sipDialPlanPersistor, //SIPAssetPersistor<SIPDialogueAsset> sipDialoguePersistor, //SIPAssetGetListDelegate<SIPRegistrarBinding> getSIPAccountBindings, SIPSorceryPersistor sipSorceryPersistor, SIPEndPoint outboundProxySocket, DialPlanEngine dialPlanEngine ) { m_sipTransport = sipTransport; m_executingScript = executingScript; m_dialPlanLogDelegate = logDelegate; CreateBridge_External = createBridge; m_sipRequest = sipRequest; m_callDirection = callDirection; m_dialPlanContext = dialPlanContext; m_getCanonicalDomainDelegate = getCanonicalDomain; m_callManager = callManager; //m_sipAccountPersistor = sipAccountPersistor; //m_sipDialPlanPersistor = sipDialPlanPersistor; //m_sipDialoguePersistor = sipDialoguePersistor; //GetSIPAccountBindings_External = getSIPAccountBindings; m_sipSorceryPersistor = sipSorceryPersistor; m_outboundProxySocket = outboundProxySocket; m_executingScript.Cleanup = CleanupDialPlanScript; if (m_dialPlanContext != null) { m_username = dialPlanContext.Owner; m_adminMemberId = dialPlanContext.AdminMemberId; m_sipProviders = dialPlanContext.SIPProviders; m_dialPlanContext.TraceLog.AppendLine("DialPlan=> Dialplan trace commenced at " + DateTime.Now.ToString("dd MMM yyyy HH:mm:ss:fff") + "."); m_dialPlanContext.CallCancelledByClient += ClientCallTerminated; SIPAssetGetDelegate<SIPAccount> getSIPAccount = null; if (m_sipSorceryPersistor != null && m_sipSorceryPersistor.SIPAccountsPersistor != null) { getSIPAccount = m_sipSorceryPersistor.SIPAccountsPersistor.Get; } m_dialStringParser = new DialStringParser(m_sipTransport, m_dialPlanContext.Owner, m_dialPlanContext.SIPAccount, m_sipProviders, getSIPAccount, m_sipSorceryPersistor.SIPRegistrarBindingPersistor.Get, m_getCanonicalDomainDelegate, logDelegate, m_dialPlanContext.SIPDialPlan.DialPlanName); } }
private void GetRules(int offset, int count, AssetViewPanel panel, SIPCallDirection ruleDirection) { if (!m_routesPanelRefreshInProgress) { m_routesPanelRefreshInProgress = true; m_riaContext.SimpleWizardRules.Clear(); var routesQuery = m_riaContext.GetSimpleWizardRulesQuery().Where(x => x.DialPlanID == m_dialPlan.ID && x.Direction == ruleDirection.ToString()).OrderBy(x => x.Priority).Skip(offset).Take(count); routesQuery.IncludeTotalCount = true; m_riaContext.Load<SimpleWizardRule>(routesQuery, LoadBehavior.RefreshCurrent, RulesLoaded, panel); } }