Beispiel #1
0
        /// <summary>
        /// Create a new response.
        /// </summary>
        /// <param name="code">Response status code</param>
        /// <param name="reason">Reason to why the status code was used.</param>
        /// <returns>A Created response.</returns>
        /// <exception cref="InvalidOperationException">Provisional responses is only valid for INVITE method.</exception>
        public IResponse CreateResponse(StatusCode code, string reason)
        {
            if (StatusCodeHelper.Is1xx(code) && Method != "INVITE")
            {
                throw new InvalidOperationException("Provisional responses is only valid for INVITE method.");
            }

            var response = new Response(SipVersion, code, reason);

            // When a 100 (Trying) response is generated, any Timestamp header field
            // present in the request MUST be copied into this 100 (Trying)
            // response.  If there is a delay in generating the response, the UAS
            // SHOULD add a delay value into the Timestamp value in the response.
            // This value MUST contain the difference between the time of sending of
            // the response and receipt of the request, measured in seconds.
            if (StatusCodeHelper.Is1xx(code) && Headers["Timestamp"] != null)
            {
                response.Headers.Add("Timestamp", Headers["Timestamp"]);
            }

            // The From field of the response MUST equal the From header field of
            // the request.  The Call-ID header field of the response MUST equal the
            // Call-ID header field of the request.  The CSeq header field of the
            // response MUST equal the CSeq field of the request.  The Via header
            // field values in the response MUST equal the Via header field values
            // in the request and MUST maintain the same ordering.
            response.From   = From;
            response.CallId = CallId;
            response.CSeq   = CSeq;
            response.Via    = (Via)Via.Clone();


            // If a request contained a To tag in the request, the To header field
            // in the response MUST equal that of the request.  However, if the To
            // header field in the request did not contain a tag, the URI in the To
            // header field in the response MUST equal the URI in the To header
            // field; additionally, the UAS MUST add a tag to the To header field in
            // the response (with the exception of the 100 (Trying) response, in
            // which a tag MAY be present).  This serves to identify the UAS that is
            // responding, possibly resulting in a component of a dialog ID.  The
            // same tag MUST be used for all responses to that request, both final
            // and provisional (again excepting the 100 (Trying)).  Procedures for
            // the generation of tags are defined in Section 19.3.
            response.To = To;
            if (To.Parameters["tag"] != null)
            {
                // RFC3261 Section 17.2.1:
                // The 100 (Trying) response is constructed
                // according to the procedures in Section 8.2.6, except that the
                // insertion of tags in the To header field of the response (when none
                // was present in the request) is downgraded from MAY to SHOULD NOT.
                if (!StatusCodeHelper.Is1xx(code))
                {
                    response.To.Parameters.Add("tag", Guid.NewGuid().ToString().Replace("-", string.Empty));
                }
            }

            return(response);
        }