/// <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); }