private void ExecuteScript( DialPlanExecutingScript executingScript, DialPlanContext dialPlanContext, DialPlanScriptFacade planFacade, string script) { try { Thread.CurrentThread.Name = "dialplanscript-" + executingScript.ScriptNumber; if (m_impersonationUsername != null && m_impersonationPassword != null) { WrapperImpersonationContext impersonationConext = new WrapperImpersonationContext(null, m_impersonationUsername, m_impersonationPassword); impersonationConext.Enter(); } //logger.Debug(Thread.CurrentThread.Name + " identity=" + WindowsIdentity.GetCurrent().Name + "."); FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Dial plan execution starting on thread " + Thread.CurrentThread.Name + " for " + dialPlanContext.Owner + ".", null)); executingScript.DialPlanScriptEngine.Execute(script, executingScript.DialPlanScriptScope); //FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Dial plan execution finished after full script run on thread " + Thread.CurrentThread.Name + " for " + dialPlanContext.Owner + ".", null)); } catch (ApplicationException appExcp) { if (appExcp.Message != "Script was halted by external intervention.") { logger.Error("ApplicationException ExecuteScript. " + appExcp.Message); FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "There was an exception executing your dial plan script: " + appExcp.Message, executingScript.Owner)); FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "ApplicationException on user " + executingScript.Owner + "'s dial plan script. " + appExcp.Message, null)); executingScript.ExecutionError = appExcp.Message; } else { FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Dial plan execution finished after being halted due to execution interrupt on thread " + Thread.CurrentThread.Name + " for " + dialPlanContext.Owner + ".", null)); } } //catch (System.Scripting.SyntaxErrorException) catch (SyntaxErrorException syntaxExcp) { logger.Warn("SyntaxErrorException. Owner=" + dialPlanContext.Owner + ", DialPlanName=" + dialPlanContext.SIPDialPlan.DialPlanName + ", Line=" + syntaxExcp.Line + "."); FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "There was a syntax error in your dial plan on line " + syntaxExcp.Line + ", please check.", executingScript.Owner)); executingScript.ExecutionError = "Dial plan syntax error"; } catch (MissingMethodException missingExcp) { logger.Warn("MissingMethodException. " + missingExcp.Message); FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "There was a missing method exception in your dial plan: " + missingExcp.Message + ".", executingScript.Owner)); executingScript.ExecutionError = "Dial plan missing method"; } catch (ThreadAbortException) { } catch (Exception excp) { logger.Error("Exception ExecuteScript (" + excp.GetType() + "). " + excp.Message); FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "There was an exception executing your dial plan script: " + excp.Message, executingScript.Owner)); FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Exception on user " + executingScript.Owner + "'s dial plan script (" + excp.GetType() + "). " + excp.Message, null)); executingScript.ExecutionError = "Dial plan exception"; } finally { executingScript.StopExecution(); } }
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 ExecuteScript( DialPlanExecutingScript executingScript, DialPlanContext dialPlanContext, DialPlanScriptFacade planFacade, string script) { try { Thread.CurrentThread.Name = "dialplanscript-" + executingScript.ScriptNumber; if (m_impersonationUsername != null && m_impersonationPassword != null) { WrapperImpersonationContext impersonationConext = new WrapperImpersonationContext(null, m_impersonationUsername, m_impersonationPassword); impersonationConext.Enter(); } //logger.Debug(Thread.CurrentThread.Name + " identity=" + WindowsIdentity.GetCurrent().Name + "."); FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Dial plan execution starting on thread " + Thread.CurrentThread.Name + " for " + dialPlanContext.Owner + ".", null)); executingScript.DialPlanScriptEngine.Execute(script, executingScript.DialPlanScriptScope); //FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Dial plan execution finished after full script run on thread " + Thread.CurrentThread.Name + " for " + dialPlanContext.Owner + ".", null)); } catch (ApplicationException appExcp) { if (appExcp.Message != "Script was halted by external intervention.") { logger.Error("ApplicationException ExecuteScript. " + appExcp.Message); FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "There was an exception executing your dial plan script: " + appExcp.Message, executingScript.Owner)); FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "ApplicationException on user " + executingScript.Owner + "'s dial plan script. " + appExcp.Message, null)); executingScript.ExecutionError = appExcp.Message; } else { FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Dial plan execution finished after being halted due to execution interrupt on thread " + Thread.CurrentThread.Name + " for " + dialPlanContext.Owner + ".", null)); } } //catch (System.Scripting.SyntaxErrorException) catch (SyntaxErrorException syntaxExcp) { logger.Warn("SyntaxErrorException. Owner=" + dialPlanContext.Owner + ", DialPlanName=" + dialPlanContext.SIPDialPlan.DialPlanName + ", Line=" + syntaxExcp.Line + "."); FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "There was a syntax error in your dial plan on line " + syntaxExcp.Line + ", please check.", executingScript.Owner)); executingScript.ExecutionError = "Dial plan syntax error"; } catch (MissingMethodException missingExcp) { logger.Warn("MissingMethodException. " + missingExcp.Message); FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "There was a missing method exception in your dial plan: " + missingExcp.Message + ".", executingScript.Owner)); executingScript.ExecutionError = "Dial plan missing method"; } catch (ThreadAbortException) { } catch (Exception excp) { logger.Error("Exception ExecuteScript (" + excp.GetType() + "). " + excp.Message); FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "There was an exception executing your dial plan script: " + excp.Message, executingScript.Owner)); FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Exception on user " + executingScript.Owner + "'s dial plan script (" + excp.GetType() + "). " + excp.Message, null)); executingScript.ExecutionError = "Dial plan exception"; } finally { executingScript.StopExecution(); } }
/// <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); } }
private void MonitorScripts() { try { while (!StopScriptMonitoring) { DialPlanExecutingScript[] killScripts = null; bool lockTaken = false; Monitor.TryEnter(m_runningScripts, 100, ref lockTaken); if (lockTaken) { try { killScripts = (from script in m_runningScripts where script.Complete || DateTime.Now > script.EndTime || DateTime.Now.Subtract(script.StartTime).TotalSeconds > ABSOLUTEMAX_SCRIPTPROCESSING_SECONDS select script).ToArray(); } finally { Monitor.Exit(m_runningScripts); } } else { logger.Warn("Dialplan engine monitoring thread could not acquire a lock on the running scripts list."); } if (killScripts != null) { for (int index = 0; index < killScripts.Length; index++) { DialPlanExecutingScript killScript = killScripts[index]; DialPlanContext dialPlanContext = killScript.ExecutingDialPlanContext; if (!killScript.Complete) { killScript.LogDelegate(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Long running dialplan script is being forcefully terminated.", killScript.Owner)); } try { if (dialPlanContext != null && !dialPlanContext.IsAnswered) { // The dialplan script has finished but the client call has not been answered. There could have be an // error executing the script or the dialplan could have completed without getting an answer. if (!killScript.ExecutionError.IsNullOrBlank()) { FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Dial plan execution completed without answering and had an execution error message of " + killScript.ExecutionError + ".", killScript.Owner)); dialPlanContext.CallFailed(SIPResponseStatusCodesEnum.InternalServerError, killScript.ExecutionError, null); } else if (killScript.LastFailureStatus != SIPResponseStatusCodesEnum.None) { FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Dial plan execution completed without answering and a last failure status of " + killScript.LastFailureStatus + " " + killScript.LastFailureReason + ".", killScript.Owner)); dialPlanContext.CallFailed(killScript.LastFailureStatus, killScript.LastFailureReason, null); } else { FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Dial plan execution completed without answering and with no last failure status.", killScript.Owner)); dialPlanContext.CallFailed(SIPResponseStatusCodesEnum.TemporarilyUnavailable, null, null); } } else { FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Dial plan execution completed with normal clearing.", killScript.Owner)); } long gcMemory = GC.GetTotalMemory(false); long physicalMemory = System.Diagnostics.Process.GetCurrentProcess().PrivateMemorySize64; FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Dial plan finished for " + killScript.Owner + ", gc memory=" + gcMemory + ", physical memory=" + physicalMemory + ", running script count=" + ScriptCount + ".", null)); } catch (Exception finallyExcp) { logger.Error("Exception MonitorScripts Kill. " + finallyExcp.Message); } finally { try { /*if (killScript.DialPlanScriptThread != null && killScript.DialPlanScriptThread.IsAlive) * { * //logger.Debug("Aborting dialplan script thread."); * killScript.DialPlanScriptThread.Abort(); * }*/ killScript.StopExecution(); } catch (ThreadStateException) { } // This exception is thrown when aborting a thread in a suspended state and is expected behaviour. catch (Exception killExcp) { logger.Error("Exception MonitorScripts aborting thread (" + killExcp.GetType().ToString() + "). " + killExcp.Message); } lock (m_runningScripts) { m_runningScripts.Remove(killScript); } logger.Debug("Executing script " + killScript.DialPlanScriptThread.Name + " removed from running scripts list, running script count=" + ScriptCount + "."); } } } Thread.Sleep(500); } if (StopScriptMonitoring) { if (m_runningScripts.Count > 0) { for (int index = 0; index < m_runningScripts.Count; index++) { if (m_runningScripts[index].DialPlanScriptThread != null && m_runningScripts[index].DialPlanScriptThread.IsAlive) { try { m_runningScripts[index].DialPlanScriptThread.Abort(); } catch (Exception finalKill) { logger.Debug("Exception on script final kill. " + finalKill.Message); } } } } } } catch (Exception excp) { logger.Error("Exception MonitorScripts. " + excp); } }
/// <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); } }