[Ignore] // Broken after NEtStandard migration. public void SingleProviderLegUnitTest() { Console.WriteLine("--> " + System.Reflection.MethodBase.GetCurrentMethod().Name); SIPRequest inviteRequest = new SIPRequest(SIPMethodsEnum.INVITE, SIPURI.ParseSIPURI("sip:1234@localhost")); SIPHeader inviteHeader = new SIPHeader(SIPFromHeader.ParseFromHeader("<sip:joe@localhost>"), SIPToHeader.ParseToHeader("<sip:jane@localhost>"), 23, CallProperties.CreateNewCallId()); SIPViaHeader viaHeader = new SIPViaHeader("127.0.0.1", 5060, CallProperties.CreateBranchId()); inviteHeader.Vias.PushViaHeader(viaHeader); inviteRequest.Header = inviteHeader; List <SIPProvider> providers = new List <SIPProvider>(); SIPProvider provider = new SIPProvider(ProviderTypes.SIP, "test", "blueface", "test", "password", SIPURI.ParseSIPURIRelaxed("sip.blueface.ie"), null, null, null, null, 3600, null, null, null, false, false, null, null, null); providers.Add(provider); DialStringParser dialStringParser = new DialStringParser(null, "test", null, providers, delegate { return(null); }, delegate { return(null); }, (host, wildcard) => { return(null); }, null, "test"); Queue <List <SIPCallDescriptor> > callQueue = dialStringParser.ParseDialString(DialPlanContextsEnum.Script, inviteRequest, "blueface", null, null, null, null, null, null, null, null, CustomerServiceLevels.Free); Assert.IsNotNull(callQueue, "The call list should have contained a call."); Assert.IsTrue(callQueue.Count == 1, "The call queue list should have contained one leg."); List <SIPCallDescriptor> firstLeg = callQueue.Dequeue(); Assert.IsNotNull(firstLeg, "The first call leg should exist."); Assert.IsTrue(firstLeg.Count == 1, "The first call leg should have had one switch call."); Assert.IsTrue(firstLeg[0].Username == "test", "The username for the first call leg was not correct."); Assert.IsTrue(firstLeg[0].Uri.ToString() == "sip:[email protected]", "The destination URI for the first call leg was not correct."); Console.WriteLine("---------------------------------"); }
/// <summary> /// See overload. /// </summary> /// <param name="switchCallTransactions">An empty list that will be filled with transactions that the ForkCall creates and that each /// represent an outgoing call. The calling object can use the list to check response codes to determine the result of each leg in the /// ForkCall.</param> public ForkCall( SIPTransport sipTransport, SIPMonitorLogDelegate statefulProxyLogEvent, QueueNewCallDelegate queueNewCall, DialStringParser dialStringParser, string username, string adminMemberId, SIPEndPoint outboundProxy, ISIPCallManager callManager, DialPlanContext dialPlanContext, out List <SIPTransaction> switchCallTransactions) : this(sipTransport, statefulProxyLogEvent, queueNewCall, dialStringParser, username, adminMemberId, outboundProxy, callManager, dialPlanContext) { switchCallTransactions = m_switchCallTransactions; }
public void SubstitueMixedDstSubStrVarTest() { Console.WriteLine("--> " + System.Reflection.MethodBase.GetCurrentMethod().Name); SIPRequest request = new SIPRequest(SIPMethodsEnum.INVITE, SIPURI.ParseSIPURI("sip:[email protected]")); request.Header = new SIPHeader(); string substitutedString = DialStringParser.SubstituteRequestVars(request, "${dst:1}123${dst}000"); Console.Write("Substituted string=" + substitutedString + "."); Assert.IsTrue(substitutedString == "80123380000", "The destination was not substituted correctly."); Console.WriteLine("---------------------------------"); }
public void SubstitueEmptyFromNameTest() { Console.WriteLine("--> " + System.Reflection.MethodBase.GetCurrentMethod().Name); SIPRequest request = new SIPRequest(SIPMethodsEnum.INVITE, SIPURI.ParseSIPURI("sip:[email protected]")); request.Header = new SIPHeader(); string substitutedString = DialStringParser.SubstituteRequestVars(request, "${fromname} <sip:user@provider>"); Console.Write("Substituted string=" + substitutedString + "."); Assert.IsTrue(substitutedString == "<sip:user@provider>", "The from header was not substituted correctly."); Console.WriteLine("---------------------------------"); }
public CallbackApp( SIPTransport sipTransport, ISIPCallManager callManager, DialStringParser dialStringParser, SIPMonitorLogDelegate logDelegate, string username, string adminMemberId, SIPEndPoint outboundProxy, SIPAssetPersistor <SIPDialogueAsset> sipDialoguePersistor) { m_sipTransport = sipTransport; m_callManager = callManager; m_dialStringParser = dialStringParser; Log_External = logDelegate; m_username = username; m_adminMemberId = adminMemberId; m_outboundProxy = outboundProxy; m_sipDialoguePersistor = sipDialoguePersistor; }
/// <remarks> /// The ForkCall allows a SIP call to be forked to multiple destinations. To do this it utilises multiple /// simultaneous SIPCallDescriptor objects and consolidates their responses to work out what should and shouldn't /// be forwarded onto the client that initiated the call. The ForkCall acts as a classic SIP forking proxy. /// /// The ForkCall is capable of both multiple forwards and also of follow on forwarding in the event of a call /// leg of multiple forwards not succeeding. As an example: /// /// Dial(provider1&provider2|provider3&provider4|provider5&provider6) /// /// The handling of this call would be: /// 1. The call would be simultaneously forwarded to provider1 and provider2, /// 2. If the call was not successfully answered in step 1 the call would be simultaneously forwarded to provider3 and provider4, /// 3. If the call was not successfully answered in step 2 the call would be simultaneously forwarded to provider5 and provider6, /// 4. If the call was not successfully answered in step 3 the client call would be sent an error response. /// 5. If the client cancels the call at any time during the call all forwarding operations will halt. /// </remarks> /// <param name="sipTransport">The SIP transport layer that will handle the forked calls.</param> /// <param name="statefulProxyLogEvent">A delegate that allows the owning object to receive notifications from the ForkCall.</param> /// <param name="queueNewCall">A delegate that can be used to queue a new call with the SIP application server call manager. This /// delegate is used when a fork call generates a B2B call that requires the incoming dialplan for a called user to be processed.</param> /// <param name="dialStringParser">The dial string parser is used when a redirect response is received on a forked call leg. The /// parser can then be applied to the redirect SIP URI to generate new call legs to be added to the ForkCall.</param> /// <param name="username">The username of the call owner.</param> /// <param name="adminMemberId">The admin ID of the call owner.</param> /// <param name="outboundProxy">The outbound proxy to use for all SIP traffic originated. Can be null if an outbound proxy is not /// being used.</param> public ForkCall( SIPTransport sipTransport, SIPMonitorLogDelegate statefulProxyLogEvent, QueueNewCallDelegate queueNewCall, DialStringParser dialStringParser, string username, string adminMemberId, SIPEndPoint outboundProxy, ISIPCallManager callManager, DialPlanContext dialPlanContext) { m_sipTransport = sipTransport; m_statefulProxyLogEvent = statefulProxyLogEvent; QueueNewCall_External = queueNewCall; m_dialStringParser = dialStringParser; m_username = username; m_adminMemberId = adminMemberId; m_outboundProxySocket = outboundProxy; m_callManager = callManager; m_dialPlanContext = dialPlanContext; }
/// <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(); } }