private SIPRequest GetByeRequest(SIPEndPoint localSIPEndPoint) { SIPRequest byeRequest = new SIPRequest(SIPMethodsEnum.BYE, RemoteTarget); SIPFromHeader byeFromHeader = SIPFromHeader.ParseFromHeader(LocalUserField.ToString()); SIPToHeader byeToHeader = SIPToHeader.ParseToHeader(RemoteUserField.ToString()); int cseq = CSeq + 1; SIPHeader byeHeader = new SIPHeader(byeFromHeader, byeToHeader, cseq, CallId); byeHeader.CSeqMethod = SIPMethodsEnum.BYE; byeRequest.Header = byeHeader; byeRequest.Header.Routes = RouteSet; byeRequest.Header.ProxySendFrom = ProxySendFrom; SIPViaHeader viaHeader = new SIPViaHeader(localSIPEndPoint, CallProperties.CreateBranchId()); byeRequest.Header.Vias.PushViaHeader(viaHeader); return byeRequest; }
/// <summary> /// Used to send a request from an internal server agent to an external SIP user agent. The difference between this method and /// the SendTransparent method is that this one will set Via headers in accordance with RFC3261. /// </summary> /// <param name="receivedOnEP">The proxy SIP end point the request was received on.</param> /// <param name="dstSocket">The SIP end point the request is being sent to.</param> /// <param name="sipRequest">The SIP request to send.</param> /// <param name="proxyBranch">The branch parameter for the top Via header that has been pre-calculated by the proxy core.</param> /// <param name="sendFromSocket">The proxy SIP end point to send this request from. If the SIP request has its ProxySendFrom header /// value set that will overrule this parameter.</param> public void SendExternal(SIPEndPoint receivedOnEP, SIPEndPoint dstSIPEndPoint, SIPRequest sipRequest, string proxyBranch, IPAddress publicIPAddress) { try { if (!IsDestinationValid(sipRequest, dstSIPEndPoint)) { logger.Debug("SendExternal failed destination check."); return; } // Determine the external SIP endpoint that the proxy will use to send this request. SIPEndPoint localSIPEndPoint = m_sipTransport.GetDefaultSIPEndPoint(dstSIPEndPoint); if (!sipRequest.Header.ProxySendFrom.IsNullOrBlank()) { SIPChannel proxyChannel = m_sipTransport.FindSIPChannel(SIPEndPoint.ParseSIPEndPoint(sipRequest.Header.ProxySendFrom)); if (proxyChannel == null) { logger.Warn("No SIP channel could be found for\n" + sipRequest.ToString()); } localSIPEndPoint = (proxyChannel != null) ? proxyChannel.SIPChannelEndPoint : localSIPEndPoint; } if (receivedOnEP != localSIPEndPoint) { // The proxy is being requested to send the request on a different socket to the one it was received on. // A second Via header is added to ensure the response can navigate back the same path. The calculated branch // parameter needs to go on the top Via header so that whichever internal socket the request is being sent to can // determine re-transmits. SIPViaHeader via = new SIPViaHeader(receivedOnEP, CallProperties.CreateBranchId()); sipRequest.Header.Vias.PushViaHeader(via); SIPViaHeader externalVia = new SIPViaHeader(localSIPEndPoint, proxyBranch); sipRequest.Header.Vias.PushViaHeader(externalVia); } else { // Only a single Via header is required as any response to this request will be sent from the same socket it gets received on. SIPViaHeader via = new SIPViaHeader(localSIPEndPoint, proxyBranch); sipRequest.Header.Vias.PushViaHeader(via); } if (sipRequest.Method != SIPMethodsEnum.REGISTER) { AdjustContactHeader(sipRequest.Header, localSIPEndPoint, publicIPAddress); } sipRequest.LocalSIPEndPoint = localSIPEndPoint; // Proxy sepecific headers that don't need to be seen by external UAs. sipRequest.Header.ProxyReceivedOn = null; sipRequest.Header.ProxyReceivedFrom = null; sipRequest.Header.ProxySendFrom = null; m_sipTransport.SendRequest(dstSIPEndPoint, sipRequest); } catch (Exception excp) { logger.Error("Exception SIPRequest SendExternal. " + excp.Message); logger.Error(sipRequest.ToString()); throw; } }
public void AddBottomViaHeader(SIPViaHeader viaHeader) { m_viaHeaders.Add(viaHeader); }
public static SIPViaHeader[] ParseSIPViaHeader(string viaHeaderStr) { List<SIPViaHeader> viaHeadersList = new List<SIPViaHeader>(); if (!viaHeaderStr.IsNullOrBlank()) { viaHeaderStr = viaHeaderStr.Trim(); // Multiple Via headers can be contained in a single line by separating them with a comma. string[] viaHeaders = SIPParameters.GetKeyValuePairsFromQuoted(viaHeaderStr, ','); foreach (string viaHeaderStrItem in viaHeaders) { if (viaHeaderStrItem == null || viaHeaderStrItem.Trim().Length == 0) { throw new SIPValidationException(SIPValidationFieldsEnum.ViaHeader, "No Contact address."); } else { SIPViaHeader viaHeader = new SIPViaHeader(); string header = viaHeaderStrItem.Trim(); int firstSpacePosn = header.IndexOf(" "); if (firstSpacePosn == -1) { throw new SIPValidationException(SIPValidationFieldsEnum.ViaHeader, "No Contact address."); } else { string versionAndTransport = header.Substring(0, firstSpacePosn); viaHeader.Version = versionAndTransport.Substring(0, versionAndTransport.LastIndexOf('/')); viaHeader.Transport = SIPProtocolsType.GetProtocolType(versionAndTransport.Substring(versionAndTransport.LastIndexOf('/') + 1)); string nextField = header.Substring(firstSpacePosn, header.Length - firstSpacePosn).Trim(); int delimIndex = nextField.IndexOf(';'); string contactAddress = null; // Some user agents include branch but have the semi-colon missing, that's easy to cope with by replacing "branch" with ";branch". if (delimIndex == -1 && nextField.Contains(m_branchKey)) { nextField = nextField.Replace(m_branchKey, ";" + m_branchKey); delimIndex = nextField.IndexOf(';'); } if (delimIndex == -1) { //logger.Warn("Via header missing semi-colon: " + header + "."); //parserError = SIPValidationError.NoBranchOnVia; //return null; contactAddress = nextField.Trim(); } else { contactAddress = nextField.Substring(0, delimIndex).Trim(); viaHeader.ViaParameters = new SIPParameters(nextField.Substring(delimIndex, nextField.Length - delimIndex), m_paramDelimChar); } if (contactAddress == null || contactAddress.Trim().Length == 0) { // Check that the branch parameter is present, without it the Via header is illegal. //if (!viaHeader.ViaParameters.Has(m_branchKey)) //{ // logger.Warn("Via header missing branch: " + header + "."); // parserError = SIPValidationError.NoBranchOnVia; // return null; //} throw new SIPValidationException(SIPValidationFieldsEnum.ViaHeader, "No Contact address."); } // Parse the contact address. int colonIndex = contactAddress.IndexOf(m_hostDelimChar); if (colonIndex != -1) { viaHeader.Host = contactAddress.Substring(0, colonIndex); if (!Int32.TryParse(contactAddress.Substring(colonIndex + 1), out viaHeader.Port)) { throw new SIPValidationException(SIPValidationFieldsEnum.ViaHeader, "Non-numeric port for IP address."); } else if (viaHeader.Port > SIPConstants.MAX_SIP_PORT) { throw new SIPValidationException(SIPValidationFieldsEnum.ViaHeader, "The port specified in a Via header exceeded the maximum allowed."); } } else { viaHeader.Host = contactAddress; } viaHeadersList.Add(viaHeader); } } } } if (viaHeadersList.Count > 0) { return viaHeadersList.ToArray(); } else { throw new SIPValidationException(SIPValidationFieldsEnum.ViaHeader, "Via list was empty."); ; } }
private SIPRequest GetRequest(SIPMethodsEnum method) { try { SIPURI uri = SIPURI.ParseSIPURIRelaxed(m_callDescriptor.Uri); SIPRequest request = new SIPRequest(method, uri); SIPFromHeader fromHeader = m_callDescriptor.GetFromHeader(); fromHeader.FromTag = CallProperties.CreateNewTag(); SIPToHeader toHeader = new SIPToHeader(null, uri, null); int cseq = Crypto.GetRandomInt(10000, 20000); SIPHeader header = new SIPHeader(fromHeader, toHeader, cseq, CallProperties.CreateNewCallId()); header.CSeqMethod = method; header.UserAgent = m_userAgent; request.Header = header; SIPViaHeader viaHeader = new SIPViaHeader(m_sipTransport.GetDefaultSIPEndPoint(), CallProperties.CreateBranchId()); request.Header.Vias.PushViaHeader(viaHeader); try { if (m_callDescriptor.CustomHeaders != null && m_callDescriptor.CustomHeaders.Count > 0) { foreach (string customHeader in m_callDescriptor.CustomHeaders) { if (customHeader.IsNullOrBlank()) { continue; } else if (customHeader.Trim().StartsWith(SIPHeaders.SIP_HEADER_USERAGENT)) { request.Header.UserAgent = customHeader.Substring(customHeader.IndexOf(":") + 1).Trim(); } else { request.Header.UnknownHeaders.Add(customHeader); } } } } catch (Exception excp) { logger.Error("Exception Parsing CustomHeader for SIPNonInviteClientUserAgent GetRequest. " + excp.Message + m_callDescriptor.CustomHeaders); } if (!m_callDescriptor.Content.IsNullOrBlank()) { request.Body = m_callDescriptor.Content; request.Header.ContentType = m_callDescriptor.ContentType; request.Header.ContentLength = request.Body.Length; } return request; } catch (Exception excp) { logger.Error("Exception SIPNonInviteClientUserAgent GetRequest. " + excp.Message); throw excp; } }
/// <summary> /// New transaction ACK requests are for 2xx responses, i.e. INVITE accepted and dialogue being created. /// </summary> /// <remarks> /// From RFC 3261 Chapter 17.1.1.3 - ACK for non-2xx final responses /// /// IMPORTANT: /// an ACK for a non-2xx response will also have the same branch ID as the INVITE whose response it acknowledges. /// /// The ACK request constructed by the client transaction MUST contain /// values for the Call-ID, From, and Request-URI that are equal to the /// values of those header fields in the request passed to the transport /// by the client transaction (call this the "original request"). The To /// header field in the ACK MUST equal the To header field in the /// response being acknowledged, and therefore will usually differ from /// the To header field in the original request by the addition of the /// tag parameter. The ACK MUST contain a single Via header field, and /// this MUST be equal to the top Via header field of the original /// request. The CSeq header field in the ACK MUST contain the same /// value for the sequence number as was present in the original request, /// but the method parameter MUST be equal to "ACK". /// /// If the INVITE request whose response is being acknowledged had Route /// header fields, those header fields MUST appear in the ACK. This is /// to ensure that the ACK can be routed properly through any downstream /// stateless proxies. /// /// From RFC 3261 Chapter 13.2.2.4 - ACK for 2xx final responses /// /// IMPORTANT: /// an ACK for a 2xx final response is a new transaction and has a new branch ID. /// /// The UAC core MUST generate an ACK request for each 2xx received from /// the transaction layer. The header fields of the ACK are constructed /// in the same way as for any request sent within a dialog (see Section /// 12) with the exception of the CSeq and the header fields related to /// authentication. The sequence number of the CSeq header field MUST be /// the same as the INVITE being acknowledged, but the CSeq method MUST /// be ACK. The ACK MUST contain the same credentials as the INVITE. If /// the 2xx contains an offer (based on the rules above), the ACK MUST /// carry an answer in its body. If the offer in the 2xx response is not /// acceptable, the UAC core MUST generate a valid answer in the ACK and /// then send a BYE immediately. /// </remarks> private SIPRequest GetNewTransactionACKRequest(SIPResponse sipResponse, SIPURI ackURI, SIPEndPoint localSIPEndPoint) { SIPRequest ackRequest = new SIPRequest(SIPMethodsEnum.ACK, ackURI.ToString()); ackRequest.LocalSIPEndPoint = localSIPEndPoint; SIPHeader header = new SIPHeader(TransactionRequest.Header.From, sipResponse.Header.To, sipResponse.Header.CSeq, sipResponse.Header.CallId); header.CSeqMethod = SIPMethodsEnum.ACK; header.AuthenticationHeader = TransactionRequest.Header.AuthenticationHeader; header.ProxySendFrom = base.TransactionRequest.Header.ProxySendFrom; if (sipResponse.Header.RecordRoutes != null) { header.Routes = sipResponse.Header.RecordRoutes.Reversed(); } ackRequest.Header = header; SIPViaHeader viaHeader = new SIPViaHeader(localSIPEndPoint, CallProperties.CreateBranchId()); ackRequest.Header.Vias.PushViaHeader(viaHeader); return ackRequest; }
private SIPRequest GetInviteRequest(SIPDialogue dialogue, SIPEndPoint localSIPEndPoint, string body) { SIPRequest inviteRequest = new SIPRequest(SIPMethodsEnum.INVITE, dialogue.RemoteTarget); SIPHeader inviteHeader = new SIPHeader(SIPFromHeader.ParseFromHeader(dialogue.LocalUserField.ToString()), SIPToHeader.ParseToHeader(dialogue.RemoteUserField.ToString()), dialogue.CSeq, dialogue.CallId); SIPURI contactURI = new SIPURI(dialogue.RemoteTarget.Scheme, localSIPEndPoint); inviteHeader.Contact = SIPContactHeader.ParseContactHeader("<" + contactURI.ToString() + ">"); inviteHeader.CSeqMethod = SIPMethodsEnum.INVITE; inviteRequest.Header = inviteHeader; inviteRequest.Header.Routes = dialogue.RouteSet; SIPViaHeader viaHeader = new SIPViaHeader(localSIPEndPoint, CallProperties.CreateBranchId()); inviteRequest.Header.Vias.PushViaHeader(viaHeader); inviteRequest.Body = body; inviteRequest.Header.ContentLength = body.Length; inviteRequest.Header.ContentType = "application/sdp"; return inviteRequest; }
private SIPRequest GetInviteRequest(IPEndPoint localContact, string inviteBody, IPEndPoint dstEndPoint) { SIPRequest inviteRequest = new SIPRequest(SIPMethodsEnum.INVITE, SIPURI.ParseSIPURI("sip:" + dstEndPoint)); SIPHeader inviteHeader = new SIPHeader(SIPFromHeader.ParseFromHeader("<sip:" + localContact + ">"), SIPToHeader.ParseToHeader("<sip:" + dstEndPoint + ">"), 1, CallProperties.CreateNewCallId()); inviteHeader.From.FromTag = CallProperties.CreateNewTag(); inviteHeader.Contact = SIPContactHeader.ParseContactHeader("sip:" + localContact); inviteHeader.CSeqMethod = SIPMethodsEnum.INVITE; inviteHeader.UserAgent = "unit test"; inviteRequest.Header = inviteHeader; SIPViaHeader viaHeader = new SIPViaHeader(localContact.Address.ToString(), localContact.Port,CallProperties.CreateBranchId(), SIPProtocolsEnum.udp); inviteRequest.Header.Vias.PushViaHeader(viaHeader); //inviteRequest.Body = inviteBody; //inviteRequest.Header.ContentLength = inviteBody.Length; inviteRequest.Header.ContentType = "application/sdp"; return inviteRequest; }
private SIPRequest GetCallbackInviteRequest(IPEndPoint localSIPEndPoint, string sdp) { string callBackURI = "sip:[email protected]"; string callBackUserField = "<" + callBackURI + ">"; SIPRequest inviteRequest = new SIPRequest(SIPMethodsEnum.INVITE, callBackURI); SIPHeader inviteHeader = new SIPHeader(callBackUserField, callBackUserField, 1, CallProperties.CreateNewCallId()); inviteHeader.CSeqMethod = SIPMethodsEnum.INVITE; inviteHeader.ContentType = "application/sdp"; SIPViaHeader viaHeader = new SIPViaHeader(localSIPEndPoint, CallProperties.CreateBranchId()); inviteHeader.Vias.PushViaHeader(viaHeader); inviteRequest.Header = inviteHeader; if (sdp == null) { sdp = "v=0" + CRLF + "o=- " + Crypto.GetRandomInt(1000, 5000).ToString() + " 2 IN IP4 " + localSIPEndPoint.Address.ToString() + CRLF + "s=session" + CRLF + "c=IN IP4 " + localSIPEndPoint.Address.ToString() + CRLF + "t=0 0" + CRLF + "m=audio " + Crypto.GetRandomInt(10000, 20000).ToString() + " RTP/AVP 0 18 101" + CRLF + "a=rtpmap:0 PCMU/8000" + CRLF + "a=rtpmap:18 G729/8000" + CRLF + "a=rtpmap:101 telephone-event/8000" + CRLF + "a=fmtp:101 0-16" + CRLF + "a=recvonly"; } inviteHeader.ContentLength = sdp.Length; inviteRequest.Body = sdp; return inviteRequest; }
/// <summary> /// Constructs a NOTIFY request to send within the implicit subscription created when processing a REFER request. /// </summary> /// <remarks> /// From RFC 3515 2.4.5: /// The body of a NOTIFY MUST begin with a SIP Response Status-Line... /// </remarks> /// <param name="referRequest">The REFER request that created the implicit refer event subscription.</param> /// <param name="referDialogue">The dialogue that the REFER request has been received within.</param> /// <param name="referResponse">The response that has been received to whatever is doing the post-REFER processing.</param> /// <param name="localEndPoint">The local SIP end point that the NOTIFY request will be sent from.</param> /// <returns>A NOTIFY request suitable for sending to the remote end of the REFER initiating dialogue.</returns> private SIPRequest GetNotifyRequest(SIPRequest referRequest, SIPDialogue referDialogue, SIPResponse referResponse, SIPEndPoint localEndPoint) { try { SIPRequest notifyRequest = new SIPRequest(SIPMethodsEnum.NOTIFY, referRequest.Header.Contact[0].ContactURI); notifyRequest.Header = new SIPHeader(SIPFromHeader.ParseFromHeader(referDialogue.LocalUserField.ToString()), SIPToHeader.ParseToHeader(referDialogue.RemoteUserField.ToString()), referDialogue.CSeq, referDialogue.CallId); notifyRequest.Header.Event = m_referNotifyEventValue; // + ";id=" + referRequest.Header.CSeq; notifyRequest.Header.CSeqMethod = SIPMethodsEnum.NOTIFY; notifyRequest.Header.SubscriptionState = (referResponse.StatusCode >= 200) ? "terminated;reason=noresource" : "active;expires=60"; notifyRequest.Header.ContentType = m_referNotifyContentType; SIPViaHeader viaHeader = new SIPViaHeader(localEndPoint, CallProperties.CreateBranchId()); notifyRequest.Header.Vias.PushViaHeader(viaHeader); notifyRequest.Body = (referResponse.SIPVersion + " " + referResponse.StatusCode + " " + referResponse.ReasonPhrase).Trim(); notifyRequest.Header.ContentLength = notifyRequest.Body.Length; return notifyRequest; } catch (Exception excp) { logger.Error("Exception GetNotifyRequest. " + excp.Message); throw; } }
public SIPRequest GetRequest(SIPMethodsEnum method, SIPURI uri, SIPToHeader to, SIPEndPoint localSIPEndPoint) { if (localSIPEndPoint == null) { localSIPEndPoint = GetDefaultSIPEndPoint(); } SIPRequest request = new SIPRequest(method, uri); request.LocalSIPEndPoint = localSIPEndPoint; SIPContactHeader contactHeader = new SIPContactHeader(null, new SIPURI(SIPSchemesEnum.sip, localSIPEndPoint)); if (!String.IsNullOrWhiteSpace(m_contactGruu)) { contactHeader.ContactURI.Parameters.Set("gr", m_contactGruu); } SIPFromHeader fromHeader = new SIPFromHeader(null, contactHeader.ContactURI, CallProperties.CreateNewTag()); SIPHeader header = new SIPHeader(contactHeader, fromHeader, to, 1, CallProperties.CreateNewCallId()); request.Header = header; header.CSeqMethod = method; header.Allow = ALLOWED_SIP_METHODS; if (m_serviceRoute != null) header.Routes.AddBottomRoute(m_serviceRoute); SIPViaHeader viaHeader = new SIPViaHeader(localSIPEndPoint, CallProperties.CreateBranchId()); header.Vias.PushViaHeader(viaHeader); return request; }
public void ProcessNotifyRequest(SIPRequest sipRequest) { try { // Hack to work around MWI request from callcentric not having a trailing CRLF and breaking some softphones like the Bria. if (sipRequest.Header.Event == MWI_EVENT_TYPE && sipRequest.Body.NotNullOrBlank() && sipRequest.Body.Substring(sipRequest.Body.Length - 2) != m_crlf) { sipRequest.Body += m_crlf; } string fromURI = (sipRequest.Header.From != null && sipRequest.Header.From.FromURI != null) ? sipRequest.Header.From.FromURI.ToString() : "unknown"; string domain = GetCanonicalDomain_External(sipRequest.URI.Host, true); if (domain != null) { SIPAccount sipAccount = GetSIPAccount_External(s => s.SIPUsername == sipRequest.URI.User && s.SIPDomain == domain); if (sipAccount != null) { List<SIPRegistrarBinding> bindings = GetSIPAccountBindings_External(b => b.SIPAccountId == sipAccount.Id, null, 0, MAX_FORWARD_BINDINGS); if (bindings != null) { foreach (SIPRegistrarBinding binding in bindings) { SIPURI dstURI = binding.MangledContactSIPURI; SIPEndPoint localSIPEndPoint = (m_outboundProxy != null) ? m_sipTransport.GetDefaultSIPEndPoint(m_outboundProxy.Protocol) : m_sipTransport.GetDefaultSIPEndPoint(dstURI.Protocol); SIPEndPoint dstSIPEndPoint = null; // If the outbound proxy is a loopback address, as it will normally be for local deployments, then it cannot be overriden. if(m_outboundProxy != null && IPAddress.IsLoopback(m_outboundProxy.Address)) { dstSIPEndPoint = m_outboundProxy; } else if (binding.ProxySIPEndPoint != null) { // If the binding has a specific proxy end point sent then the request needs to be forwarded to the proxy's default end point for it to take care of. dstSIPEndPoint = new SIPEndPoint(SIPProtocolsEnum.udp, new IPEndPoint(binding.ProxySIPEndPoint.Address, m_defaultSIPPort)); } else if (m_outboundProxy != null) { dstSIPEndPoint = m_outboundProxy; } else { SIPDNSLookupResult lookupResult = m_sipTransport.GetURIEndPoint(dstURI, false); if(lookupResult.LookupError != null) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.MWI, "A NOTIFY request from " + fromURI + " was not forwarded due to DNS failure for " + dstURI.Host + ", " + lookupResult.LookupError + ".", sipAccount.Owner)); } else { dstSIPEndPoint = lookupResult.GetSIPEndPoint(); } } if (dstSIPEndPoint != null) { // Rather than create a brand new request copy the received one and modify the headers that need to be unique. SIPRequest notifyRequest = sipRequest.Copy(); notifyRequest.URI = dstURI; notifyRequest.Header.Contact = SIPContactHeader.CreateSIPContactList(new SIPURI(dstURI.Scheme, localSIPEndPoint)); notifyRequest.Header.To = new SIPToHeader(null, dstURI, null); notifyRequest.Header.CallId = CallProperties.CreateNewCallId(); SIPViaHeader viaHeader = new SIPViaHeader(localSIPEndPoint, CallProperties.CreateBranchId()); notifyRequest.Header.Vias = new SIPViaSet(); notifyRequest.Header.Vias.PushViaHeader(viaHeader); // If the binding has a proxy socket defined set the header to ask the upstream proxy to use it. if (binding.ProxySIPEndPoint != null) { notifyRequest.Header.ProxySendFrom = binding.ProxySIPEndPoint.ToString(); // If the binding has a specific proxy end point sent then the request needs to be forwarded to the proxy's default end point for it to take care of. dstSIPEndPoint = new SIPEndPoint(SIPProtocolsEnum.udp, new IPEndPoint(binding.ProxySIPEndPoint.Address, m_defaultSIPPort)); } Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.MWI, "Forwarding NOTIFY request from " + fromURI + " to registered binding at " + dstURI.ToString() + ", proxy " + dstSIPEndPoint.ToString() + ".", sipAccount.Owner)); SIPNonInviteTransaction notifyTransaction = m_sipTransport.CreateNonInviteTransaction(notifyRequest, dstSIPEndPoint, localSIPEndPoint, dstSIPEndPoint); notifyTransaction.SendReliableRequest(); } else { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.MWI, "A NOTIFY request from " + fromURI + " was not forwarded as no destination end point was resolved.", sipAccount.Owner)); } } // Send OK response to server. SIPResponse okResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null); m_sipTransport.SendResponse(okResponse); } else { // Send unavailable response to server. Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.MWI, "NOTIFY request from " + fromURI + " for " + sipAccount.SIPUsername + "@" + sipAccount.SIPDomain + " but no bindings available, responding with temporarily unavailable.", sipAccount.Owner)); SIPResponse notAvailableResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.TemporarilyUnavailable, null); m_sipTransport.SendResponse(notAvailableResponse); } } else { // Send Not found response to server. Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.MWI, "NOTIFY request from " + fromURI + " for " + sipRequest.URI.ToString() + " but no matching SIP account, responding with not found.", null)); SIPResponse notFoundResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.NotFound, null); m_sipTransport.SendResponse(notFoundResponse); } } else { // Send Not Serviced response to server. Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.MWI, "NOTIFY request from " + fromURI + " for a non-serviced domain responding with not found.", null)); SIPResponse notServicedResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.NotFound, "Domain not serviced"); m_sipTransport.SendResponse(notServicedResponse); } } catch (Exception excp) { logger.Error("Exception SIPNotifyManager ProcessNotifyRequest. " + excp.Message); } }
private SIPRequest GetDummyINVITERequest(SIPURI dummyURI) { string dummyFrom = "<sip:[email protected]>"; string dummyContact = "sip:127.0.0.1:1234"; SIPRequest inviteRequest = new SIPRequest(SIPMethodsEnum.INVITE, dummyURI); SIPHeader inviteHeader = new SIPHeader(SIPFromHeader.ParseFromHeader(dummyFrom), new SIPToHeader(null, dummyURI, null), 1, CallProperties.CreateNewCallId()); inviteHeader.From.FromTag = CallProperties.CreateNewTag(); inviteHeader.Contact = SIPContactHeader.ParseContactHeader(dummyContact); inviteHeader.CSeqMethod = SIPMethodsEnum.INVITE; inviteHeader.UserAgent = "unittest"; inviteRequest.Header = inviteHeader; SIPViaHeader viaHeader = new SIPViaHeader("127.0.0.1", 1234, CallProperties.CreateBranchId(), SIPProtocolsEnum.udp); inviteRequest.Header.Vias.PushViaHeader(viaHeader); inviteRequest.Body = "dummy"; inviteRequest.Header.ContentLength = inviteRequest.Body.Length; inviteRequest.Header.ContentType = "application/sdp"; return inviteRequest; }
/// <summary> /// Used to send a SIP request received from an external user agent to an internal SIP server agent. /// </summary> /// <param name="receivedFromEP">The SIP end point the proxy received the request from.</param> /// <param name="receivedOnEP">The SIP end point the proxy received the request on.</param> /// <param name="dstSocket">The internal socket to send the request to.</param> /// <param name="sipRequest">The SIP request to send.</param> /// <param name="proxyBranch">The branch to set on the Via header when sending the request. The branch should be calculated /// by the proxy core so that looped requests can be detected.</param> /// <param name="sendFromSocket">The proxy socket to send the request from.</param> public void SendInternal(SIPEndPoint receivedFromEP, SIPEndPoint receivedOnEP, string dstSocket, SIPRequest sipRequest, string proxyBranch, string sendFromSocket) { try { if (!IsDestinationValid(sipRequest, dstSocket)) { logger.Debug("SendInternal failed destination check."); return; } sipRequest.Header.ProxyReceivedFrom = receivedFromEP.ToString(); sipRequest.Header.ProxyReceivedOn = receivedOnEP.ToString(); SIPEndPoint dstSIPEndPoint = SIPEndPoint.ParseSIPEndPoint(dstSocket); SIPEndPoint localSIPEndPoint = SIPEndPoint.ParseSIPEndPoint(sendFromSocket); if (receivedOnEP != localSIPEndPoint) { // The proxy is being requested to send the request on a different socket to the one it was received on. // A second Via header is added to ensure the response can navigate back the same path. The calculated branch // parameter needs to go on the top Via header so that whichever internal socket the request is being sent to can // determine re-transmits. SIPViaHeader via = new SIPViaHeader(receivedOnEP, CallProperties.CreateBranchId()); sipRequest.Header.Vias.PushViaHeader(via); SIPViaHeader topVia = new SIPViaHeader(localSIPEndPoint, proxyBranch); sipRequest.Header.Vias.PushViaHeader(topVia); } else { // Only a single Via header is required as any response to this request will be sent from the same socket it gets received on. SIPViaHeader via = new SIPViaHeader(localSIPEndPoint, proxyBranch); sipRequest.Header.Vias.PushViaHeader(via); } sipRequest.LocalSIPEndPoint = localSIPEndPoint; m_sipTransport.SendRequest(dstSIPEndPoint, sipRequest); } catch (Exception excp) { logger.Error("Exception SIPRequest SendInternal. " + excp.Message); logger.Error(sipRequest.ToString()); throw; } }
private SIPRequest GetByeRequest(SIPResponse inviteResponse, SIPURI byeURI, SIPEndPoint localSIPEndPoint) { SIPRequest byeRequest = new SIPRequest(SIPMethodsEnum.BYE, byeURI); byeRequest.LocalSIPEndPoint = localSIPEndPoint; SIPFromHeader byeFromHeader = inviteResponse.Header.From; SIPToHeader byeToHeader = inviteResponse.Header.To; int cseq = inviteResponse.Header.CSeq + 1; SIPHeader byeHeader = new SIPHeader(byeFromHeader, byeToHeader, cseq, inviteResponse.Header.CallId); byeHeader.CSeqMethod = SIPMethodsEnum.BYE; byeHeader.ProxySendFrom = m_serverTransaction.TransactionRequest.Header.ProxySendFrom; byeRequest.Header = byeHeader; byeRequest.Header.Routes = (inviteResponse.Header.RecordRoutes != null) ? inviteResponse.Header.RecordRoutes.Reversed() : null; SIPViaHeader viaHeader = new SIPViaHeader(localSIPEndPoint, CallProperties.CreateBranchId()); byeRequest.Header.Vias.PushViaHeader(viaHeader); return byeRequest; }
/// <summary> /// Forwards a SIP request through the Proxy. This method differs from the standard Send in that irrespective of whether the Proxy is /// receiving and sending on different sockets only a single Via header will ever be allowed on the request. It is then up to the /// response processing logic to determine from which Proxy socket to forward the request and to add back on the Via header for the /// end agent. This method is only ever used for requests destined for EXTERNAL SIP end points. /// </summary> /// <param name="dstSIPEndPoint">The destination SIP socket to send the request to.</param> /// <param name="sipRequest">The SIP request to send.</param> /// default channel that matches the destination end point should be used.</param> public void SendTransparent(SIPEndPoint dstSIPEndPoint, SIPRequest sipRequest, IPAddress publicIPAddress) { try { if (!IsDestinationValid(sipRequest, dstSIPEndPoint)) { logger.Debug("SendTransparent failed destination check."); return; } // Determine the external SIP endpoint that the proxy will use to send this request. SIPEndPoint localSIPEndPoint = null; if (!sipRequest.Header.ProxySendFrom.IsNullOrBlank()) { SIPChannel proxyChannel = m_sipTransport.FindSIPChannel(SIPEndPoint.ParseSIPEndPoint(sipRequest.Header.ProxySendFrom)); localSIPEndPoint = (proxyChannel != null) ? proxyChannel.SIPChannelEndPoint : null; } localSIPEndPoint = localSIPEndPoint ?? m_sipTransport.GetDefaultSIPEndPoint(dstSIPEndPoint); // Create the single Via header for the outgoing request. It uses the passed in branchid which has been taken from the // request that's being forwarded. If this proxy is behind a NAT and the public IP is known that's also set on the Via. string proxyBranch = sipRequest.Header.Vias.PopTopViaHeader().Branch; sipRequest.Header.Vias = new SIPViaSet(); SIPViaHeader via = new SIPViaHeader(localSIPEndPoint, proxyBranch); if (publicIPAddress != null) { via.Host = publicIPAddress.ToString(); } sipRequest.Header.Vias.PushViaHeader(via); if (sipRequest.Method != SIPMethodsEnum.REGISTER) { AdjustContactHeader(sipRequest.Header, localSIPEndPoint, publicIPAddress); } // If dispatcher is being used record the transaction so responses are sent to the correct internal socket. if (m_dispatcher != null && sipRequest.Method != SIPMethodsEnum.REGISTER && sipRequest.Method != SIPMethodsEnum.ACK && sipRequest.Method != SIPMethodsEnum.NOTIFY) { //Log("RecordDispatch for " + sipRequest.Method + " " + sipRequest.URI.ToString() + " to " + sipRequest.RemoteSIPEndPoint.ToString() + "."); m_dispatcher.RecordDispatch(sipRequest, sipRequest.RemoteSIPEndPoint); } // Proxy sepecific headers that don't need to be seen by external UAs. sipRequest.Header.ProxyReceivedOn = null; sipRequest.Header.ProxyReceivedFrom = null; sipRequest.Header.ProxySendFrom = null; sipRequest.LocalSIPEndPoint = localSIPEndPoint; m_sipTransport.SendRequest(dstSIPEndPoint, sipRequest); } catch (Exception excp) { logger.Error("Exception SendTransparent. " + excp.Message); logger.Error(sipRequest.ToString()); throw; } }
//private void ByeFinalResponseReceived(IPEndPoint localEndPoint, IPEndPoint remoteEndPoint, SIPTransaction sipTransaction, SIPResponse sipResponse) //{ // Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.DialPlan, "BYE response " + sipResponse.StatusCode + " " + sipResponse.ReasonPhrase + ".", Owner)); //} private SIPRequest GetInviteRequest(SIPCallDescriptor sipCallDescriptor, string branchId, string callId, SIPEndPoint localSIPEndPoint, SIPRouteSet routeSet, string content, string contentType) { SIPRequest inviteRequest = new SIPRequest(SIPMethodsEnum.INVITE, sipCallDescriptor.Uri); inviteRequest.LocalSIPEndPoint = localSIPEndPoint; SIPHeader inviteHeader = new SIPHeader(sipCallDescriptor.GetFromHeader(), SIPToHeader.ParseToHeader(sipCallDescriptor.To), 1, callId); inviteHeader.From.FromTag = CallProperties.CreateNewTag(); // For incoming calls forwarded via the dial plan the username needs to go into the Contact header. inviteHeader.Contact = new List<SIPContactHeader>() { new SIPContactHeader(null, new SIPURI(inviteRequest.URI.Scheme, localSIPEndPoint)) }; inviteHeader.Contact[0].ContactURI.User = sipCallDescriptor.Username; inviteHeader.CSeqMethod = SIPMethodsEnum.INVITE; inviteHeader.UserAgent = m_userAgent; inviteHeader.Routes = routeSet; inviteRequest.Header = inviteHeader; if (!sipCallDescriptor.ProxySendFrom.IsNullOrBlank()) { inviteHeader.ProxySendFrom = sipCallDescriptor.ProxySendFrom; } SIPViaHeader viaHeader = new SIPViaHeader(localSIPEndPoint, branchId); inviteRequest.Header.Vias.PushViaHeader(viaHeader); inviteRequest.Body = content; inviteRequest.Header.ContentLength = (inviteRequest.Body != null) ? inviteRequest.Body.Length : 0; inviteRequest.Header.ContentType = contentType; // Add custom switchboard headers. if (CallDescriptor.SwitchboardHeaders != null) { inviteHeader.SwitchboardOriginalCallID = CallDescriptor.SwitchboardHeaders.SwitchboardOriginalCallID; //inviteHeader.SwitchboardCallerDescription = CallDescriptor.SwitchboardHeaders.SwitchboardCallerDescription; inviteHeader.SwitchboardLineName = CallDescriptor.SwitchboardHeaders.SwitchboardLineName; //inviteHeader.SwitchboardOwner = CallDescriptor.SwitchboardHeaders.SwitchboardOwner; //inviteHeader.SwitchboardOriginalFrom = CallDescriptor.SwitchboardHeaders.SwitchboardOriginalFrom; } // Add custom CRM headers. if (CallDescriptor.CRMHeaders != null) { inviteHeader.CRMPersonName = CallDescriptor.CRMHeaders.PersonName; inviteHeader.CRMCompanyName = CallDescriptor.CRMHeaders.CompanyName; inviteHeader.CRMPictureURL = CallDescriptor.CRMHeaders.AvatarURL; } try { if (sipCallDescriptor.CustomHeaders != null && sipCallDescriptor.CustomHeaders.Count > 0) { foreach (string customHeader in sipCallDescriptor.CustomHeaders) { if (customHeader.IsNullOrBlank()) { continue; } else if (customHeader.Trim().StartsWith(SIPHeaders.SIP_HEADER_USERAGENT)) { inviteRequest.Header.UserAgent = customHeader.Substring(customHeader.IndexOf(":") + 1).Trim(); } else { inviteRequest.Header.UnknownHeaders.Add(customHeader); } } } } catch (Exception excp) { logger.Error("Exception Parsing CustomHeader for GetInviteRequest. " + excp.Message + sipCallDescriptor.CustomHeaders); } return inviteRequest; }
private SIPRequest GetOptionsRequest(SIPURI serverURI, int cseq, IPEndPoint contact) { SIPRequest optionsRequest = new SIPRequest(SIPMethodsEnum.OPTIONS, serverURI); SIPFromHeader fromHeader = new SIPFromHeader(null, SIPURI.ParseSIPURI("sip:" + contact.ToString()), null); SIPToHeader toHeader = new SIPToHeader(null, serverURI, null); string callId = CallProperties.CreateNewCallId(); string branchId = CallProperties.CreateBranchId(); SIPHeader header = new SIPHeader(fromHeader, toHeader, cseq, callId); header.CSeqMethod = SIPMethodsEnum.OPTIONS; header.MaxForwards = 0; SIPViaHeader viaHeader = new SIPViaHeader(contact.Address.ToString(), contact.Port, branchId); header.Vias.PushViaHeader(viaHeader); optionsRequest.Header = header; return optionsRequest; }
private SIPRequest GetUpdateRequest(SIPRequest inviteRequest, CRMHeaders crmHeaders) { SIPRequest updateRequest = new SIPRequest(SIPMethodsEnum.UPDATE, inviteRequest.URI); updateRequest.LocalSIPEndPoint = inviteRequest.LocalSIPEndPoint; SIPHeader inviteHeader = inviteRequest.Header; SIPHeader updateHeader = new SIPHeader(inviteHeader.From, inviteHeader.To, inviteHeader.CSeq + 1, inviteHeader.CallId); inviteRequest.Header.CSeq++; updateRequest.Header = updateHeader; updateHeader.CSeqMethod = SIPMethodsEnum.UPDATE; updateHeader.Routes = inviteHeader.Routes; updateHeader.ProxySendFrom = inviteHeader.ProxySendFrom; SIPViaHeader viaHeader = new SIPViaHeader(inviteRequest.LocalSIPEndPoint, CallProperties.CreateBranchId()); updateHeader.Vias.PushViaHeader(viaHeader); // Add custom CRM headers. if (crmHeaders != null) { updateHeader.CRMPersonName = crmHeaders.PersonName; updateHeader.CRMCompanyName = crmHeaders.CompanyName; updateHeader.CRMPictureURL = crmHeaders.AvatarURL; } return updateRequest; }
/// <summary> /// In transaction ACK requests are for non-2xx responses, i.e. INVITE rejected and no dialogue being created. /// </summary> private SIPRequest GetInTransactionACKRequest(SIPResponse sipResponse, SIPURI ackURI, SIPEndPoint localSIPEndPoint) { SIPRequest ackRequest = new SIPRequest(SIPMethodsEnum.ACK, ackURI.ToString()); ackRequest.LocalSIPEndPoint = localSIPEndPoint; SIPHeader header = new SIPHeader(TransactionRequest.Header.From, sipResponse.Header.To, sipResponse.Header.CSeq, sipResponse.Header.CallId); header.CSeqMethod = SIPMethodsEnum.ACK; header.AuthenticationHeader = TransactionRequest.Header.AuthenticationHeader; header.Routes = base.TransactionRequest.Header.Routes; header.ProxySendFrom = base.TransactionRequest.Header.ProxySendFrom; ackRequest.Header = header; SIPViaHeader viaHeader = new SIPViaHeader(localSIPEndPoint, sipResponse.Header.Vias.TopViaHeader.Branch); ackRequest.Header.Vias.PushViaHeader(viaHeader); return ackRequest; }
private SIPRequest GetRegistrationRequest(SIPProvider sipProvider, SIPProviderBinding binding, SIPEndPoint localSIPEndPoint, int expiry, SIPEndPoint registrarEndPoint) { try { if (!binding.BindingSIPURI.Parameters.Has(m_regAgentContactId)) { binding.BindingSIPURI.Parameters.Set(m_regAgentContactId, Crypto.GetRandomString(6)); } string realm = binding.RegistrarRealm; SIPURI registerURI = SIPURI.ParseSIPURIRelaxed(realm); SIPURI regUserURI = SIPURI.ParseSIPURIRelaxed(sipProvider.ProviderUsername + "@" + realm); SIPFromHeader fromHeader = new SIPFromHeader(null, regUserURI, CallProperties.CreateNewTag()); SIPToHeader toHeader = new SIPToHeader(null, regUserURI, null); SIPContactHeader contactHeader = new SIPContactHeader(null, binding.BindingSIPURI); //contactHeader.Expires = binding.BindingExpiry; string callId = binding.Id.ToString(); int cseq = ++binding.CSeq; SIPRequest registerRequest = new SIPRequest(SIPMethodsEnum.REGISTER, registerURI); registerRequest.LocalSIPEndPoint = localSIPEndPoint; SIPHeader header = new SIPHeader(contactHeader, fromHeader, toHeader, cseq, callId); header.CSeqMethod = SIPMethodsEnum.REGISTER; header.UserAgent = m_userAgentString; header.Expires = binding.BindingExpiry; SIPViaHeader viaHeader = new SIPViaHeader(localSIPEndPoint, CallProperties.CreateBranchId()); header.Vias.PushViaHeader(viaHeader); SIPRoute registrarRoute = new SIPRoute(new SIPURI(binding.RegistrarServer.Scheme, registrarEndPoint), true); header.Routes.PushRoute(registrarRoute); if (sipProvider != null && !sipProvider.CustomHeaders.IsNullOrBlank()) { string[] customerHeadersList = sipProvider.CustomHeaders.Split(SIPProvider.CUSTOM_HEADERS_SEPARATOR); if (customerHeadersList != null && customerHeadersList.Length > 0) { foreach (string customHeader in customerHeadersList) { if (customHeader.IndexOf(':') == -1) { logger.Debug("Skipping custom header due to missing colon, " + customHeader + "."); continue; } else { string headerName = customHeader.Substring(0, customHeader.IndexOf(':')); if (headerName != null && Regex.Match(headerName.Trim(), "(Via|From|To|Contact|CSeq|Call-ID|Max-Forwards|Content)", RegexOptions.IgnoreCase).Success) { logger.Debug("Skipping custom header due to an non-permitted string in header name, " + customHeader + "."); continue; } else { if (headerName == SIPConstants.SIP_USERAGENT_STRING) { header.UserAgent = customHeader.Substring(customHeader.IndexOf(':') + 1); } else { header.UnknownHeaders.Add(customHeader.Trim()); } } } } } } registerRequest.Header = header; return registerRequest; } catch (Exception excp) { logger.Error("Exception GetRegistrationRequest. " + excp.Message); throw excp; } }
public SIPRequest GetRequest(SIPMethodsEnum method, SIPURI uri, SIPToHeader to, SIPEndPoint localSIPEndPoint) { if (localSIPEndPoint == null) { localSIPEndPoint = GetDefaultSIPEndPoint(); } SIPRequest request = new SIPRequest(method, uri); request.LocalSIPEndPoint = localSIPEndPoint; SIPContactHeader contactHeader = new SIPContactHeader(null, new SIPURI(SIPSchemesEnum.sip, localSIPEndPoint)); SIPFromHeader fromHeader = new SIPFromHeader(null, contactHeader.ContactURI, CallProperties.CreateNewTag()); SIPHeader header = new SIPHeader(contactHeader, fromHeader, to, 1, CallProperties.CreateNewCallId()); request.Header = header; header.CSeqMethod = method; header.Allow = ALLOWED_SIP_METHODS; SIPViaHeader viaHeader = new SIPViaHeader(localSIPEndPoint, CallProperties.CreateBranchId()); header.Vias.PushViaHeader(viaHeader); return request; }
public void MultipleForwardsWithLocalUnitTest() { 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("test", "provider1", "user", "password", SIPURI.ParseSIPURIRelaxed("sip.blueface.ie"), null, null, null, null, 3600, null, null, null, false, false); SIPProvider provider2 = new SIPProvider("test", "provider2", "user", "password", SIPURI.ParseSIPURIRelaxed("sip.blueface.ie"), null, null, null, null, 3600, null, null, null, false, false); providers.Add(provider); providers.Add(provider2); DialStringParser dialStringParser = new DialStringParser(null, "test", null, providers, (where) => { return null; }, (where, offset, count, orderby) => { return null; }, (host, wildcard) => { return null; }, null); Queue<List<SIPCallDescriptor>> callQueue = dialStringParser.ParseDialString(DialPlanContextsEnum.Script, inviteRequest, "local&1234@provider2", null, null, null, null, null); 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 == 2, "The first call leg should have had two switch calls."); Console.WriteLine("First destination uri=" + firstLeg[0].Uri.ToString()); Console.WriteLine("Second destination uri=" + firstLeg[1].Uri.ToString()); Console.WriteLine("---------------------------------"); }
/// <summary> /// Pushes a new Via header onto the top of the array. /// </summary> public void PushViaHeader(SIPViaHeader viaHeader) { m_viaHeaders.Insert(0, viaHeader); }
public void NoMatchingProviderUnitTest() { 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("test", "blueface", "test", "password", SIPURI.ParseSIPURIRelaxed("sip.blueface.ie"), null, null, null, null, 3600, null, null, null, false, false); providers.Add(provider); DialStringParser dialStringParser = new DialStringParser(null, "test", null, providers, delegate { return null; }, null, (host, wildcard) => { return null; }, null); Queue<List<SIPCallDescriptor>> callQueue = dialStringParser.ParseDialString(DialPlanContextsEnum.Script, inviteRequest, "303@noprovider", null, null, null, null, null); Assert.IsNotNull(callQueue, "The call list should be returned."); Assert.IsTrue(callQueue.Count == 1, "The call queue list should not 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 == DialStringParser.m_anonymousUsername, "The username for the first call leg was not correct."); Assert.IsTrue(firstLeg[0].Uri.ToString() == "sip:303@noprovider", "The destination URI for the first call leg was not correct."); Console.WriteLine("---------------------------------"); }
public void CreateNewViaHeaderTest() { Console.WriteLine("--> " + System.Reflection.MethodBase.GetCurrentMethod().Name); SIPViaHeader viaHeader = new SIPViaHeader("192.168.1.2", 5063, "abcdefgh"); Assert.IsTrue(viaHeader.Host == "192.168.1.2", "Incorrect Host for Via header."); Assert.IsTrue(viaHeader.Port == 5063, "Incorrect Port for Via header."); Assert.IsTrue(viaHeader.Branch == "abcdefgh", "Incorrect Branch for Via header."); Console.WriteLine("---------------------------------------------------"); }
private SIPRequest GetReferRequest(SIPEndPoint localSIPEndPoint, SIPURI referTo) { SIPRequest referRequest = new SIPRequest(SIPMethodsEnum.REFER, RemoteTarget); SIPFromHeader referFromHeader = SIPFromHeader.ParseFromHeader(LocalUserField.ToString()); SIPToHeader referToHeader = SIPToHeader.ParseToHeader(RemoteUserField.ToString()); int cseq = ++CSeq; SIPHeader referHeader = new SIPHeader(referFromHeader, referToHeader, cseq, CallId); referHeader.CSeqMethod = SIPMethodsEnum.REFER; referRequest.Header = referHeader; referRequest.Header.ReferTo = referTo.ToString(); referRequest.Header.Routes = RouteSet; referRequest.Header.ProxySendFrom = ProxySendFrom; SIPViaHeader viaHeader = new SIPViaHeader(localSIPEndPoint, CallProperties.CreateBranchId()); referRequest.Header.Vias.PushViaHeader(viaHeader); return referRequest; }