예제 #1
0
        /// <summary>
        /// Builds the REFER request to initiate an attended transfer on an established call.
        /// </summary>
        /// <param name="target">A target dialogue representing the Transferee.</param>
        /// <returns>A SIP REFER request.</returns>
        private SIPRequest GetReferRequest(SIPDialogue target)
        {
            SIPRequest referRequest = Dialogue.GetInDialogRequest(SIPMethodsEnum.REFER);
            SIPURI     targetUri    = target.RemoteTarget.CopyOf();

            referRequest.Header.Contact = new List <SIPContactHeader> {
                SIPContactHeader.GetDefaultSIPContactHeader()
            };

            SIPParameters replacesHeaders = new SIPParameters();

            if (target.Direction == SIPCallDirection.Out)
            {
                replacesHeaders.Set("Replaces", SIPEscape.SIPURIParameterEscape($"{target.CallId};to-tag={target.RemoteTag};from-tag={target.LocalTag}"));
                var from = new SIPUserField(target.LocalUserField.Name, target.LocalUserField.URI.CopyOf(), null);
                referRequest.Header.ReferredBy = from.ToString();
            }
            else
            {
                replacesHeaders.Set("Replaces", SIPEscape.SIPURIParameterEscape($"{target.CallId};to-tag={target.RemoteTag};from-tag={target.LocalTag}"));
                var from = new SIPUserField(target.RemoteUserField.Name, target.RemoteUserField.URI.CopyOf(), null);
                referRequest.Header.ReferredBy = from.ToString();
            }

            targetUri.Headers = replacesHeaders;
            var referTo = new SIPUserField(null, targetUri, null);

            referRequest.Header.ReferTo = referTo.ToString();

            return(referRequest);
        }
예제 #2
0
        public SIPResponse GetOkResponse(string contentType, string messageBody)
        {
            SIPResponse okResponse = new SIPResponse(SIPResponseStatusCodesEnum.Ok, null);

            okResponse.SetSendFromHints(TransactionRequest.LocalSIPEndPoint);

            SIPHeader requestHeader = TransactionRequest.Header;

            okResponse.Header = new SIPHeader(
                SIPContactHeader.GetDefaultSIPContactHeader(TransactionRequest.URI.Scheme),
                requestHeader.From, requestHeader.To,
                requestHeader.CSeq,
                requestHeader.CallId);
            okResponse.Header.To.ToTag     = m_localTag;
            okResponse.Header.CSeqMethod   = requestHeader.CSeqMethod;
            okResponse.Header.Vias         = requestHeader.Vias;
            okResponse.Header.Server       = SIPConstants.SipUserAgentVersionString;
            okResponse.Header.MaxForwards  = Int32.MinValue;
            okResponse.Header.RecordRoutes = requestHeader.RecordRoutes;
            okResponse.Header.Supported    = SIPExtensionHeaders.REPLACES + ", " + SIPExtensionHeaders.NO_REFER_SUB
                                             + ((PrackSupported == true) ? ", " + SIPExtensionHeaders.PRACK : "");

            okResponse.Body = messageBody;
            okResponse.Header.ContentType   = contentType;
            okResponse.Header.ContentLength = (messageBody != null) ? messageBody.Length : 0;

            return(okResponse);
        }
예제 #3
0
        public SIPResponse GetOkResponse(string contentType, string messageBody)
        {
            try
            {
                SIPResponse okResponse = new SIPResponse(SIPResponseStatusCodesEnum.Ok, null);
                okResponse.SetSendFromHints(TransactionRequest.LocalSIPEndPoint);

                SIPHeader requestHeader = TransactionRequest.Header;
                okResponse.Header              = new SIPHeader(SIPContactHeader.GetDefaultSIPContactHeader(), requestHeader.From, requestHeader.To, requestHeader.CSeq, requestHeader.CallId);
                okResponse.Header.To.ToTag     = m_localTag;
                okResponse.Header.CSeqMethod   = requestHeader.CSeqMethod;
                okResponse.Header.Vias         = requestHeader.Vias;
                okResponse.Header.Server       = m_sipServerAgent;
                okResponse.Header.MaxForwards  = Int32.MinValue;
                okResponse.Header.RecordRoutes = requestHeader.RecordRoutes;
                okResponse.Header.Supported    = (PrackSupported == true) ? SIPExtensionHeaders.PRACK : null;

                okResponse.Body = messageBody;
                okResponse.Header.ContentType   = contentType;
                okResponse.Header.ContentLength = (messageBody != null) ? messageBody.Length : 0;

                return(okResponse);
            }
            catch (Exception excp)
            {
                logger.LogError("Exception GetOkResponse. " + excp.Message);
                throw excp;
            }
        }
예제 #4
0
        /// <summary>
        /// Builds the REFER request to transfer an established call.
        /// </summary>
        /// <param name="sipDialogue">A SIP dialogue object representing the established call.</param>
        /// <param name="referToUri">The SIP URI to transfer the call to.</param>
        /// <returns>A SIP REFER request.</returns>
        private static SIPRequest GetReferRequest(SIPClientUserAgent uac, SIPURI referToUri)
        {
            SIPDialogue sipDialogue = uac.SIPDialogue;

            SIPRequest referRequest = new SIPRequest(SIPMethodsEnum.REFER, sipDialogue.RemoteTarget);

            referRequest.SetSendFromHints(uac.ServerTransaction.TransactionRequest.LocalSIPEndPoint);

            SIPFromHeader referFromHeader = SIPFromHeader.ParseFromHeader(sipDialogue.LocalUserField.ToString());
            SIPToHeader   referToHeader   = SIPToHeader.ParseToHeader(sipDialogue.RemoteUserField.ToString());
            int           cseq            = sipDialogue.CSeq + 1;

            sipDialogue.CSeq++;

            SIPHeader referHeader = new SIPHeader(referFromHeader, referToHeader, cseq, sipDialogue.CallId);

            referHeader.CSeqMethod            = SIPMethodsEnum.REFER;
            referRequest.Header               = referHeader;
            referRequest.Header.Routes        = sipDialogue.RouteSet;
            referRequest.Header.ProxySendFrom = sipDialogue.ProxySendFrom;
            referRequest.Header.Vias.PushViaHeader(SIPViaHeader.GetDefaultSIPViaHeader());
            referRequest.Header.ReferTo = referToUri.ToString();
            referRequest.Header.Contact = new List <SIPContactHeader>()
            {
                SIPContactHeader.GetDefaultSIPContactHeader()
            };

            return(referRequest);
        }
        private SIPRequest GetDummyINVITERequest(SIPURI dummyURI)
        {
            string     dummyFrom     = "<sip:[email protected]>";
            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      = new List <SIPContactHeader> {
                SIPContactHeader.GetDefaultSIPContactHeader()
            };
            inviteHeader.CSeqMethod = SIPMethodsEnum.INVITE;
            inviteHeader.UserAgent  = "unittest";
            inviteRequest.Header    = inviteHeader;

            SIPViaHeader viaHeader = SIPViaHeader.GetDefaultSIPViaHeader();

            inviteRequest.Header.Vias.PushViaHeader(viaHeader);

            inviteRequest.Body = "dummy";
            inviteRequest.Header.ContentLength = inviteRequest.Body.Length;
            inviteRequest.Header.ContentType   = "application/sdp";

            return(inviteRequest);
        }
예제 #6
0
        /// <summary>
        /// Builds the REFER request to initiate a blind transfer on an established call.
        /// </summary>
        /// <param name="referToUri">The SIP URI to transfer the call to.</param>
        /// <returns>A SIP REFER request.</returns>
        private SIPRequest GetReferRequest(SIPURI referToUri)
        {
            SIPRequest referRequest = Dialogue.GetInDialogRequest(SIPMethodsEnum.REFER);

            referRequest.Header.ReferTo   = referToUri.ToString();
            referRequest.Header.Supported = SIPExtensionHeaders.NO_REFER_SUB;
            referRequest.Header.Contact   = new List <SIPContactHeader> {
                SIPContactHeader.GetDefaultSIPContactHeader()
            };
            return(referRequest);
        }
예제 #7
0
        /// <summary>
        /// Sends a re-INVITE request to the remote call party with the supplied SDP.
        /// </summary>
        private void SendReInviteRequest(SDP sdp)
        {
            if (Dialogue == null)
            {
                logger.LogWarning("No dialog available, re-INVITE request cannot be sent.");
            }
            else
            {
                Dialogue.SDP = sdp.ToString();

                var reinviteRequest = Dialogue.GetInDialogRequest(SIPMethodsEnum.INVITE);
                reinviteRequest.Header.UserAgent   = m_userAgent;
                reinviteRequest.Header.ContentType = m_sdpContentType;
                reinviteRequest.Body             = sdp.ToString();
                reinviteRequest.Header.Supported = SIPExtensionHeaders.PRACK;

                if (m_uac != null)
                {
                    reinviteRequest.Header.Contact = m_uac.ServerTransaction.TransactionRequest.Header.Contact;
                    reinviteRequest.SetSendFromHints(m_uac.ServerTransaction.TransactionRequest.LocalSIPEndPoint);
                }
                else if (m_uas != null)
                {
                    reinviteRequest.Header.Contact = m_uas.ClientTransaction.TransactionFinalResponse.Header.Contact;
                    reinviteRequest.SetSendFromHints(m_uas.ClientTransaction.TransactionFinalResponse.LocalSIPEndPoint);
                }
                else
                {
                    reinviteRequest.Header.Contact = new List <SIPContactHeader>()
                    {
                        SIPContactHeader.GetDefaultSIPContactHeader()
                    };
                }

                UACInviteTransaction reinviteTransaction = new UACInviteTransaction(m_transport, reinviteRequest, m_outboundProxy);
                reinviteTransaction.SendInviteRequest();
                reinviteTransaction.UACInviteTransactionFinalResponseReceived += ReinviteRequestFinalResponseReceived;
            }
        }
예제 #8
0
        /// <summary>
        /// Initiates a SUBSCRIBE request to a notification server.
        /// </summary>
        /// <param name="subscribeURI">The SIP user that dialog notifications are being subscribed to.</param>
        public void Subscribe(SIPURI subscribeURI, int expiry, SIPEventPackagesEnum sipEventPackage, string subscribeCallID, SIPURI contactURI)
        {
            try
            {
                if (m_attempts >= MAX_SUBSCRIBE_ATTEMPTS)
                {
                    logger.LogWarning($"Subscription to {subscribeURI} reached the maximum number of allowed attempts without a failure condition.");
                    m_subscribed = false;
                    SubscriptionFailed?.Invoke(subscribeURI, SIPResponseStatusCodesEnum.InternalServerError, "Subscription reached the maximum number of allowed attempts.");
                    m_waitForSubscribeResponse.Set();
                }
                else
                {
                    m_attempts++;
                    m_localCSeq++;

                    SIPRequest subscribeRequest = SIPRequest.GetRequest(
                        SIPMethodsEnum.SUBSCRIBE,
                        m_resourceURI,
                        new SIPToHeader(null, subscribeURI, m_subscriptionToTag),
                        new SIPFromHeader(null, new SIPURI(m_authUsername, m_authDomain, null, m_resourceURI.Scheme, SIPProtocolsEnum.udp), m_subscriptionFromTag));


                    if (contactURI != null)
                    {
                        subscribeRequest.Header.Contact = new List <SIPContactHeader>()
                        {
                            new SIPContactHeader(null, contactURI)
                        };
                    }
                    else
                    {
                        subscribeRequest.Header.Contact = new List <SIPContactHeader>()
                        {
                            SIPContactHeader.GetDefaultSIPContactHeader(subscribeRequest.URI.Scheme)
                        };
                    }

                    subscribeRequest.Header.CSeq    = m_localCSeq;
                    subscribeRequest.Header.Expires = expiry;
                    subscribeRequest.Header.Event   = SIPEventPackageType.GetEventHeader(sipEventPackage);
                    subscribeRequest.Header.CallId  = subscribeCallID;

                    if (!m_filter.IsNullOrBlank())
                    {
                        subscribeRequest.Body = m_filter;
                        subscribeRequest.Header.ContentLength = m_filter.Length;
                        subscribeRequest.Header.ContentType   = m_filterTextType;
                    }

                    SIPNonInviteTransaction subscribeTransaction = new SIPNonInviteTransaction(m_sipTransport, subscribeRequest, m_outboundProxy);
                    subscribeTransaction.NonInviteTransactionFinalResponseReceived += SubscribeTransactionFinalResponseReceived;
                    subscribeTransaction.NonInviteTransactionFailed += SubscribeTransactionFailed;

                    LastSubscribeAttempt = DateTime.Now;

                    subscribeTransaction.SendRequest();
                }
            }
            catch (Exception excp)
            {
                logger.LogError("Exception SIPNotifierClient Subscribe. " + excp.Message);
                SubscriptionFailed?.Invoke(m_resourceURI, SIPResponseStatusCodesEnum.InternalServerError, "Exception Subscribing. " + excp.Message);
                m_waitForSubscribeResponse.Set();
            }
        }
예제 #9
0
        private SIPRequest GetInviteRequest(SIPCallDescriptor sipCallDescriptor, string branchId, string callId, SIPRouteSet routeSet, string content, string contentType)
        {
            SIPRequest inviteRequest = new SIPRequest(SIPMethodsEnum.INVITE, sipCallDescriptor.Uri);

            SIPHeader inviteHeader = new SIPHeader(sipCallDescriptor.GetFromHeader(), SIPToHeader.ParseToHeader(sipCallDescriptor.To), 1, callId);

            inviteHeader.From.FromTag = CallProperties.CreateNewTag();

            inviteHeader.Contact = new List <SIPContactHeader>()
            {
                SIPContactHeader.GetDefaultSIPContactHeader(inviteRequest.URI.Scheme)
            };
            inviteHeader.Contact[0].ContactURI.User = sipCallDescriptor.Username;
            inviteHeader.CSeqMethod = SIPMethodsEnum.INVITE;
            inviteHeader.UserAgent  = SIPConstants.SipUserAgentVersionString;
            inviteHeader.Routes     = routeSet;
            inviteHeader.Supported  = SIPExtensionHeaders.REPLACES + ", " + SIPExtensionHeaders.NO_REFER_SUB
                                      + ((PrackSupported == true) ? ", " + SIPExtensionHeaders.PRACK : "");

            inviteRequest.Header = inviteHeader;

            if (!sipCallDescriptor.ProxySendFrom.IsNullOrBlank())
            {
                inviteHeader.ProxySendFrom = sipCallDescriptor.ProxySendFrom;
            }

            SIPViaHeader viaHeader = new SIPViaHeader(new IPEndPoint(IPAddress.Any, 0), branchId);

            inviteRequest.Header.Vias.PushViaHeader(viaHeader);

            inviteRequest.Body = content;
            inviteRequest.Header.ContentLength = (inviteRequest.Body != null) ? inviteRequest.Body.Length : 0;
            inviteRequest.Header.ContentType   = contentType;

            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 if (customHeader.Trim().StartsWith(SIPHeaders.SIP_HEADER_TO + ":"))
                        {
                            var customToHeader = SIPUserField.ParseSIPUserField(customHeader.Substring(customHeader.IndexOf(":") + 1).Trim());
                            if (customToHeader != null)
                            {
                                inviteRequest.Header.To.ToUserField = customToHeader;
                            }
                        }
                        else
                        {
                            inviteRequest.Header.UnknownHeaders.Add(customHeader);
                        }
                    }
                }
            }
            catch (Exception excp)
            {
                logger.LogError("Exception Parsing CustomHeader for GetInviteRequest. " + excp.Message + sipCallDescriptor.CustomHeaders);
            }

            if (AdjustInvite != null)
            {
                inviteRequest = AdjustInvite(inviteRequest);
            }

            return(inviteRequest);
        }
예제 #10
0
        /// <summary>
        /// Because this is a server user agent the SIP transport must start listening for client user agents.
        /// </summary>
        private async Task OnRequest(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest)
        {
            try
            {
                var banResult = _sipFail2Ban.IsBanned(remoteEndPoint);
                if (banResult == BanReasonsEnum.None)
                {
                    if (sipRequest.Header.From != null &&
                        sipRequest.Header.From.FromTag != null &&
                        sipRequest.Header.To != null &&
                        sipRequest.Header.To.ToTag != null)
                    {
                        _sipCallManager.ProcessInDialogueRequest(localSIPEndPoint, remoteEndPoint, sipRequest);
                    }
                    else
                    {
                        switch (sipRequest.Method)
                        {
                        case SIPMethodsEnum.BYE:
                        case SIPMethodsEnum.CANCEL:
                            // BYE's and CANCEL's should always have dialog fields set.
                            SIPResponse badResponse = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.BadRequest, null);
                            await _sipTransport.SendResponseAsync(badResponse);

                            break;

                        case SIPMethodsEnum.INVITE:
                            if (!await WasRejected(sipRequest))
                            {
                                _logger.LogInformation($"Incoming call request: {localSIPEndPoint}<-{remoteEndPoint} {sipRequest.URI}.");
                                _b2bUserAgentCore.AddInviteRequest(sipRequest);
                            }
                            break;

                        case SIPMethodsEnum.OPTIONS:
                            SIPResponse optionsResponse = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null);
                            optionsResponse.Header.Contact = new List <SIPContactHeader> {
                                SIPContactHeader.GetDefaultSIPContactHeader(sipRequest.URI.Scheme)
                            };
                            optionsResponse.Header.Server = SIPConstants.SIP_USERAGENT_STRING;
                            await _sipTransport.SendResponseAsync(optionsResponse);

                            break;

                        case SIPMethodsEnum.REGISTER:
                            if (!await WasRejected(sipRequest))
                            {
                                _registrarCore.AddRegisterRequest(localSIPEndPoint, remoteEndPoint, sipRequest);
                            }
                            break;

                        case SIPMethodsEnum.SUBSCRIBE:
                            if (!await WasRejected(sipRequest))
                            {
                                _subscriberCore.AddSubscribeRequest(localSIPEndPoint, remoteEndPoint, sipRequest);
                            }
                            break;

                        default:
                            var notAllowedResp = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.MethodNotAllowed, null);
                            await _sipTransport.SendResponseAsync(notAllowedResp);

                            break;
                        }
                    }
                }
                else
                {
                    _logger.LogWarning($"Ban list hit for {remoteEndPoint} and {banResult} dropped request {sipRequest.StatusLine}, user agent {sipRequest.Header.UserAgent}.");
                }
            }
            catch (Exception reqExcp)
            {
                _logger.LogWarning($"Exception handling {sipRequest.Method}. {reqExcp.Message}");
            }
        }