Пример #1
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 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;

                header.Vias.PushViaHeader(SIPViaHeader.GetDefaultSIPViaHeader());

                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.LogError("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.LogError("Exception SIPNonInviteClientUserAgent GetRequest. " + excp.Message);
                throw;
            }
        }
Пример #3
0
        /// <summary>
        /// New transaction ACK requests are for 2xx responses, i.e. INVITE accepted and dialogue being created.
        /// </summary>
        /// <remarks>
        /// 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 GetNewTransactionAcknowledgeRequest(SIPMethodsEnum method, SIPResponse sipResponse,
                                                               SIPURI ackURI)
        {
            SIPRequest ackRequest = new SIPRequest(method, ackURI.ToString());

            ackRequest.SetSendFromHints(sipResponse.LocalSIPEndPoint);

            SIPHeader header = new SIPHeader(TransactionRequest.Header.From, sipResponse.Header.To,
                                             sipResponse.Header.CSeq, sipResponse.Header.CallId);

            header.CSeqMethod           = method;
            header.AuthenticationHeader = TransactionRequest.Header.AuthenticationHeader;
            header.ProxySendFrom        = base.TransactionRequest.Header.ProxySendFrom;

            // If the UAS supplies a desired Record-Route list use that first. Otherwise fall back to any Route list used in the original transaction.
            if (sipResponse.Header.RecordRoutes != null)
            {
                header.Routes = sipResponse.Header.RecordRoutes.Reversed();
            }
            else if (base.TransactionRequest.Header.Routes != null)
            {
                header.Routes = base.TransactionRequest.Header.Routes;
            }

            ackRequest.Header = header;
            ackRequest.Header.Vias.PushViaHeader(SIPViaHeader.GetDefaultSIPViaHeader());

            return(ackRequest);
        }
        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);
        }
Пример #5
0
        /// <summary>
        /// Builds a very basic SIP request. In most cases additional headers will need to be added in order for it to be useful.
        /// When this method is called the channel used for sending the request has not been decided. The headers below depend on
        /// the sending channel. By setting them to "0.0.0.0:0" the send request methods will substitute in the appropriate value
        /// at send time:
        /// - Top Via header.
        /// - From header.
        /// - Contact header.
        /// </summary>
        /// <param name="method">The method for the SIP request.</param>
        /// <param name="uri">The destination URI for the request.</param>
        /// <param name="to">The To header for the request.</param>
        /// <param name="from">The From header for the request.</param>
        /// <returns>A SIP request object.</returns>
        public static SIPRequest GetRequest(SIPMethodsEnum method, SIPURI uri, SIPToHeader to, SIPFromHeader from)
        {
            SIPRequest request = new SIPRequest(method, uri);

            SIPHeader header = new SIPHeader(from, to, 1, CallProperties.CreateNewCallId());

            request.Header    = header;
            header.CSeqMethod = method;
            header.Allow      = m_allowedSIPMethods;
            header.Vias.PushViaHeader(SIPViaHeader.GetDefaultSIPViaHeader());

            return(request);
        }
        private SIPRequest GetByeRequest()
        {
            SIPRequest    byeRequest    = new SIPRequest(SIPMethodsEnum.BYE, SIPDialogue.RemoteTarget);
            SIPFromHeader byeFromHeader = SIPFromHeader.ParseFromHeader(SIPDialogue.LocalUserField.ToString());
            SIPToHeader   byeToHeader   = SIPToHeader.ParseToHeader(SIPDialogue.RemoteUserField.ToString());
            int           cseq          = SIPDialogue.CSeq + 1;

            SIPHeader byeHeader = new SIPHeader(byeFromHeader, byeToHeader, cseq, SIPDialogue.CallId);

            byeHeader.CSeqMethod            = SIPMethodsEnum.BYE;
            byeRequest.Header               = byeHeader;
            byeRequest.Header.Routes        = SIPDialogue.RouteSet;
            byeRequest.Header.ProxySendFrom = SIPDialogue.ProxySendFrom;
            byeRequest.Header.Vias.PushViaHeader(SIPViaHeader.GetDefaultSIPViaHeader());

            return(byeRequest);
        }
Пример #7
0
        /// <summary>
        /// In transaction ACK requests are for non-2xx responses, i.e. INVITE rejected and no 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.
        /// </remarks>
        private SIPRequest GetInTransactionACKRequest(SIPResponse sipResponse, SIPURI ackURI)
        {
            SIPRequest ackRequest = new SIPRequest(SIPMethodsEnum.ACK, ackURI.ToString());

            ackRequest.SetSendFromHints(sipResponse.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;
            ackRequest.Header.Vias.PushViaHeader(SIPViaHeader.GetDefaultSIPViaHeader());

            return(ackRequest);
        }
Пример #8
0
        /// <summary>
        /// Builds a basic SIP request with the header fields set to correctly identify it as an
        /// in dialog request. Calling this method also increments the dialog's local CSeq counter.
        /// This is safe to do even if the request does not end up being sent.
        /// </summary>
        /// <param name="method">The method of the SIP request to create.</param>
        /// <returns>An in dialog SIP request.</returns>
        public SIPRequest GetInDialogRequest(SIPMethodsEnum method)
        {
            CSeq++;

            SIPRequest    inDialogRequest = new SIPRequest(method, RemoteTarget);
            SIPFromHeader fromHeader      = SIPFromHeader.ParseFromHeader(LocalUserField.ToString());
            SIPToHeader   toHeader        = SIPToHeader.ParseToHeader(RemoteUserField.ToString());
            int           cseq            = CSeq;

            SIPHeader header = new SIPHeader(fromHeader, toHeader, cseq, CallId);

            header.CSeqMethod                    = method;
            inDialogRequest.Header               = header;
            inDialogRequest.Header.Routes        = RouteSet;
            inDialogRequest.Header.ProxySendFrom = ProxySendFrom;
            inDialogRequest.Header.Vias.PushViaHeader(SIPViaHeader.GetDefaultSIPViaHeader());

            return(inDialogRequest);
        }
Пример #9
0
        private SIPRequest GetByeRequest(SIPResponse inviteResponse, SIPURI byeURI)
        {
            SIPRequest byeRequest = new SIPRequest(SIPMethodsEnum.BYE, byeURI);

            byeRequest.SetSendFromHints(inviteResponse.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;
            byeRequest.Header.Vias.PushViaHeader(SIPViaHeader.GetDefaultSIPViaHeader(null));

            return(byeRequest);
        }