/// <summary> /// Processes actions initiated by the callmanager web service EXCEPT for the callback method. /// </summary> /// <param name="username">The UNAUTHENTICATED username that was specified in the callmanager request URL.</param> /// <param name="number">The number parameter that was specified in the callmanager request URL.</param> /// <param name="dialplanName">The dialplan to use to process web calls, typically this will be ahrd coded to a known dialplan name.</param> /// <param name="replacesCallID">The replacesCallID parameter that was specified in the callmanager request URL.</param> /// <returns>A string that is returned to the user making the callmanager request that inidcates what action was taken.</returns> public string ProcessWebCall(string username, string number, string dialplanName, string replacesCallID) { //bool wasExecutionCountIncremented = false; Customer customer = null; SIPDialPlan dialPlan = null; try { customer = m_customerPersistor.Get(c => c.CustomerUsername == username); SIPDialogue replacesDialogue = (!replacesCallID.IsNullOrBlank() && customer != null) ? m_sipDialogueManager.GetDialogueRelaxed(customer.CustomerUsername, replacesCallID) : null; if (customer == null) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Web " + dialplanName + " rejected for " + username + " and " + number + ", as no matching user.", null)); return "Sorry no matching user was found, the " + dialplanName + " was not initiated."; } else if (customer.Suspended) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Web " + dialplanName + " rejected for " + username + " and " + number + ", user account is suspended.", null)); return "Sorry the user's account is suspended."; } else if (customer.ServiceLevel == CustomerServiceLevels.PremiumPayReqd.ToString() || customer.ServiceLevel == CustomerServiceLevels.ProfessionalPayReqd.ToString() || customer.ServiceLevel == CustomerServiceLevels.SwitchboardPayReqd.ToString()) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Web " + dialplanName + " rejected for " + username + " and " + number + ", user account requires payment.", null)); return "Sorry the user's account requires payment."; } else if (!replacesCallID.IsNullOrBlank() && replacesDialogue == null) { return "Sorry the blind transfer could not be initiated, the Call-ID to transfer could not be found."; } else { dialPlan = GetDialPlan_External(d => d.Owner == username && d.DialPlanName == dialplanName); if (dialPlan == null) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Web " + dialplanName + " rejected as no " + dialplanName + " dialplan exists.", username)); return "Sorry the specified user has not enabled callbacks, the callback was not initiated."; } else { if (!IsDialPlanExecutionAllowed(dialPlan, customer)) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Execution of web call for dialplan " + dialplanName + " was not processed as maximum execution count has been reached.", username)); return "Sorry the callback was not initiated, dial plan execution exceeded maximum allowed"; } else { //IncrementDialPlanExecutionCount(dialPlan, customer, originalExecutionCount + 1); //IncrementCustomerExecutionCount(customer); Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Web call for " + dialplanName + " initialising to " + number + ".", username)); ISIPServerUserAgent uas = null; if (replacesCallID.IsNullOrBlank()) { UASInviteTransaction dummyTransaction = GetDummyWebCallbackTransaction(number); uas = new SIPServerUserAgent(m_sipTransport, m_outboundProxy, username, SIPDomainManager.DEFAULT_LOCAL_DOMAIN, SIPCallDirection.Out, GetSIPAccount_External, null, Log_External, dummyTransaction); } else { SIPDialogue oppositeDialogue = m_sipDialogueManager.GetOppositeDialogue(replacesDialogue); uas = new SIPTransferServerUserAgent(Log_External, m_sipDialogueManager.DialogueTransfer, m_sipTransport, m_outboundProxy, replacesDialogue, oppositeDialogue, number, customer.CustomerUsername, customer.AdminId); m_inProgressTransfers.Add(oppositeDialogue, uas as SIPTransferServerUserAgent); } dialPlan.AuthorisedApps = customer.AuthorisedApps + ";" + dialPlan.AuthorisedApps; DialPlanScriptContext scriptContext = new DialPlanScriptContext( Log_External, m_sipTransport, CreateDialogueBridge, m_outboundProxy, uas, dialPlan, GetSIPProviders_External(p => p.Owner == username, null, 0, Int32.MaxValue), m_traceDirectory, null, customer, null, GetCanonicalDomain_External); //scriptContext.DialPlanComplete += () => { DecrementCustomerExecutionCount(customer); }; m_dialPlanEngine.Execute(scriptContext, uas, SIPCallDirection.Out, CreateDialogueBridge, this); if (replacesCallID.IsNullOrBlank()) { return "Web call was successfully initiated."; } else { return "Blind transfer was successfully initiated."; } } } } } catch (Exception excp) { logger.Error("Exception SIPCallManager ProcessWebCall. " + excp.Message); //if (wasExecutionCountIncremented) //{ //DecrementDialPlanExecutionCount(dialPlan, customer.Id, originalExecutionCount); //DecrementCustomerExecutionCount(customer); //} return "Sorry there was an unexpected error, the callback was not initiated."; } }
/// <summary> /// Processes an in dialogue REFER request that specifies a new destination for an existing call leg. /// </summary> /// <param name="username">The username of the user the transfer is being processed for.</param> /// <param name="referTo">The Refer-To header URI from the REFER request.</param> /// <param name="dialplanName">The dialplan to use to process the transfer.</param> /// <param name="replacesCallID">The call ID that is being replaced by the new dialogue if one is created.</param> /// <returns>A SIP server user agent.</returns> public ISIPServerUserAgent BlindTransfer(string username, SIPURI referTo, string dialplanName, SIPDialogue replacesDialogue) { if (dialplanName.IsNullOrBlank()) { throw new ApplicationException("A dial plan name must be provided when processing a blind transfer."); } else if (referTo == null) { throw new ApplicationException("The refer to URI cannot be empty when processing a blind transfer."); } else if (replacesDialogue == null) { throw new ApplicationException("The blind transfer could not be initiated, the dialogue to transfer could not be found."); } //bool wasExecutionCountIncremented = false; Customer customer = null; SIPDialPlan dialPlan = null; try { customer = m_customerPersistor.Get(c => c.CustomerUsername == username); if (customer == null) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Blind transfer using dialplan " + dialplanName + " rejected for " + username + " and " + referTo.ToString() + ", as no matching user.", username)); throw new ApplicationException("No matching user was found, the blind transfer was not initiated."); } else if (customer.Suspended) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Blind transfer using dialplan " + dialplanName + " rejected for " + username + " and " + referTo.ToString() + ", user account is suspended.", username)); throw new ApplicationException("The user's account is suspended, the blind transfer was not initiated."); } else { dialPlan = GetDialPlan_External(d => d.Owner == username && d.DialPlanName == dialplanName); if (dialPlan == null) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Blind transfer rejected as no " + dialplanName + " dialplan exists.", username)); throw new ApplicationException("The blind transfer could not be initiated, no dialplan with name " + dialplanName + " could be found."); } else { if (!IsDialPlanExecutionAllowed(dialPlan, customer)) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Execution of blind transfer for dialplan " + dialplanName + " was not processed as maximum execution count has been reached.", username)); throw new ApplicationException("The blind transfer was not initiated, dial plan execution exceeded maximum allowed"); } else { //IncrementCustomerExecutionCount(customer); Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Blind transfer for dialplan " + dialplanName + " starting for " + referTo.ToString() + ".", username)); SIPDialogue oppositeDialogue = m_sipDialogueManager.GetOppositeDialogue(replacesDialogue); ISIPServerUserAgent uas = new SIPTransferServerUserAgent(Log_External, m_sipDialogueManager.DialogueTransfer, m_sipTransport, m_outboundProxy, replacesDialogue, oppositeDialogue, referTo.ToString(), customer.CustomerUsername, customer.AdminId); DialPlanScriptContext scriptContext = new DialPlanScriptContext( Log_External, m_sipTransport, CreateDialogueBridge, m_outboundProxy, uas, dialPlan, GetSIPProviders_External(p => p.Owner == username, null, 0, Int32.MaxValue), m_traceDirectory, null, customer, null, GetCanonicalDomain_External); //scriptContext.DialPlanComplete += () => { DecrementCustomerExecutionCount(customer); }; m_dialPlanEngine.Execute(scriptContext, uas, SIPCallDirection.Out, CreateDialogueBridge, this); return uas; } } } } catch (ApplicationException) { throw; } catch (Exception excp) { logger.Error("Exception SIPCallManager BlindTransfer. " + excp.Message); //if (wasExecutionCountIncremented) //{ //DecrementDialPlanExecutionCount(dialPlan, customer.Id, originalExecutionCount); //DecrementCustomerExecutionCount(customer); //} throw; } }